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

Collapse All | Expand All

(-)model/org/eclipse/jdt/core/IJavaModelStatusConstants.java (+12 lines)
Lines 320-323 Link Here
320
	 * @since 3.2
320
	 * @since 3.2
321
	 */
321
	 */
322
	public static final int UNKNOWN_JAVADOC_FORMAT = 1009;
322
	public static final int UNKNOWN_JAVADOC_FORMAT = 1009;
323
	/**
324
	 * <p>Status constant indicating that the variable is deprecated.</p>
325
	 * 
326
	 * @since 3.3
327
	 */
328
	public static final int DEPRECATED_VARIABLE = 1010;
329
	/**
330
	 * <p>Status constant indicating that the variable is read-only.</p>
331
	 * 
332
	 * @since 3.3
333
	 */
334
	public static final int READ_ONLY_VARIABLE = 1011;
323
}
335
}
(-)model/org/eclipse/jdt/core/IClasspathEntry.java (-37 / +37 lines)
Lines 15-21 Link Here
15
/** 
15
/** 
16
 * An entry on a Java project classpath identifying one or more package fragment
16
 * An entry on a Java project classpath identifying one or more package fragment
17
 * roots. A classpath entry has a content kind (either source, 
17
 * roots. A classpath entry has a content kind (either source, 
18
 * <code>K_SOURCE</code>, or binary, <code>K_BINARY</code>), which is inherited
18
 * {@link IPackageFragmentRoot#K_SOURCE}, or binary, {@link IPackageFragmentRoot#K_BINARY}), which is inherited
19
 * by each package fragment root and package fragment associated with the entry.
19
 * by each package fragment root and package fragment associated with the entry.
20
 * <p>
20
 * <p>
21
 * A classpath entry can refer to any of the following:<ul>
21
 * A classpath entry can refer to any of the following:<ul>
Lines 29-35 Link Here
29
 *		represent compilation units. All compilation units will be compiled when
29
 *		represent compilation units. All compilation units will be compiled when
30
 * 		the project is built. The classpath entry must specify the
30
 * 		the project is built. The classpath entry must specify the
31
 *		absolute path to the root folder. Entries of this kind are 
31
 *		absolute path to the root folder. Entries of this kind are 
32
 *		associated with the <code>CPE_SOURCE</code> constant.
32
 *		associated with the {@link #CPE_SOURCE} constant.
33
 *      Source classpath entries can carry inclusion and exclusion patterns for
33
 *      Source classpath entries can carry inclusion and exclusion patterns for
34
 *      selecting which source files appear as compilation
34
 *      selecting which source files appear as compilation
35
 *      units and get compiled when the project is built.
35
 *      units and get compiled when the project is built.
Lines 40-46 Link Here
40
 *		package fragments and <code>.class</code> files.  The classpath entry
40
 *		package fragments and <code>.class</code> files.  The classpath entry
41
 *		must specify the absolute path to the JAR (or root folder), and in case it refers
41
 *		must specify the absolute path to the JAR (or root folder), and in case it refers
42
 *		to an external JAR, then there is no associated resource in the workbench. Entries 
42
 *		to an external JAR, then there is no associated resource in the workbench. Entries 
43
 *		of this kind are associated with the <code>CPE_LIBRARY</code> constant.</li>
43
 *		of this kind are associated with the {@link #CPE_LIBRARY} constant.</li>
44
 * 
44
 * 
45
 *	<li>A required project. In this case the entry identifies another project in
45
 *	<li>A required project. In this case the entry identifies another project in
46
 *		the workspace. The required project is used as a binary library when compiling
46
 *		the workspace. The required project is used as a binary library when compiling
Lines 51-100 Link Here
51
 *		is performed against a required project's source code, and compilation is 
51
 *		is performed against a required project's source code, and compilation is 
52
 *		performed against a required project's last built state.  The
52
 *		performed against a required project's last built state.  The
53
 *		classpath entry must specify the absolute path to the
53
 *		classpath entry must specify the absolute path to the
54
 *		project. Entries of this kind are  associated with the <code>CPE_PROJECT</code>
54
 *		project. Entries of this kind are  associated with the {@link #CPE_PROJECT}
55
 *		constant. 
55
 *		constant. 
56
 * 		Note: referencing a required project with a classpath entry refers to the source 
56
 * 		Note: referencing a required project with a classpath entry refers to the source 
57
 *     code or associated <code>.class</code> files located in its output location. 
57
 *     code or associated <code>.class</code> files located in its output location. 
58
 *     It will also automatically include any other libraries or projects that the required project's classpath 
58
 *     It will also automatically include any other libraries or projects that the required project's classpath 
59
 *     refers to, iff the corresponding classpath entries are tagged as being exported 
59
 *     refers to, iff the corresponding classpath entries are tagged as being exported 
60
 *     (<code>IClasspathEntry#isExported</code>). 
60
 *     ({@link IClasspathEntry#isExported}). 
61
 *    Unless exporting some classpath entries, classpaths are not chained by default - 
61
 *    Unless exporting some classpath entries, classpaths are not chained by default - 
62
 *    each project must specify its own classpath in its entirety.</li>
62
 *    each project must specify its own classpath in its entirety.</li>
63
 * 
63
 * 
64
 *  <li> A path beginning in a classpath variable defined globally to the workspace.
64
 *  <li> A path beginning in a classpath variable defined globally to the workspace.
65
 *		Entries of this kind are  associated with the <code>CPE_VARIABLE</code> constant.  
65
 *		Entries of this kind are  associated with the {@link #CPE_VARIABLE} constant.  
66
 *      Classpath variables are created using <code>JavaCore#setClasspathVariable</code>,
66
 *      Classpath variables are created using {@link JavaCore#setClasspathVariable(String, IPath, org.eclipse.core.runtime.IProgressMonitor)},
67
 * 		and gets resolved, to either a project or library entry, using
67
 * 		and gets resolved, to either a project or library entry, using
68
 *      <code>JavaCore#getResolvedClasspathVariable</code>.
68
 *      {@link JavaCore#getResolvedClasspathEntry(IClasspathEntry)}.
69
 *		It is also possible to register an automatic initializer (<code>ClasspathVariableInitializer</code>),
69
 *		It is also possible to register an automatic initializer ({@link ClasspathVariableInitializer}),
70
 * 	which will be invoked through the extension point "org.eclipse.jdt.core.classpathVariableInitializer".
70
 * 	which will be invoked through the extension point "org.eclipse.jdt.core.classpathVariableInitializer".
71
 * 	After resolution, a classpath variable entry may either correspond to a project or a library entry. </li>
71
 * 	After resolution, a classpath variable entry may either correspond to a project or a library entry. </li>
72
 * 
72
 * 
73
 *  <li> A named classpath container identified by its container path.
73
 *  <li> A named classpath container identified by its container path.
74
 *     A classpath container provides a way to indirectly reference a set of classpath entries through
74
 *     A classpath container provides a way to indirectly reference a set of classpath entries through
75
 *     a classpath entry of kind <code>CPE_CONTAINER</code>. Typically, a classpath container can
75
 *     a classpath entry of kind {@link #CPE_CONTAINER}. Typically, a classpath container can
76
 *     be used to describe a complex library composed of multiple JARs, projects or classpath variables,
76
 *     be used to describe a complex library composed of multiple JARs, projects or classpath variables,
77
 *     considering also that containers can be mapped differently on each project. Several projects can
77
 *     considering also that containers can be mapped differently on each project. Several projects can
78
 *     reference the same generic container path, but have each of them actually bound to a different
78
 *     reference the same generic container path, but have each of them actually bound to a different
79
 *     container object.
79
 *     container object.
80
 *     The container path is a formed by a first ID segment followed with extra segments, 
80
 *     The container path is a formed by a first ID segment followed with extra segments, 
81
 *     which can be used as additional hints for resolving this container reference. If no container was ever 
81
 *     which can be used as additional hints for resolving this container reference. If no container was ever 
82
 *     recorded for this container path onto this project (using <code>setClasspathContainer</code>, 
82
 *     recorded for this container path onto this project (using {@link JavaCore#setClasspathContainer}, 
83
 * 	then a <code>ClasspathContainerInitializer</code> will be activated if any was registered for this 
83
 * 	then a {@link ClasspathContainerInitializer} will be activated if any was registered for this 
84
 * 	container ID onto the extension point "org.eclipse.jdt.core.classpathContainerInitializer".
84
 * 	container ID onto the extension point "org.eclipse.jdt.core.classpathContainerInitializer".
85
 * 	A classpath container entry can be resolved explicitly using <code>JavaCore#getClasspathContainer</code>
85
 * 	A classpath container entry can be resolved explicitly using {@link JavaCore#getClasspathContainer}
86
 * 	and the resulting container entries can contain any non-container entry. In particular, it may contain variable
86
 * 	and the resulting container entries can contain any non-container entry. In particular, it may contain variable
87
 *     entries, which in turn needs to be resolved before being directly used. 
87
 *     entries, which in turn needs to be resolved before being directly used. 
88
 * 	<br> Also note that the container resolution APIs include an IJavaProject argument, so as to allow the same
88
 * 	<br> Also note that the container resolution APIs include an IJavaProject argument, so as to allow the same
89
 * 	container path to be interpreted in different ways for different projects. </li>
89
 * 	container path to be interpreted in different ways for different projects. </li>
90
 * </ul>
90
 * </ul>
91
 * </p>
91
 * </p>
92
 * The result of <code>IJavaProject#getResolvedClasspath</code> will have all entries of type
92
 * The result of {@link IJavaProject#getResolvedClasspath} will have all entries of type
93
 * <code>CPE_VARIABLE</code> and <code>CPE_CONTAINER</code> resolved to a set of 
93
 * {@link #CPE_VARIABLE} and {@link #CPE_CONTAINER} resolved to a set of 
94
 * <code>CPE_SOURCE</code>, <code>CPE_LIBRARY</code> or <code>CPE_PROJECT</code>
94
 * {@link #CPE_SOURCE}, {@link #CPE_LIBRARY} or {@link #CPE_PROJECT}
95
 * classpath entries.
95
 * classpath entries.
96
 * <p>
96
 * <p>
97
 * Any classpath entry other than a source folder (kind <code>CPE_SOURCE</code>) can
97
 * Any classpath entry other than a source folder (kind {@link #CPE_SOURCE}) can
98
 * be marked as being exported. Exported entries are automatically contributed to
98
 * be marked as being exported. Exported entries are automatically contributed to
99
 * dependent projects, along with the project's default output folder, which is
99
 * dependent projects, along with the project's default output folder, which is
100
 * implicitly exported, and any auxiliary output folders specified on source
100
 * implicitly exported, and any auxiliary output folders specified on source
Lines 102-108 Link Here
102
 * followed by the any exported entries.
102
 * followed by the any exported entries.
103
 * <p>
103
 * <p>
104
 * This interface is not intended to be implemented by clients.
104
 * This interface is not intended to be implemented by clients.
105
 * Classpath entries can be created via methods on <code>JavaCore</code>.
105
 * Classpath entries can be created via methods on {@link JavaCore}.
106
 * </p>
106
 * </p>
107
 *
107
 *
108
 * @see JavaCore#newLibraryEntry(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath)
108
 * @see JavaCore#newLibraryEntry(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath)
Lines 170-180 Link Here
170
	 * Returns the kind of files found in the package fragments identified by this
170
	 * Returns the kind of files found in the package fragments identified by this
171
	 * classpath entry.
171
	 * classpath entry.
172
	 *
172
	 *
173
	 * @return <code>IPackageFragmentRoot.K_SOURCE</code> for files containing
173
	 * @return {@link IPackageFragmentRoot#K_SOURCE} for files containing
174
	 *   source code, and <code>IPackageFragmentRoot.K_BINARY</code> for binary
174
	 *   source code, and {@link IPackageFragmentRoot#K_BINARY} for binary
175
	 *   class files.
175
	 *   class files.
176
	 *   There is no specified value for an entry denoting a variable (<code>CPE_VARIABLE</code>)
176
	 *   There is no specified value for an entry denoting a variable ({@link #CPE_VARIABLE})
177
	 *   or a classpath container (<code>CPE_CONTAINER</code>).
177
	 *   or a classpath container ({@link #CPE_CONTAINER}).
178
	 */
