### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java,v retrieving revision 1.42 diff -u -r1.42 ClasspathInitializerTests.java --- src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java 10 Jan 2007 18:13:53 -0000 1.42 +++ src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java 18 Jan 2007 14:27:15 -0000 @@ -19,6 +19,7 @@ import org.eclipse.jdt.core.*; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.core.JavaModelManager; +import org.eclipse.jdt.internal.core.JavaModelStatus; import org.eclipse.jdt.internal.core.UserLibraryClasspathContainer; import org.eclipse.jdt.internal.core.UserLibraryManager; @@ -1088,6 +1089,122 @@ } /** + * @bug 138599: [model][classpath] Need a way to mark a classpath variable as deprecated + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=138599" + */ +public void testVariableInitializerDeprecated() throws CoreException { + try { + // Create initializer + String varName = "TEST_DEPRECATED"; + String filePath = "/P1/lib.jar"; + VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] {varName, filePath})); + assertEquals("JavaCore classpath value should have been initialized", JavaCore.getClasspathVariable(varName).toString(), filePath); + + // Verify that Classpath Variable is deprecated + assertEquals("JavaCore classpath variable should be deprecated", "Test deprecated flag", JavaCore.getClasspathVariableDeprecationMessage(varName)); + + // Create project + IJavaProject project = createJavaProject("P1"); + createFile("/P1/lib.jar", ""); + IClasspathEntry variable = JavaCore.newVariableEntry(new Path("TEST_DEPRECATED"), null, null); + IJavaModelStatus status = JavaConventions.validateClasspathEntry(project, variable, false); + assertStatus("Classpath variable 'TEST_DEPRECATED' in project P1 is deprecated: 'Test deprecated flag'", status); + assertFalse("Status should not be OK", status.isOK()); + assertEquals("Status should have WARNING severity", IStatus.WARNING, status.getSeverity()); + assertEquals("Status should have deprecated code", IJavaModelStatusConstants.DEPRECATED_VARIABLE, status.getCode()); + } finally { + VariablesInitializer.reset(); + deleteProject("P1"); + } +} +public void testVariableInitializerUnboundAndDeprecated() throws CoreException { + try { + // Create initializer + String varName = "TEST_DEPRECATED"; + String filePath = "/P1/lib.jar"; + VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] {varName, filePath})); + assertEquals("JavaCore classpath value should have been initialized", JavaCore.getClasspathVariable(varName).toString(), filePath); + + // Verify that Classpath Variable is deprecated + assertEquals("JavaCore classpath variable should be deprecated", "Test deprecated flag", JavaCore.getClasspathVariableDeprecationMessage(varName)); + + // Create project + IJavaProject project = createJavaProject("P1"); + IClasspathEntry variable = JavaCore.newVariableEntry(new Path("TEST_DEPRECATED"), null, null); + IJavaModelStatus status = JavaConventions.validateClasspathEntry(project, variable, false); + assertStatus("Project P1 is missing required library: 'lib.jar'", status); + assertFalse("Status should not be OK", status.isOK()); + assertEquals("Status should have WARNING severity", IStatus.ERROR, status.getSeverity()); + assertEquals("Status should have deprecated code", IJavaModelStatusConstants.INVALID_CLASSPATH, status.getCode()); + } finally { + VariablesInitializer.reset(); + deleteProject("P1"); + } +} + +/** + * @bug 156226: [model][classpath] Allow classpath variable to be marked as non modifiable + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=156226" + */ +public void testVariableInitializerReadOnly() throws CoreException { + try { + // Create initializer + String varName = "TEST_READ_ONLY"; + String path = "/P1/lib.jar"; + VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] { varName, path })); + assertEquals("JavaCore classpath value should have been initialized", JavaCore.getClasspathVariable(varName).toString(), path); + + // verify that Classpath Variable is read-only + assertTrue("JavaCore classpath variable should be read-only", JavaCore.isClasspathVariableReadOnly(varName)); + + // Create project + IJavaProject project = createJavaProject("P1"); + createFile("/P1/lib.jar", ""); + IClasspathEntry variable = JavaCore.newVariableEntry(new Path("TEST_READ_ONLY"), null, null); + IJavaModelStatus status = JavaConventions.validateClasspathEntry(project, variable, false); + assertStatus("Classpath variable 'TEST_READ_ONLY' in project P1 is read only", status); + assertFalse("Status should not be OK", status.isOK()); + assertEquals("Status should have WARNING severity", IStatus.WARNING, status.getSeverity()); + assertEquals("Status should have deprecated code", IJavaModelStatusConstants.READ_ONLY_VARIABLE, status.getCode()); + } finally { + VariablesInitializer.reset(); + deleteProject("P1"); + } +} +public void testVariableInitializerDeprecatedAndReadOnly() throws CoreException { + try { + // Create initializer + String varName = "TEST_DEPRECATED_READ_ONLY"; + String path = "/P1/lib.jar"; + VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] { varName, path })); + assertEquals("JavaCore classpath value should have been initialized", JavaCore.getClasspathVariable(varName).toString(), path); + + // verify that Classpath Variable is read-only + assertEquals("JavaCore classpath variable should be deprecated", "A deprecated and read-only initializer", JavaCore.getClasspathVariableDeprecationMessage(varName)); + assertTrue("JavaCore classpath variable should be read-only", JavaCore.isClasspathVariableReadOnly(varName)); + + // Create project + IJavaProject project = createJavaProject("P1"); + createFile("/P1/lib.jar", ""); + IClasspathEntry variable = JavaCore.newVariableEntry(new Path("TEST_DEPRECATED_READ_ONLY"), null, null); + IJavaModelStatus status = JavaConventions.validateClasspathEntry(project, variable, false); + assertStatus("Several warnings/errors occured", status); + assertTrue("Wrong kind of status", status instanceof JavaModelStatus); + JavaModelStatus jms = (JavaModelStatus) status; + IStatus[] children = jms.getChildren(); + assertEquals("Wrong number of children for multi-status", 2, children.length); + assertStatus("Classpath variable 'TEST_DEPRECATED_READ_ONLY' in project P1 is deprecated: 'A deprecated and read-only initializer'", children[0]); + assertStatus("Classpath variable 'TEST_DEPRECATED_READ_ONLY' in project P1 is read only", children[1]); + assertFalse("Status should not be OK", status.isOK()); + assertEquals("Status should have WARNING severity", IStatus.WARNING, status.getSeverity()); + assertEquals("Status should have deprecated code", IJavaModelStatusConstants.DEPRECATED_VARIABLE, status.getCode()); + } finally { + VariablesInitializer.reset(); + deleteProject("P1"); + } +} + +/** * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=61872" */ public void testUserLibraryInitializer1() throws CoreException { 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.157 diff -u -r1.157 ClasspathTests.java --- src/org/eclipse/jdt/core/tests/model/ClasspathTests.java 17 Jan 2007 20:54:42 -0000 1.157 +++ src/org/eclipse/jdt/core/tests/model/ClasspathTests.java 18 Jan 2007 14:27:16 -0000 @@ -35,7 +35,6 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IAccessRule; import org.eclipse.jdt.core.IClasspathAttribute; @@ -128,22 +127,6 @@ entry, decoded); } -protected void assertStatus(String expected, IStatus status) { - String actual = status.getMessage(); - if (!expected.equals(actual)) { - System.out.print(Util.displayString(actual, 2)); - System.out.println(","); - } - assertEquals(expected, actual); -} -protected void assertStatus(String message, String expected, IStatus status) { - String actual = status.getMessage(); - if (!expected.equals(actual)) { - System.out.print(Util.displayString(actual, 2)); - System.out.println(","); - } - assertEquals(message, expected, actual); -} protected File createFile(File parent, String name, String content) throws IOException { File file = new File(parent, name); FileOutputStream out = new FileOutputStream(file); @@ -1795,6 +1778,7 @@ this.deleteProject("P2"); } } + /** * Adding an entry to the classpath for a library that does not exist * should not break the model. The classpath should contain the Index: src/org/eclipse/jdt/core/tests/model/ModifyingResourceTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModifyingResourceTests.java,v retrieving revision 1.45 diff -u -r1.45 ModifyingResourceTests.java --- src/org/eclipse/jdt/core/tests/model/ModifyingResourceTests.java 20 Dec 2006 16:11:55 -0000 1.45 +++ src/org/eclipse/jdt/core/tests/model/ModifyingResourceTests.java 18 Jan 2007 14:27:16 -0000 @@ -20,9 +20,6 @@ import org.eclipse.jdt.internal.compiler.batch.Main; import org.eclipse.jdt.internal.core.JavaElement; -/* - * Tests that modify resources in the workspace. - */ public class ModifyingResourceTests extends AbstractJavaModelTests { public ModifyingResourceTests(String name) { @@ -38,6 +35,22 @@ expected, actual); } +protected void assertStatus(String expected, IStatus status) { + String actual = status.getMessage(); + if (!expected.equals(actual)) { + System.out.print(Util.displayString(actual, 2)); + System.out.println(","); + } + assertEquals(expected, actual); +} +protected void assertStatus(String message, String expected, IStatus status) { + String actual = status.getMessage(); + if (!expected.equals(actual)) { + System.out.print(Util.displayString(actual, 2)); + System.out.println(","); + } + assertEquals(message, expected, actual); +} /** * E.g. * org.eclipse.jdt.tests.core.ModifyingResourceTests.generateClassFile( Index: plugin.xml =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/plugin.xml,v retrieving revision 1.29 diff -u -r1.29 plugin.xml --- plugin.xml 19 Oct 2006 02:47:24 -0000 1.29 +++ plugin.xml 18 Jan 2007 14:27:14 -0000 @@ -12,6 +12,22 @@ + + + + + + #P org.eclipse.jdt.core Index: model/org/eclipse/jdt/core/IJavaModelStatusConstants.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java,v retrieving revision 1.37 diff -u -r1.37 IJavaModelStatusConstants.java --- model/org/eclipse/jdt/core/IJavaModelStatusConstants.java 10 May 2006 18:03:42 -0000 1.37 +++ model/org/eclipse/jdt/core/IJavaModelStatusConstants.java 18 Jan 2007 14:27:20 -0000 @@ -320,4 +320,16 @@ * @since 3.2 */ public static final int UNKNOWN_JAVADOC_FORMAT = 1009; + /** + *

