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