### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: model/org/eclipse/jdt/core/IClasspathEntry.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathEntry.java,v retrieving revision 1.65 diff -u -r1.65 IClasspathEntry.java --- model/org/eclipse/jdt/core/IClasspathEntry.java 27 Jun 2008 16:04:00 -0000 1.65 +++ model/org/eclipse/jdt/core/IClasspathEntry.java 4 Feb 2010 07:36:02 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -105,6 +105,7 @@ *
* * @see JavaCore#newLibraryEntry(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + * @see JavaCore#newLibraryEntry(IPath, IPath, IPath, IClasspathEntry, IClasspathEntry[], boolean, IAccessRule[], IClasspathAttribute[], boolean) * @see JavaCore#newProjectEntry(org.eclipse.core.runtime.IPath) * @see JavaCore#newSourceEntry(org.eclipse.core.runtime.IPath) * @see JavaCore#newVariableEntry(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) @@ -418,6 +419,64 @@ */ IPath getSourceAttachmentRootPath(); + + /** + * Returns the library entry that is referencing this classpath entry. For CPE_LIBRARY, + * this is the classpath entry that is representing the jar that mentionsthis
+ * in the Class-Path clause of it's MANIFEST. For entry kinds other than CPE_LIBRARY,
+ * this returns null.
+ *
+ * @return the classpath entry that is referencing this entry.
+ * @since 3.6
+ */
+ IClasspathEntry getReferencingEntry();
+
+ /**
+ * Returns an array of classpath entries that are chained to this
. For the entry
+ * kind CPE_LIBRARY, the method returns the libraries that are included in the Class-Path
+ * clause of the MANIFEST file. For other entry kinds, this method returns an empty array.
+ * If a chained library is already part of the raw classpath of the project, that will not be
+ * included in the returned list.
+ * + * The chained libraries attached to a particular classpath entry depends on the following + * factors apart from the MANIFEST entries: + *
this
. Apart from this,
+ * it could also affect the chained libraries of the other classpath entries in the project's
+ * raw classpath.
+ *
+ * + * The chained libraries themselves will not have any further chained entries. The order of the + * chained entries will be the order in which they are specified in the MANIFEST file. + *
+ * + * @return the array of classpath entries that this entry makes references to. + * @since 3.6 + */ + IClasspathEntry[] getChainedEntries(); + + /** + * Returns whether the chained Jars should be included as part of the resolved build path. + * For entry kinds other than library {@link #CPE_LIBRARY}, this flag does not affect the + * classpath in any way. Setting this flag off will detach all the chained entries from + *this
entry at once. However, this does not always guarantee that these
+ * libraries will be removed from the resolved classpath.
+ * + * For more, refer to {@link IClasspathEntry#getChainedEntries()}
+ * + * @return whether or not the chained jars should be excluded from this classpath entry. + * @since 3.6 + */ + boolean excludeChainedJars(); + /** * Returns whether this entry is exported to dependent projects. * Always returnsfalse
for source entries (kind
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.103
diff -u -r1.103 IJavaProject.java
--- model/org/eclipse/jdt/core/IJavaProject.java 27 Oct 2008 14:47:36 -0000 1.103
+++ model/org/eclipse/jdt/core/IJavaProject.java 4 Feb 2010 07:36:03 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -611,7 +611,10 @@
* The resulting resolved classpath is accurate for the given point in time.
* If the project's raw classpath is later modified, or if classpath
* variables are changed, the resolved classpath can become out of date.
- * Because of this, hanging on resolved classpath is not recommended.
+ * Because of this, hanging on resolved classpath is not recommended.
+ * One such classpath attributes that can affect the resolved classpath is
+ * {@link IClasspathEntry#excludeChainedJars()}. This flag determines whether or
+ * not referenced (or chained) jars are included in the resolved classpath.
*
*
* Note that if the resolution creates duplicate entries
Index: model/org/eclipse/jdt/core/JavaCore.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java,v
retrieving revision 1.647
diff -u -r1.647 JavaCore.java
--- model/org/eclipse/jdt/core/JavaCore.java 13 Jan 2010 15:13:42 -0000 1.647
+++ model/org/eclipse/jdt/core/JavaCore.java 4 Feb 2010 07:36:10 -0000
@@ -3993,6 +3993,94 @@
* Creates and returns a new classpath entry of kind CPE_LIBRARY
for the JAR or folder
* identified by the given absolute path. This specifies that all package fragments within the root
* will have children of type IClassFile
.
+ * This method is fully equivalent to calling
+ * {@link #newLibraryEntry(IPath, IPath, IPath, IClasspathEntry[], boolean, IAccessRule[], IClasspathAttribute[], boolean)
+ * newLibraryEntry(path, sourceAttachmentPath, sourceAttachmentRootPath, ClasspathEntry.NO_ENTRIES, false, new IAccessRule[0], new IClasspathAttribute[0], isExported)}.
+ *
+ * @param path the path to the library
+ * @param sourceAttachmentPath the absolute path of the corresponding source archive or folder,
+ * or null
if none. Note, since 3.0, an empty path is allowed to denote no source attachment.
+ * and will be automatically converted to null
. Since 3.4, this path can also denote a path external
+ * to the workspace.
+ * @param sourceAttachmentRootPath the location of the root of the source files within the source archive or folder
+ * or null
if this location should be automatically detected.
+ * @param accessRules the possibly empty list of access rules for this entry
+ * @param extraAttributes the possibly empty list of extra attributes to persist with this entry
+ * @param isExported indicates whether this entry is contributed to dependent
+ * projects in addition to the output location
+ * @return a new library classpath entry
+ * @since 3.1
+ */
+ public static IClasspathEntry newLibraryEntry(
+ IPath path,
+ IPath sourceAttachmentPath,
+ IPath sourceAttachmentRootPath,
+ IAccessRule[] accessRules,
+ IClasspathAttribute[] extraAttributes,
+ boolean isExported) {
+
+ return newLibraryEntry(
+ path,
+ sourceAttachmentPath,
+ sourceAttachmentRootPath,
+ ClasspathEntry.NO_ENTRIES,
+ false,
+ accessRules,
+ extraAttributes,
+ isExported);
+ }
+
+
+ /**
+ * Creates and returns a new classpath entry of kind CPE_LIBRARY
for the JAR or folder
+ * identified by the given absolute path. This specifies that all package fragments within the root
+ * will have children of type IClassFile
.
+ * This method is fully equivalent to calling
+ * {@link #newLibraryEntry(IPath, IPath, IPath, IClasspathEntry, IClasspathEntry[], boolean, IAccessRule[], IClasspathAttribute[], boolean)
+ * newLibraryEntry(path, sourceAttachmentPath, sourceAttachmentRootPath, null, chainedEntries, false, new IAccessRule[0], new IClasspathAttribute[0], isExported)}.
+ *
+ * @param path the path to the library
+ * @param sourceAttachmentPath the absolute path of the corresponding source archive or folder,
+ * or null
if none. Note, since 3.0, an empty path is allowed to denote no source attachment.
+ * and will be automatically converted to null
. Since 3.4, this path can also denote a path external
+ * to the workspace.
+ * @param sourceAttachmentRootPath the location of the root of the source files within the source archive or folder
+ * or null
if this location should be automatically detected.
+ * @param chainedEntries the libraries that are chained to this entry, e.g. via MANIFEST file
+ * @param excludeChained indicates whether the chained library entries need to be resolved or not.
+ * @param accessRules the possibly empty list of access rules for this entry
+ * @param extraAttributes the possibly empty list of extra attributes to persist with this entry
+ * @param isExported indicates whether this entry is contributed to dependent
+ * projects in addition to the output location
+ * @return a new library classpath entry
+ * @since 3.6
+ */
+ public static IClasspathEntry newLibraryEntry(
+ IPath path,
+ IPath sourceAttachmentPath,
+ IPath sourceAttachmentRootPath,
+ IClasspathEntry[] chainedEntries,
+ boolean excludeChained,
+ IAccessRule[] accessRules,
+ IClasspathAttribute[] extraAttributes,
+ boolean isExported) {
+
+ return newLibraryEntry(
+ path,
+ sourceAttachmentPath,
+ sourceAttachmentRootPath,
+ null,
+ chainedEntries,
+ excludeChained,
+ accessRules,
+ extraAttributes,
+ isExported);
+ }
+
+ /**
+ * Creates and returns a new classpath entry of kind CPE_LIBRARY
for the JAR or folder
+ * identified by the given absolute path. This specifies that all package fragments within the root
+ * will have children of type IClassFile
.
*
* A library entry is used to denote a prerequisite JAR or root folder containing binaries. * The target JAR can either be defined internally to the workspace (absolute path relative @@ -4038,8 +4126,7 @@ *
* Since 3.5, if the libray is a ZIP archive, the "Class-Path" clause (if any) in the "META-INF/MANIFEST.MF" is read * and referenced ZIP archives are added to the {@link IJavaProject#getResolvedClasspath(boolean) resolved classpath}. - *
- * + * * @param path the path to the library * @param sourceAttachmentPath the absolute path of the corresponding source archive or folder, * ornull
if none. Note, since 3.0, an empty path is allowed to denote no source attachment.
@@ -4047,17 +4134,23 @@
* to the workspace.
* @param sourceAttachmentRootPath the location of the root of the source files within the source archive or folder
* or null
if this location should be automatically detected.
+ * @param referencingEntry the library entry that refers to this library entry, e.g. via MANIFEST file
+ * @param chainedEntries the libraries that are chained to this entry, e.g. via MANIFEST file
+ * @param excludeChained indicates whether the chained library entries need to be resolved or not.
* @param accessRules the possibly empty list of access rules for this entry
* @param extraAttributes the possibly empty list of extra attributes to persist with this entry
* @param isExported indicates whether this entry is contributed to dependent
* projects in addition to the output location
* @return a new library classpath entry
- * @since 3.1
+ * @since 3.6
*/
public static IClasspathEntry newLibraryEntry(
IPath path,
IPath sourceAttachmentPath,
IPath sourceAttachmentRootPath,
+ IClasspathEntry referencingEntry,
+ IClasspathEntry[] chainedEntries,
+ boolean excludeChained,
IAccessRule[] accessRules,
IClasspathAttribute[] extraAttributes,
boolean isExported) {
@@ -4089,6 +4182,9 @@
sourceAttachmentPath,
sourceAttachmentRootPath,
null, // specific output folder
+ referencingEntry,
+ chainedEntries,
+ excludeChained,
isExported,
accessRules,
false, // no access rules to combine
Index: model/org/eclipse/jdt/internal/core/ClasspathEntry.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java,v
retrieving revision 1.123
diff -u -r1.123 ClasspathEntry.java
--- model/org/eclipse/jdt/internal/core/ClasspathEntry.java 1 Feb 2010 11:13:25 -0000 1.123
+++ model/org/eclipse/jdt/internal/core/ClasspathEntry.java 4 Feb 2010 07:36:12 -0000
@@ -92,11 +92,14 @@
public static final String TAG_COMBINE_ACCESS_RULES = "combineaccessrules"; //$NON-NLS-1$
public static final String TAG_ACCESS_RULES = "accessrules"; //$NON-NLS-1$
public static final String TAG_ACCESS_RULE = "accessrule"; //$NON-NLS-1$
+ public static final String TAG_REFERENCES = "references"; //$NON-NLS-1$
+ public static final String TAG_REFERENCE = "reference"; //$NON-NLS-1$
public static final String TAG_PATTERN = "pattern"; //$NON-NLS-1$
public static final String TAG_ACCESSIBLE = "accessible"; //$NON-NLS-1$
public static final String TAG_NON_ACCESSIBLE = "nonaccessible"; //$NON-NLS-1$
public static final String TAG_DISCOURAGED = "discouraged"; //$NON-NLS-1$
public static final String TAG_IGNORE_IF_BETTER = "ignoreifbetter"; //$NON-NLS-1$
+ public static final String TAG_EXCLUDE_CHAINED = "excludechained"; //$NON-NLS-1$
/**
* Describes the kind of classpath entry - one of
@@ -141,7 +144,7 @@
private IPath[] exclusionPatterns;
private char[][] fullExclusionPatternChars;
private final static char[][] UNINIT_PATTERNS = new char[][] { "Non-initialized yet".toCharArray() }; //$NON-NLS-1$
- private final static ClasspathEntry[] NO_ENTRIES = new ClasspathEntry[0];
+ public final static ClasspathEntry[] NO_ENTRIES = new ClasspathEntry[0];
private final static IPath[] NO_PATHS = new IPath[0];
private final static IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
@@ -197,6 +200,13 @@
* a non-null
value.
*/
public IPath sourceAttachmentRootPath;
+
+ public IClasspathEntry[] chainedEntries;
+
+ public IClasspathEntry referencingEntry;
+
+ public boolean excludeChainedJars = false;
+
/**
* Specific output location (for this source entry)
@@ -220,6 +230,37 @@
*/
IClasspathAttribute[] extraAttributes;
+ public ClasspathEntry(
+ int contentKind,
+ int entryKind,
+ IPath path,
+ IPath[] inclusionPatterns,
+ IPath[] exclusionPatterns,
+ IPath sourceAttachmentPath,
+ IPath sourceAttachmentRootPath,
+ IPath specificOutputLocation,
+ boolean isExported,
+ IAccessRule[] accessRules,
+ boolean combineAccessRules,
+ IClasspathAttribute[] extraAttributes) {
+
+ this( contentKind,
+ entryKind,
+ path,
+ inclusionPatterns,
+ exclusionPatterns,
+ sourceAttachmentPath,
+ sourceAttachmentRootPath,
+ specificOutputLocation,
+ null,
+ null,
+ false,
+ isExported,
+ accessRules,
+ combineAccessRules,
+ extraAttributes);
+ }
+
/**
* Creates a class path entry of the specified kind with the given path.
*/
@@ -232,6 +273,9 @@
IPath sourceAttachmentPath,
IPath sourceAttachmentRootPath,
IPath specificOutputLocation,
+ IClasspathEntry referencingEntry,
+ IClasspathEntry[] chainedEntries,
+ boolean excludeChainedJars,
boolean isExported,
IAccessRule[] accessRules,
boolean combineAccessRules,
@@ -242,7 +286,10 @@
this.path = path;
this.inclusionPatterns = inclusionPatterns;
this.exclusionPatterns = exclusionPatterns;
-
+ this.referencingEntry = referencingEntry;
+ this.excludeChainedJars = excludeChainedJars;
+ this.chainedEntries = chainedEntries;
+
int length;
if (accessRules != null && (length = accessRules.length) > 0) {
AccessRule[] rules = new AccessRule[length];
@@ -379,6 +426,43 @@
System.arraycopy(result, 0, result = new IAccessRule[index], 0, index);
return result;
}
+
+ static IClasspathEntry[] decodeReferences(NodeList list, IClasspathEntry parent) {
+ if (list == null) return null;
+ int length = list.getLength();
+ if (length == 0) return null;
+ IClasspathEntry[] result = new IClasspathEntry[length];
+ int index = 0;
+ for (int i = 0; i < length; i++) {
+ Node referencedEntry = list.item(i);
+ if (referencedEntry.getNodeType() == Node.ELEMENT_NODE) {
+ Element elementReference = (Element) referencedEntry;
+ String path = elementReference.getAttribute(TAG_PATH);
+ String sourceAttachment = elementReference.getAttribute(TAG_SOURCEPATH);
+ String sourceRoot = elementReference.getAttribute(TAG_ROOTPATH);
+ result[index++] =
+ new ClasspathEntry(
+ parent.getContentKind(),
+ parent.getEntryKind(),
+ new Path(path),
+ parent.getInclusionPatterns(),
+ parent.getExclusionPatterns(),
+ "".equals(sourceAttachment) ? null : new Path(sourceAttachment), //$NON-NLS-1$
+ "".equals(sourceRoot) ? null : new Path(sourceRoot), //$NON-NLS-1$
+ parent.getOutputLocation(),
+ parent,
+ new IClasspathEntry[0],
+ parent.excludeChainedJars(),
+ parent.isExported(),
+ parent.getAccessRules(),
+ parent.combineAccessRules(),
+ parent.getExtraAttributes());
+ }
+ }
+ if (index != length)
+ System.arraycopy(result, 0, result = new ClasspathEntry[index], 0, index);
+ return result;
+ }
/**
* Decode some element tag containing a sequence of patterns into IPath[]
@@ -494,36 +578,13 @@
parameters.put(TAG_KIND, ClasspathEntry.kindToString(this.entryKind));
- IPath xmlPath = this.path;
- if (this.entryKind != IClasspathEntry.CPE_VARIABLE && this.entryKind != IClasspathEntry.CPE_CONTAINER) {
- // translate to project relative from absolute (unless a device path)
- if (xmlPath.isAbsolute()) {
- if (projectPath != null && projectPath.isPrefixOf(xmlPath)) {
- if (xmlPath.segment(0).equals(projectPath.segment(0))) {
- xmlPath = xmlPath.removeFirstSegments(1);
- xmlPath = xmlPath.makeRelative();
- } else {
- xmlPath = xmlPath.makeAbsolute();
- }
- }
+ encodePathAttributes(projectPath, parameters);
+
+ if (this.entryKind == IClasspathEntry.CPE_LIBRARY) {
+ if (this.excludeChainedJars) {
+ parameters.put(TAG_EXCLUDE_CHAINED, "true"); //$NON-NLS-1$
}
}
- parameters.put(TAG_PATH, String.valueOf(xmlPath));
-
- if (this.sourceAttachmentPath != null) {
- xmlPath = this.sourceAttachmentPath;
- // translate to project relative from absolute
- if (this.entryKind != IClasspathEntry.CPE_VARIABLE && projectPath != null && projectPath.isPrefixOf(xmlPath)) {
- if (xmlPath.segment(0).equals(projectPath.segment(0))) {
- xmlPath = xmlPath.removeFirstSegments(1);
- xmlPath = xmlPath.makeRelative();
- }
- }
- parameters.put(TAG_SOURCEPATH, String.valueOf(xmlPath));
- }
- if (this.sourceAttachmentRootPath != null) {
- parameters.put(TAG_ROOTPATH, String.valueOf(this.sourceAttachmentRootPath));
- }
if (this.isExported) {
parameters.put(TAG_EXPORTED, "true");//$NON-NLS-1$
}
@@ -553,12 +614,15 @@
boolean hasRestrictions = getAccessRuleSet() != null; // access rule set is null if no access rules
ArrayList unknownChildren = unknownXmlElements != null ? unknownXmlElements.children : null;
boolean hasUnknownChildren = unknownChildren != null;
+ boolean hasChainedEntries = getChainedEntries().length > 0 ? true : false;
+
+ /* close tag if no extra attributes, no restriction, no unknown children and no chained classpath entries */
writer.printTag(
TAG_CLASSPATHENTRY,
parameters,
indent,
newLine,
- !hasExtraAttributes && !hasRestrictions && !hasUnknownChildren/*close tag if no extra attributes, no restriction and no unknown children*/);
+ !hasExtraAttributes && !hasRestrictions && !hasUnknownChildren && !hasChainedEntries);
if (hasExtraAttributes)
encodeExtraAttributes(writer, indent, newLine);
@@ -566,13 +630,49 @@
if (hasRestrictions)
encodeAccessRules(writer, indent, newLine);
+ if (this.getChainedEntries().length > 0) {
+ encodeReferences(writer, projectPath, indent, newLine);
+ }
if (hasUnknownChildren)
encodeUnknownChildren(writer, indent, newLine, unknownChildren);
- if (hasExtraAttributes || hasRestrictions || hasUnknownChildren)
+ if (hasExtraAttributes || hasRestrictions || hasUnknownChildren || hasChainedEntries)
writer.endTag(TAG_CLASSPATHENTRY, indent, true/*insert new line*/);
}
+ private void encodePathAttributes(IPath projectPath, HashMap parameters) {
+ IPath xmlPath = this.path;
+ if (this.entryKind != IClasspathEntry.CPE_VARIABLE && this.entryKind != IClasspathEntry.CPE_CONTAINER) {
+ // translate to project relative from absolute (unless a device path)
+ if (xmlPath.isAbsolute()) {
+ if (projectPath != null && projectPath.isPrefixOf(xmlPath)) {
+ if (xmlPath.segment(0).equals(projectPath.segment(0))) {
+ xmlPath = xmlPath.removeFirstSegments(1);
+ xmlPath = xmlPath.makeRelative();
+ } else {
+ xmlPath = xmlPath.makeAbsolute();
+ }
+ }
+ }
+ }
+ parameters.put(TAG_PATH, String.valueOf(xmlPath));
+
+ if (this.sourceAttachmentPath != null) {
+ xmlPath = this.sourceAttachmentPath;
+ // translate to project relative from absolute
+ if (this.entryKind != IClasspathEntry.CPE_VARIABLE && projectPath != null && projectPath.isPrefixOf(xmlPath)) {
+ if (xmlPath.segment(0).equals(projectPath.segment(0))) {
+ xmlPath = xmlPath.removeFirstSegments(1);
+ xmlPath = xmlPath.makeRelative();
+ }
+ }
+ parameters.put(TAG_SOURCEPATH, String.valueOf(xmlPath));
+ }
+ if (this.sourceAttachmentRootPath != null) {
+ parameters.put(TAG_ROOTPATH, String.valueOf(this.sourceAttachmentRootPath));
+ }
+ }
+
void encodeExtraAttributes(XMLWriter writer, boolean indent, boolean newLine) {
writer.startTag(TAG_ATTRIBUTES, indent);
for (int i = 0; i < this.extraAttributes.length; i++) {
@@ -617,6 +717,18 @@
writer.printTag(TAG_ACCESS_RULE, parameters, indent, newLine, true);
}
+
+ void encodeReferences(XMLWriter writer, IPath projectPath, boolean indent, boolean newLine) {
+ writer.startTag(TAG_REFERENCES, indent);
+ IClasspathEntry[] references = getChainedEntries();
+ for (int index = 0, length = references.length; index < length; index++) {
+ // Set the capacity to maximum possible
+ HashMap parameters = new HashMap(3);
+ ((ClasspathEntry)references[index]).encodePathAttributes(projectPath, parameters);
+ writer.printTag(TAG_REFERENCE, parameters, indent, newLine, true);
+ }
+ writer.endTag(TAG_REFERENCES, indent, true/*insert new line*/);
+ }
private void encodeUnknownChildren(XMLWriter writer, boolean indent, boolean newLine, ArrayList unknownChildren) {
for (int i = 0, length = unknownChildren.size(); i < length; i++) {
@@ -657,7 +769,8 @@
// exported flag (optional)
boolean isExported = removeAttribute(TAG_EXPORTED, attributes).equals("true"); //$NON-NLS-1$
-
+ boolean excludeChained = removeAttribute(TAG_EXCLUDE_CHAINED, attributes).equals("true"); //$NON-NLS-1$
+
// inclusion patterns (optional)
IPath[] inclusionPatterns = decodePatterns(attributes, TAG_INCLUDING);
if (inclusionPatterns == null) inclusionPatterns = INCLUDE_ALL;
@@ -685,35 +798,6 @@
// custom output location
IPath outputLocation = element.hasAttribute(TAG_OUTPUT) ? projectPath.append(removeAttribute(TAG_OUTPUT, attributes)) : null;
- String[] unknownAttributes = null;
- ArrayList unknownChildren = null;
-
- if (unknownElements != null) {
- // unknown attributes
- int unknownAttributeLength = attributes.getLength();
- if (unknownAttributeLength != 0) {
- unknownAttributes = new String[unknownAttributeLength*2];
- for (int i = 0; i < unknownAttributeLength; i++) {
- Node attribute = attributes.item(i);
- unknownAttributes[i*2] = attribute.getNodeName();
- unknownAttributes[i*2 + 1] = attribute.getNodeValue();
- }
- }
-
- // unknown children
- for (int i = 0, length = foundChildren.length; i < length; i++) {
- if (!foundChildren[i]) {
- Node node = children.item(i);
- if (node.getNodeType() != Node.ELEMENT_NODE) continue;
- if (unknownChildren == null)
- unknownChildren = new ArrayList();
- StringBuffer buffer = new StringBuffer();
- decodeUnknownNode(node, buffer, project);
- unknownChildren.add(buffer.toString());
- }
- }
- }
-
// recreate the CP entry
IClasspathEntry entry = null;
switch (kind) {
@@ -738,9 +822,14 @@
path,
sourceAttachmentPath,
sourceAttachmentRootPath,
+ null,
+ excludeChained,
accessRules,
extraAttributes,
isExported);
+ NodeList referencesList = getChildAttributes(TAG_REFERENCES, children, foundChildren);
+ IClasspathEntry[] references = decodeReferences(referencesList, entry);
+ ((ClasspathEntry)entry).setChainedEntries(references);
break;
case IClasspathEntry.CPE_SOURCE :
// must be an entry in this project or specify another project
@@ -807,6 +896,35 @@
default :
throw new AssertionFailedException(Messages.bind(Messages.classpath_unknownKind, kindAttr));
}
+
+ String[] unknownAttributes = null;
+ ArrayList unknownChildren = null;
+
+ if (unknownElements != null) {
+ // unknown attributes
+ int unknownAttributeLength = attributes.getLength();
+ if (unknownAttributeLength != 0) {
+ unknownAttributes = new String[unknownAttributeLength*2];
+ for (int i = 0; i < unknownAttributeLength; i++) {
+ Node attribute = attributes.item(i);
+ unknownAttributes[i*2] = attribute.getNodeName();
+ unknownAttributes[i*2 + 1] = attribute.getNodeValue();
+ }
+ }
+
+ // unknown children
+ for (int i = 0, length = foundChildren.length; i < length; i++) {
+ if (!foundChildren[i]) {
+ Node node = children.item(i);
+ if (node.getNodeType() != Node.ELEMENT_NODE) continue;
+ if (unknownChildren == null)
+ unknownChildren = new ArrayList();
+ StringBuffer buffer = new StringBuffer();
+ decodeUnknownNode(node, buffer, project);
+ unknownChildren.add(buffer.toString());
+ }
+ }
+ }
if (unknownAttributes != null || unknownChildren != null) {
UnknownXmlElements unknownXmlElements = new UnknownXmlElements();
@@ -1019,6 +1137,9 @@
if (this.entryKind != otherEntry.getEntryKind())
return false;
+ if (this.excludeChainedJars != otherEntry.excludeChainedJars())
+ return false;
+
if (this.isExported != otherEntry.isExported())
return false;
@@ -1178,6 +1299,26 @@
return this.sourceAttachmentRootPath;
}
+
+ public boolean excludeChainedJars() {
+ return this.excludeChainedJars;
+ }
+
+ public IClasspathEntry getReferencingEntry() {
+ return this.referencingEntry;
+ }
+
+ public IClasspathEntry[] getChainedEntries() {
+ if (this.chainedEntries == null) {
+ this.chainedEntries = new IClasspathEntry[0];
+ }
+ return this.chainedEntries;
+ }
+
+ public void setChainedEntries(IClasspathEntry[] entries) {
+ this.chainedEntries = entries;
+ }
+
/**
* Returns the hash code for this classpath entry
*/
@@ -1380,6 +1521,9 @@
getSourceAttachmentPath(),
getSourceAttachmentRootPath(),
getOutputLocation(),
+ this.getReferencingEntry(),
+ this.getChainedEntries(),
+ this.excludeChainedJars(),
this.isExported,
getAccessRules(),
this.combineAccessRules,
@@ -1398,18 +1542,21 @@
ClasspathEntry[] result = new ClasspathEntry[length];
for (int i = 0; i < length; i++) {
result[i] = new ClasspathEntry(
- getContentKind(),
- getEntryKind(),
- paths[i],
- this.inclusionPatterns,
- this.exclusionPatterns,
- getSourceAttachmentPath(),
- getSourceAttachmentRootPath(),
- getOutputLocation(),
- this.isExported,
- getAccessRules(),
- this.combineAccessRules,
- this.extraAttributes);
+ getContentKind(),
+ getEntryKind(),
+ paths[i],
+ this.inclusionPatterns,
+ this.exclusionPatterns,
+ null,
+ null,
+ getOutputLocation(),
+ this,
+ null,
+ false,
+ this.isExported,
+ getAccessRules(),
+ this.combineAccessRules,
+ this.extraAttributes);
}
return result;
}
Index: model/org/eclipse/jdt/internal/core/JavaProject.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java,v
retrieving revision 1.427
diff -u -r1.427 JavaProject.java
--- model/org/eclipse/jdt/internal/core/JavaProject.java 8 Jul 2009 07:12:08 -0000 1.427
+++ model/org/eclipse/jdt/internal/core/JavaProject.java 4 Feb 2010 07:36:14 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -19,6 +19,7 @@
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
+import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -2541,6 +2542,7 @@
ResolvedClasspath result = new ResolvedClasspath();
LinkedHashSet resolvedEntries = new LinkedHashSet();
+ Set newChainedEntries = new LinkedHashSet();
int length = rawClasspath.length;
for (int i = 0; i < length; i++) {
@@ -2565,10 +2567,10 @@
// resolve Class-Path: in manifest
ClasspathEntry[] extraEntries = ((ClasspathEntry) resolvedEntry).resolvedChainedLibraries();
for (int j = 0, length2 = extraEntries.length; j < length2; j++) {
- addToResult(rawEntry, extraEntries[j], result, resolvedEntries, externalFoldersManager);
+ addToResult(rawEntry, extraEntries[j], result, resolvedEntries, externalFoldersManager, true);
}
}
- addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager);
+ addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, false);
}
break;
@@ -2607,11 +2609,11 @@
// resolve Class-Path: in manifest
ClasspathEntry[] extraEntries = cEntry.resolvedChainedLibraries();
for (int k = 0, length2 = extraEntries.length; k < length2; k++) {
- addToResult(rawEntry, extraEntries[k], result, resolvedEntries, externalFoldersManager);
+ addToResult(rawEntry, extraEntries[k], result, resolvedEntries, externalFoldersManager, true);
}
}
}
- addToResult(rawEntry, cEntry, result, resolvedEntries, externalFoldersManager);
+ addToResult(rawEntry, cEntry, result, resolvedEntries, externalFoldersManager, false);
}
break;
@@ -2620,30 +2622,96 @@
resolvedEntry = ((ClasspathEntry) rawEntry).resolvedDotDot();
if (resolveChainedLibraries) {
- // resolve Class-Path: in manifest
- ClasspathEntry[] extraEntries = ((ClasspathEntry) resolvedEntry).resolvedChainedLibraries();
- for (int k = 0, length2 = extraEntries.length; k < length2; k++) {
- addToResult(rawEntry, extraEntries[k], result, resolvedEntries, externalFoldersManager);
+ if (rawEntry.excludeChainedJars()) {
+ ((ClasspathEntry)rawEntry).setChainedEntries(new IClasspathEntry[0]);
+ } else {
+ // resolve Class-Path: in manifest
+ ClasspathEntry[] extraEntries = ((ClasspathEntry) resolvedEntry).resolvedChainedLibraries();
+ for (int k = 0, length2 = extraEntries.length; k < length2; k++) {
+ newChainedEntries.add(extraEntries[k].getPath());
+ addToResult(rawEntry, extraEntries[k], result, resolvedEntries, externalFoldersManager, true);
+ }
}
}
-
- addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager);
+ addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, false);
break;
default :
- addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager);
+ addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, false);
break;
}
}
+
+ if (resolveChainedLibraries && newChainedEntries.size() > 0) {
+ populateChainedEntries(rawClasspath, result, newChainedEntries);
+ }
result.resolvedClasspath = new IClasspathEntry[resolvedEntries.size()];
resolvedEntries.toArray(result.resolvedClasspath);
return result;
}
- private void addToResult(IClasspathEntry rawEntry, IClasspathEntry resolvedEntry, ResolvedClasspath result, LinkedHashSet resolvedEntries, ExternalFoldersManager externalFoldersManager) {
+ private void populateChainedEntries(IClasspathEntry[] rawClasspath, ResolvedClasspath result, Set newChainedEntries) {
+ // Collect the old chained entries before overwriting them as these potentially have
+ // the old attributes user added
+ Map oldChainedEntries = new HashMap();
+ for (int index = 0; index < rawClasspath.length; index++) {
+ if (rawClasspath[index].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+ IClasspathEntry[] chainedEntries = ((ClasspathEntry)rawClasspath[index]).getChainedEntries();
+ for (int chainIndex = 0; chainIndex < chainedEntries.length; chainIndex++) {
+ oldChainedEntries.put(chainedEntries[chainIndex].getPath(), chainedEntries[chainIndex]);
+ }
+ }
+ }
+
+ Map rawEntryChainsMap = new HashMap();
+ Iterator iter = newChainedEntries.iterator();
+ while (iter.hasNext()) {
+ IPath chainedEntryPath = (IPath) iter.next();
+ IClasspathEntry rawEntry = (IClasspathEntry)result.rawReverseMap.get(chainedEntryPath);
+ // Filter out the chained libraries that ended up with raw entry of kind other than CPE_LIBRARY
+ // For e.g. library xyz.jar is referenced in MANIFEST of abc.jar, which is in the raw classpath
+ // And if xyz.jar is part of a resolved container, then xyz.jar will not be considered as part of the container
+ // and not a chained library of abc.jar
+ if (rawEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+ IClasspathEntry chainedEntry = (ClasspathEntry)oldChainedEntries.get(chainedEntryPath);
+ IClasspathEntry resolvedEntry = (IClasspathEntry)result.rootPathToResolvedEntries.get(chainedEntryPath);
+ if (chainedEntry != null) {
+ copyFromOldChainedEntry(resolvedEntry, chainedEntry);
+ }
+ Set chainsSet = (Set)rawEntryChainsMap.get(rawEntry);
+ if (chainsSet == null) {
+ chainsSet = new LinkedHashSet();
+ rawEntryChainsMap.put(rawEntry, chainsSet);
+ }
+ chainsSet.add(resolvedEntry);
+ }
+ }
+
+ iter = rawEntryChainsMap.keySet().iterator();
+ while(iter.hasNext()) {
+ ClasspathEntry rawEntry = (ClasspathEntry) iter.next();
+ Set chainsSet = (Set)rawEntryChainsMap.get(rawEntry);
+ IClasspathEntry[] chainedEntries = new IClasspathEntry[chainsSet.size()];
+ rawEntry.setChainedEntries((IClasspathEntry[])chainsSet.toArray(chainedEntries));
+ }
+ }
+
+ private void addToResult(IClasspathEntry rawEntry, IClasspathEntry resolvedEntry, ResolvedClasspath result,
+ LinkedHashSet resolvedEntries, ExternalFoldersManager externalFoldersManager, boolean isChainedEntry) {
+
IPath resolvedPath;
- if (result.rawReverseMap.get(resolvedPath = resolvedEntry.getPath()) == null) {
+ IClasspathEntry oldResolvedEntry = (IClasspathEntry)result.rootPathToResolvedEntries.get(resolvedPath = resolvedEntry.getPath());
+
+ if (oldResolvedEntry == null || (!isChainedEntry && oldResolvedEntry.getReferencingEntry() != null)) {
+ // If the entry has already been resolved, overwrite with the new one when:
+ // current resolvedEntry is a raw entry (!isChainedEntry) and previously resolved entry was a chained entry
+ // This ensures that preference is always given for a raw entry over a chained entry
+
+ if (oldResolvedEntry != null) {
+ resolvedEntries.remove(result.rootPathToResolvedEntries.get(resolvedPath));
+ }
result.rawReverseMap.put(resolvedPath, rawEntry);
result.rootPathToResolvedEntries.put(resolvedPath, resolvedEntry);
+ resolvedEntries.add(resolvedEntry);
}
resolvedEntries.add(resolvedEntry);
if (resolvedEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && ExternalFoldersManager.isExternalFolderPath(resolvedPath)) {
@@ -2651,6 +2719,17 @@
}
}
+ private void copyFromOldChainedEntry(IClasspathEntry resolvedEntry, IClasspathEntry chainedEntry) {
+ IPath path = chainedEntry.getSourceAttachmentPath();
+ if ( path != null) {
+ ((ClasspathEntry) resolvedEntry).sourceAttachmentPath = path;
+ }
+ path = chainedEntry.getSourceAttachmentRootPath();
+ if (path != null) {
+ ((ClasspathEntry) resolvedEntry).sourceAttachmentRootPath = path;
+ }
+ }
+
/*
* Resolve the given perProjectInfo's raw classpath and store the resolved classpath in the perProjectInfo.
*/
#P org.eclipse.jdt.core.tests.model
Index: src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java,v
retrieving revision 1.206
diff -u -r1.206 ClasspathTests.java
--- src/org/eclipse/jdt/core/tests/model/ClasspathTests.java 3 Feb 2010 06:38:02 -0000 1.206
+++ src/org/eclipse/jdt/core/tests/model/ClasspathTests.java 4 Feb 2010 07:36:23 -0000
@@ -88,8 +88,8 @@
// All specified tests which do not belong to the class are skipped...
static {
// Names of tests to run: can be "testBugXXXX" or "BugXXXX")
-// TESTS_PREFIX = "testClasspathDuplicateExtraAttribute";
-// TESTS_NAMES = new String[] {"testClasspathValidation42"};
+// TESTS_PREFIX = "testBug252341";
+// TESTS_NAMES = new String[] {"testBug252341a"};
// TESTS_NUMBERS = new int[] { 23, 28, 38 };
// TESTS_RANGE = new int[] { 21, 38 };
}
@@ -4881,7 +4881,7 @@
*/
public void testNoResourceChange06() throws CoreException {
ILogListener listener = new ILogListener(){
- private StringBuffer buffer = new StringBuffer();
+ private final StringBuffer buffer = new StringBuffer();
public void logging(IStatus status, String plugin) {
this.buffer.append(status);
this.buffer.append('\n');
@@ -6026,7 +6026,7 @@
}
}
/**
- * Additional test for bug 300136 - Test that the the errors are reported when the
+ * Additional test for bug 300136 - Test that the errors are reported when the
* optional attribute is not used.
*
* @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=300136"
@@ -6069,5 +6069,191 @@
JavaCore.removeClasspathVariable("INVALID_LIB", null);
}
}
+public void testBug252341a() throws Exception {
+ try {
+ IJavaProject p = createJavaProject("P");
+ addLibrary(p, "lib1.jar", "abc.zip", new String[0],
+ new String[] {
+ "META-INF/MANIFEST.MF",
+ "Manifest-Version: 1.0\n" +
+ "Class-Path: lib2.jar lib3.jar\n",
+ },
+ JavaCore.VERSION_1_4);
+ createFile("/P/lib2.jar", "");
+ createFile("/P/lib3.jar", "");
+ IClasspathEntry[] resolvedClasspath = p.getResolvedClasspath(true);
+ assertClasspathEquals(resolvedClasspath,
+ "/P[CPE_SOURCE][K_SOURCE][isExported:false]\n" +
+ ""+ getExternalJCLPathString() + "[CPE_LIBRARY][K_BINARY][isExported:false]\n" +
+ "/P/lib2.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib3.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib1.jar[CPE_LIBRARY][K_BINARY][sourcePath:/P/abc.zip][isExported:true]");
+
+ IClasspathEntry[] rawClasspath = p.getRawClasspath();
+ assertClasspathEquals(rawClasspath,
+ "/P[CPE_SOURCE][K_SOURCE][isExported:false]\n" +
+ "JCL_LIB[CPE_VARIABLE][K_SOURCE][isExported:false]\n" +
+ "/P/lib1.jar[CPE_LIBRARY][K_BINARY][sourcePath:/P/abc.zip][isExported:true]");
+
+ assertClasspathEquals(resolvedClasspath[4].getChainedEntries(),
+ "/P/lib2.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib3.jar[CPE_LIBRARY][K_BINARY][isExported:true]");
+
+ assertEquals("source attachment", resolvedClasspath[4].getSourceAttachmentPath().toPortableString(), "/P/abc.zip");
+ assertNull("source attachment", resolvedClasspath[2].getSourceAttachmentPath());
+ assertNull("source attachment", resolvedClasspath[3].getSourceAttachmentPath());
+
+ ((ClasspathEntry)resolvedClasspath[2]).sourceAttachmentPath = new Path("/P/efg.zip");
+ ((ClasspathEntry)resolvedClasspath[3]).sourceAttachmentPath = new Path("/P/xyz.zip");
+
+ p.setRawClasspath(rawClasspath, null);
+
+ p.close();
+ p.open(null);
+ resolvedClasspath = p.getResolvedClasspath(true);
+
+ assertClasspathEquals(resolvedClasspath,
+ "/P[CPE_SOURCE][K_SOURCE][isExported:false]\n" +
+ ""+ getExternalJCLPathString() + "[CPE_LIBRARY][K_BINARY][isExported:false]\n" +
+ "/P/lib2.jar[CPE_LIBRARY][K_BINARY][sourcePath:/P/efg.zip][isExported:true]\n" +
+ "/P/lib3.jar[CPE_LIBRARY][K_BINARY][sourcePath:/P/xyz.zip][isExported:true]\n" +
+ "/P/lib1.jar[CPE_LIBRARY][K_BINARY][sourcePath:/P/abc.zip][isExported:true]");
+
+ } finally {
+ deleteProject("P");
+ }
+}
+public void testBug252341b() throws Exception {
+ try {
+ IJavaProject p = createJavaProject("P");
+ addLibrary(p, "lib1.jar", null, new String[0],
+ new String[] {
+ "META-INF/MANIFEST.MF",
+ "Manifest-Version: 1.0\n" +
+ "Class-Path: lib3.jar lib4.jar\n",
+ },
+ JavaCore.VERSION_1_4);
+
+ addLibrary(p, "lib2.jar", null, new String[0],
+ new String[] {
+ "META-INF/MANIFEST.MF",
+ "Manifest-Version: 1.0\n" +
+ "Class-Path: lib3.jar lib5.jar\n",
+ },
+ JavaCore.VERSION_1_4);
+ createFile("/P/lib3.jar", "");
+ createFile("/P/lib4.jar", "");
+ createFile("/P/lib5.jar", "");
+
+ IClasspathEntry[] resolvedClasspath = p.getResolvedClasspath(true);
+ assertClasspathEquals(resolvedClasspath,
+ "/P[CPE_SOURCE][K_SOURCE][isExported:false]\n" +
+ ""+ getExternalJCLPathString() + "[CPE_LIBRARY][K_BINARY][isExported:false]\n" +
+ "/P/lib3.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib4.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib1.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib5.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib2.jar[CPE_LIBRARY][K_BINARY][isExported:true]");
+ assertClasspathEquals(
+ resolvedClasspath[4].getChainedEntries(),
+ "/P/lib3.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib4.jar[CPE_LIBRARY][K_BINARY][isExported:true]");
+ assertClasspathEquals(
+ resolvedClasspath[6].getChainedEntries(),
+ "/P/lib5.jar[CPE_LIBRARY][K_BINARY][isExported:true]");
+ } finally {
+ deleteProject("P");
+ }
+}
+public void testBug252341c() throws Exception {
+ try {
+ IJavaProject p = createJavaProject("P");
+ addLibrary(p, "lib1.jar", null, new String[0],
+ new String[] {
+ "META-INF/MANIFEST.MF",
+ "Manifest-Version: 1.0\n" +
+ "Class-Path: lib3.jar lib4.jar\n",
+ },
+ JavaCore.VERSION_1_4);
+
+ addLibrary(p, "lib2.jar", null, new String[0],
+ new String[] {
+ "META-INF/MANIFEST.MF",
+ "Manifest-Version: 1.0\n" +
+ "Class-Path: lib3.jar lib5.jar\n",
+ },
+ JavaCore.VERSION_1_4);
+ createFile("/P/lib3.jar", "");
+ createFile("/P/lib4.jar", "");
+ createFile("/P/lib5.jar", "");
+
+ IClasspathEntry[] rawClasspath = p.getRawClasspath();
+ assertClasspathEquals(
+ rawClasspath,
+ "/P[CPE_SOURCE][K_SOURCE][isExported:false]\n" +
+ "JCL_LIB[CPE_VARIABLE][K_SOURCE][isExported:false]\n" +
+ "/P/lib1.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib2.jar[CPE_LIBRARY][K_BINARY][isExported:true]");
+
+ IClasspathEntry[] resolvedClasspath = p.getResolvedClasspath(true);
+ assertClasspathEquals(resolvedClasspath,
+ "/P[CPE_SOURCE][K_SOURCE][isExported:false]\n" +
+ ""+ getExternalJCLPathString() + "[CPE_LIBRARY][K_BINARY][isExported:false]\n" +
+ "/P/lib3.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib4.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib1.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib5.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib2.jar[CPE_LIBRARY][K_BINARY][isExported:true]");
+
+ assertClasspathEquals(
+ resolvedClasspath[4].getChainedEntries(),
+ "/P/lib3.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib4.jar[CPE_LIBRARY][K_BINARY][isExported:true]");
+ assertClasspathEquals(
+ resolvedClasspath[6].getChainedEntries(),
+ "/P/lib5.jar[CPE_LIBRARY][K_BINARY][isExported:true]");
+
+ ((ClasspathEntry)rawClasspath[2]).excludeChainedJars = true;
+ p.setRawClasspath(rawClasspath, null);
+ resolvedClasspath = p.getResolvedClasspath(true);
+
+ assertClasspathEquals(resolvedClasspath,
+ "/P[CPE_SOURCE][K_SOURCE][isExported:false]\n" +
+ ""+ getExternalJCLPathString() + "[CPE_LIBRARY][K_BINARY][isExported:false]\n" +
+ "/P/lib1.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib3.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib5.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib2.jar[CPE_LIBRARY][K_BINARY][isExported:true]");
+
+ //Flip it back to false
+ ((ClasspathEntry)rawClasspath[2]).excludeChainedJars = false;
+ p.setRawClasspath(rawClasspath, null);
+ resolvedClasspath = p.getResolvedClasspath(true);
+
+ assertClasspathEquals(resolvedClasspath,
+ "/P[CPE_SOURCE][K_SOURCE][isExported:false]\n" +
+ ""+ getExternalJCLPathString() + "[CPE_LIBRARY][K_BINARY][isExported:false]\n" +
+ "/P/lib3.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib4.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib1.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib5.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib2.jar[CPE_LIBRARY][K_BINARY][isExported:true]");
+
+ //Remove the first jar entirely from the classpath
+ IClasspathEntry[] newRawClasspath = new IClasspathEntry[rawClasspath.length-1];
+ System.arraycopy(rawClasspath, 0, newRawClasspath, 0, 2);
+ System.arraycopy(rawClasspath, 3, newRawClasspath, 2, 1);
+ p.setRawClasspath(newRawClasspath, null);
+ resolvedClasspath = p.getResolvedClasspath(true);
+ assertClasspathEquals(resolvedClasspath,
+ "/P[CPE_SOURCE][K_SOURCE][isExported:false]\n" +
+ ""+ getExternalJCLPathString() + "[CPE_LIBRARY][K_BINARY][isExported:false]\n" +
+ "/P/lib3.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib5.jar[CPE_LIBRARY][K_BINARY][isExported:true]\n" +
+ "/P/lib2.jar[CPE_LIBRARY][K_BINARY][isExported:true]");
+ } finally {
+ deleteProject("P");
+ }
+}
}
#P org.eclipse.jdt.ui
Index: ui/org/eclipse/jdt/internal/ui/wizards/buildpaths/CPListElement.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/wizards/buildpaths/CPListElement.java,v
retrieving revision 1.79
diff -u -r1.79 CPListElement.java
--- ui/org/eclipse/jdt/internal/ui/wizards/buildpaths/CPListElement.java 14 Feb 2009 07:57:06 -0000 1.79
+++ ui/org/eclipse/jdt/internal/ui/wizards/buildpaths/CPListElement.java 4 Feb 2010 07:36:27 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -49,7 +49,8 @@
public static final String OUTPUT= "output"; //$NON-NLS-1$
public static final String EXCLUSION= "exclusion"; //$NON-NLS-1$
public static final String INCLUSION= "inclusion"; //$NON-NLS-1$
-
+ public static final String CHAINED_JARS= "chainedjars"; //$NON-NLS-1$
+ public static final String EXCLUDE_CHAINS="exclude_chains"; //$NON-NLS-1$
public static final String ACCESSRULES= "accessrules"; //$NON-NLS-1$
public static final String COMBINE_ACCESSRULES= "combineaccessrules"; //$NON-NLS-1$
@@ -112,6 +113,9 @@
createAttributeElement(NATIVE_LIB_PATH, null, false);
break;
case IClasspathEntry.CPE_LIBRARY:
+ createAttributeElement(CHAINED_JARS, null, true);
+ createAttributeElement(EXCLUDE_CHAINS, Boolean.FALSE, true);
+ //$FALL-THROUGH$
case IClasspathEntry.CPE_VARIABLE:
createAttributeElement(SOURCEATTACHMENT, null, true);
createAttributeElement(JAVADOC, null, false);
@@ -185,8 +189,10 @@
return JavaCore.newSourceEntry(fPath, inclusionPattern, exclusionPattern, outputLocation, extraAttributes);
case IClasspathEntry.CPE_LIBRARY: {
IPath attach= (IPath) getAttribute(SOURCEATTACHMENT);
+ IClasspathEntry[] referencedJars = (IClasspathEntry[]) getAttribute(CHAINED_JARS);
+ boolean excludeChainedJars = ((Boolean) getAttribute(EXCLUDE_CHAINS)).booleanValue();
IAccessRule[] accesRules= (IAccessRule[]) getAttribute(ACCESSRULES);
- return JavaCore.newLibraryEntry(fPath, attach, null, accesRules, extraAttributes, isExported());
+ return JavaCore.newLibraryEntry(fPath, attach, null, referencedJars, excludeChainedJars, accesRules, extraAttributes, isExported());
}
case IClasspathEntry.CPE_PROJECT: {
IAccessRule[] accesRules= (IAccessRule[]) getAttribute(ACCESSRULES);
@@ -625,6 +631,8 @@
elem.setAttribute(INCLUSION, curr.getInclusionPatterns());
elem.setAttribute(ACCESSRULES, curr.getAccessRules());
elem.setAttribute(COMBINE_ACCESSRULES, new Boolean(curr.combineAccessRules()));
+ elem.setAttribute(CHAINED_JARS, curr.getChainedEntries());
+ elem.setAttribute(EXCLUDE_CHAINS, new Boolean(curr.excludeChainedJars()));
IClasspathAttribute[] extraAttributes= curr.getExtraAttributes();
for (int i= 0; i < extraAttributes.length; i++) {
@@ -709,6 +717,8 @@
appendEncodedAccessRules((IAccessRule[]) elem.getValue(), buf).append(';');
} else if (COMBINE_ACCESSRULES.equals(key)) {
buf.append(((Boolean) elem.getValue()).booleanValue()).append(';');
+ } else if (EXCLUDE_CHAINS.equals(key)) {
+ buf.append(((Boolean) elem.getValue()).booleanValue()).append(';');
}
} else {
appendEncodedString((String) elem.getValue(), buf);