178
	 */
179
	int getContentKind();
179
	int getContentKind();
180
180
Lines 183-198 Link Here
183
	 *
183
	 *
184
	 * @return one of:
184
	 * @return one of:
185
	 * <ul>
185
	 * <ul>
186
	 * <li><code>CPE_SOURCE</code> - this entry describes a source root in
186
	 * <li>{@link #CPE_SOURCE} - this entry describes a source root in
187
	 		its project
187
	 		its project
188
	 * <li><code>CPE_LIBRARY</code> - this entry describes a folder or JAR
188
	 * <li>{@link #CPE_LIBRARY} - this entry describes a folder or JAR
189
	 		containing binaries
189
	 		containing binaries
190
	 * <li><code>CPE_PROJECT</code> - this entry describes another project
190
	 * <li>{@link #CPE_PROJECT} - this entry describes another project
191
	 *
191
	 *
192
	 * <li><code>CPE_VARIABLE</code> - this entry describes a project or library
192
	 * <li>{@link #CPE_VARIABLE} - this entry describes a project or library
193
	 *  	indirectly via a classpath variable in the first segment of the path
193
	 *  	indirectly via a classpath variable in the first segment of the path
194
	 * *
194
	 * *
195
	 * <li><code>CPE_CONTAINER</code> - this entry describes set of entries
195
	 * <li>{@link #CPE_CONTAINER} - this entry describes set of entries
196
	 *  	referenced indirectly via a classpath container
196
	 *  	referenced indirectly via a classpath container
197
	 * </ul>
197
	 * </ul>
198
	 */
198
	 */
Lines 344-354 Link Here
344
	/**
344
	/**
345
	 * Returns the full path to the specific location where the builder writes 
345
	 * Returns the full path to the specific location where the builder writes 
346
	 * <code>.class</code> files generated for this source entry 
346
	 * <code>.class</code> files generated for this source entry 
347
	 * (entry kind <code>CPE_SOURCE</code>).
347
	 * (entry kind {@link #CPE_SOURCE}).
348
	 * <p>
348
	 * <p>
349
	 * Source entries can optionally be associated with a specific output location.
349
	 * Source entries can optionally be associated with a specific output location.
350
	 * If none is provided, the source entry will be implicitly associated with its project
350
	 * If none is provided, the source entry will be implicitly associated with its project
351
	 * default output location (see <code>IJavaProject#getOutputLocation</code>).
351
	 * default output location (see {@link IJavaProject#getOutputLocation}).
352
	 * </p><p>
352
	 * </p><p>
353
	 * NOTE: A specific output location cannot coincidate with another source/library entry.
353
	 * NOTE: A specific output location cannot coincidate with another source/library entry.
354
	 * </p>
354
	 * </p>
Lines 364-387 Link Here
364
	 * Returns the path of this classpath entry.
364
	 * Returns the path of this classpath entry.
365
	 *
365
	 *
366
	 * The meaning of the path of a classpath entry depends on its entry kind:<ul>
366
	 * The meaning of the path of a classpath entry depends on its entry kind:<ul>
367
	 *	<li>Source code in the current project (<code>CPE_SOURCE</code>) -  
367
	 *	<li>Source code in the current project ({@link #CPE_SOURCE}) -  
368
	 *      The path associated with this entry is the absolute path to the root folder. </li>
368
	 *      The path associated with this entry is the absolute path to the root folder. </li>
369
	 *	<li>A binary library in the current project (<code>CPE_LIBRARY</code>) - the path
369
	 *	<li>A binary library in the current project ({@link #CPE_LIBRARY}) - the path
370
	 *		associated with this entry is the absolute path to the JAR (or root folder), and 
370
	 *		associated with this entry is the absolute path to the JAR (or root folder), and 
371
	 *		in case it refers to an external JAR, then there is no associated resource in 
371
	 *		in case it refers to an external JAR, then there is no associated resource in 
372
	 *		the workbench.
372
	 *		the workbench.
373
	 *	<li>A required project (<code>CPE_PROJECT</code>) - the path of the entry denotes the
373
	 *	<li>A required project ({@link #CPE_PROJECT}) - the path of the entry denotes the
374
	 *		path to the corresponding project resource.</li>
374
	 *		path to the corresponding project resource.</li>
375
	 *  <li>A variable entry (<code>CPE_VARIABLE</code>) - the first segment of the path 
375
	 *  <li>A variable entry ({@link #CPE_VARIABLE}) - the first segment of the path 
376
	 *      is the name of a classpath variable. If this classpath variable
376
	 *      is the name of a classpath variable. If this classpath variable
377
	 *		is bound to the path <i>P</i>, the path of the corresponding classpath entry
377
	 *		is bound to the path <i>P</i>, the path of the corresponding classpath entry
378
	 *		is computed by appending to <i>P</i> the segments of the returned
378
	 *		is computed by appending to <i>P</i> the segments of the returned
379
	 *		path without the variable.</li>
379
	 *		path without the variable.</li>
380
	 *  <li> A container entry (<code>CPE_CONTAINER</code>) - the path of the entry
380
	 *  <li> A container entry ({@link #CPE_CONTAINER}) - the path of the entry
381
	 * 	is the name of the classpath container, which can be bound indirectly to a set of classpath 
381
	 * 	is the name of the classpath container, which can be bound indirectly to a set of classpath 
382
	 * 	entries after resolution. The containerPath is a formed by a first ID segment followed with 
382
	 * 	entries after resolution. The containerPath is a formed by a first ID segment followed with 
383
	 *     extra segments that can be used as additional hints for resolving this container 
383
	 *     extra segments that can be used as additional hints for resolving this container 
384
	 * 	reference (also see <code>IClasspathContainer</code>).
384
	 * 	reference (also see {@link IClasspathContainer}).
385
	 * </li>
385
	 * </li>
386
	 * </ul>
386
	 * </ul>
387
	 *
387
	 *
Lines 410-416 Link Here
410
	 * Returns the path within the source archive or folder where package fragments
410
	 * Returns the path within the source archive or folder where package fragments
411
	 * are located. An empty path indicates that packages are located at
411
	 * are located. An empty path indicates that packages are located at
412
	 * the root of the source archive or folder. Returns a non-<code>null</code> value
412
	 * the root of the source archive or folder. Returns a non-<code>null</code> value
413
	 * if and only if <code>getSourceAttachmentPath</code> returns 
413
	 * if and only if {@link #getSourceAttachmentPath} returns 
414
	 * a non-<code>null</code> value.
414
	 * a non-<code>null</code> value.
415
	 *
415
	 *
416
	 * @return the path within the source archive or folder, or <code>null</code> if
416
	 * @return the path within the source archive or folder, or <code>null</code> if
Lines 421-427 Link Here
421
	/**
421
	/**
422
	 * Returns whether this entry is exported to dependent projects.
422
	 * Returns whether this entry is exported to dependent projects.
423
	 * Always returns <code>false</code> for source entries (kind
423
	 * Always returns <code>false</code> for source entries (kind
424
	 * <code>CPE_SOURCE</code>), which cannot be exported.
424
	 * {@link #CPE_SOURCE}), which cannot be exported.
425
	 * 
425
	 * 
426
	 * @return <code>true</code> if exported, and <code>false</code> otherwise
426
	 * @return <code>true</code> if exported, and <code>false</code> otherwise
427
	 * @since 2.0
427
	 * @since 2.0
(-)model/org/eclipse/jdt/core/ClasspathVariableInitializer.java (+29 lines)
Lines 25-30 Link Here
25
 */
25
 */
26
public abstract class ClasspathVariableInitializer {
26
public abstract class ClasspathVariableInitializer {
27
27
28
	/**
29
	 * Initialized variable flags.
30
	 */
31
	int flags = 0; // default is no flag
32
	final static int DEPRECATED = 0x01;
33
	final static int READ_ONLY  = 0x02;
34
28
    /**
35
    /**
29
     * Creates a new classpath variable initializer.
36
     * Creates a new classpath variable initializer.
30
     */
37
     */
Lines 49-52 Link Here
49
     * @see JavaCore#setClasspathVariables(String[], org.eclipse.core.runtime.IPath[], org.eclipse.core.runtime.IProgressMonitor)
56
     * @see JavaCore#setClasspathVariables(String[], org.eclipse.core.runtime.IPath[], org.eclipse.core.runtime.IProgressMonitor)
50
     */
57
     */
51
    public abstract void initialize(String variable);
58
    public abstract void initialize(String variable);
59
60
	/**
61
	 * Return whether the initialized variable is deprecated or not.
62
	 * 
63
	 * @return <code>true</code> if the initialized variable is deprecated,
64
	 * 	<code>false</code> otherwise.
65
	 * @since 3.3
66
	 */
67
	public final boolean isDeprecated() {
68
		return (this.flags & DEPRECATED) != 0;
69
	}
70
71
	/**
72
	 * Return whether the initialized variable is read-only or not.
73
	 * 
74
	 * @return <code>true</code> if the initialized variable is read-only,
75
	 * 	<code>false</code> otherwise.
76
	 * @since 3.3
77
	 */
78
	public final boolean isReadOnly() {
79
		return (this.flags & READ_ONLY) != 0;
80
	}
52
}
81
}
(-)model/org/eclipse/jdt/core/JavaCore.java (-53 / +125 lines)
Lines 1617-1671 Link Here
1617
			return variablePath;
1617
			return variablePath;
1618
		}
1618
		}
1619
1619
1620
		// even if persisted value exists, initializer is given priority, only if no initializer is found the persisted value is reused
1620
		return initializeClasspathVariable(variableName, variablePath);
1621
		final ClasspathVariableInitializer initializer = JavaCore.getClasspathVariableInitializer(variableName);
1622
		if (initializer != null){
1623
			if (JavaModelManager.CP_RESOLVE_VERBOSE){
1624
				Util.verbose(
1625
					"CPVariable INIT - triggering initialization\n" + //$NON-NLS-1$
1626
					"	variable: " + variableName + '\n' + //$NON-NLS-1$
1627
					"	initializer: " + initializer + '\n' + //$NON-NLS-1$
1628
					"	invocation stack trace:"); //$NON-NLS-1$
1629
				new Exception("<Fake exception>").printStackTrace(System.out); //$NON-NLS-1$
1630
			}
1631
			manager.variablePut(variableName, JavaModelManager.VARIABLE_INITIALIZATION_IN_PROGRESS); // avoid initialization cycles
1632
			boolean ok = false;
1633
			try {
1634
				// let OperationCanceledException go through
1635
				// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59363)
1636
				initializer.initialize(variableName);
1637
				
1638
				variablePath = manager.variableGet(variableName); // initializer should have performed side-effect
1639
				if (variablePath == JavaModelManager.VARIABLE_INITIALIZATION_IN_PROGRESS) return null; // break cycle (initializer did not init or reentering call)
1640
				if (JavaModelManager.CP_RESOLVE_VERBOSE){
1641
					Util.verbose(
1642
						"CPVariable INIT - after initialization\n" + //$NON-NLS-1$
1643
						"	variable: " + variableName +'\n' + //$NON-NLS-1$
1644
						"	variable path: " + variablePath); //$NON-NLS-1$
1645
				}
1646
				manager.variablesWithInitializer.add(variableName);
1647
				ok = true;
1648
			} catch (RuntimeException e) {
1649
				if (JavaModelManager.CP_RESOLVE_VERBOSE) {
1650
					e.printStackTrace();
1651
				}
1652
				throw e;
1653
			} catch (Error e) {
1654
				if (JavaModelManager.CP_RESOLVE_VERBOSE) {
1655
					e.printStackTrace();
1656
				}
1657
				throw e;
1658
			} finally {
1659
				if (!ok) JavaModelManager.getJavaModelManager().variablePut(variableName, null); // flush cache
1660
			}
1661
		} else {
1662
			if (JavaModelManager.CP_RESOLVE_VERBOSE){
1663
				Util.verbose(
1664
					"CPVariable INIT - no initializer found\n" + //$NON-NLS-1$
1665
					"	variable: " + variableName); //$NON-NLS-1$
1666
			}
1667
		}
1668
		return variablePath;
1669
	}
1621
	}
1670
1622
1671
	/**
1623
	/**
Lines 1690-1696 Link Here
1690
				IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
1642
				IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
1691
				for(int j = 0; j < configElements.length; j++){
1643
				for(int j = 0; j < configElements.length; j++){
1692
					try {
1644
					try {
1693
						String varAttribute = configElements[j].getAttribute("variable"); //$NON-NLS-1$
1645
						IConfigurationElement configElement = configElements[j];
1646
						String varAttribute = configElement.getAttribute("variable"); //$NON-NLS-1$
1694
						if (variable.equals(varAttribute)) {
1647
						if (variable.equals(varAttribute)) {
1695
							if (JavaModelManager.CP_RESOLVE_VERBOSE) {
1648
							if (JavaModelManager.CP_RESOLVE_VERBOSE) {
1696
								Util.verbose(
1649
								Util.verbose(
Lines 1700-1706 Link Here
1700
							}						
1653
							}						
1701
							Object execExt = configElements[j].createExecutableExtension("class"); //$NON-NLS-1$
1654
							Object execExt = configElements[j].createExecutableExtension("class"); //$NON-NLS-1$
1702
							if (execExt instanceof ClasspathVariableInitializer){
1655
							if (execExt instanceof ClasspathVariableInitializer){
1703
								return (ClasspathVariableInitializer)execExt;
1656
								ClasspathVariableInitializer initializer = (ClasspathVariableInitializer)execExt;
1657
								String deprecatedAttribute = configElement.getAttribute("deprecated"); //$NON-NLS-1$
1658
								if (deprecatedAttribute != null) {
1659
									initializer.flags |= ClasspathVariableInitializer.DEPRECATED;
1660
								}
1661
								String readOnlyAttribute = configElement.getAttribute("readOnly"); //$NON-NLS-1$
1662
								if (JavaModelManager.TRUE.equals(readOnlyAttribute)) {
1663
									initializer.flags |= ClasspathVariableInitializer.READ_ONLY;
1664
								}
1665
								return initializer;
1704
							}
1666
							}
1705
						}
1667
						}
1706
					} catch(CoreException e){
1668
					} catch(CoreException e){
Lines 3012-3018 Link Here
3012
			if (monitor != null) monitor.done();
2974
			if (monitor != null) monitor.done();
3013
		}
2975
		}
3014
	}
2976
	}
3015
	
2977
2978
	/*
2979
	 * Initialize classpath variable
2980
	 */
2981
	private static IPath initializeClasspathVariable(final String variableName, IPath variablePath) {
2982
		// even if persisted value exists, initializer is given priority, only if no initializer is found the persisted value is reused
2983
		final ClasspathVariableInitializer initializer = JavaCore.getClasspathVariableInitializer(variableName);
2984
		if (initializer != null){
2985
			if (JavaModelManager.CP_RESOLVE_VERBOSE){
2986
				Util.verbose(
2987
					"CPVariable INIT - triggering initialization\n" + //$NON-NLS-1$
2988
					"	variable: " + variableName + '\n' + //$NON-NLS-1$
2989
					"	initializer: " + initializer + '\n' + //$NON-NLS-1$
2990
					"	invocation stack trace:"); //$NON-NLS-1$
2991
				new Exception("<Fake exception>").printStackTrace(System.out); //$NON-NLS-1$
2992
			}
2993
		    JavaModelManager manager = JavaModelManager.getJavaModelManager();
2994
			manager.variablePut(variableName, JavaModelManager.VARIABLE_INITIALIZATION_IN_PROGRESS); // avoid initialization cycles
2995
			boolean ok = false;
2996
			try {
2997
				// let OperationCanceledException go through
2998
				// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59363)
2999
				initializer.initialize(variableName);
3000
				
3001
				variablePath = manager.variableGet(variableName); // initializer should have performed side-effect
3002
				if (variablePath == JavaModelManager.VARIABLE_INITIALIZATION_IN_PROGRESS) return null; // break cycle (initializer did not init or reentering call)
3003
				if (JavaModelManager.CP_RESOLVE_VERBOSE){
3004
					Util.verbose(
3005
						"CPVariable INIT - after initialization\n" + //$NON-NLS-1$
3006
						"	variable: " + variableName +'\n' + //$NON-NLS-1$
3007
						"	variable path: " + variablePath); //$NON-NLS-1$
3008
				}
3009
				manager.variablesWithInitializer.put(variableName, initializer.flags);
3010
				ok = true;
3011
			} catch (RuntimeException e) {
3012
				if (JavaModelManager.CP_RESOLVE_VERBOSE) {
3013
					e.printStackTrace();
3014
				}
3015
				throw e;
3016
			} catch (Error e) {
3017
				if (JavaModelManager.CP_RESOLVE_VERBOSE) {
3018
					e.printStackTrace();
3019
				}
3020
				throw e;
3021
			} finally {
3022
				if (!ok) JavaModelManager.getJavaModelManager().variablePut(variableName, null); // flush cache
3023
			}
3024
		} else {
3025
			if (JavaModelManager.CP_RESOLVE_VERBOSE){
3026
				Util.verbose(
3027
					"CPVariable INIT - no initializer found\n" + //$NON-NLS-1$
3028
					"	variable: " + variableName); //$NON-NLS-1$
3029
			}
3030
		}
3031
		return variablePath;
3032
	}
3033
3034
	/**
3035
	 * Returns whether a given classpath variable is deprecated or not.
3036
	 *
3037
	 * @param variableName
3038
	 * @return <code>true</code> if the classpath variable is deprecated,
3039
	 * 	<code>false</code> otherwise of if the variable is not initialized yet.
3040
	 * @since 3.3
3041
	 */
3042
	public static boolean isClasspathVariableDeprecated(final String variableName) {
3043
	    JavaModelManager manager = JavaModelManager.getJavaModelManager();
3044
		IPath variablePath = manager.variableGet(variableName);
3045
		if (variablePath == JavaModelManager.VARIABLE_INITIALIZATION_IN_PROGRESS){
3046
		    return false;  // currently do not store previous session result
3047
		}
3048
		
3049
		if (variablePath != null) {
3050
			if (variablePath == JavaModelManager.CP_ENTRY_IGNORE_PATH) {
3051
				return false;
3052
			}
3053
		} else {
3054
			initializeClasspathVariable(variableName, variablePath);
3055
		}
3056
3057
		int flags = manager.variableFlagsGet(variableName);
3058
		return flags > 0 && (flags & 0x01) != 0;
3059
	}
3060
3061
	/**
3062
	 * Returns whether a given classpath variable is deprecated or not.
3063
	 *
3064
	 * @param variableName
3065
	 * @return <code>true</code> if the classpath variable is deprecated,
3066
	 * 	<code>false</code> otherwise of if the variable is not initialized yet.
3067
	 * @since 3.3
3068
	 */
3069
	public static boolean isClasspathVariableReadOnly(final String variableName) {
3070
	    JavaModelManager manager = JavaModelManager.getJavaModelManager();
3071
		IPath variablePath = manager.variableGet(variableName);
3072
		if (variablePath == JavaModelManager.VARIABLE_INITIALIZATION_IN_PROGRESS){
3073
		    return false;  // currently do not store previous session result
3074
		}
3075
		
3076
		if (variablePath != null) {
3077
			if (variablePath == JavaModelManager.CP_ENTRY_IGNORE_PATH) {
3078
				return false;
3079
			}
3080
		} else {
3081
			initializeClasspathVariable(variableName, variablePath);
3082
		}
3083
3084
		int flags = manager.variableFlagsGet(variableName);
3085
		return flags > 0 && (flags & 0x02) != 0;
3086
	}
3087
3016
	/**
3088
	/**
3017
	 * Returns whether the given file name's extension is a Java-like extension.
3089
	 * Returns whether the given file name's extension is a Java-like extension.
3018
	 * 
3090
	 * 
Lines 3023-3029 Link Here
3023
	public static boolean isJavaLikeFileName(String fileName) {
3095
	public static boolean isJavaLikeFileName(String fileName) {
3024
		return Util.isJavaLikeFileName(fileName);
3096
		return Util.isJavaLikeFileName(fileName);
3025
	}
3097
	}
3026
	
3098
3027
	/**
3099
	/**
3028
	 * Returns whether the given marker references the given Java element.
3100
	 * Returns whether the given marker references the given Java element.
3029
	 * Used for markers, which denote a Java element rather than a resource.
3101
	 * Used for markers, which denote a Java element rather than a resource.
(-)model/org/eclipse/jdt/internal/core/JavaModelOperation.java (-1 / +1 lines)
Lines 61-67 Link Here
61
	protected HashMap attributes;
61
	protected HashMap attributes;
62
62
63
	public static final String HAS_MODIFIED_RESOURCE_ATTR = "hasModifiedResource"; //$NON-NLS-1$
63
	public static final String HAS_MODIFIED_RESOURCE_ATTR = "hasModifiedResource"; //$NON-NLS-1$
64
	public static final String TRUE = "true"; //$NON-NLS-1$
64
	public static final String TRUE = JavaModelManager.TRUE;
65
	//public static final String FALSE = "false";
65
	//public static final String FALSE = "false";
66
		
66
		
67
	/**
67
	/**
(-)model/org/eclipse/jdt/internal/core/JavaModelStatus.java (-45 / +72 lines)
Lines 126-132 Link Here
126
		this(code, new IJavaElement[]{element});
126
		this(code, new IJavaElement[]{element});
127
		this.string = string;
127
		this.string = string;
128
	}
128
	}
129
	
129
130
	/**
130
	/**
131
	 * Constructs an Java model status with the given corresponding
131
	 * Constructs an Java model status with the given corresponding
132
	 * element and path
132
	 * element and path
Lines 134-140 Link Here
134
	public JavaModelStatus(int code, IJavaElement element, IPath path) {
134
	public JavaModelStatus(int code, IJavaElement element, IPath path) {
135
		this(code, new IJavaElement[]{element});
135
		this(code, new IJavaElement[]{element});
136
		this.path = path;
136
		this.path = path;
137
	}	
137
	}
138
139
	/**
140
     * Constructs an Java model status with the given corresponding
141
     * element and path
142
     */
143
    public JavaModelStatus(int severity, int code, IJavaElement element, IPath path) {
144
    	super(severity, JavaCore.PLUGIN_ID, code, "JavaModelStatus", null); //$NON-NLS-1$
145
    	this.elements= new IJavaElement[]{element};
146
    	this.path = path;
147
    }
148
138
	/**
149
	/**
139
	 * Constructs an Java model status with the given corresponding
150
	 * Constructs an Java model status with the given corresponding
140
	 * element, path and string
151
	 * element, path and string
Lines 172-177 Link Here
172
	 * Returns the message that is relevant to the code of this status.
183
	 * Returns the message that is relevant to the code of this status.
173
	 */
184
	 */
174
	public String getMessage() {
185
	public String getMessage() {
186
		if (isMultiStatus()) {
187
			return Messages.status_multiple;
188
		}
175
		Throwable exception = getException();
189
		Throwable exception = getException();
176
		if (exception == null) {
190
		if (exception == null) {
177
			switch (getCode()) {
191
			switch (getCode()) {
Lines 326-378 Link Here
326
					if (description == null) description = path.makeRelative().toString();
340
					if (description == null) description = path.makeRelative().toString();
327
					return Messages.bind(Messages.classpath_invalidContainer, new String[] {description, javaProject.getElementName()}); 
341
					return Messages.bind(Messages.classpath_invalidContainer, new String[] {description, javaProject.getElementName()}); 
328
342
329
			case CP_VARIABLE_PATH_UNBOUND:
343
				case CP_VARIABLE_PATH_UNBOUND:
330
				javaProject = (IJavaProject)elements[0];
344
					javaProject = (IJavaProject)elements[0];
331
				return Messages.bind(Messages.classpath_unboundVariablePath, new String[] {path.makeRelative().toString(), javaProject.getElementName()}); 
345
					return Messages.bind(Messages.classpath_unboundVariablePath, new String[] {path.makeRelative().toString(), javaProject.getElementName()}); 
332
					
346
333
			case CLASSPATH_CYCLE: 
347
				case CLASSPATH_CYCLE: 
334
				javaProject = (IJavaProject)elements[0];
348
					javaProject = (IJavaProject)elements[0];
335
				return Messages.bind(Messages.classpath_cycle, javaProject.getElementName()); 
349
					return Messages.bind(Messages.classpath_cycle, javaProject.getElementName()); 
336
												 
337
			case DISABLED_CP_EXCLUSION_PATTERNS:
338
				javaProject = (IJavaProject)elements[0];
339
				String projectName = javaProject.getElementName();
340
				IPath newPath = path;
341
				if (path.segment(0).toString().equals(projectName)) {
342
					newPath = path.removeFirstSegments(1);
343
				}
344
				return Messages.bind(Messages.classpath_disabledInclusionExclusionPatterns, new String[] {newPath.makeRelative().toString(), projectName}); 
345
346
			case DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS:
347
				javaProject = (IJavaProject)elements[0];
348
				projectName = javaProject.getElementName();
349
				newPath = path;
350
				if (path.segment(0).toString().equals(projectName)) {
351
					newPath = path.removeFirstSegments(1);
352
				}
353
				return Messages.bind(Messages.classpath_disabledMultipleOutputLocations, new String[] {newPath.makeRelative().toString(), projectName}); 
354
350
355
			case INCOMPATIBLE_JDK_LEVEL:
351
				case DISABLED_CP_EXCLUSION_PATTERNS:
356
					javaProject = (IJavaProject)elements[0];
352
					javaProject = (IJavaProject)elements[0];
357
					return Messages.bind(Messages.classpath_incompatibleLibraryJDKLevel, new String[]{	
353
					String projectName = javaProject.getElementName();
358
						javaProject.getElementName(), 
354
					IPath newPath = path;
359
						javaProject.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true), 
355
					if (path.segment(0).toString().equals(projectName)) {
360
						path.makeRelative().toString(),
356
						newPath = path.removeFirstSegments(1);
361
						string,
357
					}
362
					});
358
					return Messages.bind(Messages.classpath_disabledInclusionExclusionPatterns, new String[] {newPath.makeRelative().toString(), projectName}); 
363
			case CANNOT_RETRIEVE_ATTACHED_JAVADOC :
359
364
				if (elements != null && elements.length == 1) {
360
				case DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS:
361
					javaProject = (IJavaProject)elements[0];
362
					projectName = javaProject.getElementName();
363
					newPath = path;
364
					if (path.segment(0).toString().equals(projectName)) {
365
						newPath = path.removeFirstSegments(1);
366
					}
367
					return Messages.bind(Messages.classpath_disabledMultipleOutputLocations, new String[] {newPath.makeRelative().toString(), projectName}); 
368
369
				case INCOMPATIBLE_JDK_LEVEL:
370
						javaProject = (IJavaProject)elements[0];
371
						return Messages.bind(Messages.classpath_incompatibleLibraryJDKLevel, new String[]{	
372
							javaProject.getElementName(), 
373
							javaProject.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true), 
374
							path.makeRelative().toString(),
375
							string,
376
						});
377
378
				case CANNOT_RETRIEVE_ATTACHED_JAVADOC :
379
					if (elements != null && elements.length == 1) {
380
						if (this.string != null) {
381
							return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, ((JavaElement)elements[0]).toStringWithAncestors(), this.string); 
382
						}
383
						return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, ((JavaElement)elements[0]).toStringWithAncestors(), ""); //$NON-NLS-1$
384
					}
365
					if (this.string != null) {
385
					if (this.string != null) {
366
						return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, ((JavaElement)elements[0]).toStringWithAncestors(), this.string); 
386
						return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, this.string, "");//$NON-NLS-1$
367
					}
387
					}
368
					return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, ((JavaElement)elements[0]).toStringWithAncestors(), ""); //$NON-NLS-1$
388
					break;
369
				}
