KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > core > refactoring > descriptors > JavaRefactoringDescriptor


1 /*******************************************************************************
2  * Copyright (c) 2006 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  *******************************************************************************/

11 package org.eclipse.jdt.core.refactoring.descriptors;
12
13 import java.text.MessageFormat JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.Map JavaDoc;
16
17 import org.eclipse.core.runtime.Assert;
18 import org.eclipse.core.runtime.CoreException;
19 import org.eclipse.core.runtime.IPath;
20 import org.eclipse.core.runtime.IStatus;
21 import org.eclipse.core.runtime.Path;
22 import org.eclipse.core.runtime.Status;
23
24 import org.eclipse.core.resources.IResource;
25 import org.eclipse.core.resources.IWorkspaceRoot;
26 import org.eclipse.core.resources.ResourcesPlugin;
27
28 import org.eclipse.ltk.core.refactoring.Refactoring;
29 import org.eclipse.ltk.core.refactoring.RefactoringContribution;
30 import org.eclipse.ltk.core.refactoring.RefactoringCore;
31 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
32 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
33
34 import org.eclipse.jdt.core.IJavaElement;
35 import org.eclipse.jdt.core.IJavaProject;
36 import org.eclipse.jdt.core.IMethod;
37 import org.eclipse.jdt.core.JavaCore;
38 import org.eclipse.jdt.core.WorkingCopyOwner;
39
40 import org.eclipse.jdt.internal.core.manipulation.JavaManipulationPlugin;
41 import org.eclipse.jdt.internal.core.refactoring.descriptors.DescriptorMessages;
42
43 /**
44  * Partial implementation of a java refactoring descriptor.
45  * <p>
46  * This class provides features common to all Java refactorings.
47  * </p>
48  * <p>
49  * Note: this class is not intended to be extended outside the refactoring
50  * framework.
51  * </p>
52  *
53  * @since 3.3
54  */

