X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaProject.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaProject.java index c8541ba..2a0a680 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaProject.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaProject.java @@ -13,32 +13,76 @@ package net.sourceforge.phpdt.internal.core; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; - +import java.io.OutputStreamWriter; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; + +import net.sourceforge.phpdt.core.IClasspathEntry; import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaModelMarker; +import net.sourceforge.phpdt.core.IJavaModelStatus; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.internal.codeassist.ISearchableNameEnvironment; +import net.sourceforge.phpdt.internal.compiler.util.ObjectVector; +import net.sourceforge.phpdt.internal.corext.Assert; +import net.sourceforge.phpeclipse.LoadPathEntry; import net.sourceforge.phpeclipse.PHPCore; import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import org.apache.xerces.dom.DocumentImpl; +import org.apache.xml.serialize.Method; +import org.apache.xml.serialize.OutputFormat; +import org.apache.xml.serialize.Serializer; +import org.apache.xml.serialize.SerializerFactory; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IProjectNature; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Preferences; import org.eclipse.core.runtime.QualifiedName; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; /** * Handle for a Java Project. @@ -58,7 +102,7 @@ import org.eclipse.core.runtime.QualifiedName; * * @see IJavaProject */ -public class JavaProject +public class JavaProject extends Openable implements IJavaProject , IProjectNature { @@ -76,6 +120,8 @@ public class JavaProject * The platform project this IJavaProject is based on */ protected IProject fProject; + protected List fLoadPathEntries; + protected boolean fScratched; /** * Name of file containing project classpath @@ -90,7 +136,7 @@ public class JavaProject /** * Value of the project's raw classpath if the .classpath file contains invalid entries. */ -// public static final IClasspathEntry[] INVALID_CLASSPATH = new IClasspathEntry[0]; + public static final IClasspathEntry[] INVALID_CLASSPATH = new IClasspathEntry[0]; private static final String CUSTOM_DEFAULT_OPTION_VALUE = "#\r\n\r#custom-non-empty-default-value#\r\n\r#"; //$NON-NLS-1$ @@ -185,7 +231,125 @@ public class JavaProject super(JAVA_PROJECT, parent, project.getName()); fProject = project; } + public void addLoadPathEntry(IProject anotherPHPProject) { + fScratched = true; + + LoadPathEntry newEntry = new LoadPathEntry(anotherPHPProject); + getLoadPathEntries().add(newEntry); + } + + public void configure() throws CoreException { + // get project description and then the associated build commands + IProjectDescription desc = fProject.getDescription(); + ICommand[] commands = desc.getBuildSpec(); + + // determine if builder already associated + boolean found = false; + for (int i = 0; i < commands.length; ++i) { + if (commands[i].getBuilderName().equals(PHPeclipsePlugin.BUILDER_PARSER_ID)) { + found = true; + break; + } + } + + // add builder if not already in project + if (!found) { + ICommand command = desc.newCommand(); + command.setBuilderName(PHPeclipsePlugin.BUILDER_PARSER_ID); + ICommand[] newCommands = new ICommand[commands.length + 1]; + + // Add it before other builders. + System.arraycopy(commands, 0, newCommands, 1, commands.length); + newCommands[0] = command; + desc.setBuildSpec(newCommands); + fProject.setDescription(desc, null); + } + } + + protected void loadLoadPathEntries() { + fLoadPathEntries = new ArrayList(); + + IFile loadPathsFile = getLoadPathEntriesFile(); + + XMLReader reader = null; + try { + reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + reader.setContentHandler(getLoadPathEntriesContentHandler()); + reader.parse(new InputSource(loadPathsFile.getContents())); + } catch (Exception e) { + //the file is nonextant or unreadable + } + } + + public List getLoadPathEntries() { + if (fLoadPathEntries == null) { + loadLoadPathEntries(); + } + + return fLoadPathEntries; + } + + protected ContentHandler getLoadPathEntriesContentHandler() { + return new ContentHandler() { + public void characters(char[] arg0, int arg1, int arg2) throws SAXException { + } + + public void endDocument() throws SAXException { + } + + public void endElement(String arg0, String arg1, String arg2) throws SAXException { + } + + public void endPrefixMapping(String arg0) throws SAXException { + } + + public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException { + } + + public void processingInstruction(String arg0, String arg1) throws SAXException { + } + + public void setDocumentLocator(Locator arg0) { + } + + public void skippedEntity(String arg0) throws SAXException { + } + + public void startDocument() throws SAXException { + } + + public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { + if ("pathentry".equals(qName)) + if ("project".equals(atts.getValue("type"))) { + IPath referencedProjectPath = new Path(atts.getValue("path")); + IProject referencedProject = getProject(referencedProjectPath.lastSegment()); + fLoadPathEntries.add(new LoadPathEntry(referencedProject)); + } + } + + public void startPrefixMapping(String arg0, String arg1) throws SAXException { + } + }; + } + + protected IFile getLoadPathEntriesFile() { + return fProject.getFile(".loadpath"); + } + + protected String getLoadPathXML() { + StringBuffer buffer = new StringBuffer(); + buffer.append(""); + Iterator pathEntriesIterator = fLoadPathEntries.iterator(); + + while (pathEntriesIterator.hasNext()) { + LoadPathEntry entry = (LoadPathEntry) pathEntriesIterator.next(); + buffer.append(entry.toXML()); + } + + buffer.append(""); + return buffer.toString(); + } /** * Adds a builder to the build spec for the given project. */ @@ -203,18 +367,18 @@ public class JavaProject } } -// protected void closing(Object info) throws JavaModelException { -// -// // forget source attachment recommendations -// IPackageFragmentRoot[] roots = this.getPackageFragmentRoots(); + protected void closing(Object info) throws JavaModelException { + + // forget source attachment recommendations + IPackageFragmentRoot[] roots = this.getPackageFragmentRoots(); // for (int i = 0; i < roots.length; i++) { // if (roots[i] instanceof JarPackageFragmentRoot){ // ((JarPackageFragmentRoot) roots[i]).setSourceAttachmentProperty(null); // } // } -// -// super.closing(info); -// } + + super.closing(info); + } @@ -222,52 +386,52 @@ public class JavaProject * Internal computation of an expanded classpath. It will eliminate duplicates, and produce copies * of exported classpath entries to avoid possible side-effects ever after. */ -// private void computeExpandedClasspath( -// JavaProject initialProject, -// boolean ignoreUnresolvedVariable, -// boolean generateMarkerOnError, -// HashSet visitedProjects, -// ObjectVector accumulatedEntries) throws JavaModelException { -// -// if (visitedProjects.contains(this)){ -// return; // break cycles if any -// } -// visitedProjects.add(this); -// -// if (generateMarkerOnError && !this.equals(initialProject)){ -// generateMarkerOnError = false; -// } -// IClasspathEntry[] immediateClasspath = -// getResolvedClasspath(ignoreUnresolvedVariable, generateMarkerOnError); -// -// IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); -// for (int i = 0, length = immediateClasspath.length; i < length; i++){ -// IClasspathEntry entry = immediateClasspath[i]; -// -// boolean isInitialProject = this.equals(initialProject); -// if (isInitialProject || entry.isExported()){ -// -// accumulatedEntries.add(entry); -// -// // recurse in project to get all its indirect exports (only consider exported entries from there on) -// if (entry.getEntryKind() == ClasspathEntry.CPE_PROJECT) { -// IResource member = workspaceRoot.findMember(entry.getPath()); -// if (member != null && member.getType() == IResource.PROJECT){ // double check if bound to project (23977) -// IProject projRsc = (IProject) member; -// if (JavaProject.hasJavaNature(projRsc)) { -// JavaProject project = (JavaProject) JavaCore.create(projRsc); -// project.computeExpandedClasspath( -// initialProject, -// ignoreUnresolvedVariable, -// generateMarkerOnError, -// visitedProjects, -// accumulatedEntries); -// } -// } -// } -// } -// } -// } + private void computeExpandedClasspath( + JavaProject initialProject, + boolean ignoreUnresolvedVariable, + boolean generateMarkerOnError, + HashSet visitedProjects, + ObjectVector accumulatedEntries) throws JavaModelException { + + if (visitedProjects.contains(this)){ + return; // break cycles if any + } + visitedProjects.add(this); + + if (generateMarkerOnError && !this.equals(initialProject)){ + generateMarkerOnError = false; + } + IClasspathEntry[] immediateClasspath = + getResolvedClasspath(ignoreUnresolvedVariable, generateMarkerOnError); + + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + for (int i = 0, length = immediateClasspath.length; i < length; i++){ + IClasspathEntry entry = immediateClasspath[i]; + + boolean isInitialProject = this.equals(initialProject); + if (isInitialProject || entry.isExported()){ + + accumulatedEntries.add(entry); + + // recurse in project to get all its indirect exports (only consider exported entries from there on) + if (entry.getEntryKind() == ClasspathEntry.CPE_PROJECT) { + IResource member = workspaceRoot.findMember(entry.getPath()); + if (member != null && member.getType() == IResource.PROJECT){ // double check if bound to project (23977) + IProject projRsc = (IProject) member; + if (JavaProject.hasJavaNature(projRsc)) { + JavaProject project = (JavaProject) PHPCore.create(projRsc); + project.computeExpandedClasspath( + initialProject, + ignoreUnresolvedVariable, + generateMarkerOnError, + visitedProjects, + accumulatedEntries); + } + } + } + } + } + } /** * Returns (local/all) the package fragment roots identified by the given project's classpath. @@ -275,140 +439,140 @@ public class JavaProject * eliminating duplicates silently. * Only works with resolved entries */ -// public IPackageFragmentRoot[] computePackageFragmentRoots(IClasspathEntry[] resolvedClasspath, boolean retrieveExportedRoots) throws JavaModelException { -// -// ObjectVector accumulatedRoots = new ObjectVector(); -// computePackageFragmentRoots( -// resolvedClasspath, -// accumulatedRoots, -// new HashSet(5), // rootIDs -// true, // inside original project -// true, // check existency -// retrieveExportedRoots); -// IPackageFragmentRoot[] rootArray = new IPackageFragmentRoot[accumulatedRoots.size()]; -// accumulatedRoots.copyInto(rootArray); -// return rootArray; -// } -// -// /** -// * Computes the package fragment roots identified by the given entry. -// * Only works with resolved entry -// */ -// public IPackageFragmentRoot[] computePackageFragmentRoots(IClasspathEntry resolvedEntry) { -// try { -// return -// computePackageFragmentRoots( -// new IClasspathEntry[]{ resolvedEntry }, -// false // don't retrieve exported roots -// ); -// } catch (JavaModelException e) { -// return new IPackageFragmentRoot[] {}; -// } -// } + public IPackageFragmentRoot[] computePackageFragmentRoots(IClasspathEntry[] resolvedClasspath, boolean retrieveExportedRoots) throws JavaModelException { + + ObjectVector accumulatedRoots = new ObjectVector(); + computePackageFragmentRoots( + resolvedClasspath, + accumulatedRoots, + new HashSet(5), // rootIDs + true, // inside original project + true, // check existency + retrieveExportedRoots); + IPackageFragmentRoot[] rootArray = new IPackageFragmentRoot[accumulatedRoots.size()]; + accumulatedRoots.copyInto(rootArray); + return rootArray; + } + + /** + * Computes the package fragment roots identified by the given entry. + * Only works with resolved entry + */ + public IPackageFragmentRoot[] computePackageFragmentRoots(IClasspathEntry resolvedEntry) { + try { + return + computePackageFragmentRoots( + new IClasspathEntry[]{ resolvedEntry }, + false // don't retrieve exported roots + ); + } catch (JavaModelException e) { + return new IPackageFragmentRoot[] {}; + } + } /** * Returns the package fragment roots identified by the given entry. In case it refers to * a project, it will follow its classpath so as to find exported roots as well. * Only works with resolved entry */ -// public void computePackageFragmentRoots( -// IClasspathEntry resolvedEntry, -// ObjectVector accumulatedRoots, -// HashSet rootIDs, -// boolean insideOriginalProject, -// boolean checkExistency, -// boolean retrieveExportedRoots) throws JavaModelException { -// -// String rootID = ((ClasspathEntry)resolvedEntry).rootID(); -// if (rootIDs.contains(rootID)) return; -// -// IPath projectPath = getProject().getFullPath(); -// IPath entryPath = resolvedEntry.getPath(); -// IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); -// -// switch(resolvedEntry.getEntryKind()){ -// -// // source folder -// case IClasspathEntry.CPE_SOURCE : -// -// if (projectPath.isPrefixOf(entryPath)){ -// if (checkExistency) { -// Object target = JavaModel.getTarget(workspaceRoot, entryPath, checkExistency); -// if (target == null) return; -// -// if (target instanceof IFolder || target instanceof IProject){ -// accumulatedRoots.add( -// getPackageFragmentRoot((IResource)target)); -// rootIDs.add(rootID); -// } -// } else { -// IPackageFragmentRoot root = getFolderPackageFragmentRoot(entryPath); -// if (root != null) { -// accumulatedRoots.add(root); -// rootIDs.add(rootID); -// } -// } -// } -// break; -// -// // internal/external JAR or folder -// case IClasspathEntry.CPE_LIBRARY : -// -// if (!insideOriginalProject && !resolvedEntry.isExported()) return; -// -// if (checkExistency) { -// Object target = JavaModel.getTarget(workspaceRoot, entryPath, checkExistency); -// if (target == null) return; -// -// if (target instanceof IResource){ -// // internal target -// IResource resource = (IResource) target; -// IPackageFragmentRoot root = getPackageFragmentRoot(resource); -// if (root != null) { -// accumulatedRoots.add(root); -// rootIDs.add(rootID); -// } -// } else { -// // external target - only JARs allowed + public void computePackageFragmentRoots( + IClasspathEntry resolvedEntry, + ObjectVector accumulatedRoots, + HashSet rootIDs, + boolean insideOriginalProject, + boolean checkExistency, + boolean retrieveExportedRoots) throws JavaModelException { + + String rootID = ((ClasspathEntry)resolvedEntry).rootID(); + if (rootIDs.contains(rootID)) return; + + IPath projectPath = getProject().getFullPath(); + IPath entryPath = resolvedEntry.getPath(); + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + + switch(resolvedEntry.getEntryKind()){ + + // source folder + case IClasspathEntry.CPE_SOURCE : + + if (projectPath.isPrefixOf(entryPath)){ + if (checkExistency) { + Object target = JavaModel.getTarget(workspaceRoot, entryPath, checkExistency); + if (target == null) return; + + if (target instanceof IFolder || target instanceof IProject){ + accumulatedRoots.add( + getPackageFragmentRoot((IResource)target)); + rootIDs.add(rootID); + } + } else { + IPackageFragmentRoot root = getFolderPackageFragmentRoot(entryPath); + if (root != null) { + accumulatedRoots.add(root); + rootIDs.add(rootID); + } + } + } + break; + + // internal/external JAR or folder + case IClasspathEntry.CPE_LIBRARY : + + if (!insideOriginalProject && !resolvedEntry.isExported()) return; + + if (checkExistency) { + Object target = JavaModel.getTarget(workspaceRoot, entryPath, checkExistency); + if (target == null) return; + + if (target instanceof IResource){ + // internal target + IResource resource = (IResource) target; + IPackageFragmentRoot root = getPackageFragmentRoot(resource); + if (root != null) { + accumulatedRoots.add(root); + rootIDs.add(rootID); + } + } else { + // external target - only JARs allowed // if (((java.io.File)target).isFile() && (Util.isArchiveFileName(entryPath.lastSegment()))) { // accumulatedRoots.add( // new JarPackageFragmentRoot(entryPath, this)); // rootIDs.add(rootID); // } -// } -// } else { -// IPackageFragmentRoot root = getPackageFragmentRoot(entryPath); -// if (root != null) { -// accumulatedRoots.add(root); -// rootIDs.add(rootID); -// } -// } -// break; -// -// // recurse into required project -// case IClasspathEntry.CPE_PROJECT : -// -// if (!retrieveExportedRoots) return; -// if (!insideOriginalProject && !resolvedEntry.isExported()) return; -// -// IResource member = workspaceRoot.findMember(entryPath); -// if (member != null && member.getType() == IResource.PROJECT){// double check if bound to project (23977) -// IProject requiredProjectRsc = (IProject) member; -// if (JavaProject.hasJavaNature(requiredProjectRsc)){ // special builder binary output -// rootIDs.add(rootID); -// JavaProject requiredProject = (JavaProject)JavaCore.create(requiredProjectRsc); -// requiredProject.computePackageFragmentRoots( -// requiredProject.getResolvedClasspath(true), -// accumulatedRoots, -// rootIDs, -// false, -// checkExistency, -// retrieveExportedRoots); -// } -// break; -// } -// } -// } + } + } else { + IPackageFragmentRoot root = getPackageFragmentRoot(entryPath); + if (root != null) { + accumulatedRoots.add(root); + rootIDs.add(rootID); + } + } + break; + + // recurse into required project + case IClasspathEntry.CPE_PROJECT : + + if (!retrieveExportedRoots) return; + if (!insideOriginalProject && !resolvedEntry.isExported()) return; + + IResource member = workspaceRoot.findMember(entryPath); + if (member != null && member.getType() == IResource.PROJECT){// double check if bound to project (23977) + IProject requiredProjectRsc = (IProject) member; + if (JavaProject.hasJavaNature(requiredProjectRsc)){ // special builder binary output + rootIDs.add(rootID); + JavaProject requiredProject = (JavaProject)PHPCore.create(requiredProjectRsc); + requiredProject.computePackageFragmentRoots( + requiredProject.getResolvedClasspath(true), + accumulatedRoots, + rootIDs, + false, + checkExistency, + retrieveExportedRoots); + } + break; + } + } + } /** * Returns (local/all) the package fragment roots identified by the given project's classpath. @@ -416,27 +580,27 @@ public class JavaProject * eliminating duplicates silently. * Only works with resolved entries */ -// public void computePackageFragmentRoots( -// IClasspathEntry[] resolvedClasspath, -// ObjectVector accumulatedRoots, -// HashSet rootIDs, -// boolean insideOriginalProject, -// boolean checkExistency, -// boolean retrieveExportedRoots) throws JavaModelException { -// -// if (insideOriginalProject){ -// rootIDs.add(rootID()); -// } -// for (int i = 0, length = resolvedClasspath.length; i < length; i++){ -// computePackageFragmentRoots( -// resolvedClasspath[i], -// accumulatedRoots, -// rootIDs, -// insideOriginalProject, -// checkExistency, -// retrieveExportedRoots); -// } -// } + public void computePackageFragmentRoots( + IClasspathEntry[] resolvedClasspath, + ObjectVector accumulatedRoots, + HashSet rootIDs, + boolean insideOriginalProject, + boolean checkExistency, + boolean retrieveExportedRoots) throws JavaModelException { + + if (insideOriginalProject){ + rootIDs.add(rootID()); + } + for (int i = 0, length = resolvedClasspath.length; i < length; i++){ + computePackageFragmentRoots( + resolvedClasspath[i], + accumulatedRoots, + rootIDs, + insideOriginalProject, + checkExistency, + retrieveExportedRoots); + } + } /** * Compute the file name to use for a given shared property @@ -446,222 +610,214 @@ public class JavaProject return '.' + qName.getLocalName(); } - /** - * Configure the project with Java nature. - */ - public void configure() throws CoreException { - - // register Java builder - addToBuildSpec(PHPeclipsePlugin.BUILDER_PARSER_ID); - } /* * Returns whether the given resource is accessible through the children or the non-Java resources of this project. * Returns true if the resource is not in the project. * Assumes that the resource is a folder or a file. */ -// public boolean contains(IResource resource) { -// -// IClasspathEntry[] classpath; -// IPath output; -// try { -// classpath = getResolvedClasspath(true); -// output = getOutputLocation(); -// } catch (JavaModelException e) { -// return false; -// } -// -// IPath fullPath = resource.getFullPath(); -// IPath innerMostOutput = output.isPrefixOf(fullPath) ? output : null; -// IClasspathEntry innerMostEntry = null; -// for (int j = 0, cpLength = classpath.length; j < cpLength; j++) { -// IClasspathEntry entry = classpath[j]; -// -// IPath entryPath = entry.getPath(); -// if ((innerMostEntry == null || innerMostEntry.getPath().isPrefixOf(entryPath)) -// && entryPath.isPrefixOf(fullPath)) { -// innerMostEntry = entry; -// } -// IPath entryOutput = classpath[j].getOutputLocation(); -// if (entryOutput != null && entryOutput.isPrefixOf(fullPath)) { -// innerMostOutput = entryOutput; -// } -// } -// if (innerMostEntry != null) { -// // special case prj==src and nested output location -// if (innerMostOutput != null && innerMostOutput.segmentCount() > 1 // output isn't project -// && innerMostEntry.getPath().segmentCount() == 1) { // 1 segment must be project name -// return false; -// } -// if (resource instanceof IFolder) { -// // folders are always included in src/lib entries -// return true; -// } -// switch (innerMostEntry.getEntryKind()) { -// case IClasspathEntry.CPE_SOURCE: -// // .class files are not visible in source folders -// return !Util.isClassFileName(fullPath.lastSegment()); -// case IClasspathEntry.CPE_LIBRARY: -// // .java files are not visible in library folders -// return !Util.isJavaFileName(fullPath.lastSegment()); -// } -// } -// if (innerMostOutput != null) { -// return false; -// } -// return true; -// } + public boolean contains(IResource resource) { + + IClasspathEntry[] classpath; + IPath output; + try { + classpath = getResolvedClasspath(true); + output = getOutputLocation(); + } catch (JavaModelException e) { + return false; + } + + IPath fullPath = resource.getFullPath(); + IPath innerMostOutput = output.isPrefixOf(fullPath) ? output : null; + IClasspathEntry innerMostEntry = null; + for (int j = 0, cpLength = classpath.length; j < cpLength; j++) { + IClasspathEntry entry = classpath[j]; + + IPath entryPath = entry.getPath(); + if ((innerMostEntry == null || innerMostEntry.getPath().isPrefixOf(entryPath)) + && entryPath.isPrefixOf(fullPath)) { + innerMostEntry = entry; + } + IPath entryOutput = classpath[j].getOutputLocation(); + if (entryOutput != null && entryOutput.isPrefixOf(fullPath)) { + innerMostOutput = entryOutput; + } + } + if (innerMostEntry != null) { + // special case prj==src and nested output location + if (innerMostOutput != null && innerMostOutput.segmentCount() > 1 // output isn't project + && innerMostEntry.getPath().segmentCount() == 1) { // 1 segment must be project name + return false; + } + if (resource instanceof IFolder) { + // folders are always included in src/lib entries + return true; + } + switch (innerMostEntry.getEntryKind()) { + case IClasspathEntry.CPE_SOURCE: + // .class files are not visible in source folders + return true; //!Util.isClassFileName(fullPath.lastSegment()); + case IClasspathEntry.CPE_LIBRARY: + // .java files are not visible in library folders + return !Util.isJavaFileName(fullPath.lastSegment()); + } + } + if (innerMostOutput != null) { + return false; + } + return true; + } /** * Record a new marker denoting a classpath problem */ -// IMarker createClasspathProblemMarker(IJavaModelStatus status) { -// -// IMarker marker = null; -// int severity; -// String[] arguments = new String[0]; -// boolean isCycleProblem = false, isClasspathFileFormatProblem = false; -// switch (status.getCode()) { -// -// case IJavaModelStatusConstants.CLASSPATH_CYCLE : -// isCycleProblem = true; -// if (JavaCore.ERROR.equals(getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true))) { -// severity = IMarker.SEVERITY_ERROR; -// } else { -// severity = IMarker.SEVERITY_WARNING; -// } -// break; -// -// case IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT : -// isClasspathFileFormatProblem = true; -// severity = IMarker.SEVERITY_ERROR; -// break; -// -// default: -// IPath path = status.getPath(); -// if (path != null) arguments = new String[] { path.toString() }; -// if (JavaCore.ERROR.equals(getOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, true))) { -// severity = IMarker.SEVERITY_ERROR; -// } else { -// severity = IMarker.SEVERITY_WARNING; -// } -// break; -// } -// -// try { -// marker = getProject().createMarker(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER); -// marker.setAttributes( -// new String[] { -// IMarker.MESSAGE, -// IMarker.SEVERITY, -// IMarker.LOCATION, -// IJavaModelMarker.CYCLE_DETECTED, -// IJavaModelMarker.CLASSPATH_FILE_FORMAT, -// IJavaModelMarker.ID, -// IJavaModelMarker.ARGUMENTS , -// }, -// new Object[] { -// status.getMessage(), -// new Integer(severity), -// Util.bind("classpath.buildPath"),//$NON-NLS-1$ -// isCycleProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$ -// isClasspathFileFormatProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$ -// new Integer(status.getCode()), -// Util.getProblemArgumentsForMarker(arguments) , -// } -// ); -// } catch (CoreException e) { -// } -// return marker; -// } + IMarker createClasspathProblemMarker(IJavaModelStatus status) { + + IMarker marker = null; + int severity; + String[] arguments = new String[0]; + boolean isCycleProblem = false, isClasspathFileFormatProblem = false; + switch (status.getCode()) { + + case IJavaModelStatusConstants.CLASSPATH_CYCLE : + isCycleProblem = true; + if (PHPCore.ERROR.equals(getOption(PHPCore.CORE_CIRCULAR_CLASSPATH, true))) { + severity = IMarker.SEVERITY_ERROR; + } else { + severity = IMarker.SEVERITY_WARNING; + } + break; + + case IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT : + isClasspathFileFormatProblem = true; + severity = IMarker.SEVERITY_ERROR; + break; + + default: + IPath path = status.getPath(); + if (path != null) arguments = new String[] { path.toString() }; + if (PHPCore.ERROR.equals(getOption(PHPCore.CORE_INCOMPLETE_CLASSPATH, true))) { + severity = IMarker.SEVERITY_ERROR; + } else { + severity = IMarker.SEVERITY_WARNING; + } + break; + } + + try { + marker = getProject().createMarker(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER); + marker.setAttributes( + new String[] { + IMarker.MESSAGE, + IMarker.SEVERITY, + IMarker.LOCATION, + IJavaModelMarker.CYCLE_DETECTED, + IJavaModelMarker.CLASSPATH_FILE_FORMAT, + IJavaModelMarker.ID, + IJavaModelMarker.ARGUMENTS , + }, + new Object[] { + status.getMessage(), + new Integer(severity), + Util.bind("classpath.buildPath"),//$NON-NLS-1$ + isCycleProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$ + isClasspathFileFormatProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$ + new Integer(status.getCode()), + Util.getProblemArgumentsForMarker(arguments) , + } + ); + } catch (CoreException e) { + } + return marker; + } /** * Returns a new element info for this element. */ -// protected OpenableElementInfo createElementInfo() { -// -// return new JavaProjectElementInfo(); -// } + protected OpenableElementInfo createElementInfo() { + + return new JavaProjectElementInfo(); + } /** * Reads and decode an XML classpath string */ -// protected IClasspathEntry[] decodeClasspath(String xmlClasspath, boolean createMarker, boolean logProblems) { -// -// ArrayList paths = new ArrayList(); -// IClasspathEntry defaultOutput = null; -// try { -// if (xmlClasspath == null) return null; -// StringReader reader = new StringReader(xmlClasspath); -// Element cpElement; -// -// try { -// DocumentBuilder parser = -// DocumentBuilderFactory.newInstance().newDocumentBuilder(); -// cpElement = parser.parse(new InputSource(reader)).getDocumentElement(); -// } catch (SAXException e) { -// throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$ -// } catch (ParserConfigurationException e) { -// throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$ -// } finally { -// reader.close(); -// } -// -// if (!cpElement.getNodeName().equalsIgnoreCase("classpath")) { //$NON-NLS-1$ -// throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$ -// } -// NodeList list = cpElement.getElementsByTagName("classpathentry"); //$NON-NLS-1$ -// int length = list.getLength(); -// -// for (int i = 0; i < length; ++i) { -// Node node = list.item(i); -// if (node.getNodeType() == Node.ELEMENT_NODE) { -// IClasspathEntry entry = ClasspathEntry.elementDecode((Element)node, this); -// if (entry != null){ -// if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) { -// defaultOutput = entry; // separate output -// } else { -// paths.add(entry); -// } -// } -// } -// } -// } catch (IOException e) { -// // bad format -// if (createMarker && this.getProject().isAccessible()) { -// this.createClasspathProblemMarker(new JavaModelStatus( -// IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, -// Util.bind("classpath.xmlFormatError", this.getElementName(), e.getMessage()))); //$NON-NLS-1$ -// } -// if (logProblems) { -// Util.log(e, -// "Exception while retrieving "+ this.getPath() //$NON-NLS-1$ -// +"/.classpath, will mark classpath as invalid"); //$NON-NLS-1$ -// } -// return INVALID_CLASSPATH; -// } catch (Assert.AssertionFailedException e) { -// // failed creating CP entries from file -// if (createMarker && this.getProject().isAccessible()) { -// this.createClasspathProblemMarker(new JavaModelStatus( -// IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, -// Util.bind("classpath.illegalEntryInClasspathFile", this.getElementName(), e.getMessage()))); //$NON-NLS-1$ -// } -// if (logProblems) { -// Util.log(e, -// "Exception while retrieving "+ this.getPath() //$NON-NLS-1$ -// +"/.classpath, will mark classpath as invalid"); //$NON-NLS-1$ -// } -// return INVALID_CLASSPATH; -// } -// int pathSize = paths.size(); -// if (pathSize > 0 || defaultOutput != null) { -// IClasspathEntry[] entries = new IClasspathEntry[pathSize + (defaultOutput == null ? 0 : 1)]; -// paths.toArray(entries); -// if (defaultOutput != null) entries[pathSize] = defaultOutput; // ensure output is last item -// return entries; -// } else { -// return null; -// } -// } + protected IClasspathEntry[] decodeClasspath(String xmlClasspath, boolean createMarker, boolean logProblems) { + + ArrayList paths = new ArrayList(); + IClasspathEntry defaultOutput = null; + try { + if (xmlClasspath == null) return null; + StringReader reader = new StringReader(xmlClasspath); + Element cpElement; + + try { + DocumentBuilder parser = + DocumentBuilderFactory.newInstance().newDocumentBuilder(); + cpElement = parser.parse(new InputSource(reader)).getDocumentElement(); + } catch (SAXException e) { + throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$ + } catch (ParserConfigurationException e) { + throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$ + } finally { + reader.close(); + } + + if (!cpElement.getNodeName().equalsIgnoreCase("classpath")) { //$NON-NLS-1$ + throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$ + } + NodeList list = cpElement.getElementsByTagName("classpathentry"); //$NON-NLS-1$ + int length = list.getLength(); + + for (int i = 0; i < length; ++i) { + Node node = list.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + IClasspathEntry entry = ClasspathEntry.elementDecode((Element)node, this); + if (entry != null){ + if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) { + defaultOutput = entry; // separate output + } else { + paths.add(entry); + } + } + } + } + } catch (IOException e) { + // bad format + if (createMarker && this.getProject().isAccessible()) { + this.createClasspathProblemMarker(new JavaModelStatus( + IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, + Util.bind("classpath.xmlFormatError", this.getElementName(), e.getMessage()))); //$NON-NLS-1$ + } + if (logProblems) { + Util.log(e, + "Exception while retrieving "+ this.getPath() //$NON-NLS-1$ + +"/.classpath, will mark classpath as invalid"); //$NON-NLS-1$ + } + return INVALID_CLASSPATH; + } catch (Assert.AssertionFailedException e) { + // failed creating CP entries from file + if (createMarker && this.getProject().isAccessible()) { + this.createClasspathProblemMarker(new JavaModelStatus( + IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, + Util.bind("classpath.illegalEntryInClasspathFile", this.getElementName(), e.getMessage()))); //$NON-NLS-1$ + } + if (logProblems) { + Util.log(e, + "Exception while retrieving "+ this.getPath() //$NON-NLS-1$ + +"/.classpath, will mark classpath as invalid"); //$NON-NLS-1$ + } + return INVALID_CLASSPATH; + } + int pathSize = paths.size(); + if (pathSize > 0 || defaultOutput != null) { + IClasspathEntry[] entries = new IClasspathEntry[pathSize + (defaultOutput == null ? 0 : 1)]; + paths.toArray(entries); + if (defaultOutput != null) entries[pathSize] = defaultOutput; // ensure output is last item + return entries; + } else { + return null; + } + } /** /** @@ -672,16 +828,16 @@ public class JavaProject // deregister Java builder removeFromBuildSpec(PHPeclipsePlugin.BUILDER_PARSER_ID); } -// -// /** -// * Returns a default class path. -// * This is the root of the project -// */ -// protected IClasspathEntry[] defaultClasspath() throws JavaModelException { -// -// return new IClasspathEntry[] { -// JavaCore.newSourceEntry(getProject().getFullPath())}; -// } + + /** + * Returns a default class path. + * This is the root of the project + */ + protected IClasspathEntry[] defaultClasspath() throws JavaModelException { + + return new IClasspathEntry[] { + PHPCore.newSourceEntry(getProject().getFullPath())}; + } /** * Returns a default output location. @@ -694,46 +850,46 @@ public class JavaProject /** * Returns the XML String encoding of the class path. */ -// protected String encodeClasspath(IClasspathEntry[] classpath, IPath outputLocation, boolean useLineSeparator) throws JavaModelException { -// -// Document document = new DocumentImpl(); -// Element cpElement = document.createElement("classpath"); //$NON-NLS-1$ -// document.appendChild(cpElement); -// -// for (int i = 0; i < classpath.length; ++i) { -// cpElement.appendChild(((ClasspathEntry)classpath[i]).elementEncode(document, getProject().getFullPath())); -// } -// -// if (outputLocation != null) { -// outputLocation = outputLocation.removeFirstSegments(1); -// outputLocation = outputLocation.makeRelative(); -// Element oElement = document.createElement("classpathentry"); //$NON-NLS-1$ -// oElement.setAttribute("kind", ClasspathEntry.kindToString(ClasspathEntry.K_OUTPUT)); //$NON-NLS-1$ -// oElement.setAttribute("path", outputLocation.toString()); //$NON-NLS-1$ -// cpElement.appendChild(oElement); -// } -// -// // produce a String output -// try { -// ByteArrayOutputStream s = new ByteArrayOutputStream(); -// OutputFormat format = new OutputFormat(); -// if (useLineSeparator) { -// format.setIndenting(true); -// format.setLineSeparator(System.getProperty("line.separator")); //$NON-NLS-1$ -// } else { -// format.setPreserveSpace(true); -// } -// Serializer serializer = -// SerializerFactory.getSerializerFactory(Method.XML).makeSerializer( -// new OutputStreamWriter(s, "UTF8"), //$NON-NLS-1$ -// format); -// serializer.asDOMSerializer().serialize(document); -// return s.toString("UTF8"); //$NON-NLS-1$ -// } catch (IOException e) { -// throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); -// } -// } -// + protected String encodeClasspath(IClasspathEntry[] classpath, IPath outputLocation, boolean useLineSeparator) throws JavaModelException { + + Document document = new DocumentImpl(); + Element cpElement = document.createElement("classpath"); //$NON-NLS-1$ + document.appendChild(cpElement); + + for (int i = 0; i < classpath.length; ++i) { + cpElement.appendChild(((ClasspathEntry)classpath[i]).elementEncode(document, getProject().getFullPath())); + } + + if (outputLocation != null) { + outputLocation = outputLocation.removeFirstSegments(1); + outputLocation = outputLocation.makeRelative(); + Element oElement = document.createElement("classpathentry"); //$NON-NLS-1$ + oElement.setAttribute("kind", ClasspathEntry.kindToString(ClasspathEntry.K_OUTPUT)); //$NON-NLS-1$ + oElement.setAttribute("path", outputLocation.toString()); //$NON-NLS-1$ + cpElement.appendChild(oElement); + } + + // produce a String output + try { + ByteArrayOutputStream s = new ByteArrayOutputStream(); + OutputFormat format = new OutputFormat(); + if (useLineSeparator) { + format.setIndenting(true); + format.setLineSeparator(System.getProperty("line.separator")); //$NON-NLS-1$ + } else { + format.setPreserveSpace(true); + } + Serializer serializer = + SerializerFactory.getSerializerFactory(Method.XML).makeSerializer( + new OutputStreamWriter(s, "UTF8"), //$NON-NLS-1$ + format); + serializer.asDOMSerializer().serialize(document); + return s.toString("UTF8"); //$NON-NLS-1$ + } catch (IOException e) { + throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); + } + } + /** * Returns true if this handle represents the same Java project * as the given handle. Two handles represent the same @@ -763,23 +919,23 @@ public class JavaProject /** * @see IJavaProject */ -// public IJavaElement findElement(IPath path) throws JavaModelException { -// -// if (path == null || path.isAbsolute()) { -// throw new JavaModelException( -// new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, path)); -// } + public IJavaElement findElement(IPath path) throws JavaModelException { + + if (path == null || path.isAbsolute()) { + throw new JavaModelException( + new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, path)); + } // try { -// -// String extension = path.getFileExtension(); -// if (extension == null) { -// String packageName = path.toString().replace(IPath.SEPARATOR, '.'); -// + + String extension = path.getFileExtension(); + if (extension == null) { + String packageName = path.toString().replace(IPath.SEPARATOR, '.'); + // IPackageFragment[] pkgFragments = // getNameLookup().findPackageFragments(packageName, false); // if (pkgFragments == null) { -// return null; -// + return null; + // } else { // // try to return one that is a child of this project // for (int i = 0, length = pkgFragments.length; i < length; i++) { @@ -792,19 +948,19 @@ public class JavaProject // // default to the first one // return pkgFragments[0]; // } -// } else if ( -// extension.equalsIgnoreCase("java") //$NON-NLS-1$ -// || extension.equalsIgnoreCase("class")) { //$NON-NLS-1$ -// IPath packagePath = path.removeLastSegments(1); -// String packageName = packagePath.toString().replace(IPath.SEPARATOR, '.'); -// String typeName = path.lastSegment(); -// typeName = typeName.substring(0, typeName.length() - extension.length() - 1); -// String qualifiedName = null; -// if (packageName.length() > 0) { -// qualifiedName = packageName + "." + typeName; //$NON-NLS-1$ -// } else { -// qualifiedName = typeName; -// } + } else if ( + extension.equalsIgnoreCase("java") //$NON-NLS-1$ + || extension.equalsIgnoreCase("class")) { //$NON-NLS-1$ + IPath packagePath = path.removeLastSegments(1); + String packageName = packagePath.toString().replace(IPath.SEPARATOR, '.'); + String typeName = path.lastSegment(); + typeName = typeName.substring(0, typeName.length() - extension.length() - 1); + String qualifiedName = null; + if (packageName.length() > 0) { + qualifiedName = packageName + "." + typeName; //$NON-NLS-1$ + } else { + qualifiedName = typeName; + } // IType type = // getNameLookup().findType( // qualifiedName, @@ -813,12 +969,12 @@ public class JavaProject // if (type != null) { // return type.getParent(); // } else { -// return null; + return null; // } -// } else { -// // unsupported extension -// return null; -// } + } else { + // unsupported extension + return null; + } // } catch (JavaModelException e) { // if (e.getStatus().getCode() // == IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST) { @@ -827,7 +983,7 @@ public class JavaProject // throw e; // } // } -// } + } /** * @see IJavaProject @@ -837,10 +993,10 @@ public class JavaProject // // return findPackageFragment0(JavaProject.canonicalizedPath(path)); // } - - /** - * non path canonicalizing version - */ +// +// /** +// * non path canonicalizing version +// */ // public IPackageFragment findPackageFragment0(IPath path) // throws JavaModelException { // @@ -850,49 +1006,49 @@ public class JavaProject /** * @see IJavaProject */ -// public IPackageFragmentRoot findPackageFragmentRoot(IPath path) -// throws JavaModelException { -// -// return findPackageFragmentRoot0(JavaProject.canonicalizedPath(path)); -// } + public IPackageFragmentRoot findPackageFragmentRoot(IPath path) + throws JavaModelException { + + return findPackageFragmentRoot0(JavaProject.canonicalizedPath(path)); + } /** * no path canonicalization */ -// public IPackageFragmentRoot findPackageFragmentRoot0(IPath path) -// throws JavaModelException { -// -// IPackageFragmentRoot[] allRoots = this.getAllPackageFragmentRoots(); -// if (!path.isAbsolute()) { -// throw new IllegalArgumentException(Util.bind("path.mustBeAbsolute")); //$NON-NLS-1$ -// } -// for (int i= 0; i < allRoots.length; i++) { -// IPackageFragmentRoot classpathRoot= allRoots[i]; -// if (classpathRoot.getPath().equals(path)) { -// return classpathRoot; -// } -// } -// return null; -// } + public IPackageFragmentRoot findPackageFragmentRoot0(IPath path) + throws JavaModelException { + + IPackageFragmentRoot[] allRoots = this.getAllPackageFragmentRoots(); + if (!path.isAbsolute()) { + throw new IllegalArgumentException(Util.bind("path.mustBeAbsolute")); //$NON-NLS-1$ + } + for (int i= 0; i < allRoots.length; i++) { + IPackageFragmentRoot classpathRoot= allRoots[i]; + if (classpathRoot.getPath().equals(path)) { + return classpathRoot; + } + } + return null; + } /** * @see IJavaProject */ -// public IPackageFragmentRoot[] findPackageFragmentRoots(IClasspathEntry entry) { -// try { -// IClasspathEntry[] classpath = this.getRawClasspath(); -// for (int i = 0, length = classpath.length; i < length; i++) { -// if (classpath[i].equals(entry)) { // entry may need to be resolved -// return -// computePackageFragmentRoots( -// getResolvedClasspath(new IClasspathEntry[] {entry}, null, true, false, null/*no reverse map*/), -// false); // don't retrieve exported roots -// } -// } -// } catch (JavaModelException e) { -// } -// return new IPackageFragmentRoot[] {}; -// } -// + public IPackageFragmentRoot[] findPackageFragmentRoots(IClasspathEntry entry) { + try { + IClasspathEntry[] classpath = this.getRawClasspath(); + for (int i = 0, length = classpath.length; i < length; i++) { + if (classpath[i].equals(entry)) { // entry may need to be resolved + return + computePackageFragmentRoots( + getResolvedClasspath(new IClasspathEntry[] {entry}, null, true, false, null/*no reverse map*/), + false); // don't retrieve exported roots + } + } + } catch (JavaModelException e) { + } + return new IPackageFragmentRoot[] {}; + } + /** * @see IJavaProject#findType(String) */ @@ -929,150 +1085,150 @@ public class JavaProject // NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES); // } // -// /** -// * Remove all markers denoting classpath problems -// */ -// protected void flushClasspathProblemMarkers(boolean flushCycleMarkers, boolean flushClasspathFormatMarkers) { -// try { -// IProject project = getProject(); -// if (project.exists()) { -// IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); -// for (int i = 0, length = markers.length; i < length; i++) { -// IMarker marker = markers[i]; -// if (flushCycleMarkers && flushClasspathFormatMarkers) { -// marker.delete(); -// } else { -// String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED); -// String classpathFileFormatAttr = (String)marker.getAttribute(IJavaModelMarker.CLASSPATH_FILE_FORMAT); -// if ((flushCycleMarkers == (cycleAttr != null && cycleAttr.equals("true"))) //$NON-NLS-1$ -// && (flushClasspathFormatMarkers == (classpathFileFormatAttr != null && classpathFileFormatAttr.equals("true")))){ //$NON-NLS-1$ -// marker.delete(); -// } -// } -// } -// } -// } catch (CoreException e) { -// } -// } -// -// /** -// * @see Openable -// */ -// protected boolean generateInfos( -// OpenableElementInfo info, -// IProgressMonitor pm, -// Map newElements, -// IResource underlyingResource) throws JavaModelException { -// -// boolean validInfo = false; -// try { -// if (getProject().isOpen()) { -// // put the info now, because computing the roots requires it -// JavaModelManager.getJavaModelManager().putInfo(this, info); -// -// // compute the pkg fragment roots -// updatePackageFragmentRoots(); -// -// // remember the timestamps of external libraries the first time they are looked up -// IClasspathEntry[] resolvedClasspath = getResolvedClasspath(true/*ignore unresolved variable*/); -// for (int i = 0, length = resolvedClasspath.length; i < length; i++) { -// IClasspathEntry entry = resolvedClasspath[i]; -// if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { -// IPath path = entry.getPath(); -// Object target = JavaModel.getTarget(ResourcesPlugin.getWorkspace().getRoot(), path, true); -// if (target instanceof java.io.File) { -// Map externalTimeStamps = JavaModelManager.getJavaModelManager().deltaProcessor.externalTimeStamps; -// if (externalTimeStamps.get(path) == null) { -// long timestamp = DeltaProcessor.getTimeStamp((java.io.File)target); -// externalTimeStamps.put(path, new Long(timestamp)); -// } -// } -// } -// } -// -// // only valid if reaches here -// validInfo = true; -// } -// } finally { -// if (!validInfo) -// JavaModelManager.getJavaModelManager().removeInfo(this); -// } -// return validInfo; -// } + /** + * Remove all markers denoting classpath problems + */ + protected void flushClasspathProblemMarkers(boolean flushCycleMarkers, boolean flushClasspathFormatMarkers) { + try { + IProject project = getProject(); + if (project.exists()) { + IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); + for (int i = 0, length = markers.length; i < length; i++) { + IMarker marker = markers[i]; + if (flushCycleMarkers && flushClasspathFormatMarkers) { + marker.delete(); + } else { + String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED); + String classpathFileFormatAttr = (String)marker.getAttribute(IJavaModelMarker.CLASSPATH_FILE_FORMAT); + if ((flushCycleMarkers == (cycleAttr != null && cycleAttr.equals("true"))) //$NON-NLS-1$ + && (flushClasspathFormatMarkers == (classpathFileFormatAttr != null && classpathFileFormatAttr.equals("true")))){ //$NON-NLS-1$ + marker.delete(); + } + } + } + } + } catch (CoreException e) { + } + } + + /** + * @see Openable + */ + protected boolean generateInfos( + OpenableElementInfo info, + IProgressMonitor pm, + Map newElements, + IResource underlyingResource) throws JavaModelException { + + boolean validInfo = false; + try { + if (getProject().isOpen()) { + // put the info now, because computing the roots requires it + JavaModelManager.getJavaModelManager().putInfo(this, info); + + // compute the pkg fragment roots + updatePackageFragmentRoots(); + + // remember the timestamps of external libraries the first time they are looked up + IClasspathEntry[] resolvedClasspath = getResolvedClasspath(true/*ignore unresolved variable*/); + for (int i = 0, length = resolvedClasspath.length; i < length; i++) { + IClasspathEntry entry = resolvedClasspath[i]; + if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { + IPath path = entry.getPath(); + Object target = JavaModel.getTarget(ResourcesPlugin.getWorkspace().getRoot(), path, true); + if (target instanceof java.io.File) { + Map externalTimeStamps = JavaModelManager.getJavaModelManager().deltaProcessor.externalTimeStamps; + if (externalTimeStamps.get(path) == null) { + long timestamp = DeltaProcessor.getTimeStamp((java.io.File)target); + externalTimeStamps.put(path, new Long(timestamp)); + } + } + } + } + + // only valid if reaches here + validInfo = true; + } + } finally { + if (!validInfo) + JavaModelManager.getJavaModelManager().removeInfo(this); + } + return validInfo; + } /** * @see IJavaProject */ -// public IPackageFragmentRoot[] getAllPackageFragmentRoots() -// throws JavaModelException { -// -// return computePackageFragmentRoots(getResolvedClasspath(true), true); -// } -// -// /** -// * Returns the classpath entry that refers to the given path -// * or null if there is no reference to the path. -// */ -// public IClasspathEntry getClasspathEntryFor(IPath path) -// throws JavaModelException { -// -// IClasspathEntry[] entries = getExpandedClasspath(true); -// for (int i = 0; i < entries.length; i++) { -// if (entries[i].getPath().equals(path)) { -// return entries[i]; -// } -// } -// return null; -// } + public IPackageFragmentRoot[] getAllPackageFragmentRoots() + throws JavaModelException { + + return computePackageFragmentRoots(getResolvedClasspath(true), true); + } + + /** + * Returns the classpath entry that refers to the given path + * or null if there is no reference to the path. + */ + public IClasspathEntry getClasspathEntryFor(IPath path) + throws JavaModelException { + + IClasspathEntry[] entries = getExpandedClasspath(true); + for (int i = 0; i < entries.length; i++) { + if (entries[i].getPath().equals(path)) { + return entries[i]; + } + } + return null; + } /* * Returns the cycle marker associated with this project or null if none. */ -// public IMarker getCycleMarker(){ -// try { -// IProject project = getProject(); -// if (project.exists()) { -// IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); -// for (int i = 0, length = markers.length; i < length; i++) { -// IMarker marker = markers[i]; -// String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED); -// if (cycleAttr != null && cycleAttr.equals("true")){ //$NON-NLS-1$ -// return marker; -// } -// } -// } -// } catch (CoreException e) { -// } -// return null; -// } -// -// /** -// * This is a helper method returning the expanded classpath for the project, as a list of classpath entries, -// * where all classpath variable entries have been resolved and substituted with their final target entries. -// * All project exports have been appended to project entries. -// */ -// public IClasspathEntry[] getExpandedClasspath(boolean ignoreUnresolvedVariable) throws JavaModelException { -// -// return getExpandedClasspath(ignoreUnresolvedVariable, false); -// } + public IMarker getCycleMarker(){ + try { + IProject project = getProject(); + if (project.exists()) { + IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); + for (int i = 0, length = markers.length; i < length; i++) { + IMarker marker = markers[i]; + String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED); + if (cycleAttr != null && cycleAttr.equals("true")){ //$NON-NLS-1$ + return marker; + } + } + } + } catch (CoreException e) { + } + return null; + } + + /** + * This is a helper method returning the expanded classpath for the project, as a list of classpath entries, + * where all classpath variable entries have been resolved and substituted with their final target entries. + * All project exports have been appended to project entries. + */ + public IClasspathEntry[] getExpandedClasspath(boolean ignoreUnresolvedVariable) throws JavaModelException { + + return getExpandedClasspath(ignoreUnresolvedVariable, false); + } /** * Internal variant which can create marker on project for invalid entries, * it will also perform classpath expansion in presence of project prerequisites * exporting their entries. */ -// public IClasspathEntry[] getExpandedClasspath( -// boolean ignoreUnresolvedVariable, -// boolean generateMarkerOnError) throws JavaModelException { -// -// ObjectVector accumulatedEntries = new ObjectVector(); -// computeExpandedClasspath(this, ignoreUnresolvedVariable, generateMarkerOnError, new HashSet(5), accumulatedEntries); -// -// IClasspathEntry[] expandedPath = new IClasspathEntry[accumulatedEntries.size()]; -// accumulatedEntries.copyInto(expandedPath); -// -// return expandedPath; -// } + public IClasspathEntry[] getExpandedClasspath( + boolean ignoreUnresolvedVariable, + boolean generateMarkerOnError) throws JavaModelException { + + ObjectVector accumulatedEntries = new ObjectVector(); + computeExpandedClasspath(this, ignoreUnresolvedVariable, generateMarkerOnError, new HashSet(5), accumulatedEntries); + + IClasspathEntry[] expandedPath = new IClasspathEntry[accumulatedEntries.size()]; + accumulatedEntries.copyInto(expandedPath); + + return expandedPath; + } /** * Returns the char that marks the start of this handles @@ -1097,31 +1253,31 @@ public class JavaProject } return null; } -// -// /** -// * Convenience method that returns the specific type of info for a Java project. -// */ -// protected JavaProjectElementInfo getJavaProjectElementInfo() -// throws JavaModelException { -// -// return (JavaProjectElementInfo) getElementInfo(); -// } + + /** + * Convenience method that returns the specific type of info for a Java project. + */ + protected JavaProjectElementInfo getJavaProjectElementInfo() + throws JavaModelException { + + return (JavaProjectElementInfo) getElementInfo(); + } /** * @see IJavaProject */ -// public NameLookup getNameLookup() throws JavaModelException { -// -// JavaProjectElementInfo info = getJavaProjectElementInfo(); -// // lock on the project info to avoid race condition -// synchronized(info){ -// NameLookup nameLookup; -// if ((nameLookup = info.getNameLookup()) == null){ -// info.setNameLookup(nameLookup = new NameLookup(this)); -// } -// return nameLookup; -// } -// } + public NameLookup getNameLookup() throws JavaModelException { + + JavaProjectElementInfo info = getJavaProjectElementInfo(); + // lock on the project info to avoid race condition + synchronized(info){ + NameLookup nameLookup; + if ((nameLookup = info.getNameLookup()) == null){ + info.setNameLookup(nameLookup = new NameLookup(this)); + } + return nameLookup; + } + } // // /** // * Returns an array of non-java resources contained in the receiver. @@ -1134,91 +1290,91 @@ public class JavaProject /** * @see org.eclipse.jdt.core.IJavaProject#getOption(String, boolean) */ -// public String getOption(String optionName, boolean inheritJavaCoreOptions) { -// -// if (JavaModelManager.OptionNames.contains(optionName)){ -// -// Preferences preferences = getPreferences(); -// if (preferences == null || preferences.isDefault(optionName)) { -// return inheritJavaCoreOptions ? PHPCore.getOption(optionName) : null; -// } -// return preferences.getString(optionName).trim(); -// } -// return null; -// } + public String getOption(String optionName, boolean inheritJavaCoreOptions) { + + if (JavaModelManager.OptionNames.contains(optionName)){ + + Preferences preferences = getPreferences(); + if (preferences == null || preferences.isDefault(optionName)) { + return inheritJavaCoreOptions ? PHPCore.getOption(optionName) : null; + } + return preferences.getString(optionName).trim(); + } + return null; + } /** * @see org.eclipse.jdt.core.IJavaProject#getOptions(boolean) */ -// public Map getOptions(boolean inheritJavaCoreOptions) { -// -// // initialize to the defaults from JavaCore options pool -// Map options = inheritJavaCoreOptions ? PHPCore.getOptions() : new Hashtable(5); -// -// Preferences preferences = getPreferences(); -// if (preferences == null) return options; // cannot do better (non-Java project) -// HashSet optionNames = JavaModelManager.OptionNames; -// -// // get preferences set to their default -// if (inheritJavaCoreOptions){ -// String[] defaultPropertyNames = preferences.defaultPropertyNames(); -// for (int i = 0; i < defaultPropertyNames.length; i++){ -// String propertyName = defaultPropertyNames[i]; -// if (optionNames.contains(propertyName)){ -// options.put(propertyName, preferences.getDefaultString(propertyName).trim()); -// } -// } -// } -// // get custom preferences not set to their default -// String[] propertyNames = preferences.propertyNames(); -// for (int i = 0; i < propertyNames.length; i++){ -// String propertyName = propertyNames[i]; -// if (optionNames.contains(propertyName)){ -// options.put(propertyName, preferences.getString(propertyName).trim()); -// } -// } -// return options; -// } + public Map getOptions(boolean inheritJavaCoreOptions) { + + // initialize to the defaults from JavaCore options pool + Map options = inheritJavaCoreOptions ? PHPCore.getOptions() : new Hashtable(5); + + Preferences preferences = getPreferences(); + if (preferences == null) return options; // cannot do better (non-Java project) + HashSet optionNames = JavaModelManager.OptionNames; + + // get preferences set to their default + if (inheritJavaCoreOptions){ + String[] defaultPropertyNames = preferences.defaultPropertyNames(); + for (int i = 0; i < defaultPropertyNames.length; i++){ + String propertyName = defaultPropertyNames[i]; + if (optionNames.contains(propertyName)){ + options.put(propertyName, preferences.getDefaultString(propertyName).trim()); + } + } + } + // get custom preferences not set to their default + String[] propertyNames = preferences.propertyNames(); + for (int i = 0; i < propertyNames.length; i++){ + String propertyName = propertyNames[i]; + if (optionNames.contains(propertyName)){ + options.put(propertyName, preferences.getString(propertyName).trim()); + } + } + return options; + } /** * @see IJavaProject */ -// public IPath getOutputLocation() throws JavaModelException { -// -// JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject); -// IPath outputLocation = perProjectInfo.outputLocation; -// if (outputLocation != null) return outputLocation; -// -// // force to read classpath - will position output location as well -// this.getRawClasspath(); -// outputLocation = perProjectInfo.outputLocation; -// if (outputLocation == null) { -// return defaultOutputLocation(); -// } -// return outputLocation; -// } -// -// /** -// * @return A handle to the package fragment root identified by the given path. -// * This method is handle-only and the element may or may not exist. Returns -// * null if unable to generate a handle from the path (for example, -// * an absolute path that has less than 1 segment. The path may be relative or -// * absolute. -// */ -// public IPackageFragmentRoot getPackageFragmentRoot(IPath path) { -// if (!path.isAbsolute()) { -// path = getPath().append(path); -// } -// int segmentCount = path.segmentCount(); -// switch (segmentCount) { -// case 0: -// return null; -// case 1: -// // default root -// return getPackageFragmentRoot(getProject()); -// default: -// // a path ending with .jar/.zip is still ambiguous and could still resolve to a source/lib folder -// // thus will try to guess based on existing resource + public IPath getOutputLocation() throws JavaModelException { + + JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject); + IPath outputLocation = perProjectInfo.outputLocation; + if (outputLocation != null) return outputLocation; + + // force to read classpath - will position output location as well + this.getRawClasspath(); + outputLocation = perProjectInfo.outputLocation; + if (outputLocation == null) { + return defaultOutputLocation(); + } + return outputLocation; + } + + /** + * @return A handle to the package fragment root identified by the given path. + * This method is handle-only and the element may or may not exist. Returns + * null if unable to generate a handle from the path (for example, + * an absolute path that has less than 1 segment. The path may be relative or + * absolute. + */ + public IPackageFragmentRoot getPackageFragmentRoot(IPath path) { + if (!path.isAbsolute()) { + path = getPath().append(path); + } + int segmentCount = path.segmentCount(); + switch (segmentCount) { + case 0: + return null; + case 1: + // default root + return getPackageFragmentRoot(getProject()); + default: + // a path ending with .jar/.zip is still ambiguous and could still resolve to a source/lib folder + // thus will try to guess based on existing resource // if (Util.isArchiveFileName(path.lastSegment())) { // IResource resource = getProject().getWorkspace().getRoot().findMember(path); // if (resource != null && resource.getType() == IResource.FOLDER){ @@ -1226,45 +1382,45 @@ public class JavaProject // } // return getPackageFragmentRoot0(path); // } else { -// return getPackageFragmentRoot(getProject().getWorkspace().getRoot().getFolder(path)); + return getPackageFragmentRoot(getProject().getWorkspace().getRoot().getFolder(path)); // } -// } -// } -// -// /** -// * The path is known to match a source/library folder entry. -// */ -// public IPackageFragmentRoot getFolderPackageFragmentRoot(IPath path) { -// if (path.segmentCount() == 1) { // default project root -// return getPackageFragmentRoot(getProject()); -// } -// return getPackageFragmentRoot(getProject().getWorkspace().getRoot().getFolder(path)); -// } -// -// /** -// * @see IJavaProject -// */ -// public IPackageFragmentRoot getPackageFragmentRoot(IResource resource) { -// -// switch (resource.getType()) { -// case IResource.FILE: + } + } + + /** + * The path is known to match a source/library folder entry. + */ + public IPackageFragmentRoot getFolderPackageFragmentRoot(IPath path) { + if (path.segmentCount() == 1) { // default project root + return getPackageFragmentRoot(getProject()); + } + return getPackageFragmentRoot(getProject().getWorkspace().getRoot().getFolder(path)); + } + + /** + * @see IJavaProject + */ + public IPackageFragmentRoot getPackageFragmentRoot(IResource resource) { + + switch (resource.getType()) { + case IResource.FILE: // if (Util.isArchiveFileName(resource.getName())) { // return new JarPackageFragmentRoot(resource, this); // } else { -// return null; + return null; // } -// case IResource.FOLDER: -// return new PackageFragmentRoot(resource, this, resource.getName()); -// case IResource.PROJECT: -// return new PackageFragmentRoot(resource, this, ""); //$NON-NLS-1$ -// default: -// return null; -// } -// } -// -// /** -// * @see IJavaProject -// */ + case IResource.FOLDER: + return new PackageFragmentRoot(resource, this, resource.getName()); + case IResource.PROJECT: + return new PackageFragmentRoot(resource, this, ""); //$NON-NLS-1$ + default: + return null; + } + } + + /** + * @see IJavaProject + */ // public IPackageFragmentRoot getPackageFragmentRoot(String jarPath) { // // return getPackageFragmentRoot0(JavaProject.canonicalizedPath(new Path(jarPath))); @@ -1277,86 +1433,86 @@ public class JavaProject // // return new JarPackageFragmentRoot(jarPath, this); // } -// -// /** -// * @see IJavaProject -// */ -// public IPackageFragmentRoot[] getPackageFragmentRoots() -// throws JavaModelException { -// -// Object[] children; -// int length; -// IPackageFragmentRoot[] roots; -// -// System.arraycopy( -// children = getChildren(), -// 0, -// roots = new IPackageFragmentRoot[length = children.length], -// 0, -// length); -// -// return roots; -// } + + /** + * @see IJavaProject + */ + public IPackageFragmentRoot[] getPackageFragmentRoots() + throws JavaModelException { + + Object[] children; + int length; + IPackageFragmentRoot[] roots; + + System.arraycopy( + children = getChildren(), + 0, + roots = new IPackageFragmentRoot[length = children.length], + 0, + length); + + return roots; + } /** * @see IJavaProject * @deprecated */ -// public IPackageFragmentRoot[] getPackageFragmentRoots(IClasspathEntry entry) { -// return findPackageFragmentRoots(entry); -// } + public IPackageFragmentRoot[] getPackageFragmentRoots(IClasspathEntry entry) { + return findPackageFragmentRoots(entry); + } /** * Returns the package fragment root prefixed by the given path, or * an empty collection if there are no such elements in the model. */ -// protected IPackageFragmentRoot[] getPackageFragmentRoots(IPath path) -// -// throws JavaModelException { -// IPackageFragmentRoot[] roots = getAllPackageFragmentRoots(); -// ArrayList matches = new ArrayList(); -// -// for (int i = 0; i < roots.length; ++i) { -// if (path.isPrefixOf(roots[i].getPath())) { -// matches.add(roots[i]); -// } -// } -// IPackageFragmentRoot[] copy = new IPackageFragmentRoot[matches.size()]; -// matches.toArray(copy); -// return copy; -// } + protected IPackageFragmentRoot[] getPackageFragmentRoots(IPath path) + + throws JavaModelException { + IPackageFragmentRoot[] roots = getAllPackageFragmentRoots(); + ArrayList matches = new ArrayList(); + + for (int i = 0; i < roots.length; ++i) { + if (path.isPrefixOf(roots[i].getPath())) { + matches.add(roots[i]); + } + } + IPackageFragmentRoot[] copy = new IPackageFragmentRoot[matches.size()]; + matches.toArray(copy); + return copy; + } /** * @see IJavaProject */ -// public IPackageFragment[] getPackageFragments() throws JavaModelException { -// -// IPackageFragmentRoot[] roots = getPackageFragmentRoots(); -// return getPackageFragmentsInRoots(roots); -// } + public IPackageFragment[] getPackageFragments() throws JavaModelException { + + IPackageFragmentRoot[] roots = getPackageFragmentRoots(); + return getPackageFragmentsInRoots(roots); + } /** * Returns all the package fragments found in the specified * package fragment roots. */ -// public IPackageFragment[] getPackageFragmentsInRoots(IPackageFragmentRoot[] roots) { -// -// ArrayList frags = new ArrayList(); -// for (int i = 0; i < roots.length; i++) { -// IPackageFragmentRoot root = roots[i]; -// try { -// IJavaElement[] rootFragments = root.getChildren(); -// for (int j = 0; j < rootFragments.length; j++) { -// frags.add(rootFragments[j]); -// } -// } catch (JavaModelException e) { -// // do nothing -// } -// } -// IPackageFragment[] fragments = new IPackageFragment[frags.size()]; -// frags.toArray(fragments); -// return fragments; -// } + public IPackageFragment[] getPackageFragmentsInRoots(IPackageFragmentRoot[] roots) { + + ArrayList frags = new ArrayList(); + for (int i = 0; i < roots.length; i++) { + IPackageFragmentRoot root = roots[i]; + try { + IJavaElement[] rootFragments = root.getChildren(); + for (int j = 0; j < rootFragments.length; j++) { + frags.add(rootFragments[j]); + } + } catch (JavaModelException e) { + // do nothing + } + } + IPackageFragment[] fragments = new IPackageFragment[frags.size()]; + frags.toArray(fragments); + return fragments; + } /* * @see IJavaElement @@ -1372,166 +1528,183 @@ public class JavaProject return fProject; } + + protected IProject getProject(String name) { + return PHPeclipsePlugin.getWorkspace().getRoot().getProject(name); + } + + public List getReferencedProjects() { + List referencedProjects = new ArrayList(); + + Iterator iterator = getLoadPathEntries().iterator(); + while (iterator.hasNext()) { + LoadPathEntry pathEntry = (LoadPathEntry) iterator.next(); + if (pathEntry.getType() == LoadPathEntry.TYPE_PROJECT) + referencedProjects.add(pathEntry.getProject()); + } + return referencedProjects; + } + /** * Returns the project custom preference pool. * Project preferences may include custom encoding. */ -// public Preferences getPreferences(){ -// IProject project = getProject(); -// if (!JavaProject.hasJavaNature(project)) return null; -// JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(project, true); -// Preferences preferences = perProjectInfo.preferences; -// if (preferences != null) return preferences; -// preferences = loadPreferences(); -// if (preferences == null) preferences = new Preferences(); -// perProjectInfo.preferences = preferences; -// return preferences; -// } + public Preferences getPreferences(){ + IProject project = getProject(); + if (!JavaProject.hasJavaNature(project)) return null; + JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(project, true); + Preferences preferences = perProjectInfo.preferences; + if (preferences != null) return preferences; + preferences = loadPreferences(); + if (preferences == null) preferences = new Preferences(); + perProjectInfo.preferences = preferences; + return preferences; + } /** * @see IJavaProject */ -// public IClasspathEntry[] getRawClasspath() throws JavaModelException { -// -// JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject); -// IClasspathEntry[] classpath = perProjectInfo.classpath; -// if (classpath != null) return classpath; -// classpath = this.readClasspathFile(false/*don't create markers*/, true/*log problems*/); -// -// // extract out the output location -// IPath outputLocation = null; -// if (classpath != null && classpath.length > 0) { -// IClasspathEntry entry = classpath[classpath.length - 1]; -// if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) { -// outputLocation = entry.getPath(); -// IClasspathEntry[] copy = new IClasspathEntry[classpath.length - 1]; -// System.arraycopy(classpath, 0, copy, 0, copy.length); -// classpath = copy; -// } -// } -// if (classpath == null) { -// return defaultClasspath(); -// } -// /* Disable validate: classpath can contain CP variables and container that need to be resolved -// if (classpath != INVALID_CLASSPATH -// && !JavaConventions.validateClasspath(this, classpath, outputLocation).isOK()) { -// classpath = INVALID_CLASSPATH; -// } -// */ -// perProjectInfo.classpath = classpath; -// perProjectInfo.outputLocation = outputLocation; -// return classpath; -// } + public IClasspathEntry[] getRawClasspath() throws JavaModelException { + + JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject); + IClasspathEntry[] classpath = perProjectInfo.classpath; + if (classpath != null) return classpath; + classpath = this.readClasspathFile(false/*don't create markers*/, true/*log problems*/); + + // extract out the output location + IPath outputLocation = null; + if (classpath != null && classpath.length > 0) { + IClasspathEntry entry = classpath[classpath.length - 1]; + if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) { + outputLocation = entry.getPath(); + IClasspathEntry[] copy = new IClasspathEntry[classpath.length - 1]; + System.arraycopy(classpath, 0, copy, 0, copy.length); + classpath = copy; + } + } + if (classpath == null) { + return defaultClasspath(); + } + /* Disable validate: classpath can contain CP variables and container that need to be resolved + if (classpath != INVALID_CLASSPATH + && !JavaConventions.validateClasspath(this, classpath, outputLocation).isOK()) { + classpath = INVALID_CLASSPATH; + } + */ + perProjectInfo.classpath = classpath; + perProjectInfo.outputLocation = outputLocation; + return classpath; + } /** * @see IJavaProject#getRequiredProjectNames */ -// public String[] getRequiredProjectNames() throws JavaModelException { -// -// return this.projectPrerequisites(getResolvedClasspath(true)); -// } + public String[] getRequiredProjectNames() throws JavaModelException { + + return this.projectPrerequisites(getResolvedClasspath(true)); + } /** * @see IJavaProject */ -// public IClasspathEntry[] getResolvedClasspath(boolean ignoreUnresolvedEntry) -// throws JavaModelException { -// -// return -// this.getResolvedClasspath( -// ignoreUnresolvedEntry, -// false); // generateMarkerOnError -// } + public IClasspathEntry[] getResolvedClasspath(boolean ignoreUnresolvedEntry) + throws JavaModelException { + + return + this.getResolvedClasspath( + ignoreUnresolvedEntry, + false); // generateMarkerOnError + } /** * Internal variant which can create marker on project for invalid entries * and caches the resolved classpath on perProjectInfo */ -// public IClasspathEntry[] getResolvedClasspath( -// boolean ignoreUnresolvedEntry, -// boolean generateMarkerOnError) -// throws JavaModelException { -// -// JavaModelManager manager = JavaModelManager.getJavaModelManager(); -// JavaModelManager.PerProjectInfo perProjectInfo = manager.getPerProjectInfoCheckExistence(fProject); -// -// // reuse cache if not needing to refresh markers or checking bound variables -// if (ignoreUnresolvedEntry && !generateMarkerOnError && perProjectInfo != null){ -// // resolved path is cached on its info -// IClasspathEntry[] infoPath = perProjectInfo.lastResolvedClasspath; -// if (infoPath != null) return infoPath; -// } -// Map reverseMap = perProjectInfo == null ? null : new HashMap(5); -// IClasspathEntry[] resolvedPath = getResolvedClasspath( -// getRawClasspath(), -// generateMarkerOnError ? getOutputLocation() : null, -// ignoreUnresolvedEntry, -// generateMarkerOnError, -// reverseMap); -// -// if (perProjectInfo != null){ -// if (perProjectInfo.classpath == null // .classpath file could not be read -// && generateMarkerOnError -// && JavaProject.hasJavaNature(fProject)) { -// this.createClasspathProblemMarker(new JavaModelStatus( -// IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, -// Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$ -// } -// -// perProjectInfo.lastResolvedClasspath = resolvedPath; -// perProjectInfo.resolvedPathToRawEntries = reverseMap; -// } -// return resolvedPath; -// } + public IClasspathEntry[] getResolvedClasspath( + boolean ignoreUnresolvedEntry, + boolean generateMarkerOnError) + throws JavaModelException { + + JavaModelManager manager = JavaModelManager.getJavaModelManager(); + JavaModelManager.PerProjectInfo perProjectInfo = manager.getPerProjectInfoCheckExistence(fProject); + + // reuse cache if not needing to refresh markers or checking bound variables + if (ignoreUnresolvedEntry && !generateMarkerOnError && perProjectInfo != null){ + // resolved path is cached on its info + IClasspathEntry[] infoPath = perProjectInfo.lastResolvedClasspath; + if (infoPath != null) return infoPath; + } + Map reverseMap = perProjectInfo == null ? null : new HashMap(5); + IClasspathEntry[] resolvedPath = getResolvedClasspath( + getRawClasspath(), + generateMarkerOnError ? getOutputLocation() : null, + ignoreUnresolvedEntry, + generateMarkerOnError, + reverseMap); + + if (perProjectInfo != null){ + if (perProjectInfo.classpath == null // .classpath file could not be read + && generateMarkerOnError + && JavaProject.hasJavaNature(fProject)) { + this.createClasspathProblemMarker(new JavaModelStatus( + IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, + Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$ + } + + perProjectInfo.lastResolvedClasspath = resolvedPath; + perProjectInfo.resolvedPathToRawEntries = reverseMap; + } + return resolvedPath; + } /** * Internal variant which can process any arbitrary classpath */ -// public IClasspathEntry[] getResolvedClasspath( -// IClasspathEntry[] classpathEntries, -// IPath projectOutputLocation, // only set if needing full classpath validation (and markers) -// boolean ignoreUnresolvedEntry, // if unresolved entries are met, should it trigger initializations -// boolean generateMarkerOnError, -// Map reverseMap) // can be null if not interested in reverse mapping -// throws JavaModelException { -// -// IJavaModelStatus status; -// if (generateMarkerOnError){ -// flushClasspathProblemMarkers(false, false); -// } -// -// int length = classpathEntries.length; -// ArrayList resolvedEntries = new ArrayList(); -// -// for (int i = 0; i < length; i++) { -// -// IClasspathEntry rawEntry = classpathEntries[i]; -// IPath resolvedPath; -// status = null; -// -// /* validation if needed */ + public IClasspathEntry[] getResolvedClasspath( + IClasspathEntry[] classpathEntries, + IPath projectOutputLocation, // only set if needing full classpath validation (and markers) + boolean ignoreUnresolvedEntry, // if unresolved entries are met, should it trigger initializations + boolean generateMarkerOnError, + Map reverseMap) // can be null if not interested in reverse mapping + throws JavaModelException { + + IJavaModelStatus status; + if (generateMarkerOnError){ + flushClasspathProblemMarkers(false, false); + } + + int length = classpathEntries.length; + ArrayList resolvedEntries = new ArrayList(); + + for (int i = 0; i < length; i++) { + + IClasspathEntry rawEntry = classpathEntries[i]; + IPath resolvedPath; + status = null; + + /* validation if needed */ // if (generateMarkerOnError || !ignoreUnresolvedEntry) { // status = JavaConventions.validateClasspathEntry(this, rawEntry, false); // if (generateMarkerOnError && !status.isOK()) createClasspathProblemMarker(status); // } -// -// switch (rawEntry.getEntryKind()){ -// -// case IClasspathEntry.CPE_VARIABLE : -// -// IClasspathEntry resolvedEntry = JavaCore.getResolvedClasspathEntry(rawEntry); -// if (resolvedEntry == null) { -// if (!ignoreUnresolvedEntry) throw new JavaModelException(status); -// } else { -// if (reverseMap != null && reverseMap.get(resolvedPath = resolvedEntry.getPath()) == null) reverseMap.put(resolvedPath , rawEntry); -// resolvedEntries.add(resolvedEntry); -// } -// break; -// + + switch (rawEntry.getEntryKind()){ + + case IClasspathEntry.CPE_VARIABLE : + + IClasspathEntry resolvedEntry = PHPCore.getResolvedClasspathEntry(rawEntry); + if (resolvedEntry == null) { + if (!ignoreUnresolvedEntry) throw new JavaModelException(status); + } else { + if (reverseMap != null && reverseMap.get(resolvedPath = resolvedEntry.getPath()) == null) reverseMap.put(resolvedPath , rawEntry); + resolvedEntries.add(resolvedEntry); + } + break; + // case IClasspathEntry.CPE_CONTAINER : // -// IClasspathContainer container = JavaCore.getClasspathContainer(rawEntry.getPath(), this); +// IClasspathContainer container = PHPCore.getClasspathContainer(rawEntry.getPath(), this); // if (container == null){ // if (!ignoreUnresolvedEntry) throw new JavaModelException(status); // break; @@ -1560,24 +1733,24 @@ public class JavaProject // resolvedEntries.add(cEntry); // } // break; -// -// default : -// -// if (reverseMap != null && reverseMap.get(resolvedPath = rawEntry.getPath()) == null) reverseMap.put(resolvedPath, rawEntry); -// resolvedEntries.add(rawEntry); -// -// } -// } -// -// IClasspathEntry[] resolvedPath = new IClasspathEntry[resolvedEntries.size()]; -// resolvedEntries.toArray(resolvedPath); -// + + default : + + if (reverseMap != null && reverseMap.get(resolvedPath = rawEntry.getPath()) == null) reverseMap.put(resolvedPath, rawEntry); + resolvedEntries.add(rawEntry); + + } + } + + IClasspathEntry[] resolvedPath = new IClasspathEntry[resolvedEntries.size()]; + resolvedEntries.toArray(resolvedPath); + // if (generateMarkerOnError && projectOutputLocation != null) { // status = JavaConventions.validateClasspath(this, resolvedPath, projectOutputLocation); // if (!status.isOK()) createClasspathProblemMarker(status); // } -// return resolvedPath; -// } + return resolvedPath; + } /* * @see IJavaElement @@ -1589,15 +1762,15 @@ public class JavaProject /** * @see IJavaProject */ -// public ISearchableNameEnvironment getSearchableNameEnvironment() -// throws JavaModelException { -// -// JavaProjectElementInfo info = getJavaProjectElementInfo(); -// if (info.getSearchableEnvironment() == null) { -// info.setSearchableEnvironment(new SearchableEnvironment(this)); -// } -// return info.getSearchableEnvironment(); -// } + public ISearchableNameEnvironment getSearchableNameEnvironment() + throws JavaModelException { + + JavaProjectElementInfo info = getJavaProjectElementInfo(); + if (info.getSearchableEnvironment() == null) { + info.setSearchableEnvironment(new SearchableEnvironment(this)); + } + return info.getSearchableEnvironment(); + } /** * Retrieve a shared property on a project. If the property is not defined, answers null. @@ -1607,15 +1780,15 @@ public class JavaProject * * @see JavaProject#setSharedProperty(String, String) */ -// public String getSharedProperty(String key) throws CoreException { -// -// String property = null; -// IFile rscFile = getProject().getFile(key); -// if (rscFile.exists()) { -// property = new String(Util.getResourceContentsAsByteArray(rscFile)); -// } -// return property; -// } + public String getSharedProperty(String key) throws CoreException { + + String property = null; + IFile rscFile = getProject().getFile(key); + if (rscFile.exists()) { + property = new String(Util.getResourceContentsAsByteArray(rscFile)); + } + return property; + } /** * @see JavaElement @@ -1636,23 +1809,23 @@ public class JavaProject /** * @see IJavaProject */ -// public boolean hasBuildState() { -// -// return JavaModelManager.getJavaModelManager().getLastBuiltState(this.getProject(), null) != null; -// } + public boolean hasBuildState() { + + return JavaModelManager.getJavaModelManager().getLastBuiltState(this.getProject(), null) != null; + } /** * @see IJavaProject */ -// public boolean hasClasspathCycle(IClasspathEntry[] preferredClasspath) { -// HashSet cycleParticipants = new HashSet(); -// updateCycleParticipants(preferredClasspath, new ArrayList(2), cycleParticipants, ResourcesPlugin.getWorkspace().getRoot(), new HashSet(2)); -// return !cycleParticipants.isEmpty(); -// } + public boolean hasClasspathCycle(IClasspathEntry[] preferredClasspath) { + HashSet cycleParticipants = new HashSet(); + updateCycleParticipants(preferredClasspath, new ArrayList(2), cycleParticipants, ResourcesPlugin.getWorkspace().getRoot(), new HashSet(2)); + return !cycleParticipants.isEmpty(); + } -// public boolean hasCycleMarker(){ -// return this.getCycleMarker() != null; -// } + public boolean hasCycleMarker(){ + return this.getCycleMarker() != null; + } public int hashCode() { return fProject.hashCode(); @@ -1674,104 +1847,104 @@ public class JavaProject /** * Answers true if the project potentially contains any source. A project which has no source is immutable. */ -// public boolean hasSource() { -// -// // look if any source folder on the classpath -// // no need for resolved path given source folder cannot be abstracted -// IClasspathEntry[] entries; -// try { -// entries = this.getRawClasspath(); -// } catch (JavaModelException e) { -// return true; // unsure -// } -// for (int i = 0, max = entries.length; i < max; i++) { -// if (entries[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) { -// return true; -// } -// } -// return false; -// } + public boolean hasSource() { + + // look if any source folder on the classpath + // no need for resolved path given source folder cannot be abstracted + IClasspathEntry[] entries; + try { + entries = this.getRawClasspath(); + } catch (JavaModelException e) { + return true; // unsure + } + for (int i = 0, max = entries.length; i < max; i++) { + if (entries[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) { + return true; + } + } + return false; + } /** * Compare current classpath with given one to see if any different. * Note that the argument classpath contains its binary output. */ -// public boolean isClasspathEqualsTo(IClasspathEntry[] newClasspath, IPath newOutputLocation, IClasspathEntry[] otherClasspathWithOutput) -// throws JavaModelException { -// -// if (otherClasspathWithOutput != null && otherClasspathWithOutput.length > 0) { -// -// int length = otherClasspathWithOutput.length; -// if (length == newClasspath.length + 1) { -// // output is amongst file entries (last one) -// -// // compare classpath entries -// for (int i = 0; i < length - 1; i++) { -// if (!otherClasspathWithOutput[i].equals(newClasspath[i])) -// return false; -// } -// // compare binary outputs -// IClasspathEntry output = otherClasspathWithOutput[length - 1]; -// if (output.getContentKind() == ClasspathEntry.K_OUTPUT -// && output.getPath().equals(newOutputLocation)) -// return true; -// } -// } -// return false; -// } + public boolean isClasspathEqualsTo(IClasspathEntry[] newClasspath, IPath newOutputLocation, IClasspathEntry[] otherClasspathWithOutput) + throws JavaModelException { + + if (otherClasspathWithOutput != null && otherClasspathWithOutput.length > 0) { + + int length = otherClasspathWithOutput.length; + if (length == newClasspath.length + 1) { + // output is amongst file entries (last one) + + // compare classpath entries + for (int i = 0; i < length - 1; i++) { + if (!otherClasspathWithOutput[i].equals(newClasspath[i])) + return false; + } + // compare binary outputs + IClasspathEntry output = otherClasspathWithOutput[length - 1]; + if (output.getContentKind() == ClasspathEntry.K_OUTPUT + && output.getPath().equals(newOutputLocation)) + return true; + } + } + return false; + } /* * @see IJavaProject */ -// public boolean isOnClasspath(IJavaElement element) { -// IPath path = element.getPath(); -// switch (element.getElementType()) { -// case IJavaElement.PACKAGE_FRAGMENT_ROOT: -// if (!((IPackageFragmentRoot)element).isArchive()) { -// // ensure that folders are only excluded if all of their children are excluded -// path = path.append("*"); //$NON-NLS-1$ -// } -// break; -// case IJavaElement.PACKAGE_FRAGMENT: -// if (!((IPackageFragmentRoot)element.getParent()).isArchive()) { -// // ensure that folders are only excluded if all of their children are excluded -// path = path.append("*"); //$NON-NLS-1$ -// } -// break; -// } -// return this.isOnClasspath(path); -// } -// private boolean isOnClasspath(IPath path) { -// IClasspathEntry[] classpath; -// try { -// classpath = this.getResolvedClasspath(true/*ignore unresolved variable*/); -// } catch(JavaModelException e){ -// return false; // not a Java project -// } -// for (int i = 0; i < classpath.length; i++) { -// IClasspathEntry entry = classpath[i]; -// if (entry.getPath().isPrefixOf(path) -// && !Util.isExcluded(path, ((ClasspathEntry)entry).fullExclusionPatternChars())) { -// return true; -// } -// } -// return false; -// } + public boolean isOnClasspath(IJavaElement element) { + IPath path = element.getPath(); + switch (element.getElementType()) { + case IJavaElement.PACKAGE_FRAGMENT_ROOT: + if (!((IPackageFragmentRoot)element).isArchive()) { + // ensure that folders are only excluded if all of their children are excluded + path = path.append("*"); //$NON-NLS-1$ + } + break; + case IJavaElement.PACKAGE_FRAGMENT: + if (!((IPackageFragmentRoot)element.getParent()).isArchive()) { + // ensure that folders are only excluded if all of their children are excluded + path = path.append("*"); //$NON-NLS-1$ + } + break; + } + return this.isOnClasspath(path); + } + private boolean isOnClasspath(IPath path) { + IClasspathEntry[] classpath; + try { + classpath = this.getResolvedClasspath(true/*ignore unresolved variable*/); + } catch(JavaModelException e){ + return false; // not a Java project + } + for (int i = 0; i < classpath.length; i++) { + IClasspathEntry entry = classpath[i]; + if (entry.getPath().isPrefixOf(path) + && !Util.isExcluded(path, ((ClasspathEntry)entry).fullExclusionPatternChars())) { + return true; + } + } + return false; + } /* * @see IJavaProject */ -// public boolean isOnClasspath(IResource resource) { -// IPath path = resource.getFullPath(); -// -// // ensure that folders are only excluded if all of their children are excluded -// if (resource.getType() == IResource.FOLDER) { -// path = path.append("*"); //$NON-NLS-1$ -// } -// -// return this.isOnClasspath(path); -// } + public boolean isOnClasspath(IResource resource) { + IPath path = resource.getFullPath(); + + // ensure that folders are only excluded if all of their children are excluded + if (resource.getType() == IResource.FOLDER) { + path = path.append("*"); //$NON-NLS-1$ + } + + return this.isOnClasspath(path); + } /* @@ -1854,36 +2027,36 @@ public class JavaProject /** * Open project if resource isn't closed */ -// protected void openWhenClosed(IProgressMonitor pm) throws JavaModelException { -// -// if (!this.fProject.isOpen()) { -// throw newNotPresentException(); -// } else { -// super.openWhenClosed(pm); -// } -// } + protected void openWhenClosed(IProgressMonitor pm) throws JavaModelException { -// public String[] projectPrerequisites(IClasspathEntry[] entries) -// throws JavaModelException { -// -// ArrayList prerequisites = new ArrayList(); -// // need resolution -// entries = getResolvedClasspath(entries, null, true, false, null/*no reverse map*/); -// for (int i = 0, length = entries.length; i < length; i++) { -// IClasspathEntry entry = entries[i]; -// if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) { -// prerequisites.add(entry.getPath().lastSegment()); -// } -// } -// int size = prerequisites.size(); -// if (size == 0) { -// return NO_PREREQUISITES; -// } else { -// String[] result = new String[size]; -// prerequisites.toArray(result); -// return result; -// } -// } + if (!this.fProject.isOpen()) { + throw newNotPresentException(); + } else { + super.openWhenClosed(pm); + } + } + + public String[] projectPrerequisites(IClasspathEntry[] entries) + throws JavaModelException { + + ArrayList prerequisites = new ArrayList(); + // need resolution + entries = getResolvedClasspath(entries, null, true, false, null/*no reverse map*/); + for (int i = 0, length = entries.length; i < length; i++) { + IClasspathEntry entry = entries[i]; + if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) { + prerequisites.add(entry.getPath().lastSegment()); + } + } + int size = prerequisites.size(); + if (size == 0) { + return NO_PREREQUISITES; + } else { + String[] result = new String[size]; + prerequisites.toArray(result); + return result; + } + } /** @@ -1891,27 +2064,27 @@ public class JavaProject * Returns null if .classfile is not present. * Returns INVALID_CLASSPATH if it has a format problem. */ -// protected IClasspathEntry[] readClasspathFile(boolean createMarker, boolean logProblems) { -// -// try { -// String xmlClasspath = getSharedProperty(CLASSPATH_FILENAME); -// if (xmlClasspath == null) return null; -// return decodeClasspath(xmlClasspath, createMarker, logProblems); -// } catch(CoreException e) { -// // file does not exist (or not accessible) -// if (createMarker && this.getProject().isAccessible()) { -// this.createClasspathProblemMarker(new JavaModelStatus( -// IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, -// Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$ -// } -// if (logProblems) { -// Util.log(e, -// "Exception while retrieving "+ this.getPath() //$NON-NLS-1$ -// +"/.classpath, will revert to default classpath"); //$NON-NLS-1$ -// } -// } -// return null; -// } + protected IClasspathEntry[] readClasspathFile(boolean createMarker, boolean logProblems) { + + try { + String xmlClasspath = getSharedProperty(CLASSPATH_FILENAME); + if (xmlClasspath == null) return null; + return decodeClasspath(xmlClasspath, createMarker, logProblems); + } catch(CoreException e) { + // file does not exist (or not accessible) + if (createMarker && this.getProject().isAccessible()) { + this.createClasspathProblemMarker(new JavaModelStatus( + IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT, + Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$ + } + if (logProblems) { + Util.log(e, + "Exception while retrieving "+ this.getPath() //$NON-NLS-1$ + +"/.classpath, will revert to default classpath"); //$NON-NLS-1$ + } + } + return null; + } /** * Removes the given builder from the build spec for the given project. @@ -1955,24 +2128,24 @@ public class JavaProject * * @return Return whether the .classpath file was modified. */ -// public boolean saveClasspath(IClasspathEntry[] newClasspath, IPath newOutputLocation) throws JavaModelException { -// -// if (!getProject().exists()) return false; -// -// IClasspathEntry[] fileEntries = readClasspathFile(false /*don't create markers*/, false/*don't log problems*/); -// if (fileEntries != null && isClasspathEqualsTo(newClasspath, newOutputLocation, fileEntries)) { -// // no need to save it, it is the same -// return false; -// } -// -// // actual file saving -// try { -// setSharedProperty(CLASSPATH_FILENAME, encodeClasspath(newClasspath, newOutputLocation, true)); -// return true; -// } catch (CoreException e) { -// throw new JavaModelException(e); -// } -// } + public boolean saveClasspath(IClasspathEntry[] newClasspath, IPath newOutputLocation) throws JavaModelException { + + if (!getProject().exists()) return false; + + IClasspathEntry[] fileEntries = readClasspathFile(false /*don't create markers*/, false/*don't log problems*/); + if (fileEntries != null && isClasspathEqualsTo(newClasspath, newOutputLocation, fileEntries)) { + // no need to save it, it is the same + return false; + } + + // actual file saving + try { + setSharedProperty(CLASSPATH_FILENAME, encodeClasspath(newClasspath, newOutputLocation, true)); + return true; + } catch (CoreException e) { + throw new JavaModelException(e); + } + } /** * Save project custom preferences to shareable file (.jprefs) @@ -2055,50 +2228,50 @@ public class JavaProject /** * @see org.eclipse.jdt.core.IJavaProject#setOptions(Map) */ -// public void setOptions(Map newOptions) { -// -// Preferences preferences; -// setPreferences(preferences = new Preferences()); // always reset (26255) -// if (newOptions != null){ -// Iterator keys = newOptions.keySet().iterator(); -// while (keys.hasNext()){ -// String key = (String)keys.next(); -// if (!JavaModelManager.OptionNames.contains(key)) continue; // unrecognized option -// // no filtering for encoding (custom encoding for project is allowed) -// String value = (String)newOptions.get(key); -// preferences.setDefault(key, CUSTOM_DEFAULT_OPTION_VALUE); // empty string isn't the default (26251) -// preferences.setValue(key, value); -// } -// } -// -// // persist options -// savePreferences(preferences); -// } + public void setOptions(Map newOptions) { + + Preferences preferences; + setPreferences(preferences = new Preferences()); // always reset (26255) + if (newOptions != null){ + Iterator keys = newOptions.keySet().iterator(); + while (keys.hasNext()){ + String key = (String)keys.next(); + if (!JavaModelManager.OptionNames.contains(key)) continue; // unrecognized option + // no filtering for encoding (custom encoding for project is allowed) + String value = (String)newOptions.get(key); + preferences.setDefault(key, CUSTOM_DEFAULT_OPTION_VALUE); // empty string isn't the default (26251) + preferences.setValue(key, value); + } + } + + // persist options + savePreferences(preferences); + } /** * @see IJavaProject */ -// public void setOutputLocation(IPath path, IProgressMonitor monitor) -// throws JavaModelException { -// -// if (path == null) { -// throw new IllegalArgumentException(Util.bind("path.nullpath")); //$NON-NLS-1$ -// } -// if (path.equals(getOutputLocation())) { -// return; -// } -// this.setRawClasspath(SetClasspathOperation.ReuseClasspath, path, monitor); -// } + public void setOutputLocation(IPath path, IProgressMonitor monitor) + throws JavaModelException { + + if (path == null) { + throw new IllegalArgumentException(Util.bind("path.nullpath")); //$NON-NLS-1$ + } + if (path.equals(getOutputLocation())) { + return; + } + this.setRawClasspath(SetClasspathOperation.ReuseClasspath, path, monitor); + } /* * Set cached preferences, no preference file is saved, only info is updated */ -// public void setPreferences(Preferences preferences) { -// IProject project = getProject(); -// if (!JavaProject.hasJavaNature(project)) return; // ignore -// JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(project, true); -// perProjectInfo.preferences = preferences; -// } + public void setPreferences(Preferences preferences) { + IProject project = getProject(); + if (!JavaProject.hasJavaNature(project)) return; // ignore + JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(project, true); + perProjectInfo.preferences = preferences; + } /** * Sets the underlying kernel project of this Java project, @@ -2117,73 +2290,73 @@ public class JavaProject /** * @see IJavaProject */ -// public void setRawClasspath( -// IClasspathEntry[] entries, -// IPath outputLocation, -// IProgressMonitor monitor) -// throws JavaModelException { -// -// setRawClasspath( -// entries, -// outputLocation, -// monitor, -// true, // canChangeResource (as per API contract) -// getResolvedClasspath(true), // ignoreUnresolvedVariable -// true, // needValidation -// true); // need to save -// } + public void setRawClasspath( + IClasspathEntry[] entries, + IPath outputLocation, + IProgressMonitor monitor) + throws JavaModelException { + + setRawClasspath( + entries, + outputLocation, + monitor, + true, // canChangeResource (as per API contract) + getResolvedClasspath(true), // ignoreUnresolvedVariable + true, // needValidation + true); // need to save + } -// public void setRawClasspath( -// IClasspathEntry[] newEntries, -// IPath newOutputLocation, -// IProgressMonitor monitor, -// boolean canChangeResource, -// IClasspathEntry[] oldResolvedPath, -// boolean needValidation, -// boolean needSave) -// throws JavaModelException { -// -// JavaModelManager manager = -// (JavaModelManager) JavaModelManager.getJavaModelManager(); -// try { -// IClasspathEntry[] newRawPath = newEntries; -// if (newRawPath == null) { //are we already with the default classpath -// newRawPath = defaultClasspath(); -// } -// SetClasspathOperation op = -// new SetClasspathOperation( -// this, -// oldResolvedPath, -// newRawPath, -// newOutputLocation, -// canChangeResource, -// needValidation, -// needSave); -// runOperation(op, monitor); -// -// } catch (JavaModelException e) { -// manager.flush(); -// throw e; -// } -// } + public void setRawClasspath( + IClasspathEntry[] newEntries, + IPath newOutputLocation, + IProgressMonitor monitor, + boolean canChangeResource, + IClasspathEntry[] oldResolvedPath, + boolean needValidation, + boolean needSave) + throws JavaModelException { + + JavaModelManager manager = + (JavaModelManager) JavaModelManager.getJavaModelManager(); + try { + IClasspathEntry[] newRawPath = newEntries; + if (newRawPath == null) { //are we already with the default classpath + newRawPath = defaultClasspath(); + } + SetClasspathOperation op = + new SetClasspathOperation( + this, + oldResolvedPath, + newRawPath, + newOutputLocation, + canChangeResource, + needValidation, + needSave); + runOperation(op, monitor); + + } catch (JavaModelException e) { + manager.flush(); + throw e; + } + } /** * @see IJavaProject */ -// public void setRawClasspath( -// IClasspathEntry[] entries, -// IProgressMonitor monitor) -// throws JavaModelException { -// -// setRawClasspath( -// entries, -// SetClasspathOperation.ReuseOutputLocation, -// monitor, -// true, // canChangeResource (as per API contract) -// getResolvedClasspath(true), // ignoreUnresolvedVariable -// true, // needValidation -// true); // need to save -// } + public void setRawClasspath( + IClasspathEntry[] entries, + IProgressMonitor monitor) + throws JavaModelException { + + setRawClasspath( + entries, + SetClasspathOperation.ReuseOutputLocation, + monitor, + true, // canChangeResource (as per API contract) + getResolvedClasspath(true), // ignoreUnresolvedVariable + true, // needValidation + true); // need to save + } /** * NOTE: null specifies default classpath, and an empty @@ -2191,21 +2364,21 @@ public class JavaProject * * @exception NotPresentException if this project does not exist. */ -// protected void setRawClasspath0(IClasspathEntry[] rawEntries) -// throws JavaModelException { -// -// JavaModelManager.PerProjectInfo info = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject); -// -// synchronized (info) { -// if (rawEntries != null) { -// info.classpath = rawEntries; -// } -// -// // clear cache of resolved classpath -// info.lastResolvedClasspath = null; -// info.resolvedPathToRawEntries = null; -// } -// } + protected void setRawClasspath0(IClasspathEntry[] rawEntries) + throws JavaModelException { + + JavaModelManager.PerProjectInfo info = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject); + + synchronized (info) { + if (rawEntries != null) { + info.classpath = rawEntries; + } + + // clear cache of resolved classpath + info.lastResolvedClasspath = null; + info.resolvedPathToRawEntries = null; + } + } /** * Record a shared persistent property onto a project. @@ -2237,109 +2410,109 @@ public class JavaProject /** * Update cycle markers for all java projects */ -// public static void updateAllCycleMarkers() throws JavaModelException { -// -// //long start = System.currentTimeMillis(); -// -// JavaModelManager manager = JavaModelManager.getJavaModelManager(); -// IJavaProject[] projects = manager.getJavaModel().getJavaProjects(); -// IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); -// -// HashSet cycleParticipants = new HashSet(); -// HashSet traversed = new HashSet(); -// int length = projects.length; -// -// // compute cycle participants -// ArrayList prereqChain = new ArrayList(); -// for (int i = 0; i < length; i++){ -// JavaProject project = (JavaProject)projects[i]; -// if (!traversed.contains(project.getPath())){ -// prereqChain.clear(); -// project.updateCycleParticipants(null, prereqChain, cycleParticipants, workspaceRoot, traversed); -// } -// } -// //System.out.println("updateAllCycleMarkers: " + (System.currentTimeMillis() - start) + " ms"); -// -// for (int i = 0; i < length; i++){ -// JavaProject project = (JavaProject)projects[i]; -// -// if (cycleParticipants.contains(project.getPath())){ -// IMarker cycleMarker = project.getCycleMarker(); -// String circularCPOption = project.getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true); -// int circularCPSeverity = JavaCore.ERROR.equals(circularCPOption) ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING; -// if (cycleMarker != null) { -// // update existing cycle marker if needed -// try { -// int existingSeverity = ((Integer)cycleMarker.getAttribute(IMarker.SEVERITY)).intValue(); -// if (existingSeverity != circularCPSeverity) { -// cycleMarker.setAttribute(IMarker.SEVERITY, circularCPSeverity); -// } -// } catch (CoreException e) { -// throw new JavaModelException(e); -// } -// } else { -// // create new marker -// project.createClasspathProblemMarker( -// new JavaModelStatus(IJavaModelStatusConstants.CLASSPATH_CYCLE, project)); -// } -// } else { -// project.flushClasspathProblemMarkers(true, false); -// } -// } -// } -// -// /** -// * If a cycle is detected, then cycleParticipants contains all the paths of projects involved in this cycle (directly and indirectly), -// * no cycle if the set is empty (and started empty) -// */ -// public void updateCycleParticipants( -// IClasspathEntry[] preferredClasspath, -// ArrayList prereqChain, -// HashSet cycleParticipants, -// IWorkspaceRoot workspaceRoot, -// HashSet traversed){ -// -// IPath path = this.getPath(); -// prereqChain.add(path); -// traversed.add(path); -// try { -// IClasspathEntry[] classpath = preferredClasspath == null ? getResolvedClasspath(true) : preferredClasspath; -// for (int i = 0, length = classpath.length; i < length; i++) { -// IClasspathEntry entry = classpath[i]; -// -// if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT){ -// IPath prereqProjectPath = entry.getPath(); -// int index = cycleParticipants.contains(prereqProjectPath) ? 0 : prereqChain.indexOf(prereqProjectPath); -// if (index >= 0) { // refer to cycle, or in cycle itself -// for (int size = prereqChain.size(); index < size; index++) { -// cycleParticipants.add(prereqChain.get(index)); -// } -// } else { -// if (!traversed.contains(prereqProjectPath)) { -// IResource member = workspaceRoot.findMember(prereqProjectPath); -// if (member != null && member.getType() == IResource.PROJECT){ -// JavaProject project = (JavaProject)JavaCore.create((IProject)member); -// project.updateCycleParticipants(null, prereqChain, cycleParticipants, workspaceRoot, traversed); -// } -// } -// } -// } -// } -// } catch(JavaModelException e){ -// } -// prereqChain.remove(path); -// } + public static void updateAllCycleMarkers() throws JavaModelException { + + //long start = System.currentTimeMillis(); + + JavaModelManager manager = JavaModelManager.getJavaModelManager(); + IJavaProject[] projects = manager.getJavaModel().getJavaProjects(); + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + + HashSet cycleParticipants = new HashSet(); + HashSet traversed = new HashSet(); + int length = projects.length; + + // compute cycle participants + ArrayList prereqChain = new ArrayList(); + for (int i = 0; i < length; i++){ + JavaProject project = (JavaProject)projects[i]; + if (!traversed.contains(project.getPath())){ + prereqChain.clear(); + project.updateCycleParticipants(null, prereqChain, cycleParticipants, workspaceRoot, traversed); + } + } + //System.out.println("updateAllCycleMarkers: " + (System.currentTimeMillis() - start) + " ms"); + + for (int i = 0; i < length; i++){ + JavaProject project = (JavaProject)projects[i]; + + if (cycleParticipants.contains(project.getPath())){ + IMarker cycleMarker = project.getCycleMarker(); + String circularCPOption = project.getOption(PHPCore.CORE_CIRCULAR_CLASSPATH, true); + int circularCPSeverity = PHPCore.ERROR.equals(circularCPOption) ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING; + if (cycleMarker != null) { + // update existing cycle marker if needed + try { + int existingSeverity = ((Integer)cycleMarker.getAttribute(IMarker.SEVERITY)).intValue(); + if (existingSeverity != circularCPSeverity) { + cycleMarker.setAttribute(IMarker.SEVERITY, circularCPSeverity); + } + } catch (CoreException e) { + throw new JavaModelException(e); + } + } else { + // create new marker + project.createClasspathProblemMarker( + new JavaModelStatus(IJavaModelStatusConstants.CLASSPATH_CYCLE, project)); + } + } else { + project.flushClasspathProblemMarkers(true, false); + } + } + } + + /** + * If a cycle is detected, then cycleParticipants contains all the paths of projects involved in this cycle (directly and indirectly), + * no cycle if the set is empty (and started empty) + */ + public void updateCycleParticipants( + IClasspathEntry[] preferredClasspath, + ArrayList prereqChain, + HashSet cycleParticipants, + IWorkspaceRoot workspaceRoot, + HashSet traversed){ + + IPath path = this.getPath(); + prereqChain.add(path); + traversed.add(path); + try { + IClasspathEntry[] classpath = preferredClasspath == null ? getResolvedClasspath(true) : preferredClasspath; + for (int i = 0, length = classpath.length; i < length; i++) { + IClasspathEntry entry = classpath[i]; + + if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT){ + IPath prereqProjectPath = entry.getPath(); + int index = cycleParticipants.contains(prereqProjectPath) ? 0 : prereqChain.indexOf(prereqProjectPath); + if (index >= 0) { // refer to cycle, or in cycle itself + for (int size = prereqChain.size(); index < size; index++) { + cycleParticipants.add(prereqChain.get(index)); + } + } else { + if (!traversed.contains(prereqProjectPath)) { + IResource member = workspaceRoot.findMember(prereqProjectPath); + if (member != null && member.getType() == IResource.PROJECT){ + JavaProject project = (JavaProject)PHPCore.create((IProject)member); + project.updateCycleParticipants(null, prereqChain, cycleParticipants, workspaceRoot, traversed); + } + } + } + } + } + } catch(JavaModelException e){ + } + prereqChain.remove(path); + } /** * Reset the collection of package fragment roots (local ones) - only if opened. * Need to check *all* package fragment roots in order to reset NameLookup */ -// public void updatePackageFragmentRoots(){ -// -// if (this.isOpen()) { -// try { -// JavaProjectElementInfo info = getJavaProjectElementInfo(); -// -// IClasspathEntry[] classpath = getResolvedClasspath(true); + public void updatePackageFragmentRoots(){ + + if (this.isOpen()) { + try { + JavaProjectElementInfo info = getJavaProjectElementInfo(); + + IClasspathEntry[] classpath = getResolvedClasspath(true); // NameLookup lookup = info.getNameLookup(); // if (lookup != null){ // IPackageFragmentRoot[] oldRoots = lookup.fPackageFragmentRoots; @@ -2356,16 +2529,42 @@ public class JavaProject // } // info.setNameLookup(null); // discard name lookup (hold onto roots) // } -// info.setNonJavaResources(null); -// info.setChildren( -// computePackageFragmentRoots(classpath, false)); -// -// } catch(JavaModelException e){ -// try { -// close(); // could not do better -// } catch(JavaModelException ex){ -// } -// } -// } -// } + info.setNonJavaResources(null); + info.setChildren( + computePackageFragmentRoots(classpath, false)); + + } catch(JavaModelException e){ + try { + close(); // could not do better + } catch(JavaModelException ex){ + } + } + } + } + + public void removeLoadPathEntry(IProject anotherPHPProject) { + Iterator entries = getLoadPathEntries().iterator(); + while (entries.hasNext()) { + LoadPathEntry entry = (LoadPathEntry) entries.next(); + if (entry.getType() == LoadPathEntry.TYPE_PROJECT && entry.getProject().getName().equals(anotherPHPProject.getName())) { + getLoadPathEntries().remove(entry); + fScratched = true; + break; + } + } + } + + public void save() throws CoreException { + if (fScratched) { + InputStream xmlPath = new ByteArrayInputStream(getLoadPathXML().getBytes()); + IFile loadPathsFile = getLoadPathEntriesFile(); + if (!loadPathsFile.exists()) + loadPathsFile.create(xmlPath, true, null); + else + loadPathsFile.setContents(xmlPath, true, false, null); + + fScratched = false; + } + } + }