389
370
				if (this.string != null) {
390
				case UNKNOWN_JAVADOC_FORMAT :
371
					return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, this.string, "");//$NON-NLS-1$
391
					return Messages.bind(Messages.status_unknown_javadoc_format, ((JavaElement)elements[0]).toStringWithAncestors()); 
372
				}
392
373
				break;
393
				case DEPRECATED_VARIABLE :
374
			case UNKNOWN_JAVADOC_FORMAT :
394
					javaProject = (IJavaProject)elements[0];
375
				return Messages.bind(Messages.status_unknown_javadoc_format, ((JavaElement)elements[0]).toStringWithAncestors()); 
395
					return Messages.bind(Messages.classpath_deprecated_variable, new String[] {path.segment(0).toString(), javaProject.getElementName()}); 
396
397
				case READ_ONLY_VARIABLE :
398
					javaProject = (IJavaProject)elements[0];
399
					return Messages.bind(Messages.classpath_read_only_variable, new String[] {path.segment(0).toString(), javaProject.getElementName()}); 
376
			}
400
			}
377
			if (string != null) {
401
			if (string != null) {
378
				return string;
402
				return string;
Lines 466-471 Link Here
466
	public static IJavaModelStatus newMultiStatus(IJavaModelStatus[] children) {
490
	public static IJavaModelStatus newMultiStatus(IJavaModelStatus[] children) {
467
		JavaModelStatus jms = new JavaModelStatus();
491
		JavaModelStatus jms = new JavaModelStatus();
468
		jms.children = children;
492
		jms.children = children;
493
		if (children != null && children.length > 0) {
494
			jms.setCode(children[0].getCode());
495
		}
469
		return jms;
496
		return jms;
470
	}
497
	}
471
	/**
498
	/**
(-)model/org/eclipse/jdt/internal/core/ClasspathEntry.java (-13 / +43 lines)
Lines 26-31 Link Here
26
import org.eclipse.core.runtime.AssertionFailedException;
26
import org.eclipse.core.runtime.AssertionFailedException;
27
import org.eclipse.core.runtime.CoreException;
27
import org.eclipse.core.runtime.CoreException;
28
import org.eclipse.core.runtime.IPath;
28
import org.eclipse.core.runtime.IPath;
29
import org.eclipse.core.runtime.IStatus;
29
import org.eclipse.core.runtime.Path;
30
import org.eclipse.core.runtime.Path;
30
import org.eclipse.jdt.core.IAccessRule;
31
import org.eclipse.jdt.core.IAccessRule;
31
import org.eclipse.jdt.core.IClasspathAttribute;
32
import org.eclipse.jdt.core.IClasspathAttribute;
Lines 1616-1636 Link Here
1616
				
1617
				
1617
			// variable entry check
1618
			// variable entry check
1618
			case IClasspathEntry.CPE_VARIABLE :
1619
			case IClasspathEntry.CPE_VARIABLE :
1619
				if (path != null && path.segmentCount() >= 1){
1620
				// Verify path
1620
					try {
1621
				if (path == null || path.segmentCount() < 1) {
1621
						entry = JavaCore.getResolvedClasspathEntry(entry);
1622
					} catch (AssertionFailedException e) {
1623
						// Catch the assertion failure and throw java model exception instead
1624
						// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=55992
1625
						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, e.getMessage());
1626
					}
1627
					if (entry == null){
1628
						return new JavaModelStatus(IJavaModelStatusConstants.CP_VARIABLE_PATH_UNBOUND, project, path);
1629
					}
1630
					return validateClasspathEntry(project, entry, checkSourceAttachment, recurseInContainers);
1631
				} else {
1632
					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalVariablePath, new String[] {entryPathMsg, projectName}));					 
1622
					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalVariablePath, new String[] {entryPathMsg, projectName}));					 
1633
				}
1623
				}
1624
				
1625
				// Resolve the entry
1626
				try {
1627
					entry = JavaCore.getResolvedClasspathEntry(entry);
1628
				} catch (AssertionFailedException e) {
1629
					// Catch the assertion failure and throw java model exception instead
1630
					// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=55992
1631
					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, e.getMessage());
1632
				}
1633
				if (entry == null){
1634
					return new JavaModelStatus(IJavaModelStatusConstants.CP_VARIABLE_PATH_UNBOUND, project, path);
1635
				}
1636
1637
				// Get validation status
1638
				IJavaModelStatus status = validateClasspathEntry(project, entry, checkSourceAttachment, recurseInContainers);
1639
				if (!status.isOK()) {
1640
					return status;
1641
				}
1642
1643
				// Verify deprecation and read-only
1644
				String variableName = path.segment(0);
1645
				if (JavaCore.isClasspathVariableDeprecated(variableName)) {
1646
					if (JavaCore.isClasspathVariableReadOnly(variableName)) {
1647
						// put the two warnings in a multi-status
1648
						return JavaModelStatus.newMultiStatus(
1649
							new IJavaModelStatus[] { 
1650
								new JavaModelStatus(IStatus.WARNING, IJavaModelStatusConstants.DEPRECATED_VARIABLE, project, path),
1651
								new JavaModelStatus(IStatus.WARNING, IJavaModelStatusConstants.READ_ONLY_VARIABLE, project, path)
1652
							}
1653
						);
1654
					}
1655
					// only deprecated warning
1656
					return new JavaModelStatus(IStatus.WARNING, IJavaModelStatusConstants.DEPRECATED_VARIABLE, project, path);
1657
				} else if (JavaCore.isClasspathVariableReadOnly(variableName)) {
1658
					// only read-on warning
1659
					return new JavaModelStatus(IStatus.WARNING, IJavaModelStatusConstants.READ_ONLY_VARIABLE, project, path);
1660
				}
1661
1662
				// Status is OK
1663
				return status;
1634
	
1664
	
1635
			// library entry check
1665
			// library entry check
1636
			case IClasspathEntry.CPE_LIBRARY :
1666
			case IClasspathEntry.CPE_LIBRARY :
(-)model/org/eclipse/jdt/internal/core/JavaModelManager.java (-25 / +37 lines)
Lines 86-94 Link Here
86
	 * Classpath variables pool
86
	 * Classpath variables pool
87
	 */
87
	 */
88
	public HashMap variables = new HashMap(5);
88
	public HashMap variables = new HashMap(5);
89
	public HashSet variablesWithInitializer = new HashSet(5);
90
	public HashMap previousSessionVariables = new HashMap(5);
89
	public HashMap previousSessionVariables = new HashMap(5);
91
	private ThreadLocal variableInitializationInProgress = new ThreadLocal();
90
	private ThreadLocal variableInitializationInProgress = new ThreadLocal();
91
92
	/**
93
	 * Map of classpath variables which have an initializer.
94
	 * Keys are variable names and values are flags corresponding to initializer
95
	 * additional attributes (currently bit0 for deprecation and bit1 for read-only)
96
	 * @see ClasspathVariableInitializer
97
	 */
98
	public HashtableOfObjectToInt variablesWithInitializer = new HashtableOfObjectToInt(5);
92
		
99
		
93
	/**
100
	/**
94
	 * Classpath containers pool
101
	 * Classpath containers pool
Lines 120-125 Link Here
120
	public final static String CP_CONTAINER_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".classpathContainer."; //$NON-NLS-1$
127
	public final static String CP_CONTAINER_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".classpathContainer."; //$NON-NLS-1$
121
	public final static String CP_ENTRY_IGNORE = "##<cp entry ignore>##"; //$NON-NLS-1$
128
	public final static String CP_ENTRY_IGNORE = "##<cp entry ignore>##"; //$NON-NLS-1$
122
	public final static IPath CP_ENTRY_IGNORE_PATH = new Path(CP_ENTRY_IGNORE);
129
	public final static IPath CP_ENTRY_IGNORE_PATH = new Path(CP_ENTRY_IGNORE);
130
	public final static String TRUE = "true"; //$NON-NLS-1$
123
	
131
	
124
	private final static int VARIABLES_AND_CONTAINERS_FILE_VERSION = 2;
132
	private final static int VARIABLES_AND_CONTAINERS_FILE_VERSION = 2;
125
133
Lines 278-286 Link Here
278
						continue;
286
						continue;
279
					}
287
					}
280
					// add config element in the group it belongs to
288
					// add config element in the group it belongs to
281
					if ("true".equals(configElement.getAttribute("modifiesEnvironment"))) //$NON-NLS-1$ //$NON-NLS-2$
289
					if (TRUE.equals(configElement.getAttribute("modifiesEnvironment"))) //$NON-NLS-1$
282
						modifyingEnv.add(configElement);
290
						modifyingEnv.add(configElement);
283
					else if ("true".equals(configElement.getAttribute("createsProblems"))) //$NON-NLS-1$ //$NON-NLS-2$
291
					else if (TRUE.equals(configElement.getAttribute("createsProblems"))) //$NON-NLS-1$
284
						creatingProblems.add(configElement);
292
						creatingProblems.add(configElement);
285
					else
293
					else
286
						others.add(configElement);
294
						others.add(configElement);
Lines 1124-1135 Link Here
1124
			if (propertyName.startsWith(CP_VARIABLE_PREFERENCES_PREFIX)) {
1132
			if (propertyName.startsWith(CP_VARIABLE_PREFERENCES_PREFIX)) {
1125
				String varName = propertyName.substring(CP_VARIABLE_PREFERENCES_PREFIX.length());
1133
				String varName = propertyName.substring(CP_VARIABLE_PREFERENCES_PREFIX.length());
1126
				JavaModelManager manager = getJavaModelManager();
1134
				JavaModelManager manager = getJavaModelManager();
1127
				if (manager.variablesWithInitializer.contains(varName)) {
1135
				if (manager.variablesWithInitializer.containsKey(varName)) {
1128
					// revert preference value as we will not apply it to JavaCore classpath variable
1136
					// revert preference value as we will not apply it to JavaCore classpath variable
1129
					String oldValue = (String) event.getOldValue();
1137
					String oldValue = (String) event.getOldValue();
1130
					if (oldValue == null) {
1138
					if (oldValue == null) {
1131
						// unexpected old value => remove variable from set
1139
						// unexpected old value => remove variable from set
1132
						manager.variablesWithInitializer.remove(varName);
1140
						manager.variablesWithInitializer.removeKey(varName);
1133
					} else {
1141
					} else {
1134
						manager.getInstancePreferences().put(varName, oldValue);
1142
						manager.getInstancePreferences().put(varName, oldValue);
1135
					}
1143
					}
Lines 1200-1257 Link Here
1200
	public void configurePluginDebugOptions(){
1208
	public void configurePluginDebugOptions(){
1201
		if(JavaCore.getPlugin().isDebugging()){
1209
		if(JavaCore.getPlugin().isDebugging()){
1202
			String option = Platform.getDebugOption(BUFFER_MANAGER_DEBUG);
1210
			String option = Platform.getDebugOption(BUFFER_MANAGER_DEBUG);
1203
			if(option != null) BufferManager.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1211
			if(option != null) BufferManager.VERBOSE = option.equalsIgnoreCase(TRUE) ;
1204
			
1212
			
1205
			option = Platform.getDebugOption(BUILDER_DEBUG);
1213
			option = Platform.getDebugOption(BUILDER_DEBUG);
1206
			if(option != null) JavaBuilder.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1214
			if(option != null) JavaBuilder.DEBUG = option.equalsIgnoreCase(TRUE) ;
1207
			
1215
			
1208
			option = Platform.getDebugOption(COMPILER_DEBUG);
1216
			option = Platform.getDebugOption(COMPILER_DEBUG);
1209
			if(option != null) Compiler.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1217
			if(option != null) Compiler.DEBUG = option.equalsIgnoreCase(TRUE) ;
1210
1218
1211
			option = Platform.getDebugOption(COMPLETION_DEBUG);
1219
			option = Platform.getDebugOption(COMPLETION_DEBUG);
1212
			if(option != null) CompletionEngine.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1220
			if(option != null) CompletionEngine.DEBUG = option.equalsIgnoreCase(TRUE) ;
1213
			
1221
			
1214
			option = Platform.getDebugOption(CP_RESOLVE_DEBUG);
1222
			option = Platform.getDebugOption(CP_RESOLVE_DEBUG);
1215
			if(option != null) JavaModelManager.CP_RESOLVE_VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1223
			if(option != null) JavaModelManager.CP_RESOLVE_VERBOSE = option.equalsIgnoreCase(TRUE) ;
1216
1224
1217
			option = Platform.getDebugOption(DELTA_DEBUG);
1225
			option = Platform.getDebugOption(DELTA_DEBUG);
1218
			if(option != null) DeltaProcessor.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1226
			if(option != null) DeltaProcessor.DEBUG = option.equalsIgnoreCase(TRUE) ;
1219
1227
1220
			option = Platform.getDebugOption(DELTA_DEBUG_VERBOSE);
1228
			option = Platform.getDebugOption(DELTA_DEBUG_VERBOSE);
1221
			if(option != null) DeltaProcessor.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1229
			if(option != null) DeltaProcessor.VERBOSE = option.equalsIgnoreCase(TRUE) ;
1222
1230
1223
			option = Platform.getDebugOption(HIERARCHY_DEBUG);
1231
			option = Platform.getDebugOption(HIERARCHY_DEBUG);
1224
			if(option != null) TypeHierarchy.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1232
			if(option != null) TypeHierarchy.DEBUG = option.equalsIgnoreCase(TRUE) ;
1225
1233
1226
			option = Platform.getDebugOption(INDEX_MANAGER_DEBUG);
1234
			option = Platform.getDebugOption(INDEX_MANAGER_DEBUG);
1227
			if(option != null) JobManager.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1235
			if(option != null) JobManager.VERBOSE = option.equalsIgnoreCase(TRUE) ;
1228
			
1236
			
1229
			option = Platform.getDebugOption(JAVAMODEL_DEBUG);
1237
			option = Platform.getDebugOption(JAVAMODEL_DEBUG);
1230
			if(option != null) JavaModelManager.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1238
			if(option != null) JavaModelManager.VERBOSE = option.equalsIgnoreCase(TRUE) ;
1231
1239
1232
			option = Platform.getDebugOption(JAVAMODELCACHE_DEBUG);
1240
			option = Platform.getDebugOption(JAVAMODELCACHE_DEBUG);
1233
			if(option != null) JavaModelCache.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1241
			if(option != null) JavaModelCache.VERBOSE = option.equalsIgnoreCase(TRUE) ;
1234
1242
1235
			option = Platform.getDebugOption(POST_ACTION_DEBUG);
1243
			option = Platform.getDebugOption(POST_ACTION_DEBUG);
1236
			if(option != null) JavaModelOperation.POST_ACTION_VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1244
			if(option != null) JavaModelOperation.POST_ACTION_VERBOSE = option.equalsIgnoreCase(TRUE) ;
1237
1245
1238
			option = Platform.getDebugOption(RESOLUTION_DEBUG);
1246
			option = Platform.getDebugOption(RESOLUTION_DEBUG);
1239
			if(option != null) NameLookup.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1247
			if(option != null) NameLookup.VERBOSE = option.equalsIgnoreCase(TRUE) ;
1240
1248
1241
			option = Platform.getDebugOption(SEARCH_DEBUG);
1249
			option = Platform.getDebugOption(SEARCH_DEBUG);
1242
			if(option != null) BasicSearchEngine.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1250
			if(option != null) BasicSearchEngine.VERBOSE = option.equalsIgnoreCase(TRUE) ;
1243
1251
1244
			option = Platform.getDebugOption(SELECTION_DEBUG);
1252
			option = Platform.getDebugOption(SELECTION_DEBUG);
1245
			if(option != null) SelectionEngine.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1253
			if(option != null) SelectionEngine.DEBUG = option.equalsIgnoreCase(TRUE) ;
1246
1254
1247
			option = Platform.getDebugOption(ZIP_ACCESS_DEBUG);
1255
			option = Platform.getDebugOption(ZIP_ACCESS_DEBUG);
1248
			if(option != null) JavaModelManager.ZIP_ACCESS_VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1256
			if(option != null) JavaModelManager.ZIP_ACCESS_VERBOSE = option.equalsIgnoreCase(TRUE) ;
1249
			
1257
			
1250
			option = Platform.getDebugOption(SOURCE_MAPPER_DEBUG_VERBOSE);
1258
			option = Platform.getDebugOption(SOURCE_MAPPER_DEBUG_VERBOSE);
1251
			if(option != null) SourceMapper.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1259
			if(option != null) SourceMapper.VERBOSE = option.equalsIgnoreCase(TRUE) ;
1252
			
1260
			
1253
			option = Platform.getDebugOption(ENABLE_NEW_FORMATTER);
1261
			option = Platform.getDebugOption(ENABLE_NEW_FORMATTER);
1254
			if(option != null) DefaultCodeFormatter.USE_NEW_FORMATTER = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
1262
			if(option != null) DefaultCodeFormatter.USE_NEW_FORMATTER = option.equalsIgnoreCase(TRUE) ;
1255
		}
1263
		}
1256
		
1264
		
1257
		// configure performance options
1265
		// configure performance options
Lines 3950-3956 Link Here
3950
		
3958
		
3951
		// Note: no need to close the Java model as this just removes Java element infos from the Java model cache
3959
		// Note: no need to close the Java model as this just removes Java element infos from the Java model cache
3952
	}
3960
	}
3953
		
3961
3954
	public synchronized IPath variableGet(String variableName){
3962
	public synchronized IPath variableGet(String variableName){
3955
		// check initialization in progress first
3963
		// check initialization in progress first
3956
		HashSet initializations = variableInitializationInProgress();
3964
		HashSet initializations = variableInitializationInProgress();
Lines 3960-3965 Link Here
3960
		return (IPath)this.variables.get(variableName);
3968
		return (IPath)this.variables.get(variableName);
3961
	}
3969
	}
3962
3970
3971
	public synchronized int variableFlagsGet(String variableName){
3972
		return this.variablesWithInitializer.get(variableName);
3973
	}
3974
3963
	/*
3975
	/*
3964
	 * Returns the set of variable names that are being initialized in the current thread.
3976
	 * Returns the set of variable names that are being initialized in the current thread.
3965
	 */
3977
	 */
Lines 4011-4017 Link Here
4011
	public void variablePreferencesPut(String variableName, IPath variablePath) {
4023
	public void variablePreferencesPut(String variableName, IPath variablePath) {
4012
		String variableKey = CP_VARIABLE_PREFERENCES_PREFIX+variableName;
4024
		String variableKey = CP_VARIABLE_PREFERENCES_PREFIX+variableName;
4013
		if (variablePath == null) {
4025
		if (variablePath == null) {
4014
			this.variablesWithInitializer.remove(variableName);
4026
			this.variablesWithInitializer.removeKey(variableName);
4015
			getInstancePreferences().remove(variableKey);
4027
			getInstancePreferences().remove(variableKey);
4016
		} else {
4028
		} else {
4017
			getInstancePreferences().put(variableKey, variablePath.toString());
4029
			getInstancePreferences().put(variableKey, variablePath.toString());
(-)schema/classpathVariableInitializer.exsd (+17 lines)
Lines 63-68 Link Here
63
               </appInfo>
63
               </appInfo>
64
            </annotation>
64
            </annotation>
65
         </attribute>
65
         </attribute>
66
         <attribute name="deprecated" type="string">
67
            <annotation>
68
               <documentation>
69
                  String explaining the reason why the associated variable is deprecated
70
               </documentation>
71
               <appInfo>
72
                  <meta.attribute translatable="true"/>
73
               </appInfo>
74
            </annotation>
75
         </attribute>
76
         <attribute name="readOnly" type="boolean">
77
            <annotation>
78
               <documentation>
79
                  Indicates that the associated variable cannot be modified
80
               </documentation>
81
            </annotation>
82
         </attribute>
66
      </complexType>
83
      </complexType>
67
   </element>
84
   </element>
68
85
(-)buildnotes_jdt-core.html (+112 lines)
Lines 43-48 Link Here
43
  </tr>
43
  </tr>
44
</table>
44
</table>
45
45
46
<a name="v_732"></a>
47
<p><hr><h1>
48
Eclipse Platform Build Notes<br>
49
Java Development Tooling Core</h1>
50
Eclipse SDK 3.3M5 - 16th January 2007
51
<br>Project org.eclipse.jdt.core v_732
52
(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_732">cvs</a>).
53
<h2>What's new in this drop</h2>
54
<ul>
55
<li>Classpath variable may now be flagged as deprecated or read-only (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138599">138599</a>
56
and bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156226">156226</a>).<br>
57
Two new attributes have been added on <code>ClasspathVariableInitializer</code> schema:
58
<pre>
59
   &lt;element name="classpathVariableInitializer"&gt;
60
      &lt;complexType&gt;
61
         ...
62
         &lt;attribute name="deprecated" type="string"&gt;
63
            &lt;annotation&gt;
64
               &lt;documentation&gt;
65
                  String explaining the reason why the associated variable is deprecated
66
               &lt;/documentation&gt;
67
               &lt;appInfo&gt;
68
                  &lt;meta.attribute translatable="true"/&gt;
69
               &lt;/appInfo&gt;
70
            &lt;/annotation&gt;
71
         &lt;/attribute&gt;
72
         &lt;attribute name="readOnly" type="boolean"&gt;
73
            &lt;annotation&gt;
74
               &lt;documentation&gt;
75
                  Indicates that the associated variable cannot be modified
76
               &lt;/documentation&gt;
77
            &lt;/annotation&gt;
78
         &lt;/attribute&gt;
79
      &lt;/complexType&gt;
80
   &lt;/element&gt;
81
</pre>
82
When these attributes are set on classpathVariableInitializer extension point, classpath entry validation
83
will return a mutli-status <code>IJavaModelStatus</code> with corresponding severity level and messages.
84
<br>
85
For example, following extension point set the <code>TEST</code> classpath variable as deprecated 
86
and read-only:
87
<pre>
88
   &lt;extension
89
         point="org.eclipse.jdt.core.classpathVariableInitializer"&gt;
90
      &lt;classpathVariableInitializer
91
            class="org.eclipse.jdt.tests.model.TestInitializer"
92
            deprecated="The reason why this variable is deprecated"
93
            readOnly="true"
94
            variable="TEST"&gt;
95
      &lt;/classpathVariableInitializer&gt;
96
   &lt;/extension&gt;
97
</pre>
98
The calling <code>JavaConventions.validateClasspathEntry(IJavaProject, IClasspathEntry, boolean)</code>
99
method on corresponding variable entry will return a status with <code>IStatus.WARNING</code> severity
100
and following message:
101
<pre>
102
Classpath variable 'TEST' in project P is deprecated; Classpath variable 'TEST' in project P is read only
103
</pre>
104
User can also get deprecated and read-only information using following API methods:
105
<ul>
106
<li><code>ClasspathVariableInitializer</code>:
107
<pre>
108
/**
109
 * Return whether the initialized variable is deprecated or not.
110
 * 
111
 * @return <code>true</code> if the initialized variable is deprecated,
112
 * 	<code>false</code> otherwise.
113
 * @since 3.3
114
 */
115
public final boolean isDeprecated()
116
/**
117
 * Return whether the initialized variable is read-only or not.
118
 * 
119
 * @return <code>true</code> if the initialized variable is read-only,
120
 * 	<code>false</code> otherwise.
121
 * @since 3.3
122
 */
123
public final boolean isReadOnly()
124
</pre>
125
</li>
126
<li><code>JavaCore</code>:
127
<pre>
128
/**
129
 * Returns whether a given classpath variable is deprecated or not.
130
 *
131
 * @param variableName
132
 * @return <code>true</code> if the classpath variable is deprecated,
133
 * 	<code>false</code> otherwise of if the variable is not initialized yet.
134
 * @since 3.3
135
 */
136
public static boolean isClasspathVariableDeprecated(final String variableName)
137
/**
138
 * Returns whether a given classpath variable is deprecated or not.
139
 *
140
 * @param variableName
141
 * @return <code>true</code> if the classpath variable is deprecated,
142
 * 	<code>false</code> otherwise of if the variable is not initialized yet.
143
 * @since 3.3
144
 */
145
public static boolean isClasspathVariableReadOnly(final String variableName)
146
</pre>
147
</li>
148
</ul>
149
</li>
150
</ul>
151
152
<h3>Problem Reports Fixed</h3>
153
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156226">156226</a>
154
[model][classpath] Allow classpath variable to be marked as non modifiable
155
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138599">138599</a>
156
[model][classpath] Need a way to mark a classpath variable as deprecated
157
46
<a name="v_731"></a>
158
<a name="v_731"></a>
47
<p><hr><h1>
159
<p><hr><h1>
48
Eclipse Platform Build Notes<br>
160
Eclipse Platform Build Notes<br>
(-)model/org/eclipse/jdt/internal/core/util/messages.properties (+3 lines)
Lines 117-122 Link Here
117
status_invalidResource = Invalid resource: {0}
117
status_invalidResource = Invalid resource: {0}
118
status_invalidResourceType = Invalid resource type for {0}
118
status_invalidResourceType = Invalid resource type for {0}
119
status_invalidSibling = Invalid sibling: {0}
119
status_invalidSibling = Invalid sibling: {0}
120
status_multiple = Several warnings/errors occured
120
status_nameCollision = {0} already exists in target
121
status_nameCollision = {0} already exists in target
121
status_noLocalContents = Cannot find local contents for resource: {0}
122
status_noLocalContents = Cannot find local contents for resource: {0}
122
status_OK = OK
123
status_OK = OK
Lines 167-172 Link Here
167
classpath_disabledMultipleOutputLocations = Multiple output locations are disabled in project {1}, cannot associate entry: ''{0}'' with a specific output
168
classpath_disabledMultipleOutputLocations = Multiple output locations are disabled in project {1}, cannot associate entry: ''{0}'' with a specific output
168
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
169
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
169
classpath_duplicateEntryExtraAttribute = Duplicate extra attribute: ''{0}'' in classpath entry ''{1}'' for project {2}
170
classpath_duplicateEntryExtraAttribute = Duplicate extra attribute: ''{0}'' in classpath entry ''{1}'' for project {2}
171
classpath_deprecated_variable = Classpath variable ''{0}'' in project {1} is deprecated
172
classpath_read_only_variable = Classpath variable ''{0}'' in project {1} is read only
170
173
171
### miscellaneous
174
### miscellaneous
172
file_notFound = File not found: ''{0}''
175
file_notFound = File not found: ''{0}''
(-)model/org/eclipse/jdt/internal/core/util/Messages.java (+3 lines)
Lines 114-119 Link Here
114
	public static String status_invalidResource;
114
	public static String status_invalidResource;
115
	public static String status_invalidResourceType;
115
	public static String status_invalidResourceType;
116
	public static String status_invalidSibling;
116
	public static String status_invalidSibling;
117
	public static String status_multiple;
117
	public static String status_nameCollision;
118
	public static String status_nameCollision;
118
	public static String status_noLocalContents;
119
	public static String status_noLocalContents;
119
	public static String status_OK;
120
	public static String status_OK;
Lines 161-166 Link Here
161
	public static String classpath_disabledMultipleOutputLocations;
162
	public static String classpath_disabledMultipleOutputLocations;
162
	public static String classpath_incompatibleLibraryJDKLevel;
163
	public static String classpath_incompatibleLibraryJDKLevel;
163
	public static String classpath_duplicateEntryExtraAttribute;
164
	public static String classpath_duplicateEntryExtraAttribute;
165
	public static String classpath_deprecated_variable;
166
	public static String classpath_read_only_variable;
164
	public static String file_notFound;
167
	public static String file_notFound;
165
	public static String file_badFormat;
168
	public static String file_badFormat;
166
	public static String path_nullPath;
169
	public static String path_nullPath;
(-)src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java (-1 / +156 lines)
Lines 11-17 Link Here
11
package org.eclipse.jdt.core.tests.model;
11
package org.eclipse.jdt.core.tests.model;
12
12
13
import java.util.HashMap;
13
import java.util.HashMap;
14
import java.util.HashSet;
14
import java.util.Map;
15
import java.util.Map;
16
import java.util.Set;
15
17
16
import org.eclipse.core.resources.*;
18
import org.eclipse.core.resources.*;
17
import org.eclipse.core.runtime.*;
19
import org.eclipse.core.runtime.*;
Lines 19-24 Link Here
19
import org.eclipse.jdt.core.*;
21
import org.eclipse.jdt.core.*;
20
import org.eclipse.jdt.core.compiler.CharOperation;
22
import org.eclipse.jdt.core.compiler.CharOperation;
21
import org.eclipse.jdt.internal.core.JavaModelManager;
23
import org.eclipse.jdt.internal.core.JavaModelManager;
24
import org.eclipse.jdt.internal.core.JavaModelStatus;
22
import org.eclipse.jdt.internal.core.UserLibraryClasspathContainer;
25
import org.eclipse.jdt.internal.core.UserLibraryClasspathContainer;
23
import org.eclipse.jdt.internal.core.UserLibraryManager;
26
import org.eclipse.jdt.internal.core.UserLibraryManager;
24
27
Lines 28-34 Link Here
28
	
31
	
29
public static class DefaultVariableInitializer implements VariablesInitializer.ITestInitializer {
32
public static class DefaultVariableInitializer implements VariablesInitializer.ITestInitializer {
30
	Map variableValues;
33
	Map variableValues;
31
	
34
	Set deprecatedVariables, readOnlyVariables;
32
	/*
35
	/*
33
	 * values is [<var name>, <var value>]*
36
	 * values is [<var name>, <var value>]*
34
	 */
37
	 */
Lines 46-51 Link Here
46
			(IPath)variableValues.get(variable), 
49
			(IPath)variableValues.get(variable), 
47
			null);
50
			null);
48
	}
51
	}
52
53
	public boolean isDeprecated(String variable) {
54
		if (deprecatedVariables == null) return false;
55
		return deprecatedVariables.contains(variable);
56
	}
57
58
	public void setDeprecated(String variable) {
59
		if (deprecatedVariables == null) deprecatedVariables = new HashSet();
60
		deprecatedVariables.add(variable);
61
	}
62
63
	public void setReadOnly(String variable) {
64
		if (readOnlyVariables == null) readOnlyVariables = new HashSet();
65
		readOnlyVariables.add(variable);
66
	}
67
68
	public boolean isReadOnly(String variable) {
69
		if (readOnlyVariables == null) return false;
70
		return readOnlyVariables.contains(variable);
71
	}
49
}
72
}
50
73
51
public static class DefaultContainerInitializer implements ContainerInitializer.ITestInitializer {
74
public static class DefaultContainerInitializer implements ContainerInitializer.ITestInitializer {
Lines 887-892 Link Here
887
				buffer.append("Setting variable " + variable + " to " + path + "\n");
910
				buffer.append("Setting variable " + variable + " to " + path + "\n");
888
				JavaCore.setClasspathVariable(variable, path, null);
911
				JavaCore.setClasspathVariable(variable, path, null);
889
			}
912
			}
913
			public void setDeprecated(String variable) {}
914
			public void setReadOnly(String variable) {}
890
		});
915
		});