55 public abstract class JavaRefactoringDescriptor extends RefactoringDescriptor {
56
57     /**
58      * Predefined argument called <code>element&lt;Number&gt;</code>.
59      * <p>
60      * This argument should be used to describe the elements being refactored.
61      * The value of this argument does not necessarily have to uniquely identify
62      * the elements. However, it must be possible to uniquely identify the
63      * elements using the value of this argument in conjunction with the values
64      * of the other user-defined attributes.
65      * </p>
66      * <p>
67      * The element arguments are simply distinguished by appending a number to
68      * the argument name, e.g. element1. The indices of this argument are one-based.
69      * </p>
70      */

71     protected static final String JavaDoc ATTRIBUTE_ELEMENT= "element"; //$NON-NLS-1$
72

73     /**
74      * Predefined argument called <code>input</code>.
75      * <p>
76      * This argument should be used to describe the element being refactored.
77      * The value of this argument does not necessarily have to uniquely identify
78      * the input element. However, it must be possible to uniquely identify the
79      * input element using the value of this argument in conjunction with the
80      * values of the other user-defined attributes.
81      * </p>
82      */

83     protected static final String JavaDoc ATTRIBUTE_INPUT= "input"; //$NON-NLS-1$
84

85     /**
86      * Predefined argument called <code>name</code>.
87      * <p>
88      * This argument should be used to name the element being refactored. The
89      * value of this argument may be shown in the user interface.
90      * </p>
91      */

92     protected static final String JavaDoc ATTRIBUTE_NAME= "name"; //$NON-NLS-1$
93

94     /**
95      * Predefined argument called <code>references</code>.
96      * <p>
97      * This argument should be used to describe whether references to the
98      * elements being refactored should be updated as well. The value of this
99      * argument is either <code>"true"</code> or <code>"false"</code>.
100      * </p>
101      */

102     protected static final String JavaDoc ATTRIBUTE_REFERENCES= "references"; //$NON-NLS-1$
103

104     /**
105      * Predefined argument called <code>selection</code>.
106      * <p>
107      * This argument should be used to describe user input selections within a
108      * text file. The value of this argument has the format "offset length".
109      * </p>
110      */

111     protected static final String JavaDoc ATTRIBUTE_SELECTION= "selection"; //$NON-NLS-1$
112

113     /** The version attribute */
114     protected static final String JavaDoc ATTRIBUTE_VERSION= "version"; //$NON-NLS-1$
115

116     /**
117      * Constant describing the jar migration flag (value: <code>65536</code>).
118      * <p>
119      * Clients should set this flag to indicate that the refactoring can be
120      * stored to a JAR file in order to be accessible to the Migrate JAR File
121      * refactoring, regardless whether there is a source attachment to the JAR
122      * file or not. If this flag is set, <code>JAR_REFACTORING</code> should
123      * be set as well.
124      * </p>
125      *
126      * @see #JAR_REFACTORING
127      */

128     public static final int JAR_MIGRATION= 1 << 16;
129
130     /**
131      * Constant describing the jar refactoring flag (value: <code>524288</code>).
132      * <p>
133      * Clients should set this flag to indicate that the refactoring in
134      * principle can be performed on binary elements originating from a JAR
135      * file. Refactorings which are able to run on binary elements, but require
136      * a correctly configured source attachment to work must set the
137      * <code>JAR_SOURCE_ATTACHMENT</code> flag as well.
138      * </p>
139      *
140      * @see #JAR_SOURCE_ATTACHMENT
141      */

142     public static final int JAR_REFACTORING= 1 << 19;
143
144     /**
145      * Constant describing the jar source attachment flag (value:
146      * <code>262144</code>).
147      * <p>
148      * Clients should set this flag to indicate that the refactoring can be
149      * performed on binary elements originating from a JAR file if and only if
150      * it has a correctly configured source attachment.
151      * </p>
152      *
153      * @see #JAR_REFACTORING
154      */

155     public static final int JAR_SOURCE_ATTACHMENT= 1 << 18;
156
157     /** The version value <code>1.0</code> */
158     protected static final String JavaDoc VALUE_VERSION_1_0= "1.0"; //$NON-NLS-1$
159

160     /**
161      * Converts the specified element to an input handle.
162      *
163      * @param project
164      * the project, or <code>null</code> for the workspace
165      * @param element
166      * the element
167      * @return a corresponding input handle
168      */

169     protected static String JavaDoc elementToHandle(final String JavaDoc project, final IJavaElement element) {
170         final String JavaDoc handle= element.getHandleIdentifier();
171         if (project != null && !(element instanceof IJavaProject)) {
172             final String JavaDoc id= element.getJavaProject().getHandleIdentifier();
173             return handle.substring(id.length());
174         }
175         return handle;
176     }
177
178     /**
179      * Converts an input handle back to the corresponding java element.
180      *
181      * @param project
182      * the project, or <code>null</code> for the workspace
183      * @param handle
184      * the input handle
185      * @return the corresponding java element, or <code>null</code> if no such
186      * element exists
187      */

188     protected static IJavaElement handleToElement(final String JavaDoc project, final String JavaDoc handle) {
189         return handleToElement(project, handle, true);
190     }
191
192     /**
193      * Converts an input handle back to the corresponding java element.
194      *
195      * @param project
196      * the project, or <code>null</code> for the workspace
197      * @param handle
198      * the input handle
199      * @param check
200      * <code>true</code> to check for existence of the element,
201      * <code>false</code> otherwise
202      * @return the corresponding java element, or <code>null</code> if no such
203      * element exists
204      */

205     protected static IJavaElement handleToElement(final String JavaDoc project, final String JavaDoc handle, final boolean check) {
206         return handleToElement(null, project, handle, check);
207     }
208
209     /**
210      * Converts an input handle back to the corresponding java element.
211      *
212      * @param owner
213      * the working copy owner
214      * @param project
215      * the project, or <code>null</code> for the workspace
216      * @param handle
217      * the input handle
218      * @param check
219      * <code>true</code> to check for existence of the element,
220      * <code>false</code> otherwise
221      * @return the corresponding java element, or <code>null</code> if no such
222      * element exists
223      */

224     protected static IJavaElement handleToElement(final WorkingCopyOwner owner, final String JavaDoc project, final String JavaDoc handle, final boolean check) {
225         IJavaElement element= null;
226         if (owner != null)
227             element= JavaCore.create(handle, owner);
228         else
229             element= JavaCore.create(handle);
230         if (element == null && project != null) {
231             final IJavaProject javaProject= JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()).getJavaProject(project);
232             final String JavaDoc identifier= javaProject.getHandleIdentifier();
233             if (owner != null)
234                 element= JavaCore.create(identifier + handle, owner);
235             else
236                 element= JavaCore.create(identifier + handle);
237         }
238         if (check && element instanceof IMethod) {
239             final IMethod method= (IMethod) element;
240             final IMethod[] methods= method.getDeclaringType().findMethods(method);
241             if (methods != null && methods.length > 0)
242                 element= methods[0];
243         }
244         if (element != null && (!check || element.exists()))
245             return element;
246         return null;
247     }
248
249     /**
250      * Converts an input handle with the given prefix back to the corresponding
251      * resource.
252      *
253      * @param project
254      * the project, or <code>null</code> for the workspace
255      * @param handle
256      * the input handle
257      *
258      * @return the corresponding resource, or <code>null</code> if no such
259      * resource exists
260      */

