KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > core > ClasspathContainerInitializer


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * IBM Corporation - added support for requesting updates of a particular
11  * container for generic container operations.
12  * - canUpdateClasspathContainer(IPath, IJavaProject)
13  * - requestClasspathContainerUpdate(IPath, IJavaProject, IClasspathContainer)
14  * IBM Corporation - allow initializers to provide a readable description
15  * of a container reference, ahead of actual resolution.
16  * - getDescription(IPath, IJavaProject)
17  *******************************************************************************/

18 package org.eclipse.jdt.core;
19
20 import org.eclipse.core.runtime.*;
21 import org.eclipse.jdt.internal.core.JavaModelStatus;
22
23 /**
24  * Abstract base implementation of all classpath container initializer.
25  * Classpath variable containers are used in conjunction with the
26  * "org.eclipse.jdt.core.classpathContainerInitializer" extension point.
27  * <p>
28  * Clients should subclass this class to implement a specific classpath
29  * container initializer. The subclass must have a public 0-argument
30  * constructor and a concrete implementation of {@link #initialize(IPath, IJavaProject)}.
31  * <p>
32  * Multiple classpath containers can be registered, each of them declares
33  * the container ID they can handle, so as to narrow the set of containers they
34  * can resolve, in other words, a container initializer is guaranteed to only be
35  * activated to resolve containers which match the ID they registered onto.
36  * <p>
37  * In case multiple container initializers collide on the same container ID, the first
38  * registered one will be invoked.
39  *
40  * @see IClasspathEntry
41  * @see IClasspathContainer
42  * @since 2.0
43  */