891
		createJavaProject("P", new String[] {}, new String[] {"TEST_LIB,TEST_SRC,TEST_ROOT"}, "");
916
		createJavaProject("P", new String[] {}, new String[] {"TEST_LIB,TEST_SRC,TEST_ROOT"}, "");
892
		assertEquals(
917
		assertEquals(
Lines 909-914 Link Here
909
				buffer.append("Setting variable " + variable + " to " + path + "\n");
934
				buffer.append("Setting variable " + variable + " to " + path + "\n");
910
				JavaCore.setClasspathVariable(variable, path, null);
935
				JavaCore.setClasspathVariable(variable, path, null);
911
			}
936
			}
937
			public void setDeprecated(String variable) {}
938
			public void setReadOnly(String variable) {}
912
		});
939
		});
913
		createJavaProject("P", new String[] {}, new String[] {"TEST_LIB,TEST_SRC,TEST_ROOT"}, "");
940
		createJavaProject("P", new String[] {}, new String[] {"TEST_LIB,TEST_SRC,TEST_ROOT"}, "");
914
		assertEquals(
941
		assertEquals(
Lines 934-939 Link Here
934
				// do nothing
961
				// do nothing
935
				buffer.append("Ignoring request to initialize");
962
				buffer.append("Ignoring request to initialize");
936
			}
963
			}
