View | Details | Raw Unified | Return to bug 338006 | Differences between
and this patch

Collapse All | Expand All

(-)model/org/eclipse/jdt/core/IJavaProject.java (-2 / +5 lines)
Lines 49-55 Link Here
49
 * Java project elements need to be opened before they can be navigated or manipulated.
49
 * Java project elements need to be opened before they can be navigated or manipulated.
50
 * The children of a Java project are the package fragment roots that are
50
 * The children of a Java project are the package fragment roots that are
51
 * defined by the classpath and contained in this project (in other words, it
51
 * defined by the classpath and contained in this project (in other words, it
52
 * does not include package fragment roots for other projects).
52
 * does not include package fragment roots for other projects). The children
53
 * (i.e. the package fragment roots) appear in the order they are defined by 
54
 * the classpath.
53
 * </p>
55
 * </p>
54
 * <p>
56
 * <p>
55
 * An instance of one of these handles can be created via
57
 * An instance of one of these handles can be created via
Lines 518-524 Link Here
518
	 * Returns all of the  package fragment roots contained in this
520
	 * Returns all of the  package fragment roots contained in this
519
	 * project, identified on this project's resolved classpath. The result
521
	 * project, identified on this project's resolved classpath. The result
520
	 * does not include package fragment roots in other projects referenced
522
	 * does not include package fragment roots in other projects referenced
521
	 * on this project's classpath.
523
	 * on this project's classpath. The package fragment roots appear in the 
524
	 * order they are defined by the classpath.
522
	 *
525
	 *
523
	 * <p>NOTE: This is equivalent to <code>getChildren()</code>.
526
	 * <p>NOTE: This is equivalent to <code>getChildren()</code>.
524
	 *
527
	 *
(-)model/org/eclipse/jdt/internal/core/DeltaProcessor.java (-2 / +61 lines)
Lines 282-293 Link Here
282
		if (parent != null && parent.isOpen()) {
282
		if (parent != null && parent.isOpen()) {
283
			try {
283
			try {
284
				OpenableElementInfo info = (OpenableElementInfo) parent.getElementInfo();
284
				OpenableElementInfo info = (OpenableElementInfo) parent.getElementInfo();
285
				info.addChild(child);
285
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=338006
286
			} catch (JavaModelException e) {
286
				// Insert the package fragment roots in the same order as the classpath order.
287
				if (child instanceof IPackageFragmentRoot)
288
					addPackageFragmentRoot(info, (IPackageFragmentRoot) child);
289
				else
290
					info.addChild(child);
291
 			} catch (JavaModelException e) {
287
				// do nothing - we already checked if open
292
				// do nothing - we already checked if open
288
			}
293
			}
289
		}
294
		}
290
	}
295
	}
296
	
297
	private void addPackageFragmentRoot(OpenableElementInfo parent, IPackageFragmentRoot child)
298
			throws JavaModelException {
299
300
		IJavaElement[] roots = parent.getChildren();
301
		if (roots.length > 0) {
302
			IClasspathEntry[] resolvedClasspath = ((JavaProject) child.getJavaProject()).getResolvedClasspath();
303
			IPath currentEntryPath = child.getResolvedClasspathEntry().getPath();
304
			int indexToInsert = -1;
305
			int lastComparedIndex = -1;
306
			int i = 0, j = 0;
307
			for (; i < roots.length && j < resolvedClasspath.length;) {
308
309
				IClasspathEntry classpathEntry = resolvedClasspath[j];
310
				if (lastComparedIndex != j && currentEntryPath.equals(classpathEntry.getPath())) {
311
					indexToInsert = i;
312
					break;
313
				}
314
				lastComparedIndex = j;
315
316
				IClasspathEntry rootEntry = ((IPackageFragmentRoot) roots[i]).getResolvedClasspathEntry();
317
				if (rootEntry.getPath().equals(classpathEntry.getPath()))
318
					i++;
319
				else
320
					j++;
321
			}
322
323
			for (; i < roots.length; i++) {
324
				// If the new root is already among the children, no need to proceed further. Just return.
325
				if (roots[i].equals(child)) {
326
					return;
327
				}
328
				// If we start seeing root's classpath entry different from the child's entry, then the child can't
329
				// be present further down the roots array.
330
				if (!((IPackageFragmentRoot) roots[i]).getResolvedClasspathEntry().getPath()
331
						.equals(currentEntryPath))
332
					break;
333
			}
334
335
			if (indexToInsert >= 0) {
336
				int newSize = roots.length + 1;
337
				IPackageFragmentRoot[] newChildren = new IPackageFragmentRoot[newSize];
338
339
				if (indexToInsert > 0)
340
					System.arraycopy(roots, 0, newChildren, 0, indexToInsert);
341
342
				newChildren[indexToInsert] = child;
343
				System.arraycopy(roots, indexToInsert, newChildren, indexToInsert + 1, (newSize - indexToInsert - 1));
344
				parent.setChildren(newChildren);
345
				return;
346
			}
347
		}
348
		parent.addChild(child);
349
	}