261     protected static IResource handleToResource(final String JavaDoc project, final String JavaDoc handle) {
262         final IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
263         if ("".equals(handle)) //$NON-NLS-1$
264
return null;
265         final IPath path= Path.fromPortableString(handle);
266         if (path == null)
267             return null;
268         if (project != null && !"".equals(project)) //$NON-NLS-1$
269
return root.getProject(project).findMember(path);
270         return root.findMember(path);
271     }
272
273     /**
274      * Converts the specified resource to an input handle.
275      *
276      * @param project
277      * the project, or <code>null</code> for the workspace
278      * @param resource
279      * the resource
280      *
281      * @return the input handle
282      */

283     protected static String JavaDoc resourceToHandle(final String JavaDoc project, final IResource resource) {
284         if (project != null && !"".equals(project)) //$NON-NLS-1$
285
return resource.getProjectRelativePath().toPortableString();
286         return resource.getFullPath().toPortableString();
287     }
288
289     /** The argument map */
290     protected final Map JavaDoc fArguments;
291
292     /**
293      * Creates a new java refactoring descriptor.
294      *
295      * @param id
296      * the unique id of the refactoring
297      */

298     protected JavaRefactoringDescriptor(final String JavaDoc id) {
299         this(id, new HashMap JavaDoc());
300     }
301
302     /**
303      * Creates a new java refactoring descriptor.
304      *
305      * @param id
306      * the unique id of the refactoring
307      * @param arguments
308      * the argument map to use
309      */

310     protected JavaRefactoringDescriptor(final String JavaDoc id, final Map JavaDoc arguments) {
311         super(id, null, DescriptorMessages.JavaRefactoringDescriptor_not_available, null, RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE);
312         fArguments= arguments;
313         fArguments.put(ATTRIBUTE_VERSION, VALUE_VERSION_1_0);
314     }
315
316     /**
317      * {@inheritDoc}
318      */

319     public Refactoring createRefactoring(final RefactoringStatus status) throws CoreException {
320         populateArgumentMap();
321         Refactoring refactoring= null;
322         final String JavaDoc id= getID();
323         final RefactoringContribution contribution= RefactoringCore.getRefactoringContribution(id);
324         if (contribution != null) {
325             final RefactoringDescriptor descriptor= contribution.createDescriptor(id, getProject(), getDescription(), getComment(), fArguments, getFlags());
326             if (descriptor != null) {
327                 refactoring= descriptor.createRefactoring(status);
328             } else
329                 JavaManipulationPlugin.log(new Status(IStatus.ERROR, JavaManipulationPlugin.getPluginId(), 0, MessageFormat.format(DescriptorMessages.JavaRefactoringDescriptor_no_resulting_descriptor, new Object JavaDoc[] { id}), null));
330         }
331         return refactoring;
332     }
333
334     /**
335      * Returns the argument map of this refactoring descriptor.
336      * <p>
337      * The returned map is a copy of the argument map. Modifying the result does
338      * not change the refactoring descriptor itself.
339      * </p>
340      * <p>
341      * Note: This API must not be extended or reimplemented and should not be
342      * called from outside the refactoring framework.
343      * </p>
344      *
345      * @return the argument map
346      */