964
			public void setDeprecated(String variable) {}
965
			public void setReadOnly(String variable) {}
937
		});
966
		});
938
		IPath path = JavaCore.getClasspathVariable("TEST_SRC");
967
		IPath path = JavaCore.getClasspathVariable("TEST_SRC");
939
		assertEquals(
968
		assertEquals(
Lines 1084-1089 Link Here
1084
		assertEquals("JavaCore preferences value should be unchanged", preferences.get(varName, "X"), initialValue);
1113
		assertEquals("JavaCore preferences value should be unchanged", preferences.get(varName, "X"), initialValue);
1085
	} finally {
1114
	} finally {
1086
		VariablesInitializer.reset();
1115
		VariablesInitializer.reset();
1116
		deleteProject("P1");
1117
	}
1118
}
1119
1120
/**
1121
 * @bug 138599: [model][classpath] Need a way to mark a classpath variable as deprecated
1122
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=138599"
1123
 */
1124
public void testVariableInitializerDeprecated() throws CoreException {
1125
	try {
1126
		// Create initializer
1127
		String varName = "TEST_DEPRECATED";
1128
		String filePath = "/P1/lib.jar";
1129
		DefaultVariableInitializer testInitializer = new DefaultVariableInitializer(new String[] {varName, filePath});
1130
		VariablesInitializer.setInitializer(testInitializer);
1131
		assertEquals("JavaCore classpath value should have been initialized", JavaCore.getClasspathVariable(varName).toString(), filePath);
1132
		
1133
		// Verify that Classpath Variable is deprecated
1134
		assertTrue("JavaCore classpath variable should be deprecated", JavaCore.isClasspathVariableDeprecated(varName));
1135
		assertTrue("Classpath Variable initializer should be deprecated", testInitializer.isDeprecated(varName));
1136
1137
		// Create project
1138
		IJavaProject project = createJavaProject("P1");
1139
		createFile("/P1/lib.jar", "");
1140
		IClasspathEntry variable = JavaCore.newVariableEntry(new Path("TEST_DEPRECATED"), null, null);
1141
		IJavaModelStatus status = JavaConventions.validateClasspathEntry(project, variable, false);
1142
		assertStatus("Classpath variable \'TEST_DEPRECATED\' in project P1 is deprecated", status);
1143
		assertFalse("Status should not be OK", status.isOK());
1144
		assertEquals("Status should have WARNING severity", IStatus.WARNING, status.getSeverity());
1145
		assertEquals("Status should have deprecated code", IJavaModelStatusConstants.DEPRECATED_VARIABLE, status.getCode());
1146
	} finally {
1147
		VariablesInitializer.reset();
1148
		deleteProject("P1");
1149
	}
1150
}
1151
public void testVariableInitializerUnboundAndDeprecated() throws CoreException {
1152
	try {
1153
		// Create initializer
1154
		String varName = "TEST_DEPRECATED";
1155
		String filePath = "/P1/lib.jar";
1156
		DefaultVariableInitializer testInitializer = new DefaultVariableInitializer(new String[] {varName, filePath});
1157
		VariablesInitializer.setInitializer(testInitializer);
1158
		assertEquals("JavaCore classpath value should have been initialized", JavaCore.getClasspathVariable(varName).toString(), filePath);
1159
		
1160
		// Verify that Classpath Variable is deprecated
1161
		assertTrue("JavaCore classpath variable should be deprecated", JavaCore.isClasspathVariableDeprecated(varName));
1162
		assertTrue("Classpath Variable initializer should be deprecated", testInitializer.isDeprecated(varName));
1163
1164
		// Create project
1165
		IJavaProject project = createJavaProject("P1");
1166
		IClasspathEntry variable = JavaCore.newVariableEntry(new Path("TEST_DEPRECATED"), null, null);
1167
		IJavaModelStatus status = JavaConventions.validateClasspathEntry(project, variable, false);
1168
		assertStatus("Project P1 is missing required library: \'lib.jar\'", status);
1169
		assertFalse("Status should not be OK", status.isOK());
1170
		assertEquals("Status should have WARNING severity", IStatus.ERROR, status.getSeverity());
1171
		assertEquals("Status should have deprecated code", IJavaModelStatusConstants.INVALID_CLASSPATH, status.getCode());
1172
	} finally {
1173
		VariablesInitializer.reset();
1174
		deleteProject("P1");
1175
	}
1176
}
1177
1178
/**
1179
 * @bug 156226: [model][classpath] Allow classpath variable to be marked as non modifiable
1180
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=156226"
1181
 */
