### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: model/org/eclipse/jdt/core/IJavaProject.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java,v retrieving revision 1.106 diff -u -r1.106 IJavaProject.java --- model/org/eclipse/jdt/core/IJavaProject.java 24 Feb 2011 16:51:58 -0000 1.106 +++ model/org/eclipse/jdt/core/IJavaProject.java 4 Mar 2011 09:25:11 -0000 @@ -49,7 +49,9 @@ * Java project elements need to be opened before they can be navigated or manipulated. * The children of a Java project are the package fragment roots that are * defined by the classpath and contained in this project (in other words, it - * does not include package fragment roots for other projects). + * does not include package fragment roots for other projects). The children + * (i.e. the package fragment roots) appear in the order they are defined by + * the classpath. *

*

* An instance of one of these handles can be created via @@ -518,7 +520,8 @@ * Returns all of the package fragment roots contained in this * project, identified on this project's resolved classpath. The result * does not include package fragment roots in other projects referenced - * on this project's classpath. + * on this project's classpath. The package fragment roots appear in the + * order they are defined by the classpath. * *

NOTE: This is equivalent to getChildren(). * Index: model/org/eclipse/jdt/internal/core/DeltaProcessor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java,v retrieving revision 1.341 diff -u -r1.341 DeltaProcessor.java --- model/org/eclipse/jdt/internal/core/DeltaProcessor.java 2 Dec 2010 07:51:52 -0000 1.341 +++ model/org/eclipse/jdt/internal/core/DeltaProcessor.java 4 Mar 2011 09:25:12 -0000 @@ -282,12 +282,71 @@ if (parent != null && parent.isOpen()) { try { OpenableElementInfo info = (OpenableElementInfo) parent.getElementInfo(); - info.addChild(child); - } catch (JavaModelException e) { + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=338006 + // Insert the package fragment roots in the same order as the classpath order. + if (child instanceof IPackageFragmentRoot) + addPackageFragmentRoot(info, (IPackageFragmentRoot) child); + else + info.addChild(child); + } catch (JavaModelException e) { // do nothing - we already checked if open } } } + + private void addPackageFragmentRoot(OpenableElementInfo parent, IPackageFragmentRoot child) + throws JavaModelException { + + IJavaElement[] roots = parent.getChildren(); + if (roots.length > 0) { + IClasspathEntry[] resolvedClasspath = ((JavaProject) child.getJavaProject()).getResolvedClasspath(); + IClasspathEntry currentEntry = child.getResolvedClasspathEntry(); + int indexToInsert = -1; + int lastComparedIndex = -1; + int i = 0, j = 0; + for (; i < roots.length && j < resolvedClasspath.length;) { + + IClasspathEntry classpathEntry = resolvedClasspath[j]; + if (lastComparedIndex != j && currentEntry.getPath().equals(classpathEntry.getPath())) { + indexToInsert = i; + break; + } + lastComparedIndex = j; + + IClasspathEntry rootEntry = ((IPackageFragmentRoot) roots[i]).getResolvedClasspathEntry(); + if (rootEntry.getPath().equals(classpathEntry.getPath())) + i++; + else + j++; + } + + for (; i < roots.length; i++) { + // If the new root is already among the children, no need to proceed further. Just return. + if (roots[i].equals(child.getPath())) { + return; + } + // If we start seeing root's classpath entry different from the child's entry, then the child can't + // be present further down the roots array. + if (!((IPackageFragmentRoot) roots[i]).getResolvedClasspathEntry().getPath() + .equals(currentEntry.getPath())) + break; + } + + if (indexToInsert >= 0) { + int newSize = roots.length + 1; + IPackageFragmentRoot[] newChildren = new IPackageFragmentRoot[newSize]; + + if (indexToInsert > 0) + System.arraycopy(roots, 0, newChildren, 0, indexToInsert); + + newChildren[indexToInsert] = child; + System.arraycopy(roots, indexToInsert, newChildren, indexToInsert + 1, (newSize - indexToInsert - 1)); + parent.setChildren(newChildren); + return; + } + } + parent.addChild(child); + } /* * Process the given delta and look for projects being added, opened, closed or * with a java nature being added or removed. #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java,v retrieving revision 1.243 diff -u -r1.243 AbstractJavaModelTests.java --- src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java 21 Feb 2011 00:53:28 -0000 1.243 +++ src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java 4 Mar 2011 09:25:14 -0000 @@ -955,6 +955,25 @@ } assertEquals(expected, actual); } + protected void assertPackageFragmentRootsEqual(IPackageFragmentRoot[] roots, String expected) { + String actual; + if (roots == null) { + actual = ""; + } else { + StringBuffer buffer = new StringBuffer(); + int length = roots.length; + for (int i=0; i\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n"); + + editFile("/P/.classpath", content); + p.open(null); + createFolder("/P/src x"); + createFolder("/P/src a"); + + IPackageFragmentRoot[] roots = p.getPackageFragmentRoots(); + assertPackageFragmentRootsEqual(roots, + "src a (not open) [in P]\n" + + "src x (not open) [in P]\n" + + ""+ getExternalJCLPathString() + " (not open)"); + + } finally { + deleteProject("P"); + } +} + }