Status constant indicating that the variable is deprecated.

+ * + * @since 3.3 + */ + public static final int DEPRECATED_VARIABLE = 1010; + /** + *

Status constant indicating that the variable is read-only.

+ * + * @since 3.3 + */ + public static final int READ_ONLY_VARIABLE = 1011; } 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.59 diff -u -r1.59 IClasspathEntry.java --- model/org/eclipse/jdt/core/IClasspathEntry.java 29 Sep 2006 17:13:57 -0000 1.59 +++ model/org/eclipse/jdt/core/IClasspathEntry.java 18 Jan 2007 14:27:20 -0000 @@ -15,7 +15,7 @@ /** * An entry on a Java project classpath identifying one or more package fragment * roots. A classpath entry has a content kind (either source, - * K_SOURCE, or binary, K_BINARY), which is inherited + * {@link IPackageFragmentRoot#K_SOURCE}, or binary, {@link IPackageFragmentRoot#K_BINARY}), which is inherited * by each package fragment root and package fragment associated with the entry. *

* A classpath entry can refer to any of the following:

*

- * The result of IJavaProject#getResolvedClasspath will have all entries of type - * CPE_VARIABLE and CPE_CONTAINER resolved to a set of - * CPE_SOURCE, CPE_LIBRARY or CPE_PROJECT + * The result of {@link IJavaProject#getResolvedClasspath} will have all entries of type + * {@link #CPE_VARIABLE} and {@link #CPE_CONTAINER} resolved to a set of + * {@link #CPE_SOURCE}, {@link #CPE_LIBRARY} or {@link #CPE_PROJECT} * classpath entries. *

- * Any classpath entry other than a source folder (kind CPE_SOURCE) can + * Any classpath entry other than a source folder (kind {@link #CPE_SOURCE}) can * be marked as being exported. Exported entries are automatically contributed to * dependent projects, along with the project's default output folder, which is * implicitly exported, and any auxiliary output folders specified on source @@ -102,7 +102,7 @@ * followed by the any exported entries. *

* This interface is not intended to be implemented by clients. - * Classpath entries can be created via methods on JavaCore. + * Classpath entries can be created via methods on {@link JavaCore}. *

* * @see JavaCore#newLibraryEntry(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) @@ -170,11 +170,11 @@ * Returns the kind of files found in the package fragments identified by this * classpath entry. * - * @return IPackageFragmentRoot.K_SOURCE for files containing - * source code, and IPackageFragmentRoot.K_BINARY for binary + * @return {@link IPackageFragmentRoot#K_SOURCE} for files containing + * source code, and {@link IPackageFragmentRoot#K_BINARY} for binary * class files. - * There is no specified value for an entry denoting a variable (CPE_VARIABLE) - * or a classpath container (CPE_CONTAINER). + * There is no specified value for an entry denoting a variable ({@link #CPE_VARIABLE}) + * or a classpath container ({@link #CPE_CONTAINER}). */ int getContentKind(); @@ -183,16 +183,16 @@ * * @return one of: * */ @@ -344,11 +344,11 @@ /** * Returns the full path to the specific location where the builder writes * .class files generated for this source entry - * (entry kind CPE_SOURCE). + * (entry kind {@link #CPE_SOURCE}). *

* Source entries can optionally be associated with a specific output location. * If none is provided, the source entry will be implicitly associated with its project - * default output location (see IJavaProject#getOutputLocation). + * default output location (see {@link IJavaProject#getOutputLocation}). *

* NOTE: A specific output location cannot coincidate with another source/library entry. *

@@ -364,24 +364,24 @@ * Returns the path of this classpath entry. * * The meaning of the path of a classpath entry depends on its entry kind: * @@ -410,7 +410,7 @@ * Returns the path within the source archive or folder where package fragments * are located. An empty path indicates that packages are located at * the root of the source archive or folder. Returns a non-null value - * if and only if getSourceAttachmentPath returns + * if and only if {@link #getSourceAttachmentPath} returns * a non-null value. * * @return the path within the source archive or folder, or null if @@ -421,7 +421,7 @@ /** * Returns whether this entry is exported to dependent projects. * Always returns false for source entries (kind - * CPE_SOURCE), which cannot be exported. + * {@link #CPE_SOURCE}), which cannot be exported. * * @return true if exported, and false otherwise * @since 2.0 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.559 diff -u -r1.559 JavaCore.java --- model/org/eclipse/jdt/core/JavaCore.java 12 Jan 2007 17:58:48 -0000 1.559 +++ model/org/eclipse/jdt/core/JavaCore.java 18 Jan 2007 14:27:22 -0000 @@ -1669,6 +1669,17 @@ } /** + * Returns deprecation message of a given classpath variable. + * + * @param variableName + * @return A string if the classpath variable is deprecated, null otherwise. + * @since 3.3 + */ + public static String getClasspathVariableDeprecationMessage(String variableName) { + return (String) JavaModelManager.getJavaModelManager().deprecatedVariables.get(variableName); + } + + /** * Helper method finding the classpath variable initializer registered for a given classpath variable name * or null if none was found while iterating over the contributions to extension point to * the extension point "org.eclipse.jdt.core.classpathVariableInitializer". @@ -1690,7 +1701,8 @@ IConfigurationElement [] configElements = extensions[i].getConfigurationElements(); for(int j = 0; j < configElements.length; j++){ try { - String varAttribute = configElements[j].getAttribute("variable"); //$NON-NLS-1$ + IConfigurationElement configElement = configElements[j]; + String varAttribute = configElement.getAttribute("variable"); //$NON-NLS-1$ if (variable.equals(varAttribute)) { if (JavaModelManager.CP_RESOLVE_VERBOSE) { Util.verbose( @@ -1700,7 +1712,16 @@ } Object execExt = configElements[j].createExecutableExtension("class"); //$NON-NLS-1$ if (execExt instanceof ClasspathVariableInitializer){ - return (ClasspathVariableInitializer)execExt; + ClasspathVariableInitializer initializer = (ClasspathVariableInitializer)execExt; + String deprecatedAttribute = configElement.getAttribute("deprecated"); //$NON-NLS-1$ + if (deprecatedAttribute != null) { + JavaModelManager.getJavaModelManager().deprecatedVariables.put(variable, deprecatedAttribute); + } + String readOnlyAttribute = configElement.getAttribute("readOnly"); //$NON-NLS-1$ + if (JavaModelManager.TRUE.equals(readOnlyAttribute)) { + JavaModelManager.getJavaModelManager().readOnlyVariables.add(variable); + } + return initializer; } } } catch(CoreException e){ @@ -3012,7 +3033,19 @@ if (monitor != null) monitor.done(); } } - + + /** + * Returns whether a given classpath variable is read-only or not. + * + * @param variableName + * @return true if the classpath variable is read-only, + * false otherwise. + * @since 3.3 + */ + public static boolean isClasspathVariableReadOnly(String variableName) { + return JavaModelManager.getJavaModelManager().readOnlyVariables.contains(variableName); + } + /** * Returns whether the given file name's extension is a Java-like extension. * @@ -3023,7 +3056,7 @@ public static boolean isJavaLikeFileName(String fileName) { return Util.isJavaLikeFileName(fileName); } - + /** * Returns whether the given marker references the given Java element. * Used for markers, which denote a Java element rather than a resource. Index: model/org/eclipse/jdt/internal/core/JavaModelOperation.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java,v retrieving revision 1.64 diff -u -r1.64 JavaModelOperation.java --- model/org/eclipse/jdt/internal/core/JavaModelOperation.java 23 Nov 2005 15:41:57 -0000 1.64 +++ model/org/eclipse/jdt/internal/core/JavaModelOperation.java 18 Jan 2007 14:27:23 -0000 @@ -61,7 +61,7 @@ protected HashMap attributes; public static final String HAS_MODIFIED_RESOURCE_ATTR = "hasModifiedResource"; //$NON-NLS-1$ - public static final String TRUE = "true"; //$NON-NLS-1$ + public static final String TRUE = JavaModelManager.TRUE; //public static final String FALSE = "false"; /** Index: model/org/eclipse/jdt/internal/core/JavaModelStatus.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelStatus.java,v retrieving revision 1.42 diff -u -r1.42 JavaModelStatus.java --- model/org/eclipse/jdt/internal/core/JavaModelStatus.java 29 Mar 2006 03:08:48 -0000 1.42 +++ model/org/eclipse/jdt/internal/core/JavaModelStatus.java 18 Jan 2007 14:27:24 -0000 @@ -126,7 +126,7 @@ this(code, new IJavaElement[]{element}); this.string = string; } - + /** * Constructs an Java model status with the given corresponding * element and path @@ -134,7 +134,19 @@ public JavaModelStatus(int code, IJavaElement element, IPath path) { this(code, new IJavaElement[]{element}); this.path = path; - } + } + + /** + * Constructs an Java model status with the given corresponding + * element and path + */ + public JavaModelStatus(int severity, int code, IJavaElement element, IPath path, String msg) { + super(severity, JavaCore.PLUGIN_ID, code, "JavaModelStatus", null); //$NON-NLS-1$ + this.elements= new IJavaElement[]{element}; + this.path = path; + this.string = msg; + } + /** * Constructs an Java model status with the given corresponding * element, path and string @@ -172,6 +184,9 @@ * Returns the message that is relevant to the code of this status. */ public String getMessage() { + if (isMultiStatus()) { + return Messages.status_multiple; + } Throwable exception = getException(); if (exception == null) { switch (getCode()) { @@ -326,53 +341,63 @@ if (description == null) description = path.makeRelative().toString(); return Messages.bind(Messages.classpath_invalidContainer, new String[] {description, javaProject.getElementName()}); - case CP_VARIABLE_PATH_UNBOUND: - javaProject = (IJavaProject)elements[0]; - return Messages.bind(Messages.classpath_unboundVariablePath, new String[] {path.makeRelative().toString(), javaProject.getElementName()}); - - case CLASSPATH_CYCLE: - javaProject = (IJavaProject)elements[0]; - return Messages.bind(Messages.classpath_cycle, javaProject.getElementName()); - - case DISABLED_CP_EXCLUSION_PATTERNS: - javaProject = (IJavaProject)elements[0]; - String projectName = javaProject.getElementName(); - IPath newPath = path; - if (path.segment(0).toString().equals(projectName)) { - newPath = path.removeFirstSegments(1); - } - return Messages.bind(Messages.classpath_disabledInclusionExclusionPatterns, new String[] {newPath.makeRelative().toString(), projectName}); - - case DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS: - javaProject = (IJavaProject)elements[0]; - projectName = javaProject.getElementName(); - newPath = path; - if (path.segment(0).toString().equals(projectName)) { - newPath = path.removeFirstSegments(1); - } - return Messages.bind(Messages.classpath_disabledMultipleOutputLocations, new String[] {newPath.makeRelative().toString(), projectName}); + case CP_VARIABLE_PATH_UNBOUND: + javaProject = (IJavaProject)elements[0]; + return Messages.bind(Messages.classpath_unboundVariablePath, new String[] {path.makeRelative().toString(), javaProject.getElementName()}); + + case CLASSPATH_CYCLE: + javaProject = (IJavaProject)elements[0]; + return Messages.bind(Messages.classpath_cycle, javaProject.getElementName()); - case INCOMPATIBLE_JDK_LEVEL: + case DISABLED_CP_EXCLUSION_PATTERNS: javaProject = (IJavaProject)elements[0]; - return Messages.bind(Messages.classpath_incompatibleLibraryJDKLevel, new String[]{ - javaProject.getElementName(), - javaProject.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true), - path.makeRelative().toString(), - string, - }); - case CANNOT_RETRIEVE_ATTACHED_JAVADOC : - if (elements != null && elements.length == 1) { + String projectName = javaProject.getElementName(); + IPath newPath = path; + if (path.segment(0).toString().equals(projectName)) { + newPath = path.removeFirstSegments(1); + } + return Messages.bind(Messages.classpath_disabledInclusionExclusionPatterns, new String[] {newPath.makeRelative().toString(), projectName}); + + case DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS: + javaProject = (IJavaProject)elements[0]; + projectName = javaProject.getElementName(); + newPath = path; + if (path.segment(0).toString().equals(projectName)) { + newPath = path.removeFirstSegments(1); + } + return Messages.bind(Messages.classpath_disabledMultipleOutputLocations, new String[] {newPath.makeRelative().toString(), projectName}); + + case INCOMPATIBLE_JDK_LEVEL: + javaProject = (IJavaProject)elements[0]; + return Messages.bind(Messages.classpath_incompatibleLibraryJDKLevel, new String[]{ + javaProject.getElementName(), + javaProject.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true), + path.makeRelative().toString(), + string, + }); + + case CANNOT_RETRIEVE_ATTACHED_JAVADOC : + if (elements != null && elements.length == 1) { + if (this.string != null) { + return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, ((JavaElement)elements[0]).toStringWithAncestors(), this.string); + } + return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, ((JavaElement)elements[0]).toStringWithAncestors(), ""); //$NON-NLS-1$ + } if (this.string != null) { - return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, ((JavaElement)elements[0]).toStringWithAncestors(), this.string); + return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, this.string, "");//$NON-NLS-1$ } - return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, ((JavaElement)elements[0]).toStringWithAncestors(), ""); //$NON-NLS-1$ - } - if (this.string != null) { - return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, this.string, "");//$NON-NLS-1$ - } - break; - case UNKNOWN_JAVADOC_FORMAT : - return Messages.bind(Messages.status_unknown_javadoc_format, ((JavaElement)elements[0]).toStringWithAncestors()); + break; + + case UNKNOWN_JAVADOC_FORMAT : + return Messages.bind(Messages.status_unknown_javadoc_format, ((JavaElement)elements[0]).toStringWithAncestors()); + + case DEPRECATED_VARIABLE : + javaProject = (IJavaProject)elements[0]; + return Messages.bind(Messages.classpath_deprecated_variable, new String[] {path.segment(0).toString(), javaProject.getElementName(), this.string}); + + case READ_ONLY_VARIABLE : + javaProject = (IJavaProject)elements[0]; + return Messages.bind(Messages.classpath_read_only_variable, new String[] {path.segment(0).toString(), javaProject.getElementName()}); } if (string != null) { return string; @@ -466,6 +491,10 @@ public static IJavaModelStatus newMultiStatus(IJavaModelStatus[] children) { JavaModelStatus jms = new JavaModelStatus(); jms.children = children; + if (children != null && children.length > 0) { + // set the code to first child otherwise the status will be OK... + jms.setCode(children[0].getCode()); + } return jms; } /** 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.94 diff -u -r1.94 ClasspathEntry.java --- model/org/eclipse/jdt/internal/core/ClasspathEntry.java 3 Oct 2006 09:43:27 -0000 1.94 +++ model/org/eclipse/jdt/internal/core/ClasspathEntry.java 18 Jan 2007 14:27:22 -0000 @@ -26,6 +26,7 @@ import org.eclipse.core.runtime.AssertionFailedException; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IAccessRule; import org.eclipse.jdt.core.IClasspathAttribute; @@ -1627,7 +1628,29 @@ if (entry == null){ return new JavaModelStatus(IJavaModelStatusConstants.CP_VARIABLE_PATH_UNBOUND, project, path); } - return validateClasspathEntry(project, entry, checkSourceAttachment, recurseInContainers); + + // get validation status + IJavaModelStatus status = validateClasspathEntry(project, entry, checkSourceAttachment, recurseInContainers); + if (!status.isOK()) return status; + + // add deprecation and read-only status if any + String variableName = path.segment(0); + String deprecatedMessage = JavaCore.getClasspathVariableDeprecationMessage(variableName); + if (deprecatedMessage != null) { + if (JavaCore.isClasspathVariableReadOnly(variableName)) { + return JavaModelStatus.newMultiStatus( + new IJavaModelStatus[] { + new JavaModelStatus(IStatus.WARNING, IJavaModelStatusConstants.DEPRECATED_VARIABLE, project, path, deprecatedMessage), + new JavaModelStatus(IStatus.WARNING, IJavaModelStatusConstants.READ_ONLY_VARIABLE, project, path, null) + } + ); + } else { + return new JavaModelStatus(IStatus.WARNING, IJavaModelStatusConstants.DEPRECATED_VARIABLE, project, path, deprecatedMessage); + } + } else if (JavaCore.isClasspathVariableReadOnly(variableName)) { + return new JavaModelStatus(IStatus.WARNING, IJavaModelStatusConstants.READ_ONLY_VARIABLE, project, path, null); + } + return status; } else { return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalVariablePath, new String[] {entryPathMsg, projectName})); } Index: model/org/eclipse/jdt/internal/core/JavaModelManager.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java,v retrieving revision 1.350 diff -u -r1.350 JavaModelManager.java --- model/org/eclipse/jdt/internal/core/JavaModelManager.java 12 Jan 2007 17:58:49 -0000 1.350 +++ model/org/eclipse/jdt/internal/core/JavaModelManager.java 18 Jan 2007 14:27:23 -0000 @@ -87,9 +87,11 @@ */ public HashMap variables = new HashMap(5); public HashSet variablesWithInitializer = new HashSet(5); + public HashMap deprecatedVariables = new HashMap(5); + public HashSet readOnlyVariables = new HashSet(5); public HashMap previousSessionVariables = new HashMap(5); private ThreadLocal variableInitializationInProgress = new ThreadLocal(); - + /** * Classpath containers pool */ @@ -120,6 +122,7 @@ public final static String CP_CONTAINER_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".classpathContainer."; //$NON-NLS-1$ public final static String CP_ENTRY_IGNORE = "####"; //$NON-NLS-1$ public final static IPath CP_ENTRY_IGNORE_PATH = new Path(CP_ENTRY_IGNORE); + public final static String TRUE = "true"; //$NON-NLS-1$ private final static int VARIABLES_AND_CONTAINERS_FILE_VERSION = 2; @@ -278,9 +281,9 @@ continue; } // add config element in the group it belongs to - if ("true".equals(configElement.getAttribute("modifiesEnvironment"))) //$NON-NLS-1$ //$NON-NLS-2$ + if (TRUE.equals(configElement.getAttribute("modifiesEnvironment"))) //$NON-NLS-1$ modifyingEnv.add(configElement); - else if ("true".equals(configElement.getAttribute("createsProblems"))) //$NON-NLS-1$ //$NON-NLS-2$ + else if (TRUE.equals(configElement.getAttribute("createsProblems"))) //$NON-NLS-1$ creatingProblems.add(configElement); else others.add(configElement); @@ -1200,58 +1203,58 @@ public void configurePluginDebugOptions(){ if(JavaCore.getPlugin().isDebugging()){ String option = Platform.getDebugOption(BUFFER_MANAGER_DEBUG); - if(option != null) BufferManager.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) BufferManager.VERBOSE = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(BUILDER_DEBUG); - if(option != null) JavaBuilder.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) JavaBuilder.DEBUG = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(COMPILER_DEBUG); - if(option != null) Compiler.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) Compiler.DEBUG = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(COMPLETION_DEBUG); - if(option != null) CompletionEngine.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) CompletionEngine.DEBUG = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(CP_RESOLVE_DEBUG); - if(option != null) JavaModelManager.CP_RESOLVE_VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) JavaModelManager.CP_RESOLVE_VERBOSE = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(DELTA_DEBUG); - if(option != null) DeltaProcessor.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) DeltaProcessor.DEBUG = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(DELTA_DEBUG_VERBOSE); - if(option != null) DeltaProcessor.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) DeltaProcessor.VERBOSE = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(HIERARCHY_DEBUG); - if(option != null) TypeHierarchy.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) TypeHierarchy.DEBUG = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(INDEX_MANAGER_DEBUG); - if(option != null) JobManager.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) JobManager.VERBOSE = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(JAVAMODEL_DEBUG); - if(option != null) JavaModelManager.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) JavaModelManager.VERBOSE = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(JAVAMODELCACHE_DEBUG); - if(option != null) JavaModelCache.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) JavaModelCache.VERBOSE = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(POST_ACTION_DEBUG); - if(option != null) JavaModelOperation.POST_ACTION_VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) JavaModelOperation.POST_ACTION_VERBOSE = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(RESOLUTION_DEBUG); - if(option != null) NameLookup.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) NameLookup.VERBOSE = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(SEARCH_DEBUG); - if(option != null) BasicSearchEngine.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) BasicSearchEngine.VERBOSE = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(SELECTION_DEBUG); - if(option != null) SelectionEngine.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) SelectionEngine.DEBUG = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(ZIP_ACCESS_DEBUG); - if(option != null) JavaModelManager.ZIP_ACCESS_VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) JavaModelManager.ZIP_ACCESS_VERBOSE = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(SOURCE_MAPPER_DEBUG_VERBOSE); - if(option != null) SourceMapper.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) SourceMapper.VERBOSE = option.equalsIgnoreCase(TRUE) ; option = Platform.getDebugOption(ENABLE_NEW_FORMATTER); - if(option != null) DefaultCodeFormatter.USE_NEW_FORMATTER = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) DefaultCodeFormatter.USE_NEW_FORMATTER = option.equalsIgnoreCase(TRUE) ; } // configure performance options @@ -3950,7 +3953,7 @@ // Note: no need to close the Java model as this just removes Java element infos from the Java model cache } - + public synchronized IPath variableGet(String variableName){ // check initialization in progress first HashSet initializations = variableInitializationInProgress(); Index: schema/classpathVariableInitializer.exsd =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd,v retrieving revision 1.6 diff -u -r1.6 classpathVariableInitializer.exsd --- schema/classpathVariableInitializer.exsd 24 May 2005 14:25:21 -0000 1.6 +++ schema/classpathVariableInitializer.exsd 18 Jan 2007 14:27:24 -0000 @@ -63,6 +63,23 @@ + + + + String explaining the reason why the associated variable is deprecated + + + + + + + + + + Indicates that the associated variable cannot be modified + + + Index: buildnotes_jdt-core.html =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/buildnotes_jdt-core.html,v retrieving revision 1.5635 diff -u -r1.5635 buildnotes_jdt-core.html --- buildnotes_jdt-core.html 16 Jan 2007 11:20:11 -0000 1.5635 +++ buildnotes_jdt-core.html 18 Jan 2007 14:27:20 -0000 @@ -43,6 +43,92 @@ + +


+Eclipse Platform Build Notes
+Java Development Tooling Core

+Eclipse SDK 3.3M5 - 16th January 2007 +
Project org.eclipse.jdt.core v_732 +(cvs). +

What's new in this drop

+
    +
  • Classpath variable may now be flagged as deprecated or read-only (see bug 138599 +and bug 156226).
    +Two new attributes have been added on ClasspathVariableInitializer schema: +
    +   <element name="classpathVariableInitializer">
    +      <complexType>
    +         ...
    +         <attribute name="deprecated" type="string">
    +            <annotation>
    +               <documentation>
    +                  String explaining the reason why the associated variable is deprecated
    +               </documentation>
    +               <appInfo>
    +                  <meta.attribute translatable="true"/>
    +               </appInfo>
    +            </annotation>
    +         </attribute>
    +         <attribute name="readOnly" type="boolean">
    +            <annotation>
    +               <documentation>
    +                  Indicates that the associated variable cannot be modified
    +               </documentation>
    +            </annotation>
    +         </attribute>
    +      </complexType>
    +   </element>
    +
    +When these attributes are set on ClasspathVariableInitializer extension point, classpath entry validation +returns a warning status if no other error was previously detected. +
    +For example, following classpathVariableInitializer extension point set +the TEST classpath variable as deprecated and read-only: +
    +   <extension
    +         point="org.eclipse.jdt.core.classpathVariableInitializer">
    +      <classpathVariableInitializer
    +            class="org.eclipse.jdt.tests.model.TestInitializer"
    +            deprecated="The reason why this variable is deprecated"
    +            readOnly="true"
    +            variable="TEST">
    +      </classpathVariableInitializer>
    +   </extension>
    +
    +Calling JavaConventions.validateClasspathEntry(IJavaProject, IClasspathEntry, boolean) +method on this variable entry will return a IStatus.WARNING multi-status with two children. +
    +Classpath variable deprecation message and read-only information are also accessible using two new added +JavaCore API methods: +
    +/**
    + * Returns deprecation message of a given classpath variable.
    + *
    + * @param variableName
    + * @return A string if the classpath variable is deprecated, null otherwise.
    + * @since 3.3
    + */
    +public static String getClasspathVariableDeprecationMessage(String variableName) 
    +
    +/**
    + * Returns whether a given classpath variable is read-only or not.
    + *
    + * @param variableName
    + * @return true if the classpath variable is read-only,
    + * 	false otherwise.
    + * @since 3.3
    + */
    +public static boolean isClasspathVariableReadOnly(String variableName)
    +
    +
  • +
+ +

Problem Reports Fixed

+156226 +[model][classpath] Allow classpath variable to be marked as non modifiable +
138599 +[model][classpath] Need a way to mark a classpath variable as deprecated +


Eclipse Platform Build Notes
Index: model/org/eclipse/jdt/internal/core/util/messages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties,v retrieving revision 1.62 diff -u -r1.62 messages.properties --- model/org/eclipse/jdt/internal/core/util/messages.properties 28 Jun 2006 08:52:07 -0000 1.62 +++ model/org/eclipse/jdt/internal/core/util/messages.properties 18 Jan 2007 14:27:24 -0000 @@ -117,6 +117,7 @@ status_invalidResource = Invalid resource: {0} status_invalidResourceType = Invalid resource type for {0} status_invalidSibling = Invalid sibling: {0} +status_multiple = Several warnings/errors occured status_nameCollision = {0} already exists in target status_noLocalContents = Cannot find local contents for resource: {0} status_OK = OK @@ -167,6 +168,8 @@ classpath_disabledMultipleOutputLocations = Multiple output locations are disabled in project {1}, cannot associate entry: ''{0}'' with a specific output classpath_incompatibleLibraryJDKLevel = Incompatible .class files version in required binaries. Project ''{0}'' is targeting a {1} runtime, but is compiled against ''{2}'' which requires a {3} runtime classpath_duplicateEntryExtraAttribute = Duplicate extra attribute: ''{0}'' in classpath entry ''{1}'' for project {2} +classpath_deprecated_variable = Classpath variable ''{0}'' in project {1} is deprecated: ''{2}'' +classpath_read_only_variable = Classpath variable ''{0}'' in project {1} is read only ### miscellaneous file_notFound = File not found: ''{0}'' Index: model/org/eclipse/jdt/internal/core/util/Messages.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java,v retrieving revision 1.14 diff -u -r1.14 Messages.java --- model/org/eclipse/jdt/internal/core/util/Messages.java 28 Jun 2006 08:52:07 -0000 1.14 +++ model/org/eclipse/jdt/internal/core/util/Messages.java 18 Jan 2007 14:27:24 -0000 @@ -114,6 +114,7 @@ public static String status_invalidResource; public static String status_invalidResourceType; public static String status_invalidSibling; + public static String status_multiple; public static String status_nameCollision; public static String status_noLocalContents; public static String status_OK; @@ -161,6 +162,8 @@ public static String classpath_disabledMultipleOutputLocations; public static String classpath_incompatibleLibraryJDKLevel; public static String classpath_duplicateEntryExtraAttribute; + public static String classpath_deprecated_variable; + public static String classpath_read_only_variable; public static String file_notFound; public static String file_badFormat; public static String path_nullPath;