1182
public void testVariableInitializerReadOnly() throws CoreException {
1183
	try {
1184
		// Create initializer
1185
		String varName = "TEST_READ_ONLY";
1186
		String path = "/P1/lib.jar";
1187
		VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] { varName, path }));
1188
		assertEquals("JavaCore classpath value should have been initialized", JavaCore.getClasspathVariable(varName).toString(), path);
1189
1190
		// verify that Classpath Variable is read-only
1191
		assertTrue("JavaCore classpath variable should be read-only", JavaCore.isClasspathVariableReadOnly(varName));
1192
		ClasspathVariableInitializer initializer = JavaCore.getClasspathVariableInitializer(varName);
1193
		assertTrue("Classpath Variable initializer should be read-only", initializer.isReadOnly());
1194
1195
		// Create project
1196
		IJavaProject project = createJavaProject("P1");
1197
		createFile("/P1/lib.jar", "");
1198
		IClasspathEntry variable = JavaCore.newVariableEntry(new Path("TEST_READ_ONLY"), null, null);
1199
		IJavaModelStatus status = JavaConventions.validateClasspathEntry(project, variable, false);
1200
		assertStatus("Classpath variable \'TEST_READ_ONLY\' in project P1 is read only", status);
1201
		assertFalse("Status should not be OK", status.isOK());