44 public abstract class ClasspathContainerInitializer {
45
46     /**
47      * Status code indicating that an attribute is not supported.
48      *
49      * @see #getAccessRulesStatus(IPath, IJavaProject)
50      * @see #getAttributeStatus(IPath, IJavaProject, String)
51      * @see #getSourceAttachmentStatus(IPath, IJavaProject)
52      *
53      * @since 3.3
54      */

55     public static final int ATTRIBUTE_NOT_SUPPORTED = 1;
56
57     /**
58      * Status code indicating that an attribute is not modifiable.
59      *
60      * @see #getAccessRulesStatus(IPath, IJavaProject)
61      * @see #getAttributeStatus(IPath, IJavaProject, String)
62      * @see #getSourceAttachmentStatus(IPath, IJavaProject)
63      *
64      * @since 3.3
65      */

66     public static final int ATTRIBUTE_READ_ONLY = 2;
67
68    /**
69      * Creates a new classpath container initializer.
70      */

71     public ClasspathContainerInitializer() {
72         // a classpath container initializer must have a public 0-argument constructor
73
}
74
75     /**
76      * Binds a classpath container to a <code>IClasspathContainer</code> for a given project,
77      * or silently fails if unable to do so.
78      * <p>
79      * A container is identified by a container path, which must be formed of two segments.
80      * The first segment is used as a unique identifier (which this initializer did register onto), and
81      * the second segment can be used as an additional hint when performing the resolution.
82      * <p>
83      * The initializer is invoked if a container path needs to be resolved for a given project, and no
84      * value for it was recorded so far. The implementation of the initializer would typically set the
85      * corresponding container using <code>JavaCore#setClasspathContainer</code>.
86      * <p>
87      * A container initialization can be indirectly performed while attempting to resolve a project
88      * classpath using <code>IJavaProject#getResolvedClasspath(</code>; or directly when using
89      * <code>JavaCore#getClasspathContainer</code>. During the initialization process, any attempt
90      * to further obtain the same container will simply return <code>null</code> so as to avoid an
91      * infinite regression of initializations.
92      * <p>
93      * A container initialization may also occur indirectly when setting a project classpath, as the operation
94      * needs to resolve the classpath for validation purpose. While the operation is in progress, a referenced
95      * container initializer may be invoked. If the initializer further tries to access the referring project classpath,
96      * it will not see the new assigned classpath until the operation has completed. Note that once the Java
97      * change notification occurs (at the end of the operation), the model has been updated, and the project
98      * classpath can be queried normally.
99      * <p>
100      * This method is called by the Java model to give the party that defined
101      * this particular kind of classpath container the chance to install
102      * classpath container objects that will be used to convert classpath
103      * container entries into simpler classpath entries. The method is typically
104      * called exactly once for a given Java project and classpath container
105      * entry. This method must not be called by other clients.
106      * <p>
107      * There are a wide variety of conditions under which this method may be
108      * invoked. To ensure that the implementation does not interfere with
109      * correct functioning of the Java model, the implementation should use
110      * only the following Java model APIs:
111      * <ul>
112      * <li>{@link JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], org.eclipse.core.runtime.IProgressMonitor)}</li>
113      * <li>{@link JavaCore#getClasspathContainer(IPath, IJavaProject)}</li>
114      * <li>{@link JavaCore#create(org.eclipse.core.resources.IWorkspaceRoot)}</li>
115      * <li>{@link JavaCore#create(org.eclipse.core.resources.IProject)}</li>
116      * <li>{@link IJavaModel#getJavaProjects()}</li>
117      * <li>Java element operations marked as "handle-only"</li>
118      * </ul>
119      * The effects of using other Java model APIs are unspecified.
120      * </p>
121      *
122      * @param containerPath a two-segment path (ID/hint) identifying the container that needs
123      * to be resolved
124      * @param project the Java project in which context the container is to be resolved.
125      * This allows generic containers to be bound with project specific values.
126      * @throws CoreException if an exception occurs during the initialization
127      *
128      * @see JavaCore#getClasspathContainer(IPath, IJavaProject)
129      * @see JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], org.eclipse.core.runtime.IProgressMonitor)
130      * @see IClasspathContainer
131      */

132     public abstract void initialize(IPath containerPath, IJavaProject project) throws CoreException;
133
134     /**
135      * Returns <code>true</code> if this container initializer can be requested to perform updates
136      * on its own container values. If so, then an update request will be performed using
137      * {@link #requestClasspathContainerUpdate(IPath, IJavaProject, IClasspathContainer)}.
138      * <p>
139      * @param containerPath the path of the container which requires to be updated
140      * @param project the project for which the container is to be updated
141      * @return returns <code>true</code> if the container can be updated
142      * @since 2.1
143      */

144     public boolean canUpdateClasspathContainer(IPath containerPath, IJavaProject project) {
145
146         // By default, classpath container initializers do not accept updating containers
147
return false;
148     }
149
150     /**
151      * Request a registered container definition to be updated according to a container suggestion. The container suggestion
152      * only acts as a place-holder to pass along the information to update the matching container definition(s) held by the
153      * container initializer. In particular, it is not expected to store the container suggestion as is, but rather adjust
154      * the actual container definition based on suggested changes.
155      * <p>
156      * IMPORTANT: In reaction to receiving an update request, a container initializer will update the corresponding
157      * container definition (after reconciling changes) at its earliest convenience, using
158      * {@link JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], IProgressMonitor)}.
159      * Until it does so, the update will not be reflected in the Java Model.
160      * <p>
161      * In order to anticipate whether the container initializer allows to update its containers, the predicate
162      * {@link #canUpdateClasspathContainer(IPath, IJavaProject)} should be used.
163      * <p>
164      * @param containerPath the path of the container which requires to be updated
165      * @param project the project for which the container is to be updated
166      * @param containerSuggestion a suggestion to update the corresponding container definition
167      * @throws CoreException when <code>JavaCore#setClasspathContainer</code> would throw any.
168      * @see JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], org.eclipse.core.runtime.IProgressMonitor)
169      * @see ClasspathContainerInitializer#canUpdateClasspathContainer(IPath, IJavaProject)
170      * @since 2.1
171      */

172
173     public void requestClasspathContainerUpdate(IPath containerPath, IJavaProject project, IClasspathContainer containerSuggestion) throws CoreException {
174
175         // By default, classpath container initializers do not accept updating containers
176
}
177
178     /**
179      * Returns a readable description for a container path. A readable description for a container path can be
180      * used for improving the display of references to container, without actually needing to resolve them.
181      * A good implementation should answer a description consistent with the description of the associated
182      * target container (see {@link IClasspathContainer#getDescription()}).
183      *
184      * @param containerPath the path of the container which requires a readable description
185      * @param project the project from which the container is referenced
186      * @return a string description of the container
187      * @since 2.1
188      */

189     public String JavaDoc getDescription(IPath containerPath, IJavaProject project) {
190
191         // By default, a container path is the only available description
192
return containerPath.makeRelative().toString();
193     }
194
195     /**
196      * Returns a classpath container that is used after this initializer failed to bind a classpath container
197      * to a {@link IClasspathContainer} for the given project. A non-<code>null</code>
198      * failure container indicates that there will be no more request to initialize the given container
199      * for the given project.
200      * <p>
201      * By default a non-<code>null</code> failure container with no classpath entries is returned.
202      * Clients wishing to get a chance to run the initializer again should override this method
203      * and return <code>null</code>.
204      * </p>
205      *
206      * @param containerPath the path of the container which failed to initialize
207      * @param project the project from which the container is referenced
208      * @return the default failure container, or <code>null</code> if wishing to run the initializer again
209      * @since 3.3
210      */

211     public IClasspathContainer getFailureContainer(final IPath containerPath, IJavaProject project) {
212         final String JavaDoc description = getDescription(containerPath, project);
213         return
214             new IClasspathContainer() {
215                 public IClasspathEntry[] getClasspathEntries() {
216                     return new IClasspathEntry[0];
217                 }
218                 public String JavaDoc getDescription() {
219                     return description;
220                 }
221                 public int getKind() {
222                     return 0;
223                 }
224                 public IPath getPath() {
225                     return containerPath;
226                 }
227                 public String JavaDoc toString() {
228                     return getDescription();
229                 }
230             };
231     }
232
233     /**
234      * Returns an object which identifies a container for comparison purpose. This allows
235      * to eliminate redundant containers when accumulating classpath entries (e.g.
236      * runtime classpath computation). When requesting a container comparison ID, one
237      * should ensure using its corresponding container initializer. Indeed, a random container
238      * initializer cannot be held responsible for determining comparison IDs for arbitrary
239      * containers.
240      * <p>
241      * @param containerPath the path of the container which is being checked
242      * @param project the project for which the container is to being checked
243      * @return returns an Object identifying the container for comparison
244      * @since 3.0
245      */

246     public Object JavaDoc getComparisonID(IPath containerPath, IJavaProject project) {
247
248         // By default, containers are identical if they have the same containerPath first segment,
249
// but this may be refined by other container initializer implementations.
250
if (containerPath == null) {
251             return null;
252         } else {
253             return containerPath.segment(0);
254         }
255     }
256
257     /**
258      * Returns the access rules attribute status according to this initializer.
259      * <p>
260      * The returned {@link IStatus status} can have one of the following severities:
261      * <ul>
262      * <li>{@link IStatus#OK OK}: means that the attribute is supported
263      * <strong>and</strong> is modifiable</li>
264      * <li>{@link IStatus#ERROR ERROR}: means that either the attribute
265      * is not supported or is not modifiable.<br>
266      * In this case, the {@link IStatus#getCode() code}will have
267      * respectively the {@link #ATTRIBUTE_NOT_SUPPORTED} value
268      * or the {@link #ATTRIBUTE_READ_ONLY} value.</li>
269      * </ul>
270      * </p><p>
271      * The status message can contain more information.
272      * </p><p>
273      * If the subclass does not override this method, then the default behavior is
274      * to return {@link IStatus#OK OK} if and only if the classpath container can
275      * be updated (see {@link #canUpdateClasspathContainer(IPath, IJavaProject)}).
276      * </p>
277      *
278      * @param containerPath the path of the container which requires to be
279      * updated
280      * @param project the project for which the container is to be updated
281      * @return returns the access rules attribute status
282      *
283      * @since 3.3
284      */

285     public IStatus getAccessRulesStatus(IPath containerPath, IJavaProject project) {
286
287         if (canUpdateClasspathContainer(containerPath, project)) {
288             return Status.OK_STATUS;
289         }
290         return new JavaModelStatus(ATTRIBUTE_READ_ONLY);
291     }
292
293     /**
294      * Returns the extra attribute status according to this initializer.
295      * <p>
296      * The returned {@link IStatus status} can have one of the following severities:
297      * <ul>
298      * <li>{@link IStatus#OK OK}: means that the attribute is supported
299      * <strong>and</strong> is modifiable</li>
300      * <li>{@link IStatus#ERROR ERROR}: means that either the attribute
301      * is not supported or is not modifiable.<br>
302      * In this case, the {@link IStatus#getCode() code}will have
303      * respectively the {@link #ATTRIBUTE_NOT_SUPPORTED} value
304      * or the {@link #ATTRIBUTE_READ_ONLY} value.</li>
305      * </ul>
306      * </p><p>
307      * The status message can contain more information.
308      * </p><p>
309      * If the subclass does not override this method, then the default behavior is
310      * to return {@link IStatus#OK OK} if and only if the classpath container can
311      * be updated (see {@link #canUpdateClasspathContainer(IPath, IJavaProject)}).
312      * </p>
313      *
314      * @param containerPath the path of the container which requires to be
315      * updated
316      * @param project the project for which the container is to be updated
317      * @param attributeKey the key of the extra attribute
318      * @return returns the extra attribute status
319      * @see IClasspathAttribute
320      *
321      * @since 3.3
322      */

323     public IStatus getAttributeStatus(IPath containerPath, IJavaProject project, String JavaDoc attributeKey) {
324
325         if (canUpdateClasspathContainer(containerPath, project)) {
326             return Status.OK_STATUS;
327         }
328         return new JavaModelStatus(ATTRIBUTE_READ_ONLY);
329     }
330
331     /**
332      * Returns the source attachment attribute status according to this initializer.
333      * <p>
334      * The returned {@link IStatus status} can have one of the following severities:
335      * <ul>
336      * <li>{@link IStatus#OK OK}: means that the attribute is supported
337      * <strong>and</strong> is modifiable</li>
338      * <li>{@link IStatus#ERROR ERROR}: means that either the attribute
339      * is not supported or is not modifiable.<br>
340      * In this case, the {@link IStatus#getCode() code}will have
341      * respectively the {@link #ATTRIBUTE_NOT_SUPPORTED} value
342      * or the {@link #ATTRIBUTE_READ_ONLY} value.</li>
343      * </ul>
344      * </p><p>
345      * The status message can contain more information.
346      * </p><p>
347      * If the subclass does not override this method, then the default behavior is
348      * to return {@link IStatus#OK OK} if and only if the classpath container can
349      * be updated (see {@link #canUpdateClasspathContainer(IPath, IJavaProject)}).
350      * </p>
351      *
352      * @param containerPath the path of the container which requires to be
353      * updated
354      * @param project the project for which the container is to be updated
355      * @return returns the source attachment attribute status
356      *
357      * @since 3.3
358      */

359     public IStatus getSourceAttachmentStatus(IPath containerPath, IJavaProject project) {
360
361         if (canUpdateClasspathContainer(containerPath, project)) {
362             return Status.OK_STATUS;
363         }
364         return new JavaModelStatus(ATTRIBUTE_READ_ONLY);
365     }
366 }
367
368
Popular Tags