291
	/*
350
	/*
292
	 * Process the given delta and look for projects being added, opened, closed or
351
	 * Process the given delta and look for projects being added, opened, closed or
293
	 * with a java nature being added or removed.
352
	 * with a java nature being added or removed.
(-)src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java (+19 lines)
Lines 955-960 Link Here
955
		}
955
		}
956
		assertEquals(expected, actual);
956
		assertEquals(expected, actual);
957
	}
957
	}
958
	protected void assertPackageFragmentRootsEqual(IPackageFragmentRoot[] roots, String expected) {
959
		String actual;
960
		if (roots == null) {
961
			actual = "<null>";
962
		} else {
963
			StringBuffer buffer = new StringBuffer();
964
			int length = roots.length;
965
			for (int i=0; i<length; i++) {
966
				buffer.append(roots[i]);
967
				if (i < length-1)
968
					buffer.append('\n');
969
			}
970
			actual = buffer.toString();
971
		}
972
		if (!actual.equals(expected)) {
973
		 	System.out.print(displayString(actual, 2));
974
		}
975
		assertEquals(expected, actual);		
976
	}
958
	/**
977
	/**
959
	 * Ensures the element is present after creation.
978
	 * Ensures the element is present after creation.
960
	 */
979
	 */
(-)src/org/eclipse/jdt/core/tests/model/ClasspathTests.java (+40 lines)
Lines 7150-7153 Link Here
7150
	}	
7150
	}	
7151
}
7151
}
7152
7152
7153
/**
7154
 * @bug 338006: IJavaProject#getPackageFragmentRoots() should return roots in order
7155
 * 
7156
 * Test whether the {@link IJavaProject#getPackageFragmentRoots()} returns the package fragment
7157
 * roots in the same order as defined by the .classpath even when the elements are added in a 
7158
 * different order.
7159
 * 
7160
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=338006"
7161
 */
7162
public void testBug338006() throws Exception {
7163
	try {
7164
		IJavaProject p = this.createJavaProject("P", new String[] {}, "bin");
7165
7166
		String content = new String(
7167
				"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
7168
				+ "<classpath>\n"
7169
				+ "<classpathentry kind=\"src\" path=\"src a\"/>\n"
7170
				+ "<classpathentry kind=\"src\" path=\"src x\"/>\n"
7171
				+ "<classpathentry kind=\"lib\" path=\""
7172
				+ getExternalJCLPath()
7173
				+ "\"/>\n"
7174
				+ "<classpathentry kind=\"output\" path=\"bin\"/>\n"
7175
				+ "</classpath>\n");
7176
7177
		editFile("/P/.classpath", content);
7178
		p.open(null);
7179
		createFolder("/P/src x");
7180
		createFolder("/P/src a");
7181
7182
		IPackageFragmentRoot[] roots = p.getPackageFragmentRoots();
7183
		assertPackageFragmentRootsEqual(roots, 
7184
				"src a (not open) [in P]\n" + 
7185
				"src x (not open) [in P]\n" + 
7186
				""+ getExternalJCLPathString() + " (not open)");
7187
7188
	} finally {
7189
		deleteProject("P");
7190
	}
7191
}
7192
7153
}
7193
}

Return to bug 338006