1202
		assertEquals("Status should have WARNING severity", IStatus.WARNING, status.getSeverity());
1203
		assertEquals("Status should have deprecated code", IJavaModelStatusConstants.READ_ONLY_VARIABLE, status.getCode());
1204
	} finally {
1205
		VariablesInitializer.reset();
1206
		deleteProject("P1");
1207
	}
1208
}
1209
public void testVariableInitializerDeprecatedAndReadOnly() throws CoreException {
1210
	try {
1211
		// Create initializer
1212
		String varName = "TEST_DEPRECATED_READ_ONLY";
1213
		String path = "/P1/lib.jar";
1214
		VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] { varName, path }));
1215
		assertEquals("JavaCore classpath value should have been initialized", JavaCore.getClasspathVariable(varName).toString(), path);
1216
1217
		// verify that Classpath Variable is read-only
1218
		assertTrue("JavaCore classpath variable should be read-only", JavaCore.isClasspathVariableDeprecated(varName));
1219
		assertTrue("JavaCore classpath variable should be read-only", JavaCore.isClasspathVariableReadOnly(varName));
1220
		ClasspathVariableInitializer initializer = JavaCore.getClasspathVariableInitializer(varName);
1221
		assertTrue("Classpath Variable initializer should be deprecated", initializer.isDeprecated());
