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