c8541ba738f03a5763380f8477db1241083fc6e3
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / JavaProject.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.io.BufferedInputStream;
14 import java.io.BufferedOutputStream;
15 import java.io.ByteArrayInputStream;
16 import java.io.File;
17 import java.io.FileInputStream;
18 import java.io.FileOutputStream;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.OutputStream;
22
23 import net.sourceforge.phpdt.core.IJavaElement;
24 import net.sourceforge.phpdt.core.IJavaProject;
25 import net.sourceforge.phpdt.core.JavaModelException;
26 import net.sourceforge.phpeclipse.PHPCore;
27 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
28
29 import org.eclipse.core.resources.ICommand;
30 import org.eclipse.core.resources.IFile;
31 import org.eclipse.core.resources.IProject;
32 import org.eclipse.core.resources.IProjectDescription;
33 import org.eclipse.core.resources.IProjectNature;
34 import org.eclipse.core.resources.IResource;
35 import org.eclipse.core.resources.IWorkspace;
36 import org.eclipse.core.resources.ResourcesPlugin;
37 import org.eclipse.core.runtime.CoreException;
38 import org.eclipse.core.runtime.IPath;
39 import org.eclipse.core.runtime.Path;
40 import org.eclipse.core.runtime.Preferences;
41 import org.eclipse.core.runtime.QualifiedName;
42
43 /**
44  * Handle for a Java Project.
45  *
46  * <p>A Java Project internally maintains a devpath that corresponds
47  * to the project's classpath. The classpath may include source folders
48  * from the current project; jars in the current project, other projects,
49  * and the local file system; and binary folders (output location) of other
50  * projects. The Java Model presents source elements corresponding to output
51  * .class files in other projects, and thus uses the devpath rather than
52  * the classpath (which is really a compilation path). The devpath mimics
53  * the classpath, except has source folder entries in place of output
54  * locations in external projects.
55  *
56  * <p>Each JavaProject has a NameLookup facility that locates elements
57  * on by name, based on the devpath.
58  *
59  * @see IJavaProject
60  */
61 public class JavaProject
62         extends Openable 
63         implements IJavaProject , IProjectNature {
64
65         /**
66          * Whether the underlying file system is case sensitive.
67          */
68         protected static final boolean IS_CASE_SENSITIVE = !new File("Temp").equals(new File("temp")); //$NON-NLS-1$ //$NON-NLS-2$
69
70         /**
71          * An empty array of strings indicating that a project doesn't have any prerequesite projects.
72          */
73         protected static final String[] NO_PREREQUISITES = new String[0];
74
75         /**
76          * The platform project this <code>IJavaProject</code> is based on
77          */
78         protected IProject fProject;
79         
80         /**
81          * Name of file containing project classpath
82          */
83         public static final String CLASSPATH_FILENAME = ".classpath";  //$NON-NLS-1$
84
85         /**
86          * Name of file containing custom project preferences
87          */
88         public static final String PREF_FILENAME = ".jprefs";  //$NON-NLS-1$
89         
90         /**
91          * Value of the project's raw classpath if the .classpath file contains invalid entries.
92          */
93 //      public static final IClasspathEntry[] INVALID_CLASSPATH = new IClasspathEntry[0];
94
95         private static final String CUSTOM_DEFAULT_OPTION_VALUE = "#\r\n\r#custom-non-empty-default-value#\r\n\r#"; //$NON-NLS-1$
96         
97         /**
98          * Returns a canonicalized path from the given external path.
99          * Note that the return path contains the same number of segments
100          * and it contains a device only if the given path contained one.
101          * @see java.io.File for the definition of a canonicalized path
102          */
103         public static IPath canonicalizedPath(IPath externalPath) {
104                 
105                 if (externalPath == null)
106                         return null;
107
108 //              if (JavaModelManager.VERBOSE) {
109 //                      System.out.println("JAVA MODEL - Canonicalizing " + externalPath.toString()); //$NON-NLS-1$
110 //              }
111
112                 if (IS_CASE_SENSITIVE) {
113 //                      if (JavaModelManager.VERBOSE) {
114 //                              System.out.println("JAVA MODEL - Canonical path is original path (file system is case sensitive)"); //$NON-NLS-1$
115 //                      }
116                         return externalPath;
117                 }
118
119                 // if not external path, return original path
120                 IWorkspace workspace = ResourcesPlugin.getWorkspace();
121                 if (workspace == null) return externalPath; // protection during shutdown (30487)
122                 if (workspace.getRoot().findMember(externalPath) != null) {
123 //                      if (JavaModelManager.VERBOSE) {
124 //                              System.out.println("JAVA MODEL - Canonical path is original path (member of workspace)"); //$NON-NLS-1$
125 //                      }
126                         return externalPath;
127                 }
128
129                 IPath canonicalPath = null;
130                 try {
131                         canonicalPath =
132                                 new Path(new File(externalPath.toOSString()).getCanonicalPath());
133                 } catch (IOException e) {
134                         // default to original path
135 //                      if (JavaModelManager.VERBOSE) {
136 //                              System.out.println("JAVA MODEL - Canonical path is original path (IOException)"); //$NON-NLS-1$
137 //                      }
138                         return externalPath;
139                 }
140                 
141                 IPath result;
142                 int canonicalLength = canonicalPath.segmentCount();
143                 if (canonicalLength == 0) {
144                         // the java.io.File canonicalization failed
145 //                      if (JavaModelManager.VERBOSE) {
146 //                              System.out.println("JAVA MODEL - Canonical path is original path (canonical path is empty)"); //$NON-NLS-1$
147 //                      }
148                         return externalPath;
149                 } else if (externalPath.isAbsolute()) {
150                         result = canonicalPath;
151                 } else {
152                         // if path is relative, remove the first segments that were added by the java.io.File canonicalization
153                         // e.g. 'lib/classes.zip' was converted to 'd:/myfolder/lib/classes.zip'
154                         int externalLength = externalPath.segmentCount();
155                         if (canonicalLength >= externalLength) {
156                                 result = canonicalPath.removeFirstSegments(canonicalLength - externalLength);
157                         } else {
158 //                              if (JavaModelManager.VERBOSE) {
159 //                                      System.out.println("JAVA MODEL - Canonical path is original path (canonical path is " + canonicalPath.toString() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
160 //                              }
161                                 return externalPath;
162                         }
163                 }
164                 
165                 // keep device only if it was specified (this is because File.getCanonicalPath() converts '/lib/classed.zip' to 'd:/lib/classes/zip')
166                 if (externalPath.getDevice() == null) {
167                         result = result.setDevice(null);
168                 } 
169 //              if (JavaModelManager.VERBOSE) {
170 //                      System.out.println("JAVA MODEL - Canonical path is " + result.toString()); //$NON-NLS-1$
171 //              }
172                 return result;
173         }
174
175         /**
176          * Constructor needed for <code>IProject.getNature()</code> and <code>IProject.addNature()</code>.
177          *
178          * @see #setProject
179          */
180         public JavaProject() {
181                 super(JAVA_PROJECT, null, null);
182         }
183
184         public JavaProject(IProject project, IJavaElement parent) {
185                 super(JAVA_PROJECT, parent, project.getName());
186                 fProject = project;
187         }
188
189         /**
190          * Adds a builder to the build spec for the given project.
191          */
192         protected void addToBuildSpec(String builderID) throws CoreException {
193
194                 IProjectDescription description = getProject().getDescription();
195                 ICommand javaCommand = getJavaCommand(description);
196
197                 if (javaCommand == null) {
198
199                         // Add a Java command to the build spec
200                         ICommand command = description.newCommand();
201                         command.setBuilderName(builderID);
202                         setJavaCommand(description, command);
203                 }
204         }
205
206 //      protected void closing(Object info) throws JavaModelException {
207 //              
208 //              // forget source attachment recommendations
209 //              IPackageFragmentRoot[] roots = this.getPackageFragmentRoots();
210 //              for (int i = 0; i < roots.length; i++) {
211 //                      if (roots[i] instanceof JarPackageFragmentRoot){
212 //                              ((JarPackageFragmentRoot) roots[i]).setSourceAttachmentProperty(null); 
213 //                      }
214 //              }
215 //              
216 //              super.closing(info);
217 //      }
218         
219
220
221         /**
222          * Internal computation of an expanded classpath. It will eliminate duplicates, and produce copies
223          * of exported classpath entries to avoid possible side-effects ever after.
224          */                     
225 //      private void computeExpandedClasspath(
226 //              JavaProject initialProject, 
227 //              boolean ignoreUnresolvedVariable,
228 //              boolean generateMarkerOnError,
229 //              HashSet visitedProjects, 
230 //              ObjectVector accumulatedEntries) throws JavaModelException {
231 //              
232 //              if (visitedProjects.contains(this)){
233 //                      return; // break cycles if any
234 //              }
235 //              visitedProjects.add(this);
236 //
237 //              if (generateMarkerOnError && !this.equals(initialProject)){
238 //                      generateMarkerOnError = false;
239 //              }
240 //              IClasspathEntry[] immediateClasspath = 
241 //                      getResolvedClasspath(ignoreUnresolvedVariable, generateMarkerOnError);
242 //                      
243 //              IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
244 //              for (int i = 0, length = immediateClasspath.length; i < length; i++){
245 //                      IClasspathEntry entry = immediateClasspath[i];
246 //
247 //                      boolean isInitialProject = this.equals(initialProject);
248 //                      if (isInitialProject || entry.isExported()){
249 //                              
250 //                              accumulatedEntries.add(entry);
251 //                              
252 //                              // recurse in project to get all its indirect exports (only consider exported entries from there on)                            
253 //                              if (entry.getEntryKind() == ClasspathEntry.CPE_PROJECT) {
254 //                                      IResource member = workspaceRoot.findMember(entry.getPath()); 
255 //                                      if (member != null && member.getType() == IResource.PROJECT){ // double check if bound to project (23977)
256 //                                              IProject projRsc = (IProject) member;
257 //                                              if (JavaProject.hasJavaNature(projRsc)) {                               
258 //                                                      JavaProject project = (JavaProject) JavaCore.create(projRsc);
259 //                                                      project.computeExpandedClasspath(
260 //                                                              initialProject, 
261 //                                                              ignoreUnresolvedVariable, 
262 //                                                              generateMarkerOnError,
263 //                                                              visitedProjects, 
264 //                                                              accumulatedEntries);
265 //                                              }
266 //                                      }
267 //                              }
268 //                      }                       
269 //              }
270 //      }
271         
272         /**
273          * Returns (local/all) the package fragment roots identified by the given project's classpath.
274          * Note: this follows project classpath references to find required project contributions,
275          * eliminating duplicates silently.
276          * Only works with resolved entries
277          */
278 //      public IPackageFragmentRoot[] computePackageFragmentRoots(IClasspathEntry[] resolvedClasspath, boolean retrieveExportedRoots) throws JavaModelException {
279 //
280 //              ObjectVector accumulatedRoots = new ObjectVector();
281 //              computePackageFragmentRoots(
282 //                      resolvedClasspath, 
283 //                      accumulatedRoots, 
284 //                      new HashSet(5), // rootIDs
285 //                      true, // inside original project
286 //                      true, // check existency
287 //                      retrieveExportedRoots);
288 //              IPackageFragmentRoot[] rootArray = new IPackageFragmentRoot[accumulatedRoots.size()];
289 //              accumulatedRoots.copyInto(rootArray);
290 //              return rootArray;
291 //      }
292 //
293 //      /**
294 //       * Computes the package fragment roots identified by the given entry.
295 //       * Only works with resolved entry
296 //       */
297 //      public IPackageFragmentRoot[] computePackageFragmentRoots(IClasspathEntry resolvedEntry) {
298 //              try {
299 //                      return 
300 //                              computePackageFragmentRoots(
301 //                                      new IClasspathEntry[]{ resolvedEntry }, 
302 //                                      false // don't retrieve exported roots
303 //                              );
304 //              } catch (JavaModelException e) {
305 //                      return new IPackageFragmentRoot[] {};
306 //              }
307 //      }
308         
309         /**
310          * Returns the package fragment roots identified by the given entry. In case it refers to
311          * a project, it will follow its classpath so as to find exported roots as well.
312          * Only works with resolved entry
313          */
314 //      public void computePackageFragmentRoots(
315 //              IClasspathEntry resolvedEntry,
316 //              ObjectVector accumulatedRoots, 
317 //              HashSet rootIDs, 
318 //              boolean insideOriginalProject,
319 //              boolean checkExistency,
320 //              boolean retrieveExportedRoots) throws JavaModelException {
321 //                      
322 //              String rootID = ((ClasspathEntry)resolvedEntry).rootID();
323 //              if (rootIDs.contains(rootID)) return;
324 //
325 //              IPath projectPath = getProject().getFullPath();
326 //              IPath entryPath = resolvedEntry.getPath();
327 //              IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
328 //              
329 //              switch(resolvedEntry.getEntryKind()){
330 //                      
331 //                      // source folder
332 //                      case IClasspathEntry.CPE_SOURCE :
333 //
334 //                              if (projectPath.isPrefixOf(entryPath)){
335 //                                      if (checkExistency) {
336 //                                              Object target = JavaModel.getTarget(workspaceRoot, entryPath, checkExistency);
337 //                                              if (target == null) return;
338 //      
339 //                                              if (target instanceof IFolder || target instanceof IProject){
340 //                                                      accumulatedRoots.add(
341 //                                                              getPackageFragmentRoot((IResource)target));
342 //                                                      rootIDs.add(rootID);
343 //                                              }
344 //                                      } else {
345 //                                              IPackageFragmentRoot root = getFolderPackageFragmentRoot(entryPath);
346 //                                              if (root != null) {
347 //                                                      accumulatedRoots.add(root);
348 //                                                      rootIDs.add(rootID);
349 //                                              }
350 //                                      }
351 //                              }
352 //                              break;
353 //
354 //                      // internal/external JAR or folder
355 //                      case IClasspathEntry.CPE_LIBRARY :
356 //                      
357 //                              if (!insideOriginalProject && !resolvedEntry.isExported()) return;
358 //                              
359 //                              if (checkExistency) {
360 //                                      Object target = JavaModel.getTarget(workspaceRoot, entryPath, checkExistency);
361 //                                      if (target == null) return;
362 //      
363 //                                      if (target instanceof IResource){
364 //                                              // internal target
365 //                                              IResource resource = (IResource) target;
366 //                                              IPackageFragmentRoot root = getPackageFragmentRoot(resource);
367 //                                              if (root != null) {
368 //                                                      accumulatedRoots.add(root);
369 //                                                      rootIDs.add(rootID);
370 //                                              }
371 //                                      } else {
372 //                                              // external target - only JARs allowed
373 //                                              if (((java.io.File)target).isFile() && (Util.isArchiveFileName(entryPath.lastSegment()))) {
374 //                                                      accumulatedRoots.add(
375 //                                                              new JarPackageFragmentRoot(entryPath, this));
376 //                                                      rootIDs.add(rootID);
377 //                                              }
378 //                                      }
379 //                              } else {
380 //                                      IPackageFragmentRoot root = getPackageFragmentRoot(entryPath);
381 //                                      if (root != null) {
382 //                                              accumulatedRoots.add(root);
383 //                                              rootIDs.add(rootID);
384 //                                      }
385 //                              }
386 //                              break;
387 //
388 //                      // recurse into required project
389 //                      case IClasspathEntry.CPE_PROJECT :
390 //
391 //                              if (!retrieveExportedRoots) return;
392 //                              if (!insideOriginalProject && !resolvedEntry.isExported()) return;
393 //
394 //                              IResource member = workspaceRoot.findMember(entryPath);
395 //                              if (member != null && member.getType() == IResource.PROJECT){// double check if bound to project (23977)
396 //                                      IProject requiredProjectRsc = (IProject) member;
397 //                                      if (JavaProject.hasJavaNature(requiredProjectRsc)){ // special builder binary output
398 //                                              rootIDs.add(rootID);
399 //                                              JavaProject requiredProject = (JavaProject)JavaCore.create(requiredProjectRsc);
400 //                                              requiredProject.computePackageFragmentRoots(
401 //                                                      requiredProject.getResolvedClasspath(true), 
402 //                                                      accumulatedRoots, 
403 //                                                      rootIDs, 
404 //                                                      false, 
405 //                                                      checkExistency, 
406 //                                                      retrieveExportedRoots);
407 //                                      }
408 //                              break;
409 //                      }
410 //              }
411 //      }
412
413         /**
414          * Returns (local/all) the package fragment roots identified by the given project's classpath.
415          * Note: this follows project classpath references to find required project contributions,
416          * eliminating duplicates silently.
417          * Only works with resolved entries
418          */
419 //      public void computePackageFragmentRoots(
420 //              IClasspathEntry[] resolvedClasspath,
421 //              ObjectVector accumulatedRoots, 
422 //              HashSet rootIDs, 
423 //              boolean insideOriginalProject,
424 //              boolean checkExistency,
425 //              boolean retrieveExportedRoots) throws JavaModelException {
426 //
427 //              if (insideOriginalProject){
428 //                      rootIDs.add(rootID());
429 //              }       
430 //              for (int i = 0, length = resolvedClasspath.length; i < length; i++){
431 //                      computePackageFragmentRoots(
432 //                              resolvedClasspath[i],
433 //                              accumulatedRoots,
434 //                              rootIDs,
435 //                              insideOriginalProject,
436 //                              checkExistency,
437 //                              retrieveExportedRoots);
438 //              }
439 //      }
440
441         /**
442          * Compute the file name to use for a given shared property
443          */
444         public String computeSharedPropertyFileName(QualifiedName qName) {
445
446                 return '.' + qName.getLocalName();
447         }
448         
449         /**
450          * Configure the project with Java nature.
451          */
452         public void configure() throws CoreException {
453
454                 // register Java builder
455                 addToBuildSpec(PHPeclipsePlugin.BUILDER_PARSER_ID);
456         }
457         /*
458          * Returns whether the given resource is accessible through the children or the non-Java resources of this project.
459          * Returns true if the resource is not in the project.
460          * Assumes that the resource is a folder or a file.
461          */
462 //      public boolean contains(IResource resource) {
463 //                      
464 //              IClasspathEntry[] classpath;
465 //              IPath output;
466 //              try {
467 //                      classpath = getResolvedClasspath(true);
468 //                      output = getOutputLocation();
469 //              } catch (JavaModelException e) {
470 //                      return false;
471 //              }
472 //              
473 //              IPath fullPath = resource.getFullPath();
474 //              IPath innerMostOutput = output.isPrefixOf(fullPath) ? output : null;
475 //              IClasspathEntry innerMostEntry = null;
476 //              for (int j = 0, cpLength = classpath.length; j < cpLength; j++) {
477 //                      IClasspathEntry entry = classpath[j];
478 //              
479 //                      IPath entryPath = entry.getPath();
480 //                      if ((innerMostEntry == null || innerMostEntry.getPath().isPrefixOf(entryPath))
481 //                                      && entryPath.isPrefixOf(fullPath)) {
482 //                              innerMostEntry = entry;
483 //                      }
484 //                      IPath entryOutput = classpath[j].getOutputLocation();
485 //                      if (entryOutput != null && entryOutput.isPrefixOf(fullPath)) {
486 //                              innerMostOutput = entryOutput;
487 //                      }
488 //              }
489 //              if (innerMostEntry != null) {
490 //                      // special case prj==src and nested output location
491 //                      if (innerMostOutput != null && innerMostOutput.segmentCount() > 1 // output isn't project
492 //                                      && innerMostEntry.getPath().segmentCount() == 1) { // 1 segment must be project name
493 //                              return false;
494 //                      }
495 //                      if  (resource instanceof IFolder) {
496 //                               // folders are always included in src/lib entries
497 //                               return true;
498 //                      }
499 //                      switch (innerMostEntry.getEntryKind()) {
500 //                              case IClasspathEntry.CPE_SOURCE:
501 //                                      // .class files are not visible in source folders 
502 //                                      return !Util.isClassFileName(fullPath.lastSegment());
503 //                              case IClasspathEntry.CPE_LIBRARY:
504 //                                      // .java files are not visible in library folders
505 //                                      return !Util.isJavaFileName(fullPath.lastSegment());
506 //                      }
507 //              }
508 //              if (innerMostOutput != null) {
509 //                      return false;
510 //              }
511 //              return true;
512 //      }
513
514         /**
515          * Record a new marker denoting a classpath problem
516          */
517 //      IMarker createClasspathProblemMarker(IJavaModelStatus status) {
518 //                      
519 //              IMarker marker = null;
520 //              int severity;
521 //              String[] arguments = new String[0];
522 //              boolean isCycleProblem = false, isClasspathFileFormatProblem = false;
523 //              switch (status.getCode()) {
524 //
525 //                      case  IJavaModelStatusConstants.CLASSPATH_CYCLE :
526 //                              isCycleProblem = true;
527 //                              if (JavaCore.ERROR.equals(getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true))) {
528 //                                      severity = IMarker.SEVERITY_ERROR;
529 //                              } else {
530 //                                      severity = IMarker.SEVERITY_WARNING;
531 //                              }
532 //                              break;
533 //
534 //                      case  IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT :
535 //                              isClasspathFileFormatProblem = true;
536 //                              severity = IMarker.SEVERITY_ERROR;
537 //                              break;
538 //
539 //                      default:
540 //                              IPath path = status.getPath();
541 //                              if (path != null) arguments = new String[] { path.toString() };
542 //                              if (JavaCore.ERROR.equals(getOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, true))) {
543 //                                      severity = IMarker.SEVERITY_ERROR;
544 //                              } else {
545 //                                      severity = IMarker.SEVERITY_WARNING;
546 //                              }
547 //                              break;
548 //              }
549 //              
550 //              try {
551 //                      marker = getProject().createMarker(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER);
552 //                      marker.setAttributes(
553 //                              new String[] { 
554 //                                      IMarker.MESSAGE, 
555 //                                      IMarker.SEVERITY, 
556 //                                      IMarker.LOCATION, 
557 //                                      IJavaModelMarker.CYCLE_DETECTED,
558 //                                      IJavaModelMarker.CLASSPATH_FILE_FORMAT,
559 //                                      IJavaModelMarker.ID,
560 //                                      IJavaModelMarker.ARGUMENTS ,
561 //                              },
562 //                              new Object[] {
563 //                                      status.getMessage(),
564 //                                      new Integer(severity), 
565 //                                      Util.bind("classpath.buildPath"),//$NON-NLS-1$
566 //                                      isCycleProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$
567 //                                      isClasspathFileFormatProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$
568 //                                      new Integer(status.getCode()),
569 //                                      Util.getProblemArgumentsForMarker(arguments) ,
570 //                              }
571 //                      );
572 //              } catch (CoreException e) {
573 //              }
574 //              return marker;
575 //      }
576         
577         /**
578          * Returns a new element info for this element.
579          */
580 //      protected OpenableElementInfo createElementInfo() {
581 //
582 //              return new JavaProjectElementInfo();
583 //      }
584
585         /**
586          * Reads and decode an XML classpath string
587          */
588 //      protected IClasspathEntry[] decodeClasspath(String xmlClasspath, boolean createMarker, boolean logProblems) {
589 //
590 //              ArrayList paths = new ArrayList();
591 //              IClasspathEntry defaultOutput = null;
592 //              try {
593 //                      if (xmlClasspath == null) return null;
594 //                      StringReader reader = new StringReader(xmlClasspath);
595 //                      Element cpElement;
596 //      
597 //                      try {
598 //                              DocumentBuilder parser =
599 //                                      DocumentBuilderFactory.newInstance().newDocumentBuilder();
600 //                              cpElement = parser.parse(new InputSource(reader)).getDocumentElement();
601 //                      } catch (SAXException e) {
602 //                              throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$
603 //                      } catch (ParserConfigurationException e) {
604 //                              throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$
605 //                      } finally {
606 //                              reader.close();
607 //                      }
608 //      
609 //                      if (!cpElement.getNodeName().equalsIgnoreCase("classpath")) { //$NON-NLS-1$
610 //                              throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$
611 //                      }
612 //                      NodeList list = cpElement.getElementsByTagName("classpathentry"); //$NON-NLS-1$
613 //                      int length = list.getLength();
614 //      
615 //                      for (int i = 0; i < length; ++i) {
616 //                              Node node = list.item(i);
617 //                              if (node.getNodeType() == Node.ELEMENT_NODE) {
618 //                                      IClasspathEntry entry = ClasspathEntry.elementDecode((Element)node, this);
619 //                                      if (entry != null){
620 //                                              if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) { 
621 //                                                      defaultOutput = entry; // separate output
622 //                                              } else {
623 //                                                      paths.add(entry);
624 //                              }
625 //                      }
626 //                              }
627 //                      }
628 //              } catch (IOException e) {
629 //                      // bad format
630 //                      if (createMarker && this.getProject().isAccessible()) {
631 //                                      this.createClasspathProblemMarker(new JavaModelStatus(
632 //                                                      IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
633 //                                                      Util.bind("classpath.xmlFormatError", this.getElementName(), e.getMessage()))); //$NON-NLS-1$
634 //                      }
635 //                      if (logProblems) {
636 //                              Util.log(e, 
637 //                                      "Exception while retrieving "+ this.getPath() //$NON-NLS-1$
638 //                                      +"/.classpath, will mark classpath as invalid"); //$NON-NLS-1$
639 //                      }
640 //                      return INVALID_CLASSPATH;
641 //              } catch (Assert.AssertionFailedException e) { 
642 //                      // failed creating CP entries from file
643 //                      if (createMarker && this.getProject().isAccessible()) {
644 //                              this.createClasspathProblemMarker(new JavaModelStatus(
645 //                                              IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
646 //                                              Util.bind("classpath.illegalEntryInClasspathFile", this.getElementName(), e.getMessage()))); //$NON-NLS-1$
647 //                      }
648 //                      if (logProblems) {
649 //                              Util.log(e, 
650 //                                      "Exception while retrieving "+ this.getPath() //$NON-NLS-1$
651 //                                      +"/.classpath, will mark classpath as invalid"); //$NON-NLS-1$
652 //                      }
653 //                      return INVALID_CLASSPATH;
654 //              }
655 //              int pathSize = paths.size();
656 //              if (pathSize > 0 || defaultOutput != null) {
657 //                      IClasspathEntry[] entries = new IClasspathEntry[pathSize + (defaultOutput == null ? 0 : 1)];
658 //                      paths.toArray(entries);
659 //                      if (defaultOutput != null) entries[pathSize] = defaultOutput; // ensure output is last item
660 //                      return entries;
661 //              } else {
662 //                      return null;
663 //              }
664 //      }
665
666         /**
667         /**
668          * Removes the Java nature from the project.
669          */
670         public void deconfigure() throws CoreException {
671
672                 // deregister Java builder
673                 removeFromBuildSpec(PHPeclipsePlugin.BUILDER_PARSER_ID);
674         }
675 //
676 //      /**
677 //       * Returns a default class path.
678 //       * This is the root of the project
679 //       */
680 //      protected IClasspathEntry[] defaultClasspath() throws JavaModelException {
681 //
682 //              return new IClasspathEntry[] {
683 //                       JavaCore.newSourceEntry(getProject().getFullPath())};
684 //      }
685
686         /**
687          * Returns a default output location.
688          * This is the project bin folder
689          */
690         protected IPath defaultOutputLocation() throws JavaModelException {
691                 return getProject().getFullPath().append("bin"); //$NON-NLS-1$
692         }
693
694         /**
695          * Returns the XML String encoding of the class path.
696          */
697 //      protected String encodeClasspath(IClasspathEntry[] classpath, IPath outputLocation, boolean useLineSeparator) throws JavaModelException {
698 //
699 //              Document document = new DocumentImpl();
700 //              Element cpElement = document.createElement("classpath"); //$NON-NLS-1$
701 //              document.appendChild(cpElement);
702 //
703 //              for (int i = 0; i < classpath.length; ++i) {
704 //                      cpElement.appendChild(((ClasspathEntry)classpath[i]).elementEncode(document, getProject().getFullPath()));
705 //              }
706 //
707 //              if (outputLocation != null) {
708 //                      outputLocation = outputLocation.removeFirstSegments(1);
709 //                      outputLocation = outputLocation.makeRelative();
710 //                      Element oElement = document.createElement("classpathentry"); //$NON-NLS-1$
711 //                      oElement.setAttribute("kind", ClasspathEntry.kindToString(ClasspathEntry.K_OUTPUT));    //$NON-NLS-1$
712 //                      oElement.setAttribute("path", outputLocation.toString()); //$NON-NLS-1$
713 //                      cpElement.appendChild(oElement);
714 //              }
715 //
716 //              // produce a String output
717 //              try {
718 //                      ByteArrayOutputStream s = new ByteArrayOutputStream();
719 //                      OutputFormat format = new OutputFormat();
720 //                      if (useLineSeparator) {
721 //                              format.setIndenting(true);
722 //                              format.setLineSeparator(System.getProperty("line.separator"));  //$NON-NLS-1$
723 //                      } else {
724 //                              format.setPreserveSpace(true);
725 //                      }                       
726 //                      Serializer serializer =
727 //                              SerializerFactory.getSerializerFactory(Method.XML).makeSerializer(
728 //                                      new OutputStreamWriter(s, "UTF8"), //$NON-NLS-1$
729 //                                      format);
730 //                      serializer.asDOMSerializer().serialize(document);
731 //                      return s.toString("UTF8"); //$NON-NLS-1$
732 //              } catch (IOException e) {
733 //                      throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
734 //              }
735 //      }
736 //      
737         /**
738          * Returns true if this handle represents the same Java project
739          * as the given handle. Two handles represent the same
740          * project if they are identical or if they represent a project with 
741          * the same underlying resource and occurrence counts.
742          *
743          * @see JavaElement#equals
744          */
745         public boolean equals(Object o) {
746
747                 if (this == o)
748                         return true;
749
750                 if (!(o instanceof JavaProject))
751                         return false;
752
753                 JavaProject other = (JavaProject) o;
754                 return getProject().equals(other.getProject())
755                         && fOccurrenceCount == other.fOccurrenceCount;
756         }
757
758         public boolean exists() {
759                 if (!hasJavaNature(fProject)) return false;
760                 return super.exists();
761         }       
762
763         /**
764          * @see IJavaProject
765          */
766 //      public IJavaElement findElement(IPath path) throws JavaModelException {
767 //
768 //              if (path == null || path.isAbsolute()) {
769 //                      throw new JavaModelException(
770 //                              new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, path));
771 //              }
772 //              try {
773 //
774 //                      String extension = path.getFileExtension();
775 //                      if (extension == null) {
776 //                              String packageName = path.toString().replace(IPath.SEPARATOR, '.');
777 //
778 //                              IPackageFragment[] pkgFragments =
779 //                                      getNameLookup().findPackageFragments(packageName, false);
780 //                              if (pkgFragments == null) {
781 //                                      return null;
782 //
783 //                              } else {
784 //                                      // try to return one that is a child of this project
785 //                                      for (int i = 0, length = pkgFragments.length; i < length; i++) {
786 //
787 //                                              IPackageFragment pkgFragment = pkgFragments[i];
788 //                                              if (this.equals(pkgFragment.getParent().getParent())) {
789 //                                                      return pkgFragment;
790 //                                              }
791 //                                      }
792 //                                      // default to the first one
793 //                                      return pkgFragments[0];
794 //                              }
795 //                      } else if (
796 //                              extension.equalsIgnoreCase("java") //$NON-NLS-1$
797 //                                      || extension.equalsIgnoreCase("class")) {  //$NON-NLS-1$
798 //                              IPath packagePath = path.removeLastSegments(1);
799 //                              String packageName = packagePath.toString().replace(IPath.SEPARATOR, '.');
800 //                              String typeName = path.lastSegment();
801 //                              typeName = typeName.substring(0, typeName.length() - extension.length() - 1);
802 //                              String qualifiedName = null;
803 //                              if (packageName.length() > 0) {
804 //                                      qualifiedName = packageName + "." + typeName; //$NON-NLS-1$
805 //                              } else {
806 //                                      qualifiedName = typeName;
807 //                              }
808 //                              IType type =
809 //                                      getNameLookup().findType(
810 //                                              qualifiedName,
811 //                                              false,
812 //                                              NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES);
813 //                              if (type != null) {
814 //                                      return type.getParent();
815 //                              } else {
816 //                                      return null;
817 //                              }
818 //                      } else {
819 //                              // unsupported extension
820 //                              return null;
821 //                      }
822 //              } catch (JavaModelException e) {
823 //                      if (e.getStatus().getCode()
824 //                              == IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST) {
825 //                              return null;
826 //                      } else {
827 //                              throw e;
828 //                      }
829 //              }
830 //      }
831
832         /**
833          * @see IJavaProject
834          */
835 //      public IPackageFragment findPackageFragment(IPath path)
836 //              throws JavaModelException {
837 //
838 //              return findPackageFragment0(JavaProject.canonicalizedPath(path));
839 //      }
840
841         /**
842          * non path canonicalizing version
843          */
844 //      public IPackageFragment findPackageFragment0(IPath path) 
845 //              throws JavaModelException {
846 //
847 //              return getNameLookup().findPackageFragment(path);
848 //      }
849
850         /**
851          * @see IJavaProject
852          */
853 //      public IPackageFragmentRoot findPackageFragmentRoot(IPath path)
854 //              throws JavaModelException {
855 //
856 //              return findPackageFragmentRoot0(JavaProject.canonicalizedPath(path));
857 //      }
858
859         /**
860          * no path canonicalization 
861          */
862 //      public IPackageFragmentRoot findPackageFragmentRoot0(IPath path)
863 //              throws JavaModelException {
864 //
865 //              IPackageFragmentRoot[] allRoots = this.getAllPackageFragmentRoots();
866 //              if (!path.isAbsolute()) {
867 //                      throw new IllegalArgumentException(Util.bind("path.mustBeAbsolute")); //$NON-NLS-1$
868 //              }
869 //              for (int i= 0; i < allRoots.length; i++) {
870 //                      IPackageFragmentRoot classpathRoot= allRoots[i];
871 //                      if (classpathRoot.getPath().equals(path)) {
872 //                              return classpathRoot;
873 //                      }
874 //              }
875 //              return null;
876 //      }
877         /**
878          * @see IJavaProject
879          */
880 //      public IPackageFragmentRoot[] findPackageFragmentRoots(IClasspathEntry entry) {
881 //              try {
882 //                      IClasspathEntry[] classpath = this.getRawClasspath();
883 //                      for (int i = 0, length = classpath.length; i < length; i++) {
884 //                              if (classpath[i].equals(entry)) { // entry may need to be resolved
885 //                                      return 
886 //                                              computePackageFragmentRoots(
887 //                                                      getResolvedClasspath(new IClasspathEntry[] {entry}, null, true, false, null/*no reverse map*/), 
888 //                                                      false); // don't retrieve exported roots
889 //                              }
890 //                      }
891 //              } catch (JavaModelException e) {
892 //              }
893 //              return new IPackageFragmentRoot[] {};
894 //      }
895 //      
896         /**
897          * @see IJavaProject#findType(String)
898          */
899 //      public IType findType(String fullyQualifiedName) throws JavaModelException {
900 //              IType type = 
901 //                      this.getNameLookup().findType(
902 //                              fullyQualifiedName, 
903 //                              false,
904 //                              NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES);
905 //              if (type == null) {
906 //                      // try to find enclosing type
907 //                      int lastDot = fullyQualifiedName.lastIndexOf('.');
908 //                      if (lastDot == -1) return null;
909 //                      type = this.findType(fullyQualifiedName.substring(0, lastDot));
910 //                      if (type != null) {
911 //                              type = type.getType(fullyQualifiedName.substring(lastDot+1));
912 //                              if (!type.exists()) {
913 //                                      return null;
914 //                              }
915 //                      }
916 //              }
917 //              return type;
918 //      }
919         
920         /**
921          * @see IJavaProject#findType(String, String)
922          */
923 //      public IType findType(String packageName, String typeQualifiedName) throws JavaModelException {
924 //              return 
925 //                      this.getNameLookup().findType(
926 //                              typeQualifiedName, 
927 //                              packageName,
928 //                              false,
929 //                              NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES);
930 //      }       
931 //      
932 //      /**
933 //       * Remove all markers denoting classpath problems
934 //       */
935 //      protected void flushClasspathProblemMarkers(boolean flushCycleMarkers, boolean flushClasspathFormatMarkers) {
936 //              try {
937 //                      IProject project = getProject();
938 //                      if (project.exists()) {
939 //                              IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
940 //                              for (int i = 0, length = markers.length; i < length; i++) {
941 //                                      IMarker marker = markers[i];
942 //                                      if (flushCycleMarkers && flushClasspathFormatMarkers) {
943 //                                              marker.delete();
944 //                                      } else {
945 //                                              String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED);
946 //                                              String classpathFileFormatAttr =  (String)marker.getAttribute(IJavaModelMarker.CLASSPATH_FILE_FORMAT);
947 //                                              if ((flushCycleMarkers == (cycleAttr != null && cycleAttr.equals("true"))) //$NON-NLS-1$
948 //                                                      && (flushClasspathFormatMarkers == (classpathFileFormatAttr != null && classpathFileFormatAttr.equals("true")))){ //$NON-NLS-1$
949 //                                                      marker.delete();
950 //                                              }
951 //                                      }
952 //                              }
953 //                      }
954 //              } catch (CoreException e) {
955 //              }
956 //      }
957 //
958 //      /**
959 //       * @see Openable
960 //       */
961 //      protected boolean generateInfos(
962 //              OpenableElementInfo info,
963 //              IProgressMonitor pm,
964 //              Map newElements,
965 //              IResource underlyingResource) throws JavaModelException {
966 //
967 //              boolean validInfo = false;
968 //              try {
969 //                      if (getProject().isOpen()) {
970 //                              // put the info now, because computing the roots requires it
971 //                              JavaModelManager.getJavaModelManager().putInfo(this, info);
972 //
973 //                              // compute the pkg fragment roots
974 //                              updatePackageFragmentRoots();                           
975 //      
976 //                              // remember the timestamps of external libraries the first time they are looked up
977 //                              IClasspathEntry[] resolvedClasspath = getResolvedClasspath(true/*ignore unresolved variable*/);
978 //                              for (int i = 0, length = resolvedClasspath.length; i < length; i++) {
979 //                                      IClasspathEntry entry = resolvedClasspath[i];
980 //                                      if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
981 //                                              IPath path = entry.getPath();
982 //                                              Object target = JavaModel.getTarget(ResourcesPlugin.getWorkspace().getRoot(), path, true);
983 //                                              if (target instanceof java.io.File) {
984 //                                                      Map externalTimeStamps = JavaModelManager.getJavaModelManager().deltaProcessor.externalTimeStamps;
985 //                                                      if (externalTimeStamps.get(path) == null) {
986 //                                                              long timestamp = DeltaProcessor.getTimeStamp((java.io.File)target);
987 //                                                              externalTimeStamps.put(path, new Long(timestamp));                                                      
988 //                                                      }
989 //                                              }
990 //                                      }
991 //                              }                       
992 //
993 //                              // only valid if reaches here                           
994 //                              validInfo = true;
995 //                      }
996 //              } finally {
997 //                      if (!validInfo)
998 //                              JavaModelManager.getJavaModelManager().removeInfo(this);
999 //              }
1000 //              return validInfo;
1001 //      }
1002
1003         /**
1004          * @see IJavaProject
1005          */
1006 //      public IPackageFragmentRoot[] getAllPackageFragmentRoots()
1007 //              throws JavaModelException {
1008 //
1009 //              return computePackageFragmentRoots(getResolvedClasspath(true), true);
1010 //      }
1011 //
1012 //      /**
1013 //       * Returns the classpath entry that refers to the given path
1014 //       * or <code>null</code> if there is no reference to the path.
1015 //       */
1016 //      public IClasspathEntry getClasspathEntryFor(IPath path)
1017 //              throws JavaModelException {
1018 //
1019 //              IClasspathEntry[] entries = getExpandedClasspath(true);
1020 //              for (int i = 0; i < entries.length; i++) {
1021 //                      if (entries[i].getPath().equals(path)) {
1022 //                              return entries[i];
1023 //                      }
1024 //              }
1025 //              return null;
1026 //      }
1027
1028         /*
1029          * Returns the cycle marker associated with this project or null if none.
1030          */
1031 //      public IMarker getCycleMarker(){
1032 //              try {
1033 //                      IProject project = getProject();
1034 //                      if (project.exists()) {
1035 //                              IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
1036 //                              for (int i = 0, length = markers.length; i < length; i++) {
1037 //                                      IMarker marker = markers[i];
1038 //                                      String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED);
1039 //                                      if (cycleAttr != null && cycleAttr.equals("true")){ //$NON-NLS-1$
1040 //                                              return marker;
1041 //                                      }
1042 //                              }
1043 //                      }
1044 //              } catch (CoreException e) {
1045 //              }
1046 //              return null;
1047 //      }
1048 //
1049 //      /**
1050 //       * This is a helper method returning the expanded classpath for the project, as a list of classpath entries, 
1051 //       * where all classpath variable entries have been resolved and substituted with their final target entries.
1052 //       * All project exports have been appended to project entries.
1053 //       */
1054 //      public IClasspathEntry[] getExpandedClasspath(boolean ignoreUnresolvedVariable) throws JavaModelException {
1055 //                      
1056 //                      return getExpandedClasspath(ignoreUnresolvedVariable, false);
1057 //      }
1058                 
1059         /**
1060          * Internal variant which can create marker on project for invalid entries,
1061          * it will also perform classpath expansion in presence of project prerequisites
1062          * exporting their entries.
1063          */
1064 //      public IClasspathEntry[] getExpandedClasspath(
1065 //              boolean ignoreUnresolvedVariable,
1066 //              boolean generateMarkerOnError) throws JavaModelException {
1067 //      
1068 //              ObjectVector accumulatedEntries = new ObjectVector();           
1069 //              computeExpandedClasspath(this, ignoreUnresolvedVariable, generateMarkerOnError, new HashSet(5), accumulatedEntries);
1070 //              
1071 //              IClasspathEntry[] expandedPath = new IClasspathEntry[accumulatedEntries.size()];
1072 //              accumulatedEntries.copyInto(expandedPath);
1073 //
1074 //              return expandedPath;
1075 //      }
1076
1077         /**
1078          * Returns the <code>char</code> that marks the start of this handles
1079          * contribution to a memento.
1080          */
1081         protected char getHandleMementoDelimiter() {
1082
1083                 return JEM_JAVAPROJECT;
1084         }
1085
1086         /**
1087          * Find the specific Java command amongst the build spec of a given description
1088          */
1089         private ICommand getJavaCommand(IProjectDescription description)
1090                 throws CoreException {
1091
1092                 ICommand[] commands = description.getBuildSpec();
1093                 for (int i = 0; i < commands.length; ++i) {
1094                         if (commands[i].getBuilderName().equals(PHPeclipsePlugin.BUILDER_PARSER_ID)) {
1095                                 return commands[i];
1096                         }
1097                 }
1098                 return null;
1099         }
1100 //
1101 //      /**
1102 //       * Convenience method that returns the specific type of info for a Java project.
1103 //       */
1104 //      protected JavaProjectElementInfo getJavaProjectElementInfo()
1105 //              throws JavaModelException {
1106 //
1107 //              return (JavaProjectElementInfo) getElementInfo();
1108 //      }
1109
1110         /**
1111          * @see IJavaProject
1112          */
1113 //      public NameLookup getNameLookup() throws JavaModelException {
1114 //
1115 //              JavaProjectElementInfo info = getJavaProjectElementInfo();
1116 //              // lock on the project info to avoid race condition
1117 //              synchronized(info){
1118 //                      NameLookup nameLookup;
1119 //                      if ((nameLookup = info.getNameLookup()) == null){
1120 //                              info.setNameLookup(nameLookup = new NameLookup(this));
1121 //                      }
1122 //                      return nameLookup;
1123 //              }
1124 //      }
1125 //
1126 //      /**
1127 //       * Returns an array of non-java resources contained in the receiver.
1128 //       */
1129 //      public Object[] getNonJavaResources() throws JavaModelException {
1130 //
1131 //              return ((JavaProjectElementInfo) getElementInfo()).getNonJavaResources(this);
1132 //      }
1133
1134         /**
1135          * @see org.eclipse.jdt.core.IJavaProject#getOption(String, boolean)
1136          */     
1137 //      public String getOption(String optionName, boolean inheritJavaCoreOptions) {
1138 //              
1139 //              if (JavaModelManager.OptionNames.contains(optionName)){
1140 //                      
1141 //                      Preferences preferences = getPreferences();
1142 //                      if (preferences == null || preferences.isDefault(optionName)) {
1143 //                              return inheritJavaCoreOptions ? PHPCore.getOption(optionName) : null;
1144 //                      }
1145 //                      return preferences.getString(optionName).trim();
1146 //              }
1147 //              return null;
1148 //      }
1149         
1150         /**
1151          * @see org.eclipse.jdt.core.IJavaProject#getOptions(boolean)
1152          */
1153 //      public Map getOptions(boolean inheritJavaCoreOptions) {
1154 //              
1155 //              // initialize to the defaults from JavaCore options pool
1156 //              Map options = inheritJavaCoreOptions ? PHPCore.getOptions() : new Hashtable(5);
1157 //
1158 //              Preferences preferences = getPreferences();
1159 //              if (preferences == null) return options; // cannot do better (non-Java project)
1160 //              HashSet optionNames = JavaModelManager.OptionNames;
1161 //              
1162 //              // get preferences set to their default
1163 //              if (inheritJavaCoreOptions){
1164 //                      String[] defaultPropertyNames = preferences.defaultPropertyNames();
1165 //                      for (int i = 0; i < defaultPropertyNames.length; i++){
1166 //                              String propertyName = defaultPropertyNames[i];
1167 //                              if (optionNames.contains(propertyName)){
1168 //                                      options.put(propertyName, preferences.getDefaultString(propertyName).trim());
1169 //                              }
1170 //                      }               
1171 //              }
1172 //              // get custom preferences not set to their default
1173 //              String[] propertyNames = preferences.propertyNames();
1174 //              for (int i = 0; i < propertyNames.length; i++){
1175 //                      String propertyName = propertyNames[i];
1176 //                      if (optionNames.contains(propertyName)){
1177 //                              options.put(propertyName, preferences.getString(propertyName).trim());
1178 //                      }
1179 //              }               
1180 //              return options;
1181 //      }
1182         
1183         /**
1184          * @see IJavaProject
1185          */
1186 //      public IPath getOutputLocation() throws JavaModelException {
1187 //
1188 //              JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject);
1189 //              IPath outputLocation = perProjectInfo.outputLocation;
1190 //              if (outputLocation != null) return outputLocation;
1191 //
1192 //              // force to read classpath - will position output location as well
1193 //              this.getRawClasspath();
1194 //              outputLocation = perProjectInfo.outputLocation;
1195 //              if (outputLocation == null) {
1196 //                      return defaultOutputLocation();
1197 //              }
1198 //              return outputLocation;
1199 //      }
1200 //
1201 //      /**
1202 //       * @return A handle to the package fragment root identified by the given path.
1203 //       * This method is handle-only and the element may or may not exist. Returns
1204 //       * <code>null</code> if unable to generate a handle from the path (for example,
1205 //       * an absolute path that has less than 1 segment. The path may be relative or
1206 //       * absolute.
1207 //       */
1208 //      public IPackageFragmentRoot getPackageFragmentRoot(IPath path) {
1209 //              if (!path.isAbsolute()) {
1210 //                      path = getPath().append(path);
1211 //              }
1212 //              int segmentCount = path.segmentCount();
1213 //              switch (segmentCount) {
1214 //                      case 0:
1215 //                              return null;
1216 //                      case 1:
1217 //                              // default root
1218 //                              return getPackageFragmentRoot(getProject());
1219 //                      default:
1220 //                              // a path ending with .jar/.zip is still ambiguous and could still resolve to a source/lib folder 
1221 //                              // thus will try to guess based on existing resource
1222 //                              if (Util.isArchiveFileName(path.lastSegment())) {
1223 //                                      IResource resource = getProject().getWorkspace().getRoot().findMember(path); 
1224 //                                      if (resource != null && resource.getType() == IResource.FOLDER){
1225 //                                              return getPackageFragmentRoot(resource);
1226 //                                      }
1227 //                                      return getPackageFragmentRoot0(path);
1228 //                              } else {
1229 //                                      return getPackageFragmentRoot(getProject().getWorkspace().getRoot().getFolder(path));
1230 //                              }
1231 //              }
1232 //      }
1233 //
1234 //      /**
1235 //       * The path is known to match a source/library folder entry.
1236 //       */
1237 //      public IPackageFragmentRoot getFolderPackageFragmentRoot(IPath path) {
1238 //              if (path.segmentCount() == 1) { // default project root
1239 //                      return getPackageFragmentRoot(getProject());
1240 //              }
1241 //              return getPackageFragmentRoot(getProject().getWorkspace().getRoot().getFolder(path));
1242 //      }
1243 //      
1244 //      /**
1245 //       * @see IJavaProject
1246 //       */
1247 //      public IPackageFragmentRoot getPackageFragmentRoot(IResource resource) {
1248 //
1249 //              switch (resource.getType()) {
1250 //                      case IResource.FILE:
1251 //                              if (Util.isArchiveFileName(resource.getName())) {
1252 //                                      return new JarPackageFragmentRoot(resource, this);
1253 //                              } else {
1254 //                                      return null;
1255 //                              }
1256 //                      case IResource.FOLDER:
1257 //                              return new PackageFragmentRoot(resource, this, resource.getName());
1258 //                      case IResource.PROJECT:
1259 //                              return new PackageFragmentRoot(resource, this, ""); //$NON-NLS-1$
1260 //                      default:
1261 //                              return null;
1262 //              }
1263 //      }
1264 //
1265 //      /**
1266 //       * @see IJavaProject
1267 //       */
1268 //      public IPackageFragmentRoot getPackageFragmentRoot(String jarPath) {
1269 //
1270 //              return getPackageFragmentRoot0(JavaProject.canonicalizedPath(new Path(jarPath)));
1271 //      }
1272 //      
1273 //      /**
1274 //       * no path canonicalization
1275 //       */
1276 //      public IPackageFragmentRoot getPackageFragmentRoot0(IPath jarPath) {
1277 //
1278 //              return new JarPackageFragmentRoot(jarPath, this);
1279 //      }
1280 //
1281 //      /**
1282 //       * @see IJavaProject
1283 //       */
1284 //      public IPackageFragmentRoot[] getPackageFragmentRoots()
1285 //              throws JavaModelException {
1286 //
1287 //              Object[] children;
1288 //              int length;
1289 //              IPackageFragmentRoot[] roots;
1290 //
1291 //              System.arraycopy(
1292 //                      children = getChildren(), 
1293 //                      0, 
1294 //                      roots = new IPackageFragmentRoot[length = children.length], 
1295 //                      0, 
1296 //                      length);
1297 //                      
1298 //              return roots;
1299 //      }
1300
1301         /**
1302          * @see IJavaProject
1303          * @deprecated
1304          */
1305 //      public IPackageFragmentRoot[] getPackageFragmentRoots(IClasspathEntry entry) {
1306 //              return findPackageFragmentRoots(entry);
1307 //      }
1308
1309         /**
1310          * Returns the package fragment root prefixed by the given path, or
1311          * an empty collection if there are no such elements in the model.
1312          */
1313 //      protected IPackageFragmentRoot[] getPackageFragmentRoots(IPath path)
1314 //
1315 //              throws JavaModelException {
1316 //              IPackageFragmentRoot[] roots = getAllPackageFragmentRoots();
1317 //              ArrayList matches = new ArrayList();
1318 //
1319 //              for (int i = 0; i < roots.length; ++i) {
1320 //                      if (path.isPrefixOf(roots[i].getPath())) {
1321 //                              matches.add(roots[i]);
1322 //                      }
1323 //              }
1324 //              IPackageFragmentRoot[] copy = new IPackageFragmentRoot[matches.size()];
1325 //              matches.toArray(copy);
1326 //              return copy;
1327 //      }
1328
1329         /**
1330          * @see IJavaProject
1331          */
1332 //      public IPackageFragment[] getPackageFragments() throws JavaModelException {
1333 //
1334 //              IPackageFragmentRoot[] roots = getPackageFragmentRoots();
1335 //              return getPackageFragmentsInRoots(roots);
1336 //      }
1337
1338         /**
1339          * Returns all the package fragments found in the specified
1340          * package fragment roots.
1341          */
1342 //      public IPackageFragment[] getPackageFragmentsInRoots(IPackageFragmentRoot[] roots) {
1343 //
1344 //              ArrayList frags = new ArrayList();
1345 //              for (int i = 0; i < roots.length; i++) {
1346 //                      IPackageFragmentRoot root = roots[i];
1347 //                      try {
1348 //                              IJavaElement[] rootFragments = root.getChildren();
1349 //                              for (int j = 0; j < rootFragments.length; j++) {
1350 //                                      frags.add(rootFragments[j]);
1351 //                              }
1352 //                      } catch (JavaModelException e) {
1353 //                              // do nothing
1354 //                      }
1355 //              }
1356 //              IPackageFragment[] fragments = new IPackageFragment[frags.size()];
1357 //              frags.toArray(fragments);
1358 //              return fragments;
1359 //      }
1360         
1361         /*
1362          * @see IJavaElement
1363          */
1364         public IPath getPath() {
1365                 return this.getProject().getFullPath();
1366         }
1367         
1368         /**
1369          * @see IJavaProject
1370          */
1371         public IProject getProject() {
1372
1373                 return fProject;
1374         }
1375
1376         /**
1377          * Returns the project custom preference pool.
1378          * Project preferences may include custom encoding.
1379          */     
1380 //      public Preferences getPreferences(){
1381 //              IProject project = getProject();
1382 //              if (!JavaProject.hasJavaNature(project)) return null;
1383 //              JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(project, true);
1384 //              Preferences preferences =  perProjectInfo.preferences;
1385 //              if (preferences != null) return preferences;
1386 //              preferences = loadPreferences();
1387 //              if (preferences == null) preferences = new Preferences();
1388 //              perProjectInfo.preferences = preferences;
1389 //              return preferences;
1390 //      }
1391
1392         /**
1393          * @see IJavaProject
1394          */
1395 //      public IClasspathEntry[] getRawClasspath() throws JavaModelException {
1396 //
1397 //              JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject);
1398 //              IClasspathEntry[] classpath = perProjectInfo.classpath;
1399 //              if (classpath != null) return classpath;
1400 //              classpath = this.readClasspathFile(false/*don't create markers*/, true/*log problems*/);
1401 //              
1402 //              // extract out the output location
1403 //              IPath outputLocation = null;
1404 //              if (classpath != null && classpath.length > 0) {
1405 //                      IClasspathEntry entry = classpath[classpath.length - 1];
1406 //                      if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) {
1407 //                              outputLocation = entry.getPath();
1408 //                              IClasspathEntry[] copy = new IClasspathEntry[classpath.length - 1];
1409 //                              System.arraycopy(classpath, 0, copy, 0, copy.length);
1410 //                              classpath = copy;
1411 //                      }
1412 //              }
1413 //              if (classpath == null) {
1414 //                      return defaultClasspath();
1415 //              }
1416 //              /* Disable validate: classpath can contain CP variables and container that need to be resolved 
1417 //              if (classpath != INVALID_CLASSPATH
1418 //                              && !JavaConventions.validateClasspath(this, classpath, outputLocation).isOK()) {
1419 //                      classpath = INVALID_CLASSPATH;
1420 //              }
1421 //              */
1422 //              perProjectInfo.classpath = classpath;
1423 //              perProjectInfo.outputLocation = outputLocation;
1424 //              return classpath;
1425 //      }
1426
1427         /**
1428          * @see IJavaProject#getRequiredProjectNames
1429          */
1430 //      public String[] getRequiredProjectNames() throws JavaModelException {
1431 //
1432 //              return this.projectPrerequisites(getResolvedClasspath(true));
1433 //      }
1434
1435         /**
1436          * @see IJavaProject
1437          */
1438 //      public IClasspathEntry[] getResolvedClasspath(boolean ignoreUnresolvedEntry)
1439 //              throws JavaModelException {
1440 //
1441 //              return 
1442 //                      this.getResolvedClasspath(
1443 //                              ignoreUnresolvedEntry, 
1444 //                              false); // generateMarkerOnError
1445 //      }
1446
1447         /**
1448          * Internal variant which can create marker on project for invalid entries
1449          * and caches the resolved classpath on perProjectInfo
1450          */
1451 //      public IClasspathEntry[] getResolvedClasspath(
1452 //              boolean ignoreUnresolvedEntry,
1453 //              boolean generateMarkerOnError)
1454 //              throws JavaModelException {
1455 //
1456 //              JavaModelManager manager = JavaModelManager.getJavaModelManager();
1457 //              JavaModelManager.PerProjectInfo perProjectInfo = manager.getPerProjectInfoCheckExistence(fProject);
1458 //              
1459 //              // reuse cache if not needing to refresh markers or checking bound variables
1460 //              if (ignoreUnresolvedEntry && !generateMarkerOnError && perProjectInfo != null){
1461 //                      // resolved path is cached on its info
1462 //                      IClasspathEntry[] infoPath = perProjectInfo.lastResolvedClasspath;
1463 //                      if (infoPath != null) return infoPath;
1464 //              }
1465 //              Map reverseMap = perProjectInfo == null ? null : new HashMap(5);
1466 //              IClasspathEntry[] resolvedPath = getResolvedClasspath(
1467 //                      getRawClasspath(), 
1468 //                      generateMarkerOnError ? getOutputLocation() : null, 
1469 //                      ignoreUnresolvedEntry, 
1470 //                      generateMarkerOnError,
1471 //                      reverseMap);
1472 //
1473 //              if (perProjectInfo != null){
1474 //                      if (perProjectInfo.classpath == null // .classpath file could not be read
1475 //                              && generateMarkerOnError 
1476 //                              && JavaProject.hasJavaNature(fProject)) {
1477 //                                      this.createClasspathProblemMarker(new JavaModelStatus(
1478 //                                              IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
1479 //                                              Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$
1480 //                              }
1481 //
1482 //                      perProjectInfo.lastResolvedClasspath = resolvedPath;
1483 //                      perProjectInfo.resolvedPathToRawEntries = reverseMap;
1484 //              }
1485 //              return resolvedPath;
1486 //      }
1487         
1488         /**
1489          * Internal variant which can process any arbitrary classpath
1490          */
1491 //      public IClasspathEntry[] getResolvedClasspath(
1492 //              IClasspathEntry[] classpathEntries,
1493 //              IPath projectOutputLocation, // only set if needing full classpath validation (and markers)
1494 //              boolean ignoreUnresolvedEntry, // if unresolved entries are met, should it trigger initializations
1495 //              boolean generateMarkerOnError,
1496 //              Map reverseMap) // can be null if not interested in reverse mapping
1497 //              throws JavaModelException {
1498 //
1499 //              IJavaModelStatus status;
1500 //              if (generateMarkerOnError){
1501 //                      flushClasspathProblemMarkers(false, false);
1502 //              }
1503 //
1504 //              int length = classpathEntries.length;
1505 //              ArrayList resolvedEntries = new ArrayList();
1506 //              
1507 //              for (int i = 0; i < length; i++) {
1508 //
1509 //                      IClasspathEntry rawEntry = classpathEntries[i];
1510 //                      IPath resolvedPath;
1511 //                      status = null;
1512 //                      
1513 //                      /* validation if needed */
1514 //                      if (generateMarkerOnError || !ignoreUnresolvedEntry) {
1515 //                              status = JavaConventions.validateClasspathEntry(this, rawEntry, false);
1516 //                              if (generateMarkerOnError && !status.isOK()) createClasspathProblemMarker(status);
1517 //                      }
1518 //
1519 //                      switch (rawEntry.getEntryKind()){
1520 //                              
1521 //                              case IClasspathEntry.CPE_VARIABLE :
1522 //                              
1523 //                                      IClasspathEntry resolvedEntry = JavaCore.getResolvedClasspathEntry(rawEntry);
1524 //                                      if (resolvedEntry == null) {
1525 //                                              if (!ignoreUnresolvedEntry) throw new JavaModelException(status);
1526 //                                      } else {
1527 //                                              if (reverseMap != null && reverseMap.get(resolvedPath = resolvedEntry.getPath()) == null) reverseMap.put(resolvedPath , rawEntry);
1528 //                                              resolvedEntries.add(resolvedEntry);
1529 //                                      }
1530 //                                      break; 
1531 //
1532 //                              case IClasspathEntry.CPE_CONTAINER :
1533 //                              
1534 //                                      IClasspathContainer container = JavaCore.getClasspathContainer(rawEntry.getPath(), this);
1535 //                                      if (container == null){
1536 //                                              if (!ignoreUnresolvedEntry) throw new JavaModelException(status);
1537 //                                              break;
1538 //                                      }
1539 //
1540 //                                      IClasspathEntry[] containerEntries = container.getClasspathEntries();
1541 //                                      if (containerEntries == null) break;
1542 //
1543 //                                      // container was bound
1544 //                                      for (int j = 0, containerLength = containerEntries.length; j < containerLength; j++){
1545 //                                              IClasspathEntry cEntry = containerEntries[j];
1546 //                                              
1547 //                                              if (generateMarkerOnError) {
1548 //                                                      IJavaModelStatus containerStatus = JavaConventions.validateClasspathEntry(this, cEntry, false);
1549 //                                                      if (!containerStatus.isOK()) createClasspathProblemMarker(containerStatus);
1550 //                                              }
1551 //                                              // if container is exported, then its nested entries must in turn be exported  (21749)
1552 //                                              if (rawEntry.isExported()){
1553 //                                                      cEntry = new ClasspathEntry(cEntry.getContentKind(),
1554 //                                                              cEntry.getEntryKind(), cEntry.getPath(),
1555 //                                                              cEntry.getExclusionPatterns(), cEntry.getSourceAttachmentPath(),
1556 //                                                              cEntry.getSourceAttachmentRootPath(), cEntry.getOutputLocation(), 
1557 //                                                              true); // duplicate container entry for tagging it as exported
1558 //                                              }
1559 //                                              if (reverseMap != null && reverseMap.get(resolvedPath = cEntry.getPath()) == null) reverseMap.put(resolvedPath, rawEntry);
1560 //                                              resolvedEntries.add(cEntry);
1561 //                                      }
1562 //                                      break;
1563 //                                                                              
1564 //                              default :
1565 //
1566 //                                      if (reverseMap != null && reverseMap.get(resolvedPath = rawEntry.getPath()) == null) reverseMap.put(resolvedPath, rawEntry);
1567 //                                      resolvedEntries.add(rawEntry);
1568 //                              
1569 //                      }                                       
1570 //              }
1571 //
1572 //              IClasspathEntry[] resolvedPath = new IClasspathEntry[resolvedEntries.size()];
1573 //              resolvedEntries.toArray(resolvedPath);
1574 //
1575 //              if (generateMarkerOnError && projectOutputLocation != null) {
1576 //                      status = JavaConventions.validateClasspath(this, resolvedPath, projectOutputLocation);
1577 //                      if (!status.isOK()) createClasspathProblemMarker(status);
1578 //              }
1579 //              return resolvedPath;
1580 //      }
1581
1582         /*
1583          * @see IJavaElement
1584          */
1585         public IResource getResource() {
1586                 return this.getProject();
1587         }
1588
1589         /**
1590          * @see IJavaProject
1591          */
1592 //      public ISearchableNameEnvironment getSearchableNameEnvironment()
1593 //              throws JavaModelException {
1594 //
1595 //              JavaProjectElementInfo info = getJavaProjectElementInfo();
1596 //              if (info.getSearchableEnvironment() == null) {
1597 //                      info.setSearchableEnvironment(new SearchableEnvironment(this));
1598 //              }
1599 //              return info.getSearchableEnvironment();
1600 //      }
1601
1602         /**
1603          * Retrieve a shared property on a project. If the property is not defined, answers null.
1604          * Note that it is orthogonal to IResource persistent properties, and client code has to decide
1605          * which form of storage to use appropriately. Shared properties produce real resource files which
1606          * can be shared through a VCM onto a server. Persistent properties are not shareable.
1607          *
1608          * @see JavaProject#setSharedProperty(String, String)
1609          */
1610 //      public String getSharedProperty(String key) throws CoreException {
1611 //
1612 //              String property = null;
1613 //              IFile rscFile = getProject().getFile(key);
1614 //              if (rscFile.exists()) {
1615 //                      property = new String(Util.getResourceContentsAsByteArray(rscFile));
1616 //              }
1617 //              return property;
1618 //      }
1619
1620         /**
1621          * @see JavaElement
1622          */
1623 //      public SourceMapper getSourceMapper() {
1624 //
1625 //              return null;
1626 //      }
1627
1628         /**
1629          * @see IJavaElement
1630          */
1631         public IResource getUnderlyingResource() throws JavaModelException {
1632                 if (!exists()) throw newNotPresentException();
1633                 return getProject();
1634         }
1635
1636         /**
1637          * @see IJavaProject
1638          */
1639 //      public boolean hasBuildState() {
1640 //
1641 //              return JavaModelManager.getJavaModelManager().getLastBuiltState(this.getProject(), null) != null;
1642 //      }
1643
1644         /**
1645          * @see IJavaProject
1646          */
1647 //      public boolean hasClasspathCycle(IClasspathEntry[] preferredClasspath) {
1648 //              HashSet cycleParticipants = new HashSet();
1649 //              updateCycleParticipants(preferredClasspath, new ArrayList(2), cycleParticipants, ResourcesPlugin.getWorkspace().getRoot(), new HashSet(2));
1650 //              return !cycleParticipants.isEmpty();
1651 //      }
1652         
1653 //      public boolean hasCycleMarker(){
1654 //              return this.getCycleMarker() != null;
1655 //      }
1656
1657         public int hashCode() {
1658                 return fProject.hashCode();
1659         }
1660
1661         /**
1662          * Returns true if the given project is accessible and it has
1663          * a java nature, otherwise false.
1664          */
1665         public static boolean hasJavaNature(IProject project) { 
1666                 try {
1667                         return project.hasNature(PHPeclipsePlugin.PHP_NATURE_ID);
1668                 } catch (CoreException e) {
1669                         // project does not exist or is not open
1670                 }
1671                 return false;
1672         }
1673         
1674         /**
1675          * Answers true if the project potentially contains any source. A project which has no source is immutable.
1676          */
1677 //      public boolean hasSource() {
1678 //
1679 //              // look if any source folder on the classpath
1680 //              // no need for resolved path given source folder cannot be abstracted
1681 //              IClasspathEntry[] entries;
1682 //              try {
1683 //                      entries = this.getRawClasspath();
1684 //              } catch (JavaModelException e) {
1685 //                      return true; // unsure
1686 //              }
1687 //              for (int i = 0, max = entries.length; i < max; i++) {
1688 //                      if (entries[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
1689 //                              return true;
1690 //                      }
1691 //              }
1692 //              return false;
1693 //      }
1694
1695         /**
1696          * Compare current classpath with given one to see if any different.
1697          * Note that the argument classpath contains its binary output.
1698          */
1699 //      public boolean isClasspathEqualsTo(IClasspathEntry[] newClasspath, IPath newOutputLocation, IClasspathEntry[] otherClasspathWithOutput)
1700 //              throws JavaModelException {
1701 //
1702 //              if (otherClasspathWithOutput != null && otherClasspathWithOutput.length > 0) {
1703 //
1704 //                      int length = otherClasspathWithOutput.length;
1705 //                      if (length == newClasspath.length + 1) {
1706 //                              // output is amongst file entries (last one)
1707 //
1708 //                              // compare classpath entries
1709 //                              for (int i = 0; i < length - 1; i++) {
1710 //                                      if (!otherClasspathWithOutput[i].equals(newClasspath[i]))
1711 //                                              return false;
1712 //                              }
1713 //                              // compare binary outputs
1714 //                              IClasspathEntry output = otherClasspathWithOutput[length - 1];
1715 //                              if (output.getContentKind() == ClasspathEntry.K_OUTPUT
1716 //                                              && output.getPath().equals(newOutputLocation))
1717 //                                      return true;
1718 //                      }
1719 //              }
1720 //              return false;
1721 //      }
1722         
1723
1724         
1725         /*
1726          * @see IJavaProject
1727          */
1728 //      public boolean isOnClasspath(IJavaElement element) {
1729 //              IPath path = element.getPath();
1730 //              switch (element.getElementType()) {
1731 //                      case IJavaElement.PACKAGE_FRAGMENT_ROOT:
1732 //                              if (!((IPackageFragmentRoot)element).isArchive()) {
1733 //                                      // ensure that folders are only excluded if all of their children are excluded
1734 //                                      path = path.append("*"); //$NON-NLS-1$
1735 //                              }
1736 //                              break;
1737 //                      case IJavaElement.PACKAGE_FRAGMENT:
1738 //                              if (!((IPackageFragmentRoot)element.getParent()).isArchive()) {
1739 //                                      // ensure that folders are only excluded if all of their children are excluded
1740 //                                      path = path.append("*"); //$NON-NLS-1$
1741 //                              }
1742 //                              break;
1743 //              }
1744 //              return this.isOnClasspath(path);
1745 //      }
1746 //      private boolean isOnClasspath(IPath path) {
1747 //              IClasspathEntry[] classpath;
1748 //              try {
1749 //                      classpath = this.getResolvedClasspath(true/*ignore unresolved variable*/);
1750 //              } catch(JavaModelException e){
1751 //                      return false; // not a Java project
1752 //              }
1753 //              for (int i = 0; i < classpath.length; i++) {
1754 //                      IClasspathEntry entry = classpath[i];
1755 //                      if (entry.getPath().isPrefixOf(path) 
1756 //                                      && !Util.isExcluded(path, ((ClasspathEntry)entry).fullExclusionPatternChars())) {
1757 //                              return true;
1758 //                      }
1759 //              }
1760 //              return false;
1761 //      }
1762         /*
1763          * @see IJavaProject
1764          */
1765 //      public boolean isOnClasspath(IResource resource) {
1766 //              IPath path = resource.getFullPath();
1767 //              
1768 //              // ensure that folders are only excluded if all of their children are excluded
1769 //              if (resource.getType() == IResource.FOLDER) {
1770 //                      path = path.append("*"); //$NON-NLS-1$
1771 //              }
1772 //              
1773 //              return this.isOnClasspath(path);
1774 //      }
1775
1776
1777         /*
1778          * load preferences from a shareable format (VCM-wise)
1779          */
1780          public Preferences loadPreferences() {
1781                 
1782                 Preferences preferences = new Preferences();
1783                 
1784 //              File prefFile = getProject().getLocation().append(PREF_FILENAME).toFile();
1785                 IPath projectMetaLocation = getProject().getPluginWorkingLocation(PHPCore.getPlugin().getDescriptor());
1786                 if (projectMetaLocation != null) {
1787                         File prefFile = projectMetaLocation.append(PREF_FILENAME).toFile();
1788                         if (prefFile.exists()) { // load preferences from file
1789                                 InputStream in = null;
1790                                 try {
1791                                         in = new BufferedInputStream(new FileInputStream(prefFile));
1792                                         preferences.load(in);
1793                                         return preferences;
1794                                 } catch (IOException e) { // problems loading preference store - quietly ignore
1795                                 } finally {
1796                                         if (in != null) {
1797                                                 try {
1798                                                         in.close();
1799                                                 } catch (IOException e) { // ignore problems with close
1800                                                 }
1801                                         }
1802                                 }
1803                         }
1804                 }
1805                 return null;
1806          }
1807          
1808         /**
1809          * @see IJavaProject#newEvaluationContext
1810          */
1811 //      public IEvaluationContext newEvaluationContext() {
1812 //
1813 //              return new EvaluationContextWrapper(new EvaluationContext(), this);
1814 //      }
1815
1816         /**
1817          * @see IJavaProject
1818          */
1819 //      public ITypeHierarchy newTypeHierarchy(
1820 //              IRegion region,
1821 //              IProgressMonitor monitor)
1822 //              throws JavaModelException {
1823 //
1824 //              if (region == null) {
1825 //                      throw new IllegalArgumentException(Util.bind("hierarchy.nullRegion"));//$NON-NLS-1$
1826 //              }
1827 //              CreateTypeHierarchyOperation op =
1828 //                      new CreateTypeHierarchyOperation(null, region, this, true);
1829 //              runOperation(op, monitor);
1830 //              return op.getResult();
1831 //      }
1832
1833         /**
1834          * @see IJavaProject
1835          */
1836 //      public ITypeHierarchy newTypeHierarchy(
1837 //              IType type,
1838 //              IRegion region,
1839 //              IProgressMonitor monitor)
1840 //              throws JavaModelException {
1841 //
1842 //              if (type == null) {
1843 //                      throw new IllegalArgumentException(Util.bind("hierarchy.nullFocusType"));//$NON-NLS-1$
1844 //              }
1845 //              if (region == null) {
1846 //                      throw new IllegalArgumentException(Util.bind("hierarchy.nullRegion"));//$NON-NLS-1$
1847 //              }
1848 //              CreateTypeHierarchyOperation op =
1849 //                      new CreateTypeHierarchyOperation(type, region, this, true);
1850 //              runOperation(op, monitor);
1851 //              return op.getResult();
1852 //      }
1853
1854         /**
1855          * Open project if resource isn't closed
1856          */
1857 //      protected void openWhenClosed(IProgressMonitor pm) throws JavaModelException {
1858 //
1859 //              if (!this.fProject.isOpen()) {
1860 //                      throw newNotPresentException();
1861 //              } else {
1862 //                      super.openWhenClosed(pm);
1863 //              }
1864 //      }
1865
1866 //      public String[] projectPrerequisites(IClasspathEntry[] entries)
1867 //              throws JavaModelException {
1868 //                      
1869 //              ArrayList prerequisites = new ArrayList();
1870 //              // need resolution
1871 //              entries = getResolvedClasspath(entries, null, true, false, null/*no reverse map*/);
1872 //              for (int i = 0, length = entries.length; i < length; i++) {
1873 //                      IClasspathEntry entry = entries[i];
1874 //                      if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
1875 //                              prerequisites.add(entry.getPath().lastSegment());
1876 //                      }
1877 //              }
1878 //              int size = prerequisites.size();
1879 //              if (size == 0) {
1880 //                      return NO_PREREQUISITES;
1881 //              } else {
1882 //                      String[] result = new String[size];
1883 //                      prerequisites.toArray(result);
1884 //                      return result;
1885 //              }
1886 //      }
1887
1888
1889         /**
1890          * Reads the .classpath file from disk and returns the list of entries it contains (including output location entry)
1891          * Returns null if .classfile is not present.
1892          * Returns INVALID_CLASSPATH if it has a format problem.
1893          */
1894 //      protected IClasspathEntry[] readClasspathFile(boolean createMarker, boolean logProblems) {
1895 //
1896 //              try {
1897 //                      String xmlClasspath = getSharedProperty(CLASSPATH_FILENAME);
1898 //                      if (xmlClasspath == null) return null;
1899 //                      return decodeClasspath(xmlClasspath, createMarker, logProblems);
1900 //              } catch(CoreException e) {
1901 //                      // file does not exist (or not accessible)
1902 //                      if (createMarker && this.getProject().isAccessible()) {
1903 //                                      this.createClasspathProblemMarker(new JavaModelStatus(
1904 //                                              IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
1905 //                                              Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$
1906 //                      }
1907 //                      if (logProblems) {
1908 //                              Util.log(e, 
1909 //                                      "Exception while retrieving "+ this.getPath() //$NON-NLS-1$
1910 //                                      +"/.classpath, will revert to default classpath"); //$NON-NLS-1$
1911 //                      }
1912 //              }
1913 //              return null;
1914 //      }
1915
1916         /**
1917          * Removes the given builder from the build spec for the given project.
1918          */
1919         protected void removeFromBuildSpec(String builderID) throws CoreException {
1920
1921                 IProjectDescription description = getProject().getDescription();
1922                 ICommand[] commands = description.getBuildSpec();
1923                 for (int i = 0; i < commands.length; ++i) {
1924                         if (commands[i].getBuilderName().equals(builderID)) {
1925                                 ICommand[] newCommands = new ICommand[commands.length - 1];
1926                                 System.arraycopy(commands, 0, newCommands, 0, i);
1927                                 System.arraycopy(commands, i + 1, newCommands, i, commands.length - i - 1);
1928                                 description.setBuildSpec(newCommands);
1929                                 getProject().setDescription(description, null);
1930                                 return;
1931                         }
1932                 }
1933         }
1934
1935
1936         /**
1937          * @see JavaElement#rootedAt(IJavaProject)
1938          */
1939         public IJavaElement rootedAt(IJavaProject project) {
1940                 return project;
1941         
1942         }
1943         
1944         /**
1945          * Answers an ID which is used to distinguish project/entries during package
1946          * fragment root computations
1947          */
1948         public String rootID(){
1949                 return "[PRJ]"+this.getProject().getFullPath(); //$NON-NLS-1$
1950         }
1951         
1952         /**
1953          * Saves the classpath in a shareable format (VCM-wise) only when necessary, that is, if  it is semantically different
1954          * from the existing one in file. Will never write an identical one.
1955          * 
1956          * @return Return whether the .classpath file was modified.
1957          */
1958 //      public boolean saveClasspath(IClasspathEntry[] newClasspath, IPath newOutputLocation) throws JavaModelException {
1959 //
1960 //              if (!getProject().exists()) return false;
1961 //
1962 //              IClasspathEntry[] fileEntries = readClasspathFile(false /*don't create markers*/, false/*don't log problems*/);
1963 //              if (fileEntries != null && isClasspathEqualsTo(newClasspath, newOutputLocation, fileEntries)) {
1964 //                      // no need to save it, it is the same
1965 //                      return false;
1966 //              }
1967 //
1968 //              // actual file saving
1969 //              try {
1970 //                      setSharedProperty(CLASSPATH_FILENAME, encodeClasspath(newClasspath, newOutputLocation, true));
1971 //                      return true;
1972 //              } catch (CoreException e) {
1973 //                      throw new JavaModelException(e);
1974 //              }
1975 //      }
1976
1977         /**
1978          * Save project custom preferences to shareable file (.jprefs)
1979          */
1980         private void savePreferences(Preferences preferences) {
1981                 
1982                 IProject project = getProject();
1983                 if (!JavaProject.hasJavaNature(project)) return; // ignore
1984                 
1985                 if (preferences == null || (!preferences.needsSaving() && preferences.propertyNames().length != 0)) {
1986                         // nothing to save
1987                         return;
1988                 }
1989         
1990                 // preferences need to be saved
1991                 // the preferences file is located in the plug-in's state area
1992                 // at a well-known name (.jprefs)
1993 //              File prefFile = getProject().getLocation().append(PREF_FILENAME).toFile();
1994                 File prefFile = project.getPluginWorkingLocation(PHPCore.getPlugin().getDescriptor()).append(PREF_FILENAME).toFile();
1995                 if (preferences.propertyNames().length == 0) {
1996                         // there are no preference settings
1997                         // rather than write an empty file, just delete any existing file
1998                         if (prefFile.exists()) {
1999                                 prefFile.delete(); // don't worry if delete unsuccessful
2000                         }
2001                         return;
2002                 }
2003                 
2004                 // write file, overwriting an existing one
2005                 OutputStream out = null;
2006                 try {
2007                         // do it as carefully as we know how so that we don't lose/mangle
2008                         // the setting in times of stress
2009                         out = new BufferedOutputStream(new FileOutputStream(prefFile));
2010                         preferences.store(out, null);
2011                 } catch (IOException e) { // problems saving preference store - quietly ignore
2012                 } finally {
2013                         if (out != null) {
2014                                 try {
2015                                         out.close();
2016                                 } catch (IOException e) { // ignore problems with close
2017                                 }
2018                         }
2019                 }
2020         }
2021
2022         /**
2023          * Update the Java command in the build spec (replace existing one if present,
2024          * add one first if none).
2025          */
2026         private void setJavaCommand(
2027                 IProjectDescription description,
2028                 ICommand newCommand)
2029                 throws CoreException {
2030
2031                 ICommand[] oldCommands = description.getBuildSpec();
2032                 ICommand oldJavaCommand = getJavaCommand(description);
2033                 ICommand[] newCommands;
2034
2035                 if (oldJavaCommand == null) {
2036                         // Add a Java build spec before other builders (1FWJK7I)
2037                         newCommands = new ICommand[oldCommands.length + 1];
2038                         System.arraycopy(oldCommands, 0, newCommands, 1, oldCommands.length);
2039                         newCommands[0] = newCommand;
2040                 } else {
2041                         for (int i = 0, max = oldCommands.length; i < max; i++) {
2042                                 if (oldCommands[i] == oldJavaCommand) {
2043                                         oldCommands[i] = newCommand;
2044                                         break;
2045                                 }
2046                         }
2047                         newCommands = oldCommands;
2048                 }
2049
2050                 // Commit the spec change into the project
2051                 description.setBuildSpec(newCommands);
2052                 getProject().setDescription(description, null);
2053         }
2054
2055         /**
2056          * @see org.eclipse.jdt.core.IJavaProject#setOptions(Map)
2057          */
2058 //      public void setOptions(Map newOptions) {
2059 //
2060 //              Preferences preferences;
2061 //              setPreferences(preferences = new Preferences()); // always reset (26255)
2062 //              if (newOptions != null){
2063 //                      Iterator keys = newOptions.keySet().iterator();
2064 //                      while (keys.hasNext()){
2065 //                              String key = (String)keys.next();
2066 //                              if (!JavaModelManager.OptionNames.contains(key)) continue; // unrecognized option
2067 //                              // no filtering for encoding (custom encoding for project is allowed)
2068 //                              String value = (String)newOptions.get(key);
2069 //                              preferences.setDefault(key, CUSTOM_DEFAULT_OPTION_VALUE); // empty string isn't the default (26251)
2070 //                              preferences.setValue(key, value);
2071 //                      }
2072 //              }
2073 //              
2074 //              // persist options
2075 //              savePreferences(preferences);   
2076 //      }
2077
2078         /**
2079          * @see IJavaProject
2080          */
2081 //      public void setOutputLocation(IPath path, IProgressMonitor monitor)
2082 //              throws JavaModelException {
2083 //
2084 //              if (path == null) {
2085 //                      throw new IllegalArgumentException(Util.bind("path.nullpath")); //$NON-NLS-1$
2086 //              }
2087 //              if (path.equals(getOutputLocation())) {
2088 //                      return;
2089 //              }
2090 //              this.setRawClasspath(SetClasspathOperation.ReuseClasspath, path, monitor);
2091 //      }
2092
2093         /*
2094          * Set cached preferences, no preference file is saved, only info is updated
2095          */
2096 //      public void setPreferences(Preferences preferences) {
2097 //              IProject project = getProject();
2098 //              if (!JavaProject.hasJavaNature(project)) return; // ignore
2099 //              JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(project, true);
2100 //              perProjectInfo.preferences = preferences;
2101 //      }
2102
2103         /**
2104          * Sets the underlying kernel project of this Java project,
2105          * and fills in its parent and name.
2106          * Called by IProject.getNature().
2107          *
2108          * @see IProjectNature#setProject
2109          */
2110         public void setProject(IProject project) {
2111
2112                 fProject = project;
2113                 fParent = JavaModelManager.getJavaModelManager().getJavaModel();
2114                 fName = project.getName();
2115         }
2116
2117         /**
2118          * @see IJavaProject
2119          */
2120 //      public void setRawClasspath(
2121 //              IClasspathEntry[] entries,
2122 //              IPath outputLocation,
2123 //              IProgressMonitor monitor)
2124 //              throws JavaModelException {
2125 //
2126 //              setRawClasspath(
2127 //                      entries, 
2128 //                      outputLocation, 
2129 //                      monitor, 
2130 //                      true, // canChangeResource (as per API contract)
2131 //                      getResolvedClasspath(true), // ignoreUnresolvedVariable
2132 //                      true, // needValidation
2133 //                      true); // need to save
2134 //      }
2135
2136 //      public void setRawClasspath(
2137 //              IClasspathEntry[] newEntries,
2138 //              IPath newOutputLocation,
2139 //              IProgressMonitor monitor,
2140 //              boolean canChangeResource,
2141 //              IClasspathEntry[] oldResolvedPath,
2142 //              boolean needValidation,
2143 //              boolean needSave)
2144 //              throws JavaModelException {
2145 //
2146 //              JavaModelManager manager =
2147 //                      (JavaModelManager) JavaModelManager.getJavaModelManager();
2148 //              try {
2149 //                      IClasspathEntry[] newRawPath = newEntries;
2150 //                      if (newRawPath == null) { //are we already with the default classpath
2151 //                              newRawPath = defaultClasspath();
2152 //                      }
2153 //                      SetClasspathOperation op =
2154 //                              new SetClasspathOperation(
2155 //                                      this, 
2156 //                                      oldResolvedPath, 
2157 //                                      newRawPath, 
2158 //                                      newOutputLocation,
2159 //                                      canChangeResource, 
2160 //                                      needValidation,
2161 //                                      needSave);
2162 //                      runOperation(op, monitor);
2163 //                      
2164 //              } catch (JavaModelException e) {
2165 //                      manager.flush();
2166 //                      throw e;
2167 //              }
2168 //      }
2169
2170         /**
2171          * @see IJavaProject
2172          */
2173 //      public void setRawClasspath(
2174 //              IClasspathEntry[] entries,
2175 //              IProgressMonitor monitor)
2176 //              throws JavaModelException {
2177 //
2178 //              setRawClasspath(
2179 //                      entries, 
2180 //                      SetClasspathOperation.ReuseOutputLocation, 
2181 //                      monitor, 
2182 //                      true, // canChangeResource (as per API contract)
2183 //                      getResolvedClasspath(true), // ignoreUnresolvedVariable
2184 //                      true, // needValidation
2185 //                      true); // need to save
2186 //      }
2187
2188         /**
2189          * NOTE: <code>null</code> specifies default classpath, and an empty
2190          * array specifies an empty classpath.
2191          *
2192          * @exception NotPresentException if this project does not exist.
2193          */
2194 //      protected void setRawClasspath0(IClasspathEntry[] rawEntries)
2195 //              throws JavaModelException {
2196 //
2197 //              JavaModelManager.PerProjectInfo info = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject);
2198 //      
2199 //              synchronized (info) {
2200 //                      if (rawEntries != null) {
2201 //                              info.classpath = rawEntries;
2202 //                      }
2203 //                      
2204 //                      // clear cache of resolved classpath
2205 //                      info.lastResolvedClasspath = null;
2206 //                      info.resolvedPathToRawEntries = null;
2207 //              }
2208 //      }
2209
2210         /**
2211          * Record a shared persistent property onto a project.
2212          * Note that it is orthogonal to IResource persistent properties, and client code has to decide
2213          * which form of storage to use appropriately. Shared properties produce real resource files which
2214          * can be shared through a VCM onto a server. Persistent properties are not shareable.
2215          * 
2216          * shared properties end up in resource files, and thus cannot be modified during
2217          * delta notifications (a CoreException would then be thrown).
2218          * 
2219          * @see JavaProject#getSharedProperty(String key)
2220          */
2221         public void setSharedProperty(String key, String value) throws CoreException {
2222
2223                 IFile rscFile = getProject().getFile(key);
2224                 InputStream inputStream = new ByteArrayInputStream(value.getBytes());
2225                 // update the resource content
2226                 if (rscFile.exists()) {
2227                         if (rscFile.isReadOnly()) {
2228                                 // provide opportunity to checkout read-only .classpath file (23984)
2229                                 ResourcesPlugin.getWorkspace().validateEdit(new IFile[]{rscFile}, null);
2230                         }
2231                         rscFile.setContents(inputStream, IResource.FORCE, null);
2232                 } else {
2233                         rscFile.create(inputStream, IResource.FORCE, null);
2234                 }
2235         }
2236
2237         /**
2238          * Update cycle markers for all java projects
2239          */
2240 //      public static void updateAllCycleMarkers() throws JavaModelException {
2241 //
2242 //              //long start = System.currentTimeMillis();
2243 //
2244 //              JavaModelManager manager = JavaModelManager.getJavaModelManager();
2245 //              IJavaProject[] projects = manager.getJavaModel().getJavaProjects();
2246 //              IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
2247 //
2248 //              HashSet cycleParticipants = new HashSet();
2249 //              HashSet traversed = new HashSet();
2250 //              int length = projects.length;
2251 //              
2252 //              // compute cycle participants
2253 //              ArrayList prereqChain = new ArrayList();
2254 //              for (int i = 0; i < length; i++){
2255 //                      JavaProject project = (JavaProject)projects[i];
2256 //                      if (!traversed.contains(project.getPath())){
2257 //                              prereqChain.clear();
2258 //                              project.updateCycleParticipants(null, prereqChain, cycleParticipants, workspaceRoot, traversed);
2259 //                      }
2260 //              }
2261 //              //System.out.println("updateAllCycleMarkers: " + (System.currentTimeMillis() - start) + " ms");
2262 //
2263 //              for (int i = 0; i < length; i++){
2264 //                      JavaProject project = (JavaProject)projects[i];
2265 //                      
2266 //                      if (cycleParticipants.contains(project.getPath())){
2267 //                              IMarker cycleMarker = project.getCycleMarker();
2268 //                              String circularCPOption = project.getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true);
2269 //                              int circularCPSeverity = JavaCore.ERROR.equals(circularCPOption) ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING;
2270 //                              if (cycleMarker != null) {
2271 //                                      // update existing cycle marker if needed
2272 //                                      try {
2273 //                                              int existingSeverity = ((Integer)cycleMarker.getAttribute(IMarker.SEVERITY)).intValue();
2274 //                                              if (existingSeverity != circularCPSeverity) {
2275 //                                                      cycleMarker.setAttribute(IMarker.SEVERITY, circularCPSeverity);
2276 //                                              }
2277 //                                      } catch (CoreException e) {
2278 //                                              throw new JavaModelException(e);
2279 //                                      }
2280 //                              } else {
2281 //                                      // create new marker
2282 //                                      project.createClasspathProblemMarker(
2283 //                                              new JavaModelStatus(IJavaModelStatusConstants.CLASSPATH_CYCLE, project)); 
2284 //                              }
2285 //                      } else {
2286 //                              project.flushClasspathProblemMarkers(true, false);
2287 //                      }                       
2288 //              }
2289 //      }
2290 //
2291 //      /**
2292 //       * If a cycle is detected, then cycleParticipants contains all the paths of projects involved in this cycle (directly and indirectly),
2293 //       * no cycle if the set is empty (and started empty)
2294 //       */
2295 //      public void updateCycleParticipants(
2296 //                      IClasspathEntry[] preferredClasspath, 
2297 //                      ArrayList prereqChain, 
2298 //                      HashSet cycleParticipants, 
2299 //                      IWorkspaceRoot workspaceRoot,
2300 //                      HashSet traversed){
2301 //
2302 //              IPath path = this.getPath();
2303 //              prereqChain.add(path);
2304 //              traversed.add(path);
2305 //              try {
2306 //                      IClasspathEntry[] classpath = preferredClasspath == null ? getResolvedClasspath(true) : preferredClasspath;
2307 //                      for (int i = 0, length = classpath.length; i < length; i++) {
2308 //                              IClasspathEntry entry = classpath[i];
2309 //                              
2310 //                              if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT){
2311 //                                      IPath prereqProjectPath = entry.getPath();
2312 //                                      int index = cycleParticipants.contains(prereqProjectPath) ? 0 : prereqChain.indexOf(prereqProjectPath);
2313 //                                      if (index >= 0) { // refer to cycle, or in cycle itself
2314 //                                              for (int size = prereqChain.size(); index < size; index++) {
2315 //                                                      cycleParticipants.add(prereqChain.get(index)); 
2316 //                                              }
2317 //                                      } else {
2318 //                                              if (!traversed.contains(prereqProjectPath)) {
2319 //                                                      IResource member = workspaceRoot.findMember(prereqProjectPath);
2320 //                                                      if (member != null && member.getType() == IResource.PROJECT){
2321 //                                                              JavaProject project = (JavaProject)JavaCore.create((IProject)member);
2322 //                                                              project.updateCycleParticipants(null, prereqChain, cycleParticipants, workspaceRoot, traversed);
2323 //                                                      }
2324 //                                              }
2325 //                                      }
2326 //                              }
2327 //                      }
2328 //              } catch(JavaModelException e){
2329 //              }
2330 //              prereqChain.remove(path);
2331 //      }
2332         /**
2333          * Reset the collection of package fragment roots (local ones) - only if opened.
2334          * Need to check *all* package fragment roots in order to reset NameLookup
2335          */
2336 //      public void updatePackageFragmentRoots(){
2337 //              
2338 //                      if (this.isOpen()) {
2339 //                              try {
2340 //                                      JavaProjectElementInfo info = getJavaProjectElementInfo();
2341 //
2342 //                                      IClasspathEntry[] classpath = getResolvedClasspath(true);
2343 //                                      NameLookup lookup = info.getNameLookup();
2344 //                                      if (lookup != null){
2345 //                                              IPackageFragmentRoot[] oldRoots = lookup.fPackageFragmentRoots;
2346 //                                              IPackageFragmentRoot[] newRoots = computePackageFragmentRoots(classpath, true);
2347 //                                              checkIdentical: { // compare all pkg fragment root lists
2348 //                                                      if (oldRoots.length == newRoots.length){
2349 //                                                              for (int i = 0, length = oldRoots.length; i < length; i++){
2350 //                                                                      if (!oldRoots[i].equals(newRoots[i])){
2351 //                                                                              break checkIdentical;
2352 //                                                                      }
2353 //                                                              }
2354 //                                                              return; // no need to update
2355 //                                                      }       
2356 //                                              }
2357 //                                              info.setNameLookup(null); // discard name lookup (hold onto roots)
2358 //                                      }                               
2359 //                                      info.setNonJavaResources(null);
2360 //                                      info.setChildren(
2361 //                                              computePackageFragmentRoots(classpath, false));         
2362 //
2363 //                              } catch(JavaModelException e){
2364 //                                      try {
2365 //                                              close(); // could not do better
2366 //                                      } catch(JavaModelException ex){
2367 //                                      }
2368 //                              }
2369 //                      }
2370 //      }
2371 }