347     protected Map JavaDoc getArguments() {
348         populateArgumentMap();
349         return new HashMap JavaDoc(fArguments);
350     }
351
352     /**
353      * Populates the refactoring descriptor argument map based on the specified
354      * arguments.
355      */

356     protected void populateArgumentMap() {
357         Assert.isTrue(!validateDescriptor().hasFatalError(), "Validation returns a fatal error status."); //$NON-NLS-1$
358
}
359
360     /**
361      * Sets the details comment of this refactoring.
362      * <p>
363      * This information is used in the user interface to show additional details
364      * about the performed refactoring. The default is to use no details
365      * comment.
366      * </p>
367      *
368      * @param comment
369      * the details comment to set, or <code>null</code> to set no
370      * details comment
371      *
372      * @see #getComment()
373      */

374     public void setComment(final String JavaDoc comment) {
375         super.setComment(comment);
376     }
377
378     /**
379      * Sets the description of this refactoring.
380      * <p>
381      * This information is used to label a refactoring in the user interface.
382      * The default is an unspecified, but legal description.
383      * </p>
384      *
385      * @param description
386      * the non-empty description of the refactoring to set
387      *
388      * @see #getDescription()
389      */

390     public void setDescription(final String JavaDoc description) {
391         super.setDescription(description);
392     }
393
394     /**
395      * Sets the flags of this refactoring.
396      * <p>
397      * The default is
398      * <code>RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE</code>,
399      * unless overridden by a concrete subclass. Clients may use refactoring
400      * flags to indicate special capabilities of Java refactorings.
401      * </p>
402      *
403      * @param flags
404      * the flags to set, or <code>RefactoringDescriptor.NONE</code>
405      * to clear the flags
406      *
407      * @see #getFlags()
408      *
409      * @see RefactoringDescriptor#NONE
410      * @see RefactoringDescriptor#STRUCTURAL_CHANGE
411      * @see RefactoringDescriptor#BREAKING_CHANGE
412      * @see RefactoringDescriptor#MULTI_CHANGE
413      *
414      * @see #JAR_MIGRATION
415      * @see #JAR_REFACTORING
416      * @see #JAR_SOURCE_ATTACHMENT
417      */

418     public void setFlags(final int flags) {
419         super.setFlags(flags);
420     }
421
422     /**
423      * Sets the project name of this refactoring.
424      * <p>
425      * The default is to associate the refactoring with the workspace.
426      * Subclasses should call this method with the project name associated with
427      * the refactoring's input elements, if available.
428      * </p>
429      *
430      * @param project
431      * the non-empty project name to set, or <code>null</code> for
432      * the workspace
433      *
434      * @see #getProject()
435      */

436     public void setProject(final String JavaDoc project) {
437         super.setProject(project);
438     }
439
440     /**
441      * Validates the refactoring descriptor with respect to the constraints
442      * imposed by the represented refactoring.
443      * <p>
444      * Clients must call this method to verify that all arguments have been
445      * correctly set and that they satisfy the constraints imposed by specific
446      * refactorings. Returning a refactoring status of severity
447      * {@link RefactoringStatus#FATAL} indicates that the refactoring descriptor
448      * cannot be used to create a refactoring instance.
449      * </p>
450      *
451      * @return a refactoring status describing the outcome of the validation
452      */

453     public RefactoringStatus validateDescriptor() {
454         RefactoringStatus status= new RefactoringStatus();
455         String JavaDoc description= getDescription();
456         if (description == null || "".equals(description)) //$NON-NLS-1$
457
status.merge(RefactoringStatus.createFatalErrorStatus(DescriptorMessages.JavaRefactoringDescriptor_no_description));
458         return status;
459     }
460 }
Popular Tags