1222
		assertTrue("Classpath Variable initializer should be read-only", initializer.isReadOnly());
1223
1224
		// Create project
1225
		IJavaProject project = createJavaProject("P1");
1226
		createFile("/P1/lib.jar", "");
1227
		IClasspathEntry variable = JavaCore.newVariableEntry(new Path("TEST_DEPRECATED_READ_ONLY"), null, null);
1228
		IJavaModelStatus status = JavaConventions.validateClasspathEntry(project, variable, false);
1229
		assertStatus("Several warnings/errors occured", status);
1230
		assertTrue("Wrong kind of status", status instanceof JavaModelStatus);
1231
		JavaModelStatus jms = (JavaModelStatus) status;
1232
		IStatus[] children = jms.getChildren();
1233
		assertEquals("Wrong number of children for multi-status", 2, children.length);
1234
		assertStatus("Classpath variable \'TEST_DEPRECATED_READ_ONLY\' in project P1 is deprecated", children[0]);
1235
		assertStatus("Classpath variable \'TEST_DEPRECATED_READ_ONLY\' in project P1 is read only", children[1]);
1236
		assertFalse("Status should not be OK", status.isOK());
1237
		assertEquals("Status should have WARNING severity", IStatus.WARNING, status.getSeverity());
1238
		assertEquals("Status should have deprecated code", IJavaModelStatusConstants.DEPRECATED_VARIABLE, status.getCode());
1239
	} finally {
1240
		VariablesInitializer.reset();
1241
		deleteProject("P1");
1087
	}
1242
	}
1088
}
1243
}
1089
1244
(-)src/org/eclipse/jdt/core/tests/model/VariablesInitializer.java (-1 / +5 lines)
Lines 21-26 Link Here
21
	
21
	
22
	public static interface ITestInitializer {
22
	public static interface ITestInitializer {
23
		public void initialize(String variable) throws JavaModelException;
23
		public void initialize(String variable) throws JavaModelException;
24
		public void setDeprecated(String variable);
25
		public void setReadOnly(String variable);
24
	}
26
	}
25
	
27
	
26
	public static void reset() {
28
	public static void reset() {
Lines 36-46 Link Here
36
	public static void setInitializer(ITestInitializer initializer) {
38
	public static void setInitializer(ITestInitializer initializer) {
37
		VariablesInitializer.initializer = initializer;
39
		VariablesInitializer.initializer = initializer;
38
	}
40
	}
39
	
41
40
	public void initialize(String variable) {
42
	public void initialize(String variable) {
41
		if (initializer == null) return;
43
		if (initializer == null) return;
42
		try {
44
		try {
43
			initializer.initialize(variable);
45
			initializer.initialize(variable);
46
			if (isDeprecated()) initializer.setDeprecated(variable);
47
			if (isReadOnly()) initializer.setReadOnly(variable);
44
		} catch (JavaModelException e) {
48
		} catch (JavaModelException e) {
45
			e.printStackTrace();
49
			e.printStackTrace();
46
		}
50
		}
(-)src/org/eclipse/jdt/core/tests/model/ClasspathTests.java (-17 / +1 lines)
Lines 35-41 Link Here
35
import org.eclipse.core.runtime.CoreException;
35
import org.eclipse.core.runtime.CoreException;
36
import org.eclipse.core.runtime.IPath;
36
import org.eclipse.core.runtime.IPath;
37
import org.eclipse.core.runtime.IProgressMonitor;
37
import org.eclipse.core.runtime.IProgressMonitor;
38
import org.eclipse.core.runtime.IStatus;
39
import org.eclipse.core.runtime.Path;
38
import org.eclipse.core.runtime.Path;
40
import org.eclipse.jdt.core.IAccessRule;
39
import org.eclipse.jdt.core.IAccessRule;
41
import org.eclipse.jdt.core.IClasspathAttribute;
40
import org.eclipse.jdt.core.IClasspathAttribute;
Lines 128-149 Link Here
128
		entry,
127
		entry,
129
		decoded);
128
		decoded);
130
}
129
}
131
protected void assertStatus(String expected, IStatus status) {
132
	String actual = status.getMessage();
133
	if (!expected.equals(actual)) {
134
	 	System.out.print(Util.displayString(actual, 2));
135
	 	System.out.println(",");
136
	}
137
	assertEquals(expected, actual);
138
}
139
protected void assertStatus(String message, String expected, IStatus status) {
140
	String actual = status.getMessage();
141
	if (!expected.equals(actual)) {
142
	 	System.out.print(Util.displayString(actual, 2));
143
	 	System.out.println(",");
144
	}
145
	assertEquals(message, expected, actual);
146
}
147
protected File createFile(File parent, String name, String content) throws IOException {
130
protected File createFile(File parent, String name, String content) throws IOException {
148
	File file = new File(parent, name);
131
	File file = new File(parent, name);
149
	FileOutputStream out = new FileOutputStream(file);
132
	FileOutputStream out = new FileOutputStream(file);
Lines 1795-1800 Link Here
1795
		this.deleteProject("P2");
1778
		this.deleteProject("P2");
1796
	}
1779
	}
1797
}
1780
}
1781
1798
/**
1782
/**
1799
 * Adding an entry to the classpath for a library that does not exist
1783
 * Adding an entry to the classpath for a library that does not exist
1800
 * should not break the model. The classpath should contain the
1784
 * should not break the model. The classpath should contain the
(-)src/org/eclipse/jdt/core/tests/model/ModifyingResourceTests.java (-3 / +16 lines)
Lines 20-28 Link Here
20
import org.eclipse.jdt.internal.compiler.batch.Main;
20
import org.eclipse.jdt.internal.compiler.batch.Main;
21
import org.eclipse.jdt.internal.core.JavaElement;
21
import org.eclipse.jdt.internal.core.JavaElement;
22
22
23
/*
24
 * Tests that modify resources in the workspace.
25
 */
26
public class ModifyingResourceTests extends AbstractJavaModelTests {
23
public class ModifyingResourceTests extends AbstractJavaModelTests {
27
	
24
	
28
public ModifyingResourceTests(String name) {
25
public ModifyingResourceTests(String name) {
Lines 38-43 Link Here
38
		expected,
35
		expected,
39
		actual);
36
		actual);
40
}
37
}
38
protected void assertStatus(String expected, IStatus status) {
39
	String actual = status.getMessage();
40
	if (!expected.equals(actual)) {
41
	 	System.out.print(Util.displayString(actual, 2));
42
	 	System.out.println(",");
43
	}
44
	assertEquals(expected, actual);
45
}
46
protected void assertStatus(String message, String expected, IStatus status) {
47
	String actual = status.getMessage();
48
	if (!expected.equals(actual)) {
49
	 	System.out.print(Util.displayString(actual, 2));
50
	 	System.out.println(",");
51
	}
52
	assertEquals(message, expected, actual);
53
}
41
/**
54
/**
42
 * E.g. <code>
55
 * E.g. <code>
43
 * org.eclipse.jdt.tests.core.ModifyingResourceTests.generateClassFile(
56
 * org.eclipse.jdt.tests.core.ModifyingResourceTests.generateClassFile(
(-)plugin.xml (+16 lines)
Lines 12-17 Link Here
12
		<classpathVariableInitializer
12
		<classpathVariableInitializer
13
			variable="TEST_ROOT"
13
			variable="TEST_ROOT"
14
			class="org.eclipse.jdt.core.tests.model.VariablesInitializer"/>
14
			class="org.eclipse.jdt.core.tests.model.VariablesInitializer"/>
15
  <classpathVariableInitializer
16
        class="org.eclipse.jdt.core.tests.model.VariablesInitializer"
17
        deprecated="Test deprecated flag"
18
        variable="TEST_DEPRECATED">
19
  </classpathVariableInitializer>
20
  <classpathVariableInitializer
21
        class="org.eclipse.jdt.core.tests.model.VariablesInitializer"
22
        readOnly="true"
23
        variable="TEST_READ_ONLY">
24
  </classpathVariableInitializer>
25
  <classpathVariableInitializer
26
        class="org.eclipse.jdt.core.tests.model.VariablesInitializer"
27
        deprecated="A deprecated and read-only initializer"
28
        readOnly="true"
29
        variable="TEST_DEPRECATED_READ_ONLY">
30
  </classpathVariableInitializer>
15
	</extension>		
31
	</extension>		
16
32
17
	<!-- Classpath container initializer -->
33
	<!-- Classpath container initializer -->

Return to bug 138599