1 /******************************************************************************* 2 * Copyright (c) 2000, 2003 IBM Corporation and others. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Common Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/cpl-v10.html 7 * 8 * Contributors: 9 * IBM Corporation - initial API and implementation 10 *******************************************************************************/ 11 package net.sourceforge.phpdt.internal.core; 12 13 import java.util.ArrayList; 14 import java.util.Map; 15 16 import net.sourceforge.phpdt.core.IJavaElement; 17 import net.sourceforge.phpdt.core.IJavaModelStatusConstants; 18 import net.sourceforge.phpdt.core.IPackageFragment; 19 import net.sourceforge.phpdt.core.IPackageFragmentRoot; 20 import net.sourceforge.phpdt.core.JavaCore; 21 import net.sourceforge.phpdt.core.JavaModelException; 22 import net.sourceforge.phpdt.core.WorkingCopyOwner; 23 import net.sourceforge.phpdt.core.compiler.CharOperation; 24 import net.sourceforge.phpdt.internal.core.util.MementoTokenizer; 25 import net.sourceforge.phpdt.internal.core.util.Util; 26 27 import org.eclipse.core.resources.IContainer; 28 import org.eclipse.core.resources.IFolder; 29 import org.eclipse.core.resources.IResource; 30 import org.eclipse.core.resources.ResourcesPlugin; 31 import org.eclipse.core.runtime.CoreException; 32 import org.eclipse.core.runtime.IPath; 33 import org.eclipse.core.runtime.IProgressMonitor; 34 import org.eclipse.core.runtime.QualifiedName; 35 36 /** 37 * @see IPackageFragmentRoot 38 */ 39 public class PackageFragmentRoot extends Openable implements 40 IPackageFragmentRoot { 41 42 /** 43 * The delimiter between the source path and root path in the attachment 44 * server property. 45 */ 46 protected final static char ATTACHMENT_PROPERTY_DELIMITER = '*'; 47 48 /* 49 * No source attachment property 50 */ 51 protected final static String NO_SOURCE_ATTACHMENT = ""; //$NON-NLS-1$ 52 53 /* 54 * No source mapper singleton 55 */ 56 // protected final static SourceMapper NO_SOURCE_MAPPER = new 57 // SourceMapper(); 58 /** 59 * The resource associated with this root. (an IResource or a java.io.File 60 * (for external jar only)) 61 */ 62 protected Object resource; 63 64 /** 65 * Constructs a package fragment root which is the root of the java package 66 * directory hierarchy. 67 */ PackageFragmentRoot(IResource resource, JavaProject project, String name)68 protected PackageFragmentRoot(IResource resource, JavaProject project, 69 String name) { 70 super(project, name); 71 this.resource = resource; 72 } 73 74 /** 75 * @see Openable 76 */ buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource)77 protected boolean buildStructure(OpenableElementInfo info, 78 IProgressMonitor pm, Map newElements, IResource underlyingResource) 79 throws JavaModelException { 80 81 // check whether this pkg fragment root can be opened 82 if (!resourceExists()) { // || !isOnClasspath()) { 83 throw newNotPresentException(); 84 } 85 86 ((PackageFragmentRootInfo) info) 87 .setRootKind(determineKind(underlyingResource)); 88 return computeChildren(info, newElements); 89 } 90 91 /** 92 * Returns the root's kind - K_SOURCE or K_BINARY, defaults to K_SOURCE if 93 * it is not on the classpath. 94 * 95 * @exception NotPresentException 96 * if the project and root do not exist. 97 */ determineKind(IResource underlyingResource)98 protected int determineKind(IResource underlyingResource) 99 throws JavaModelException { 100 // IClasspathEntry[] entries= 101 // ((JavaProject)getJavaProject()).getExpandedClasspath(true); 102 // for (int i= 0; i < entries.length; i++) { 103 // IClasspathEntry entry= entries[i]; 104 // if (entry.getPath().equals(underlyingResource.getFullPath())) { 105 // return entry.getContentKind(); 106 // } 107 // } 108 return IPackageFragmentRoot.K_SOURCE; 109 } 110 111 /** 112 * Compute the package fragment children of this package fragment root. 113 * 114 * @exception JavaModelException 115 * The resource associated with this package fragment root 116 * does not exist 117 */ computeChildren(OpenableElementInfo info, Map newElements)118 protected boolean computeChildren(OpenableElementInfo info, Map newElements) 119 throws JavaModelException { 120 // Note the children are not opened (so not added to newElements) for a 121 // regular package fragment root 122 // Howver they are opened for a Jar package fragment root (see 123 // JarPackageFragmentRoot#computeChildren) 124 try { 125 // the underlying resource may be a folder or a project (in the case 126 // that the project folder 127 // is actually the package fragment root) 128 IResource underlyingResource = getResource(); 129 if (underlyingResource.getType() == IResource.FOLDER 130 || underlyingResource.getType() == IResource.PROJECT) { 131 ArrayList vChildren = new ArrayList(5); 132 IContainer rootFolder = (IContainer) underlyingResource; 133 // char[][] inclusionPatterns = fullInclusionPatternChars(); 134 char[][] exclusionPatterns = fullExclusionPatternChars(); 135 computeFolderChildren(rootFolder, !Util.isExcluded(rootFolder, 136 exclusionPatterns), "", vChildren, exclusionPatterns); //$NON-NLS-1$ 137 138 IJavaElement[] children = new IJavaElement[vChildren.size()]; 139 vChildren.toArray(children); 140 info.setChildren(children); 141 } 142 } catch (JavaModelException e) { 143 // problem resolving children; structure remains unknown 144 info.setChildren(new IJavaElement[] {}); 145 throw e; 146 } 147 return true; 148 } 149 150 /** 151 * Starting at this folder, create package fragments and add the fragments 152 * that are not exclused to the collection of children. 153 * 154 * @exception JavaModelException 155 * The resource associated with this package fragment does 156 * not exist 157 */ computeFolderChildren(IContainer folder, boolean isIncluded, String prefix, ArrayList vChildren, char[][] exclusionPatterns)158 protected void computeFolderChildren(IContainer folder, boolean isIncluded, 159 String prefix, ArrayList vChildren, char[][] exclusionPatterns) 160 throws JavaModelException { 161 // , char[][] inclusionPatterns, char[][] exclusionPatterns) throws 162 // JavaModelException { 163 164 if (isIncluded) { 165 IPackageFragment pkg = getPackageFragment(prefix); 166 vChildren.add(pkg); 167 } 168 try { 169 JavaProject javaProject = (JavaProject) getJavaProject(); 170 IResource[] members = folder.members(); 171 boolean hasIncluded = isIncluded; 172 for (int i = 0, max = members.length; i < max; i++) { 173 IResource member = members[i]; 174 String memberName = member.getName(); 175 176 switch (member.getType()) { 177 178 case IResource.FOLDER: 179 if (Util.isValidFolderNameForPackage(memberName)) { 180 boolean isMemberIncluded = !Util.isExcluded(member, 181 exclusionPatterns); 182 // keep looking inside as long as included already, or 183 // may have child included due to inclusion patterns 184 // if (isMemberIncluded || inclusionPatterns != null) { 185 // // eliminate binary output only if nested inside 186 // direct subfolders 187 // if (javaProject.contains(member)) { 188 // String newPrefix; 189 // if (prefix.length() == 0) { 190 // newPrefix = memberName; 191 // } else { 192 // newPrefix = prefix + "." + memberName; //$NON-NLS-1$ 193 // } 194 // computeFolderChildren((IFolder) member, 195 // isMemberIncluded, newPrefix, vChildren, 196 // inclusionPatterns, 197 // exclusionPatterns); 198 // } 199 // } 200 } 201 break; 202 case IResource.FILE: 203 // inclusion filter may only include files, in which case we 204 // still want to include the immediate parent package 205 // (lazily) 206 if (!hasIncluded 207 && Util.isValidCompilationUnitName(memberName) 208 && !Util.isExcluded(member, exclusionPatterns)) { 209 hasIncluded = true; 210 IPackageFragment pkg = getPackageFragment(prefix); 211 vChildren.add(pkg); 212 } 213 break; 214 } 215 } 216 } catch (IllegalArgumentException e) { 217 throw new JavaModelException(e, 218 IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST); // could 219 // be 220 // thrown 221 // by 222 // ElementTree 223 // when 224 // path 225 // is not found 226 } catch (CoreException e) { 227 throw new JavaModelException(e); 228 } 229 } 230 231 /** 232 * @see IPackageFragmentRoot 233 */ 234 // public void attachSource(IPath sourcePath, IPath rootPath, 235 // IProgressMonitor monitor) throws JavaModelException { 236 // try { 237 // verifyAttachSource(sourcePath); 238 // if (monitor != null) { 239 // monitor.beginTask(ProjectPrefUtil.bind("element.attachingSource"), 2); 240 // //$NON-NLS-1$ 241 // } 242 // SourceMapper oldMapper= getSourceMapper(); 243 // IWorkspace workspace = ResourcesPlugin.getWorkspace(); 244 // boolean rootNeedsToBeClosed= false; 245 // 246 // if (sourcePath == null) { 247 // //source being detached 248 // rootNeedsToBeClosed= true; 249 // setSourceMapper(null); 250 // /* Disable deltas (see 1GDTUSD) 251 // // fire a delta to notify the UI about the source detachement. 252 // JavaModelManager manager = (JavaModelManager) 253 // JavaModelManager.getJavaModelManager(); 254 // JavaModel model = (JavaModel) getJavaModel(); 255 // JavaElementDelta attachedSourceDelta = new JavaElementDelta(model); 256 // attachedSourceDelta .sourceDetached(this); // this would be a 257 // PackageFragmentRoot 258 // manager.registerResourceDelta(attachedSourceDelta ); 259 // manager.fire(); // maybe you want to fire the change later. Let us know 260 // about it. 261 // */ 262 // } else { 263 // /* 264 // // fire a delta to notify the UI about the source attachement. 265 // JavaModelManager manager = (JavaModelManager) 266 // JavaModelManager.getJavaModelManager(); 267 // JavaModel model = (JavaModel) getJavaModel(); 268 // JavaElementDelta attachedSourceDelta = new JavaElementDelta(model); 269 // attachedSourceDelta .sourceAttached(this); // this would be a 270 // PackageFragmentRoot 271 // manager.registerResourceDelta(attachedSourceDelta ); 272 // manager.fire(); // maybe you want to fire the change later. Let us know 273 // about it. 274 // */ 275 // 276 // //check if different from the current attachment 277 // IPath storedSourcePath= getSourceAttachmentPath(); 278 // IPath storedRootPath= getSourceAttachmentRootPath(); 279 // if (monitor != null) { 280 // monitor.worked(1); 281 // } 282 // if (storedSourcePath != null) { 283 // if (!(storedSourcePath.equals(sourcePath) && (rootPath != null && 284 // rootPath.equals(storedRootPath)) || storedRootPath == null)) 285 // { 286 // rootNeedsToBeClosed= true; 287 // } 288 // } 289 // // check if source path is valid 290 // Object target = JavaModel.getTarget(workspace.getRoot(), sourcePath, 291 // false); 292 // if (target == null) { 293 // if (monitor != null) { 294 // monitor.done(); 295 // } 296 // throw new JavaModelException(new 297 // JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, sourcePath)); 298 // } 299 // SourceMapper mapper = createSourceMapper(sourcePath, rootPath); 300 // if (rootPath == null && mapper.rootPath != null) { 301 // // as a side effect of calling the SourceMapper constructor, the root 302 // path was computed 303 // rootPath = new Path(mapper.rootPath); 304 // } 305 // setSourceMapper(mapper); 306 // } 307 // if (sourcePath == null) { 308 // setSourceAttachmentProperty(null); //remove the property 309 // } else { 310 // //set the property to the path of the mapped source 311 // setSourceAttachmentProperty( 312 // sourcePath.toString() 313 // + (rootPath == null ? "" : (ATTACHMENT_PROPERTY_DELIMITER + 314 // rootPath.toString()))); //$NON-NLS-1$ 315 // } 316 // if (rootNeedsToBeClosed) { 317 // if (oldMapper != null) { 318 // oldMapper.close(); 319 // } 320 // BufferManager manager= BufferManager.getDefaultBufferManager(); 321 // Enumeration openBuffers= manager.getOpenBuffers(); 322 // while (openBuffers.hasMoreElements()) { 323 // IBuffer buffer= (IBuffer) openBuffers.nextElement(); 324 // IOpenable possibleMember= buffer.getOwner(); 325 // if (isAncestorOf((IJavaElement) possibleMember)) { 326 // buffer.close(); 327 // } 328 // } 329 // if (monitor != null) { 330 // monitor.worked(1); 331 // } 332 // } 333 // } catch (JavaModelException e) { 334 // setSourceAttachmentProperty(null); // loose info - will be recomputed 335 // throw e; 336 // } finally { 337 // if (monitor != null) { 338 // monitor.done(); 339 // } 340 // } 341 // } 342 // SourceMapper createSourceMapper(IPath sourcePath, IPath rootPath) { 343 // SourceMapper mapper = new SourceMapper( 344 // sourcePath, 345 // rootPath == null ? null : rootPath.toOSString(), 346 // this.isExternal() ? JavaCore.getOptions() : 347 // this.getJavaProject().getOptions(true)); // only project options if 348 // associated with 349 // resource 350 // return mapper; 351 // } 352 /* 353 * @see net.sourceforge.phpdt.core.IPackageFragmentRoot#delete 354 */ 355 // public void delete( 356 // int updateResourceFlags, 357 // int updateModelFlags, 358 // IProgressMonitor monitor) 359 // throws JavaModelException { 360 // 361 // DeletePackageFragmentRootOperation op = new 362 // DeletePackageFragmentRootOperation(this, updateResourceFlags, 363 // updateModelFlags); 364 // runOperation(op, monitor); 365 // } 366 /** 367 * This root is being closed. If this root has an associated source 368 * attachment, close it too. 369 * 370 * @see JavaElement 371 */ 372 // protected void closing(Object info) throws JavaModelException { TODO 373 // remove after 2.1 374 // ((PackageFragmentRootInfo) info).sourceMapper = null; 375 // super.closing(info); 376 // } 377 /** 378 * Compute the package fragment children of this package fragment root. 379 * 380 * @exception JavaModelException 381 * The resource associated with this package fragment root 382 * does not exist 383 */ 384 // protected boolean computeChildren(OpenableElementInfo info) throws 385 // JavaModelException { 386 // try { 387 // // the underlying resource may be a folder or a project (in the case that 388 // the project folder 389 // // is actually the package fragment root) 390 // IResource resource = getResource(); 391 // if (resource.getType() == IResource.FOLDER || resource.getType() == 392 // IResource.PROJECT) { 393 // ArrayList vChildren = new ArrayList(5); 394 // char[][] exclusionPatterns = fullExclusionPatternChars(); 395 // computeFolderChildren((IContainer) resource, "", vChildren, 396 // exclusionPatterns); //$NON-NLS-1$ 397 // IJavaElement[] children = new IJavaElement[vChildren.size()]; 398 // vChildren.toArray(children); 399 // info.setChildren(children); 400 // } 401 // } catch (JavaModelException e) { 402 // //problem resolving children; structure remains unknown 403 // info.setChildren(new IJavaElement[]{}); 404 // throw e; 405 // } 406 // return true; 407 // } 408 /** 409 * Starting at this folder, create package fragments and add the fragments 410 * that are not exclused to the collection of children. 411 * 412 * @exception JavaModelException 413 * The resource associated with this package fragment does 414 * not exist 415 */ 416 // protected void computeFolderChildren(IContainer folder, String prefix, 417 // ArrayList vChildren, char[][] exclusionPatterns) throws 418 // JavaModelException { 419 // IPackageFragment pkg = getPackageFragment(prefix); 420 // vChildren.add(pkg); 421 // try { 422 // JavaProject javaProject = (JavaProject)getJavaProject(); 423 // IResource[] members = folder.members(); 424 // for (int i = 0, max = members.length; i < max; i++) { 425 // IResource member = members[i]; 426 // String memberName = member.getName(); 427 // if (member.getType() == IResource.FOLDER 428 // && ProjectPrefUtil.isValidFolderNameForPackage(memberName) 429 // && !ProjectPrefUtil.isExcluded(member, exclusionPatterns)) { 430 // 431 // // eliminate binary output only if nested inside direct subfolders 432 // if (javaProject.contains(member)) { 433 // String newPrefix; 434 // if (prefix.length() == 0) { 435 // newPrefix = memberName; 436 // } else { 437 // newPrefix = prefix + "." + memberName; //$NON-NLS-1$ 438 // } 439 // computeFolderChildren((IFolder) member, newPrefix, vChildren, 440 // exclusionPatterns); 441 // } 442 // } 443 // } 444 // } catch(IllegalArgumentException e){ 445 // throw new JavaModelException(e, 446 // IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST); // could be thrown by 447 // ElementTree when path 448 // is not found 449 // } catch (CoreException e) { 450 // throw new JavaModelException(e); 451 // } 452 // } 453 /* 454 * Computes and returns the source attachment root path for the given source 455 * attachment path. Returns <code> null </code> if none could be found. 456 * 457 * @param sourceAttachmentPath the given absolute path to the source archive 458 * or folder @return the computed source attachment root path or <code> null 459 * </cde> if none could be found @throws JavaModelException 460 */ 461 // public IPath computeSourceAttachmentRootPath(IPath sourceAttachmentPath) 462 // throws JavaModelException { 463 // IPath sourcePath = this.getSourceAttachmentPath(); 464 // if (sourcePath == null) return null; 465 // SourceMapper mapper = 466 // new SourceMapper( 467 // sourcePath, 468 // null, // detect root path 469 // this.isExternal() ? JavaCore.getOptions() : 470 // this.getJavaProject().getOptions(true) // only project options if 471 // associated with 472 // resource 473 // ); 474 // if (mapper.rootPath == null) return null; 475 // return new Path(mapper.rootPath); 476 // } 477 /* 478 * @see net.sourceforge.phpdt.core.IPackageFragmentRoot#copy 479 */ 480 // public void copy( 481 // IPath destination, 482 // int updateResourceFlags, 483 // int updateModelFlags, 484 // IClasspathEntry sibling, 485 // IProgressMonitor monitor) 486 // throws JavaModelException { 487 // 488 // CopyPackageFragmentRootOperation op = 489 // new CopyPackageFragmentRootOperation(this, destination, 490 // updateResourceFlags, updateModelFlags, sibling); 491 // runOperation(op, monitor); 492 // } 493 /** 494 * Returns a new element info for this element. 495 */ createElementInfo()496 protected Object createElementInfo() { 497 return new PackageFragmentRootInfo(); 498 } 499 500 /** 501 * @see IPackageFragmentRoot 502 */ 503 // public IPackageFragment createPackageFragment(String name, boolean force, 504 // IProgressMonitor monitor) throws JavaModelException { 505 // CreatePackageFragmentOperation op = new 506 // CreatePackageFragmentOperation(this, name, force); 507 // runOperation(op, monitor); 508 // return getPackageFragment(name); 509 // } 510 /** 511 * Returns the root's kind - K_SOURCE or K_BINARY, defaults to K_SOURCE if 512 * it is not on the classpath. 513 * 514 * @exception NotPresentException 515 * if the project and root do not exist. 516 */ 517 // protected int determineKind(IResource underlyingResource) throws 518 // JavaModelException { 519 // IClasspathEntry[] entries= 520 // ((JavaProject)getJavaProject()).getExpandedClasspath(true); 521 // for (int i= 0; i < entries.length; i++) { 522 // IClasspathEntry entry= entries[i]; 523 // if (entry.getPath().equals(underlyingResource.getFullPath())) { 524 // return entry.getContentKind(); 525 // } 526 // } 527 // return IPackageFragmentRoot.K_SOURCE; 528 // } 529 /** 530 * Compares two objects for equality; for <code>PackageFragmentRoot</code>s, 531 * equality is having the same <code>JavaModel</code>, same resources, 532 * and occurrence count. 533 * 534 */ equals(Object o)535 public boolean equals(Object o) { 536 if (this == o) 537 return true; 538 if (!(o instanceof PackageFragmentRoot)) 539 return false; 540 PackageFragmentRoot other = (PackageFragmentRoot) o; 541 return getJavaModel().equals(other.getJavaModel()) 542 && this.resource.equals(other.resource) 543 && occurrenceCount == other.occurrenceCount; 544 } 545 546 /** 547 * @see IJavaElement 548 */ 549 // public boolean exists() { 550 // return super.exists() 551 // && isOnClasspath(); 552 // } 553 // public IClasspathEntry findSourceAttachmentRecommendation() { 554 // try { 555 // IPath rootPath = this.getPath(); 556 // IClasspathEntry entry; 557 // IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); 558 // 559 // // try on enclosing project first 560 // JavaProject parentProject = (JavaProject) getJavaProject(); 561 // try { 562 // entry = parentProject.getClasspathEntryFor(rootPath); 563 // if (entry != null){ 564 // Object target = JavaModel.getTarget(workspaceRoot, 565 // entry.getSourceAttachmentPath(), true); 566 // if (target instanceof IFile){ 567 // IFile file = (IFile) target; 568 // if (ProjectPrefUtil.isArchiveFileName(file.getName())){ 569 // return entry; 570 // } 571 // } else if (target instanceof IFolder) { 572 // return entry; 573 // } 574 // if (target instanceof java.io.File){ 575 // java.io.File file = (java.io.File) target; 576 // if (file.isFile()) { 577 // if (ProjectPrefUtil.isArchiveFileName(file.getName())){ 578 // return entry; 579 // } 580 // } else { 581 // // external directory 582 // return entry; 583 // } 584 // } 585 // } 586 // } catch(JavaModelException e){ 587 // } 588 // 589 // // iterate over all projects 590 // IJavaModel model = getJavaModel(); 591 // IJavaProject[] jProjects = model.getJavaProjects(); 592 // for (int i = 0, max = jProjects.length; i < max; i++){ 593 // JavaProject jProject = (JavaProject) jProjects[i]; 594 // if (jProject == parentProject) continue; // already done 595 // try { 596 // entry = jProject.getClasspathEntryFor(rootPath); 597 // if (entry != null){ 598 // Object target = JavaModel.getTarget(workspaceRoot, 599 // entry.getSourceAttachmentPath(), true); 600 // if (target instanceof IFile){ 601 // IFile file = (IFile) target; 602 // if (ProjectPrefUtil.isArchiveFileName(file.getName())){ 603 // return entry; 604 // } 605 // } else if (target instanceof IFolder) { 606 // return entry; 607 // } 608 // if (target instanceof java.io.File){ 609 // java.io.File file = (java.io.File) target; 610 // if (file.isFile()) { 611 // if (ProjectPrefUtil.isArchiveFileName(file.getName())){ 612 // return entry; 613 // } 614 // } else { 615 // // external directory 616 // return entry; 617 // } 618 // } 619 // } 620 // } catch(JavaModelException e){ 621 // } 622 // } 623 // } catch(JavaModelException e){ 624 // } 625 // 626 // return null; 627 // } 628 /* 629 * Returns the exclusion patterns from the classpath entry associated with 630 * this root. 631 */ fullExclusionPatternChars()632 char[][] fullExclusionPatternChars() { 633 return null; 634 // try { 635 636 // if (this.isOpen() && this.getKind() != IPackageFragmentRoot.K_SOURCE) 637 // return null; 638 // ClasspathEntry entry = (ClasspathEntry)getRawClasspathEntry(); 639 // if (entry == null) { 640 // return null; 641 // } else { 642 // return entry.fullExclusionPatternChars(); 643 // } 644 // } catch (JavaModelException e) { 645 // return null; 646 // } 647 } 648 649 /** 650 * @see Openable 651 */ generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource)652 protected boolean generateInfos(OpenableElementInfo info, 653 IProgressMonitor pm, Map newElements, IResource underlyingResource) 654 throws JavaModelException { 655 656 // ((PackageFragmentRootInfo) 657 // info).setRootKind(determineKind(underlyingResource)); 658 // return computeChildren(info); 659 return false; 660 } 661 662 /** 663 * @see JavaElement#getHandleMemento() 664 */ getHandleMementoDelimiter()665 protected char getHandleMementoDelimiter() { 666 return JavaElement.JEM_PACKAGEFRAGMENTROOT; 667 } 668 669 /** 670 * @see IJavaElement 671 */ getElementType()672 public int getElementType() { 673 return PACKAGE_FRAGMENT_ROOT; 674 } 675 676 /* 677 * @see JavaElement 678 */ getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner)679 public IJavaElement getHandleFromMemento(String token, 680 MementoTokenizer memento, WorkingCopyOwner owner) { 681 switch (token.charAt(0)) { 682 case JEM_COUNT: 683 return getHandleUpdatingCountFromMemento(memento, owner); 684 case JEM_PACKAGEFRAGMENT: 685 String pkgName; 686 if (memento.hasMoreTokens()) { 687 pkgName = memento.nextToken(); 688 char firstChar = pkgName.charAt(0); 689 // if (firstChar == JEM_CLASSFILE || firstChar == 690 // JEM_COMPILATIONUNIT || firstChar == JEM_COUNT) { 691 if (firstChar == JEM_COMPILATIONUNIT || firstChar == JEM_COUNT) { 692 token = pkgName; 693 pkgName = IPackageFragment.DEFAULT_PACKAGE_NAME; 694 } else { 695 token = null; 696 } 697 } else { 698 pkgName = IPackageFragment.DEFAULT_PACKAGE_NAME; 699 token = null; 700 } 701 JavaElement pkg = (JavaElement) getPackageFragment(pkgName); 702 if (token == null) { 703 return pkg.getHandleFromMemento(memento, owner); 704 } else { 705 return pkg.getHandleFromMemento(token, memento, owner); 706 } 707 } 708 return null; 709 } 710 711 /** 712 * @see JavaElement#getHandleMemento() 713 */ getHandleMemento()714 public String getHandleMemento() { 715 IPath path; 716 IResource underlyingResource = getResource(); 717 if (underlyingResource != null) { 718 // internal jar or regular root 719 if (getResource().getProject() 720 .equals(getJavaProject().getProject())) { 721 path = underlyingResource.getProjectRelativePath(); 722 } else { 723 path = underlyingResource.getFullPath(); 724 } 725 } else { 726 // external jar 727 path = getPath(); 728 } 729 StringBuffer buff = new StringBuffer(((JavaElement) getParent()) 730 .getHandleMemento()); 731 buff.append(getHandleMementoDelimiter()); 732 escapeMementoName(buff, path.toString()); 733 if (this.occurrenceCount > 1) { 734 buff.append(JEM_COUNT); 735 buff.append(this.occurrenceCount); 736 } 737 return buff.toString(); 738 } 739 740 /** 741 * @see IPackageFragmentRoot 742 */ getKind()743 public int getKind() throws JavaModelException { 744 return ((PackageFragmentRootInfo) getElementInfo()).getRootKind(); 745 } 746 747 /** 748 * Returns an array of non-java resources contained in the receiver. 749 */ 750 // public Object[] getNonJavaResources() throws JavaModelException { 751 // return ((PackageFragmentRootInfo) 752 // getElementInfo()).getNonJavaResources(getJavaProject(), getResource(), 753 // this); 754 // } 755 /** 756 * @see IPackageFragmentRoot 757 */ getPackageFragment(String packageName)758 public IPackageFragment getPackageFragment(String packageName) { 759 if (packageName.indexOf(' ') != -1) { // tolerate package names with 760 // spaces (e.g. 'x . y') 761 // (http://bugs.eclipse.org/bugs/show_bug.cgi?id=21957) 762 char[][] compoundName = Util.toCompoundChars(packageName); 763 StringBuffer buffer = new StringBuffer(packageName.length()); 764 for (int i = 0, length = compoundName.length; i < length; i++) { 765 buffer.append(CharOperation.trim(compoundName[i])); 766 if (i != length - 1) { 767 buffer.append('.'); 768 } 769 } 770 packageName = buffer.toString(); 771 } 772 return new PackageFragment(this, packageName); 773 } 774 775 /** 776 * Returns the package name for the given folder (which is a decendent of 777 * this root). 778 */ getPackageName(IFolder folder)779 protected String getPackageName(IFolder folder) throws JavaModelException { 780 IPath myPath = getPath(); 781 IPath pkgPath = folder.getFullPath(); 782 int mySegmentCount = myPath.segmentCount(); 783 int pkgSegmentCount = pkgPath.segmentCount(); 784 StringBuffer name = new StringBuffer( 785 IPackageFragment.DEFAULT_PACKAGE_NAME); 786 for (int i = mySegmentCount; i < pkgSegmentCount; i++) { 787 if (i > mySegmentCount) { 788 name.append('.'); 789 } 790 name.append(pkgPath.segment(i)); 791 } 792 return name.toString(); 793 } 794 795 /** 796 * @see IJavaElement 797 */ getPath()798 public IPath getPath() { 799 return getResource().getFullPath(); 800 } 801 802 /* 803 * @see IPackageFragmentRoot 804 */ 805 // public IClasspathEntry getRawClasspathEntry() throws JavaModelException { 806 // 807 // IClasspathEntry rawEntry = null; 808 // IJavaProject project = this.getJavaProject(); 809 // project.getResolvedClasspath(true); // force the reverse rawEntry cache 810 // to be populated 811 // JavaModelManager.PerProjectInfo perProjectInfo = 812 // JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject()); 813 // if (perProjectInfo != null && perProjectInfo.resolvedPathToRawEntries != 814 // null) { 815 // rawEntry = (IClasspathEntry) 816 // perProjectInfo.resolvedPathToRawEntries.get(this.getPath()); 817 // } 818 // return rawEntry; 819 // } 820 /* 821 * @see IJavaElement 822 */ getResource()823 public IResource getResource() { 824 return (IResource) this.resource; 825 } 826 827 /** 828 * @see IPackageFragmentRoot 829 */ 830 // public IPath getSourceAttachmentPath() throws JavaModelException { 831 // if (getKind() != K_BINARY) return null; 832 // 833 // String serverPathString= getSourceAttachmentProperty(); 834 // if (serverPathString == null) { 835 // return null; 836 // } 837 // int index= serverPathString.lastIndexOf(ATTACHMENT_PROPERTY_DELIMITER); 838 // if (index < 0) { 839 // // no root path specified 840 // return new Path(serverPathString); 841 // } else { 842 // String serverSourcePathString= serverPathString.substring(0, index); 843 // return new Path(serverSourcePathString); 844 // } 845 // } 846 /** 847 * Returns the server property for this package fragment root's source 848 * attachement. 849 */ 850 // protected String getSourceAttachmentProperty() throws JavaModelException 851 // { 852 // String propertyString = null; 853 // QualifiedName qName= getSourceAttachmentPropertyName(); 854 // try { 855 // propertyString = 856 // ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName); 857 // 858 // // if no existing source attachment information, then lookup a 859 // recommendation from classpath entries 860 // if (propertyString == null) { 861 // IClasspathEntry recommendation = findSourceAttachmentRecommendation(); 862 // if (recommendation != null) { 863 // IPath rootPath = recommendation.getSourceAttachmentRootPath(); 864 // propertyString = 865 // recommendation.getSourceAttachmentPath().toString() 866 // + ((rootPath == null) 867 // ? "" : //$NON-NLS-1$ 868 // (ATTACHMENT_PROPERTY_DELIMITER + rootPath.toString())); 869 // setSourceAttachmentProperty(propertyString); 870 // } else { 871 // // mark as being already looked up 872 // setSourceAttachmentProperty(NO_SOURCE_ATTACHMENT); 873 // } 874 // } else if (NO_SOURCE_ATTACHMENT.equals(propertyString)) { 875 // // already looked up and no source attachment found 876 // return null; 877 // } 878 // return propertyString; 879 // } catch (CoreException ce) { 880 // throw new JavaModelException(ce); 881 // } 882 // } 883 /** 884 * Returns the qualified name for the source attachment property of this 885 * root. 886 */ getSourceAttachmentPropertyName()887 protected QualifiedName getSourceAttachmentPropertyName() 888 throws JavaModelException { 889 return new QualifiedName(JavaCore.PLUGIN_ID, 890 "sourceattachment: " + this.getPath().toOSString()); //$NON-NLS-1$ 891 } 892 setSourceAttachmentProperty(String property)893 public void setSourceAttachmentProperty(String property) { 894 try { 895 ResourcesPlugin.getWorkspace().getRoot().setPersistentProperty( 896 this.getSourceAttachmentPropertyName(), property); 897 } catch (CoreException ce) { 898 } 899 } 900 901 /** 902 * For use by <code>AttachSourceOperation</code> only. Sets the source 903 * mapper associated with this root. 904 */ 905 // public void setSourceMapper(SourceMapper mapper) throws 906 // JavaModelException { 907 // ((PackageFragmentRootInfo) getElementInfo()).setSourceMapper(mapper); 908 // } 909 /** 910 * @see IPackageFragmentRoot 911 */ 912 // public IPath getSourceAttachmentRootPath() throws JavaModelException { 913 // if (getKind() != K_BINARY) return null; 914 // 915 // String serverPathString= getSourceAttachmentProperty(); 916 // if (serverPathString == null) { 917 // return null; 918 // } 919 // int index = serverPathString.lastIndexOf(ATTACHMENT_PROPERTY_DELIMITER); 920 // if (index == -1) return null; 921 // String serverRootPathString= 922 // IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH; 923 // if (index != serverPathString.length() - 1) { 924 // serverRootPathString= serverPathString.substring(index + 1); 925 // } 926 // return new Path(serverRootPathString); 927 // } 928 /** 929 * @see JavaElement 930 */ 931 // public SourceMapper getSourceMapper() { 932 // SourceMapper mapper; 933 // try { 934 // PackageFragmentRootInfo rootInfo = (PackageFragmentRootInfo) 935 // getElementInfo(); 936 // mapper = rootInfo.getSourceMapper(); 937 // if (mapper == null) { 938 // // first call to this method 939 // IPath sourcePath= getSourceAttachmentPath(); 940 // if (sourcePath != null) { 941 // IPath rootPath= getSourceAttachmentRootPath(); 942 // mapper = this.createSourceMapper(sourcePath, rootPath); 943 // if (rootPath == null && mapper.rootPath != null) { 944 // // as a side effect of calling the SourceMapper constructor, the root 945 // path was computed 946 // rootPath = new Path(mapper.rootPath); 947 // 948 // //set the property to the path of the mapped source 949 // this.setSourceAttachmentProperty( 950 // sourcePath.toString() 951 // + ATTACHMENT_PROPERTY_DELIMITER 952 // + rootPath.toString()); 953 // } 954 // rootInfo.setSourceMapper(mapper); 955 // } else { 956 // // remember that no source is attached 957 // rootInfo.setSourceMapper(NO_SOURCE_MAPPER); 958 // mapper = null; 959 // } 960 // } else if (mapper == NO_SOURCE_MAPPER) { 961 // // a previous call to this method found out that no source was attached 962 // mapper = null; 963 // } 964 // } catch (JavaModelException e) { 965 // // no source can be attached 966 // mapper = null; 967 // } 968 // return mapper; 969 // } 970 /** 971 * @see IJavaElement 972 */ getUnderlyingResource()973 public IResource getUnderlyingResource() throws JavaModelException { 974 if (!exists()) 975 throw newNotPresentException(); 976 return getResource(); 977 } 978 hashCode()979 public int hashCode() { 980 return this.resource.hashCode(); 981 } 982 983 /** 984 * @see IPackageFragmentRoot 985 */ isArchive()986 public boolean isArchive() { 987 return false; 988 } 989 990 /** 991 * @see IPackageFragmentRoot 992 */ isExternal()993 public boolean isExternal() { 994 return false; 995 } 996 997 /* 998 * Returns whether this package fragment root is on the classpath of its 999 * project. 1000 */ 1001 // protected boolean isOnClasspath() { 1002 // if (this.getElementType() == IJavaElement.JAVA_PROJECT){ 1003 // return true; 1004 // } 1005 // 1006 // IPath path = this.getPath(); 1007 // try { 1008 // // check package fragment root on classpath of its project 1009 // IJavaProject project = this.getJavaProject(); 1010 // IClasspathEntry[] classpath = project.getResolvedClasspath(true); 1011 // for (int i = 0, length = classpath.length; i < length; i++) { 1012 // IClasspathEntry entry = classpath[i]; 1013 // if (entry.getPath().equals(path)) { 1014 // return true; 1015 // } 1016 // } 1017 // } catch(JavaModelException e){ 1018 // // could not read classpath, then assume it is outside 1019 // } 1020 // return false; 1021 // } 1022 /* 1023 * @see net.sourceforge.phpdt.core.IPackageFragmentRoot#move 1024 */ 1025 // public void move( 1026 // IPath destination, 1027 // int updateResourceFlags, 1028 // int updateModelFlags, 1029 // IClasspathEntry sibling, 1030 // IProgressMonitor monitor) 1031 // throws JavaModelException { 1032 // 1033 // MovePackageFragmentRootOperation op = 1034 // new MovePackageFragmentRootOperation(this, destination, 1035 // updateResourceFlags, updateModelFlags, sibling); 1036 // runOperation(op, monitor); 1037 // } 1038 // 1039 // 1040 // protected void openWhenClosed(IProgressMonitor pm) throws 1041 // JavaModelException { 1042 // if (!this.resourceExists() 1043 // || !this.isOnClasspath()) { 1044 // throw newNotPresentException(); 1045 // } 1046 // super.openWhenClosed(pm); 1047 // } 1048 /** 1049 * Recomputes the children of this element, based on the current state of 1050 * the workbench. 1051 */ 1052 // public void refreshChildren() { 1053 // try { 1054 // OpenableElementInfo info= (OpenableElementInfo)getElementInfo(); 1055 // computeChildren(info); 1056 // } catch (JavaModelException e) { 1057 // // do nothing. 1058 // } 1059 // } 1060 // /* 1061 // * @see JavaElement#rootedAt(IJavaProject) 1062 // */ 1063 // public IJavaElement rootedAt(IJavaProject project) { 1064 // return 1065 // new PackageFragmentRoot( 1066 // getResource(), 1067 // project, 1068 // name); 1069 // } 1070 /** 1071 * @private Debugging purposes 1072 */ toStringInfo(int tab, StringBuffer buffer, Object info)1073 protected void toStringInfo(int tab, StringBuffer buffer, Object info) { 1074 buffer.append(this.tabString(tab)); 1075 if (getElementName().length() == 0) { 1076 buffer.append("[project root]"); //$NON-NLS-1$ 1077 } else { 1078 IPath path = getPath(); 1079 if (getJavaProject().getElementName().equals(path.segment(0))) { 1080 buffer.append(path.removeFirstSegments(1).makeRelative()); 1081 } else { 1082 buffer.append(path); 1083 } 1084 } 1085 if (info == null) { 1086 buffer.append(" (not open)"); //$NON-NLS-1$ 1087 } 1088 } 1089 1090 /** 1091 * Possible failures: 1092 * <ul> 1093 * <li>ELEMENT_NOT_PRESENT - the root supplied to the operation does not 1094 * exist 1095 * <li>INVALID_ELEMENT_TYPES - the root is not of kind K_BINARY 1096 * <li>RELATIVE_PATH - the path supplied to this operation must be an 1097 * absolute path 1098 * </ul> 1099 */ 1100 // protected void verifyAttachSource(IPath sourcePath) throws 1101 // JavaModelException { 1102 // if (!exists()) { 1103 // throw newNotPresentException(); 1104 // } else if (this.getKind() != K_BINARY) { 1105 // throw new JavaModelException(new 1106 // JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this)); 1107 // } else if (sourcePath != null && !sourcePath.isAbsolute()) { 1108 // throw new JavaModelException(new 1109 // JavaModelStatus(IJavaModelStatusConstants.RELATIVE_PATH, sourcePath)); 1110 // } 1111 // } 1112 }