KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > refactoring > structure > ExtractSupertypeProcessor


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

11 package org.eclipse.jdt.internal.corext.refactoring.structure;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Arrays JavaDoc;
15 import java.util.Collection JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.HashSet JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.LinkedList JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Map JavaDoc;
22 import java.util.Set JavaDoc;
23
24 import org.eclipse.text.edits.MalformedTreeException;
25 import org.eclipse.text.edits.TextEdit;
26 import org.eclipse.text.edits.TextEditCopier;
27
28 import org.eclipse.core.runtime.Assert;
29 import org.eclipse.core.runtime.CoreException;
30 import org.eclipse.core.runtime.IProgressMonitor;
31 import org.eclipse.core.runtime.NullProgressMonitor;
32 import org.eclipse.core.runtime.OperationCanceledException;
33 import org.eclipse.core.runtime.SubProgressMonitor;
34
35 import org.eclipse.core.resources.IFile;
36
37 import org.eclipse.jface.text.BadLocationException;
38 import org.eclipse.jface.text.Document;
39 import org.eclipse.jface.text.IDocument;
40
41 import org.eclipse.ltk.core.refactoring.Change;
42 import org.eclipse.ltk.core.refactoring.GroupCategory;
43 import org.eclipse.ltk.core.refactoring.GroupCategorySet;
44 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
45 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
46 import org.eclipse.ltk.core.refactoring.TextChange;
47 import org.eclipse.ltk.core.refactoring.TextEditBasedChange;
48 import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
49 import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
50
51 import org.eclipse.jdt.core.Flags;
52 import org.eclipse.jdt.core.ICompilationUnit;
53 import org.eclipse.jdt.core.IJavaElement;
54 import org.eclipse.jdt.core.IJavaProject;
55 import org.eclipse.jdt.core.IMember;
56 import org.eclipse.jdt.core.IMethod;
57 import org.eclipse.jdt.core.IType;
58 import org.eclipse.jdt.core.ITypeParameter;
59 import org.eclipse.jdt.core.JavaModelException;
60 import org.eclipse.jdt.core.dom.AST;
61 import org.eclipse.jdt.core.dom.ASTNode;
62 import org.eclipse.jdt.core.dom.ASTParser;
63 import org.eclipse.jdt.core.dom.ASTRequestor;
64 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
65 import org.eclipse.jdt.core.dom.CompilationUnit;
66 import org.eclipse.jdt.core.dom.IBinding;
67 import org.eclipse.jdt.core.dom.IMethodBinding;
68 import org.eclipse.jdt.core.dom.ITypeBinding;
69 import org.eclipse.jdt.core.dom.MethodDeclaration;
70 import org.eclipse.jdt.core.dom.Modifier;
71 import org.eclipse.jdt.core.dom.ParameterizedType;
72 import org.eclipse.jdt.core.dom.Type;
73 import org.eclipse.jdt.core.dom.TypeDeclaration;
74 import org.eclipse.jdt.core.dom.TypeParameter;
75 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
76 import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
77 import org.eclipse.jdt.core.formatter.CodeFormatter;
78 import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
79 import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
80
81 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
82 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
83 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2;
84 import org.eclipse.jdt.internal.corext.refactoring.Checks;
85 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptor;
86 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
87 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
88 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
89 import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange;
90 import org.eclipse.jdt.internal.corext.refactoring.changes.CreateCompilationUnitChange;
91 import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
92 import org.eclipse.jdt.internal.corext.refactoring.changes.MultiStateCompilationUnitChange;
93 import org.eclipse.jdt.internal.corext.refactoring.code.ScriptableRefactoring;
94 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
95 import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
96 import org.eclipse.jdt.internal.corext.refactoring.util.TextEditBasedChangeManager;
97 import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil;
98 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
99 import org.eclipse.jdt.internal.corext.util.JdtFlags;
100 import org.eclipse.jdt.internal.corext.util.Messages;
101
102 import org.eclipse.jdt.ui.CodeGeneration;
103 import org.eclipse.jdt.ui.JavaElementLabels;
104
105 import org.eclipse.jdt.internal.ui.JavaPlugin;
106 import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
107
108 /**
109  * Refactoring processor for the extract supertype refactoring.
110  *
111  * @since 3.2
112  */

113 public final class ExtractSupertypeProcessor extends PullUpRefactoringProcessor {
114
115     /** The extract attribute */
116     private static final String JavaDoc ATTRIBUTE_EXTRACT= "extract"; //$NON-NLS-1$
117

118     /** The types attribute */
119     private static final String JavaDoc ATTRIBUTE_TYPES= "types"; //$NON-NLS-1$
120

121     /** The extract supertype group category set */
122     private static final GroupCategorySet SET_EXTRACT_SUPERTYPE= new GroupCategorySet(new GroupCategory("org.eclipse.jdt.internal.corext.extractSupertype", //$NON-NLS-1$
123
RefactoringCoreMessages.ExtractSupertypeProcessor_category_name, RefactoringCoreMessages.ExtractSupertypeProcessor_category_description));
124
125     /**
126      * The changes of the working copy layer (element type:
127      * <ICompilationUnit, TextEditBasedChange>)
128      * <p>
129      * The compilation units are all primary working copies or normal
130      * compilation units.
131      * </p>
132      */

133     private final Map JavaDoc fLayerChanges= new HashMap JavaDoc();
134
135     /** The possible extract supertype candidates, or the empty array */
136     private IType[] fPossibleCandidates= {};
137
138     /** The source of the supertype */
139     private String JavaDoc fSuperSource;
140
141     /** The name of the extracted type */
142     private String JavaDoc fTypeName= ""; //$NON-NLS-1$
143

144     /** The types where to extract the supertype */
145     private IType[] fTypesToExtract= {};
146
147     /**
148      * Creates a new extract supertype refactoring processor.
149      *
150      * @param members
151      * the members to extract, or <code>null</code> if invoked by
152      * scripting
153      * @param settings
154      * the code generation settings, or <code>null</code> if
155      * invoked by scripting
156      */

157     public ExtractSupertypeProcessor(final IMember[] members, final CodeGenerationSettings settings) {
158         super(members, settings, true);
159         if (members != null) {
160             final IType declaring= getDeclaringType();
161             if (declaring != null)
162                 fTypesToExtract= new IType[] { declaring};
163         }
164     }
165
166     /**
167      * {@inheritDoc}
168      */

169     protected final RefactoringStatus checkDeclaringSuperTypes(final IProgressMonitor monitor) throws JavaModelException {
170         return new RefactoringStatus();
171     }
172     
173     protected CompilationUnitRewrite getCompilationUnitRewrite(final Map JavaDoc rewrites, final ICompilationUnit unit) {
174         Assert.isNotNull(rewrites);
175         Assert.isNotNull(unit);
176         CompilationUnitRewrite rewrite= (CompilationUnitRewrite) rewrites.get(unit);
177         if (rewrite == null) {
178             rewrite= new CompilationUnitRewrite(fOwner, unit);
179             rewrite.rememberContent();
180             rewrites.put(unit, rewrite);
181         }
182         return rewrite;
183     }
184
185     /**
186      * Checks whether the compilation unit to be extracted is valid.
187      *
188      * @return a status describing the outcome of the
189      */

190     public RefactoringStatus checkExtractedCompilationUnit() {
191         final RefactoringStatus status= new RefactoringStatus();
192         final ICompilationUnit cu= getDeclaringType().getCompilationUnit();
193         if (fTypeName == null || "".equals(fTypeName)) //$NON-NLS-1$
194
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.Checks_Choose_name);
195         status.merge(Checks.checkTypeName(fTypeName));
196         if (status.hasFatalError())
197             return status;
198         status.merge(Checks.checkCompilationUnitName(JavaModelUtil.getRenamedCUName(cu, fTypeName)));
199         if (status.hasFatalError())
200             return status;
201         status.merge(Checks.checkCompilationUnitNewName(cu, fTypeName));
202         return status;
203     }
204
205     /**
206      * {@inheritDoc}
207      */

208     public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, final CheckConditionsContext context) throws CoreException, OperationCanceledException {
209         final RefactoringStatus status= new RefactoringStatus();
210         try {
211             monitor.beginTask("", 1); //$NON-NLS-1$
212
monitor.setTaskName(RefactoringCoreMessages.ExtractSupertypeProcessor_checking);
213             status.merge(checkExtractedCompilationUnit());
214             if (status.hasFatalError())
215                 return status;
216             return super.checkFinalConditions(new SubProgressMonitor(monitor, 1), context);
217         } finally {
218             monitor.done();
219         }
220     }
221
222     /**
223      * Computes the destination type based on the new name.
224      *
225      * @param name the new name
226      * @return the destination type
227      */

228     public IType computeExtractedType(final String JavaDoc name) {
229         if (name != null && !name.equals("")) {//$NON-NLS-1$
230
final IType declaring= getDeclaringType();
231             try {
232                 final ICompilationUnit[] units= declaring.getPackageFragment().getCompilationUnits(fOwner);
233                 final String JavaDoc newName= JavaModelUtil.getRenamedCUName(declaring.getCompilationUnit(), name);
234                 ICompilationUnit result= null;
235                 for (int index= 0; index < units.length; index++) {
236                     if (units[index].getElementName().equals(newName))
237                         result= units[index];
238                 }
239                 if (result != null) {
240                     final IType type= result.getType(name);
241                     setDestinationType(type);
242                     return type;
243                 }
244             } catch (JavaModelException exception) {
245                 JavaPlugin.log(exception);
246             }
247         }
248         return null;
249     }
250
251     /**
252      * {@inheritDoc}
253      */

254     public Change createChange(final IProgressMonitor monitor) throws CoreException, OperationCanceledException {
255         try {
256             final Map JavaDoc arguments= new HashMap JavaDoc();
257             String JavaDoc project= null;
258             final IType declaring= getDeclaringType();
259             final IJavaProject javaProject= declaring.getJavaProject();
260             if (javaProject != null)
261                 project= javaProject.getElementName();
262             int flags= JavaRefactoringDescriptor.JAR_MIGRATION | JavaRefactoringDescriptor.JAR_REFACTORING | RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE;
263             try {
264                 if (declaring.isLocal() || declaring.isAnonymous())
265                     flags|= JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
266             } catch (JavaModelException exception) {
267                 JavaPlugin.log(exception);
268             }
269             final String JavaDoc description= Messages.format(RefactoringCoreMessages.ExtractSupertypeProcessor_descriptor_description_short, fTypeName);
270             final String JavaDoc header= Messages.format(RefactoringCoreMessages.ExtractSupertypeProcessor_descriptor_description, new String JavaDoc[] { JavaElementLabels.getElementLabel(fDestinationType, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getElementLabel(fCachedDeclaringType, JavaElementLabels.ALL_FULLY_QUALIFIED)});
271             final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header);
272             final IType[] types= getTypesToExtract();
273             String JavaDoc[] settings= new String JavaDoc[types.length];
274             for (int index= 0; index < settings.length; index++)
275                 settings[index]= JavaElementLabels.getElementLabel(types[index], JavaElementLabels.ALL_FULLY_QUALIFIED);
276             comment.addSetting(JDTRefactoringDescriptorComment.createCompositeSetting(RefactoringCoreMessages.ExtractSupertypeProcessor_subtypes_pattern, settings));
277             comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractSupertypeProcessor_refactored_element_pattern, JavaElementLabels.getElementLabel(fDestinationType, JavaElementLabels.ALL_FULLY_QUALIFIED)));
278             settings= new String JavaDoc[fMembersToMove.length];
279             for (int index= 0; index < settings.length; index++)
280                 settings[index]= JavaElementLabels.getElementLabel(fMembersToMove[index], JavaElementLabels.ALL_FULLY_QUALIFIED);
281             comment.addSetting(JDTRefactoringDescriptorComment.createCompositeSetting(RefactoringCoreMessages.ExtractInterfaceProcessor_extracted_members_pattern, settings));
282             addSuperTypeSettings(comment, true);
283             final JDTRefactoringDescriptor descriptor= new JDTRefactoringDescriptor(IJavaRefactorings.EXTRACT_SUPERCLASS, project, description, comment.asString(), arguments, flags);
284             arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_NAME, fTypeName);
285             arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_INPUT, descriptor.elementToHandle(getDeclaringType()));
286             arguments.put(ATTRIBUTE_REPLACE, Boolean.valueOf(fReplace).toString());
287             arguments.put(ATTRIBUTE_INSTANCEOF, Boolean.valueOf(fInstanceOf).toString());
288             arguments.put(ATTRIBUTE_STUBS, Boolean.valueOf(fCreateMethodStubs).toString());
289             arguments.put(ATTRIBUTE_EXTRACT, new Integer JavaDoc(fMembersToMove.length).toString());
290             for (int offset= 0; offset < fMembersToMove.length; offset++)
291                 arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (offset + 1), descriptor.elementToHandle(fMembersToMove[offset]));
292             arguments.put(ATTRIBUTE_DELETE, new Integer JavaDoc(fDeletedMethods.length).toString());
293             for (int offset= 0; offset < fDeletedMethods.length; offset++)
294                 arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (offset + fMembersToMove.length + 1), descriptor.elementToHandle(fDeletedMethods[offset]));
295             arguments.put(ATTRIBUTE_ABSTRACT, new Integer JavaDoc(fAbstractMethods.length).toString());
296             for (int offset= 0; offset < fAbstractMethods.length; offset++)
297                 arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (offset + fMembersToMove.length + fDeletedMethods.length + 1), descriptor.elementToHandle(fAbstractMethods[offset]));
298             arguments.put(ATTRIBUTE_TYPES, new Integer JavaDoc(fTypesToExtract.length).toString());
299             for (int offset= 0; offset < fTypesToExtract.length; offset++)
300                 arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (offset + fMembersToMove.length + fDeletedMethods.length + fAbstractMethods.length + 1), descriptor.elementToHandle(fTypesToExtract[offset]));
301             final DynamicValidationRefactoringChange change= new DynamicValidationRefactoringChange(descriptor, RefactoringCoreMessages.ExtractSupertypeProcessor_extract_supertype, fChangeManager.getAllChanges());
302             final IFile file= ResourceUtil.getFile(declaring.getCompilationUnit());
303             if (fSuperSource != null && fSuperSource.length() > 0)
304                 change.add(new CreateCompilationUnitChange(declaring.getPackageFragment().getCompilationUnit(JavaModelUtil.getRenamedCUName(declaring.getCompilationUnit(), fTypeName)), fSuperSource, file.getCharset(false)));
305             return change;
306         } finally {
307             monitor.done();
308             clearCaches();
309         }
310     }
311
312     /**
313      * Creates the new extracted supertype.
314      *
315      * @param superType
316      * the super type, or <code>null</code> if no super type (ie.
317      * <code>java.lang.Object</code>) is available
318      * @param monitor
319      * the progress monitor
320      * @return a status describing the outcome of the operation
321      * @throws CoreException
322      * if an error occurs
323      */

324     protected final RefactoringStatus createExtractedSuperType(final IType superType, final IProgressMonitor monitor) throws CoreException {
325         Assert.isNotNull(monitor);
326         fSuperSource= null;
327         final RefactoringStatus status= new RefactoringStatus();
328         try {
329             monitor.beginTask(RefactoringCoreMessages.ExtractSupertypeProcessor_preparing, 20);
330             final IType declaring= getDeclaringType();
331             final CompilationUnitRewrite declaringRewrite= new CompilationUnitRewrite(fOwner, declaring.getCompilationUnit());
332             final AbstractTypeDeclaration declaringDeclaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(declaring, declaringRewrite.getRoot());
333             if (declaringDeclaration != null) {
334                 final String JavaDoc name= JavaModelUtil.getRenamedCUName(declaring.getCompilationUnit(), fTypeName);
335                 final ICompilationUnit original= declaring.getPackageFragment().getCompilationUnit(name);
336                 final ICompilationUnit copy= getSharedWorkingCopy(original.getPrimary(), new SubProgressMonitor(monitor, 10));
337                 fSuperSource= createSuperTypeSource(copy, superType, declaringDeclaration, status, new SubProgressMonitor(monitor, 10));
338                 if (fSuperSource != null) {
339                     copy.getBuffer().setContents(fSuperSource);
340                     JavaModelUtil.reconcile(copy);
341                 }
342             }
343         } finally {
344             monitor.done();
345         }
346         return status;
347     }
348
349     /**
350      * Creates a working copy for the modified subtype.
351      *
352      * @param unit
353      * the compilation unit
354      * @param root
355      * the compilation unit node
356      * @param subDeclaration
357      * the declaration of the subtype to modify
358      * @param extractedType
359      * the extracted super type
360      * @param extractedBinding
361      * the binding of the extracted super type
362      * @param status
363      * the refactoring status
364      */

365     protected final void createModifiedSubType(final ICompilationUnit unit, final CompilationUnit root, final IType extractedType, final ITypeBinding extractedBinding, final AbstractTypeDeclaration subDeclaration, final RefactoringStatus status) {
366         Assert.isNotNull(unit);
367         Assert.isNotNull(subDeclaration);
368         Assert.isNotNull(extractedType);
369         try {
370             final CompilationUnitRewrite rewrite= new CompilationUnitRewrite(fOwner, unit, root);
371             createTypeSignature(rewrite, subDeclaration, extractedType, extractedBinding, new NullProgressMonitor());
372             final Document document= new Document(unit.getBuffer().getContents());
373             final CompilationUnitChange change= rewrite.createChange();
374             if (change != null) {
375                 fLayerChanges.put(unit.getPrimary(), change);
376                 final TextEdit edit= change.getEdit();
377                 if (edit != null) {
378                     final TextEditCopier copier= new TextEditCopier(edit);
379                     final TextEdit copy= copier.perform();
380                     copy.apply(document, TextEdit.NONE);
381                 }
382             }
383             final ICompilationUnit copy= getSharedWorkingCopy(unit, new NullProgressMonitor());
384             copy.getBuffer().setContents(document.get());
385             JavaModelUtil.reconcile(copy);
386         } catch (CoreException exception) {
387             JavaPlugin.log(exception);
388             status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
389         } catch (MalformedTreeException exception) {
390             JavaPlugin.log(exception);
391             status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
392         } catch (BadLocationException exception) {
393             JavaPlugin.log(exception);
394             status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
395         }
396     }
397
398     /**
399      * Creates the necessary constructors for the extracted supertype.
400      *
401      * @param targetRewrite
402      * the target compilation unit rewrite
403      * @param superType
404      * the super type, or <code>null</code> if no super type (ie.
405      * <code>java.lang.Object</code>) is available
406      * @param targetDeclaration
407      * the type declaration of the target type
408      * @param status
409      * the refactoring status
410      */

411     protected final void createNecessaryConstructors(final CompilationUnitRewrite targetRewrite, final IType superType, final AbstractTypeDeclaration targetDeclaration, final RefactoringStatus status) {
412         Assert.isNotNull(targetRewrite);
413         Assert.isNotNull(targetDeclaration);
414         if (superType != null) {
415             final ITypeBinding binding= targetDeclaration.resolveBinding();
416             if (binding != null && binding.isClass()) {
417                 final IMethodBinding[] bindings= StubUtility2.getVisibleConstructors(binding, true, true);
418                 int deprecationCount= 0;
419                 for (int i= 0; i < bindings.length; i++) {
420                     if (bindings[i].isDeprecated())
421                         deprecationCount++;
422                 }
423                 final ListRewrite rewrite= targetRewrite.getASTRewrite().getListRewrite(targetDeclaration, TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
424                 if (rewrite != null) {
425                     boolean createDeprecated= deprecationCount == bindings.length;
426                     for (int i= 0; i < bindings.length; i++) {
427                         IMethodBinding curr= bindings[i];
428                         if (!curr.isDeprecated() || createDeprecated) {
429                             MethodDeclaration stub;
430                             try {
431                                 stub= StubUtility2.createConstructorStub(targetRewrite.getCu(), targetRewrite.getASTRewrite(), targetRewrite.getImportRewrite(), curr, binding.getName(), Modifier.PUBLIC, false, false, fSettings);
432                                 if (stub != null)
433                                     rewrite.insertLast(stub, null);
434                             } catch (CoreException exception) {
435                                 JavaPlugin.log(exception);
436                                 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
437                             }
438                         }
439                     }
440                 }
441             }
442         }
443     }
444
445     /**
446      * Creates the source for the new compilation unit containing the supertype.
447      *
448      * @param extractedWorkingCopy
449      * the working copy of the new extracted supertype
450      * @param superType
451      * the super type, or <code>null</code> if no super type (ie.
452      * <code>java.lang.Object</code>) is available
453      * @param declaringDeclaration
454      * the declaration of the declaring type
455      * @param status
456      * the refactoring status
457      * @param monitor
458      * the progress monitor to display progress
459      * @return the source of the new compilation unit, or <code>null</code>
460      * @throws CoreException
461      * if an error occurs
462      */

463     protected final String JavaDoc createSuperTypeSource(final ICompilationUnit extractedWorkingCopy, final IType superType, final AbstractTypeDeclaration declaringDeclaration, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
464         Assert.isNotNull(extractedWorkingCopy);
465         Assert.isNotNull(declaringDeclaration);
466         Assert.isNotNull(status);
467         Assert.isNotNull(monitor);
468         String JavaDoc source= null;
469         try {
470             monitor.beginTask("", 2); //$NON-NLS-1$
471
monitor.setTaskName(RefactoringCoreMessages.ExtractSupertypeProcessor_preparing);
472             final IType declaring= getDeclaringType();
473             final String JavaDoc delimiter= StubUtility.getLineDelimiterUsed(extractedWorkingCopy.getJavaProject());
474             String JavaDoc typeComment= null;
475             String JavaDoc fileComment= null;
476             if (fSettings.createComments) {
477                 final ITypeParameter[] parameters= declaring.getTypeParameters();
478                 final String JavaDoc[] names= new String JavaDoc[parameters.length];
479                 for (int index= 0; index < parameters.length; index++)
480                     names[index]= parameters[index].getElementName();
481                 typeComment= CodeGeneration.getTypeComment(extractedWorkingCopy, fTypeName, names, delimiter);
482                 fileComment= CodeGeneration.getFileComment(extractedWorkingCopy, delimiter);
483             }
484             final StringBuffer JavaDoc buffer= new StringBuffer JavaDoc(64);
485             final ITypeBinding binding= declaringDeclaration.resolveBinding();
486             if (binding != null) {
487                 final ITypeBinding superBinding= binding.getSuperclass();
488                 if (superBinding != null)
489                     fTypeBindings.add(superBinding);
490                 final ITypeBinding[] bindings= binding.getInterfaces();
491                 for (int i= 0; i < bindings.length; i++) {
492                     fTypeBindings.add(bindings[i]);
493                 }
494             }
495             final String JavaDoc imports= createTypeImports(extractedWorkingCopy, monitor);
496             if (imports != null && !"".equals(imports)) { //$NON-NLS-1$
497
buffer.append(imports);
498             }
499             createTypeDeclaration(extractedWorkingCopy, superType, declaringDeclaration, typeComment, buffer, status, new SubProgressMonitor(monitor, 1));
500             source= createTypeTemplate(extractedWorkingCopy, "", fileComment, "", buffer.toString()); //$NON-NLS-1$ //$NON-NLS-2$
501
if (source == null) {
502                 if (!declaring.getPackageFragment().isDefaultPackage()) {
503                     if (imports.length() > 0)
504                         buffer.insert(0, imports);
505                     buffer.insert(0, "package " + declaring.getPackageFragment().getElementName() + ";"); //$NON-NLS-1$//$NON-NLS-2$
506
}
507                 source= buffer.toString();
508             }
509             final IDocument document= new Document(source);
510             final TextEdit edit= CodeFormatterUtil.format2(CodeFormatter.K_COMPILATION_UNIT, source, 0, delimiter, extractedWorkingCopy.getJavaProject().getOptions(true));
511             if (edit != null) {
512                 try {
513                     edit.apply(document, TextEdit.UPDATE_REGIONS);
514                 } catch (MalformedTreeException exception) {
515                     JavaPlugin.log(exception);
516                     status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
517                 } catch (BadLocationException exception) {
518                     JavaPlugin.log(exception);
519                     status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
520                 }
521                 source= document.get();
522             }
523         } finally {
524             monitor.done();
525         }
526         return source;
527     }
528
529     /**
530      * Creates the declaration of the new supertype, excluding any comments or
531      * package declaration.
532      *
533      * @param extractedWorkingCopy
534      * the working copy of the new extracted supertype
535      * @param superType
536      * the super type, or <code>null</code> if no super type (ie.
537      * <code>java.lang.Object</code>) is available
538      * @param declaringDeclaration
539      * the declaration of the declaring type
540      * @param comment
541      * the comment of the new type declaration
542      * @param buffer
543      * the string buffer containing the declaration
544      * @param status
545      * the refactoring status
546      * @param monitor
547      * the progress monitor to use
548      * @throws CoreException
549      * if an error occurs
550      */

551     protected final void createTypeDeclaration(final ICompilationUnit extractedWorkingCopy, final IType superType, final AbstractTypeDeclaration declaringDeclaration, final String JavaDoc comment, final StringBuffer JavaDoc buffer, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
552         Assert.isNotNull(extractedWorkingCopy);
553         Assert.isNotNull(declaringDeclaration);
554         Assert.isNotNull(buffer);
555         Assert.isNotNull(status);
556         Assert.isNotNull(monitor);
557         try {
558             monitor.beginTask("", 1); //$NON-NLS-1$
559
monitor.setTaskName(RefactoringCoreMessages.ExtractSupertypeProcessor_preparing);
560             final IJavaProject project= extractedWorkingCopy.getJavaProject();
561             final String JavaDoc delimiter= StubUtility.getLineDelimiterUsed(project);
562             if (comment != null && !"".equals(comment)) { //$NON-NLS-1$
563
buffer.append(comment);
564                 buffer.append(delimiter);
565             }
566             buffer.append(JdtFlags.VISIBILITY_STRING_PUBLIC);
567             if (superType != null && Flags.isAbstract(superType.getFlags())) {
568                 buffer.append(' ');
569                 buffer.append("abstract "); //$NON-NLS-1$
570
}
571             buffer.append(' ');
572             buffer.append("class "); //$NON-NLS-1$
573
buffer.append(fTypeName);
574             if (superType != null && !"java.lang.Object".equals(superType.getFullyQualifiedName())) { //$NON-NLS-1$
575
buffer.append(' ');
576                 if (superType.isInterface())
577                     buffer.append("implements "); //$NON-NLS-1$
578
else
579                     buffer.append("extends "); //$NON-NLS-1$
580
buffer.append(superType.getElementName());
581             }
582             buffer.append(" {"); //$NON-NLS-1$
583
buffer.append(delimiter);
584             buffer.append(delimiter);
585             buffer.append('}');
586             final String JavaDoc string= buffer.toString();
587             extractedWorkingCopy.getBuffer().setContents(string);
588             final IDocument document= new Document(string);
589             final CompilationUnitRewrite targetRewrite= new CompilationUnitRewrite(fOwner, extractedWorkingCopy);
590             final AbstractTypeDeclaration targetDeclaration= (AbstractTypeDeclaration) targetRewrite.getRoot().types().get(0);
591             createTypeParameters(targetRewrite, superType, declaringDeclaration, targetDeclaration);
592             createTypeSignature(targetRewrite, superType, declaringDeclaration, targetDeclaration);
593             createNecessaryConstructors(targetRewrite, superType, targetDeclaration, status);
594             final TextEdit edit= targetRewrite.createChange().getEdit();
595             try {
596                 edit.apply(document, TextEdit.UPDATE_REGIONS);
597             } catch (MalformedTreeException exception) {
598                 JavaPlugin.log(exception);
599                 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
600             } catch (BadLocationException exception) {
601                 JavaPlugin.log(exception);
602                 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
603             }
604             buffer.setLength(0);
605             buffer.append(document.get());
606         } finally {
607             monitor.done();
608         }
609     }
610
611     /**
612      * Creates the type parameters of the new supertype.
613      *
614      * @param targetRewrite
615      * the target compilation unit rewrite
616      * @param subType
617      * the subtype
618      * @param sourceDeclaration
619      * the type declaration of the source type
620      * @param targetDeclaration
621      * the type declaration of the target type
622      */

623     protected final void createTypeParameters(final CompilationUnitRewrite targetRewrite, final IType subType, final AbstractTypeDeclaration sourceDeclaration, final AbstractTypeDeclaration targetDeclaration) {
624         Assert.isNotNull(targetRewrite);
625         Assert.isNotNull(sourceDeclaration);
626         Assert.isNotNull(targetDeclaration);
627         if (sourceDeclaration instanceof TypeDeclaration) {
628             TypeParameter parameter= null;
629             final ListRewrite rewrite= targetRewrite.getASTRewrite().getListRewrite(targetDeclaration, TypeDeclaration.TYPE_PARAMETERS_PROPERTY);
630             for (final Iterator JavaDoc iterator= ((TypeDeclaration) sourceDeclaration).typeParameters().iterator(); iterator.hasNext();) {
631                 parameter= (TypeParameter) iterator.next();
632                 final ASTNode node= ASTNode.copySubtree(targetRewrite.getAST(), parameter);
633                 rewrite.insertLast(node, null);
634             }
635         }
636     }
637
638     /**
639      * Creates a new type signature of a subtype.
640      *
641      * @param subRewrite
642      * the compilation unit rewrite of a subtype
643      * @param declaration
644      * the type declaration of a subtype
645      * @param extractedType
646      * the extracted super type
647      * @param extractedBinding
648      * the binding of the extracted super type
649      * @param monitor
650      * the progress monitor to use
651      * @throws JavaModelException
652      * if the type parameters cannot be retrieved
653      */

654     protected final void createTypeSignature(final CompilationUnitRewrite subRewrite, final AbstractTypeDeclaration declaration, final IType extractedType, final ITypeBinding extractedBinding, final IProgressMonitor monitor) throws JavaModelException {
655         Assert.isNotNull(subRewrite);
656         Assert.isNotNull(declaration);
657         Assert.isNotNull(extractedType);
658         Assert.isNotNull(monitor);
659         try {
660             monitor.beginTask(RefactoringCoreMessages.ExtractSupertypeProcessor_preparing, 10);
661             final AST ast= subRewrite.getAST();
662             Type type= null;
663             if (extractedBinding != null) {
664                 type= subRewrite.getImportRewrite().addImport(extractedBinding, ast);
665             } else {
666                 subRewrite.getImportRewrite().addImport(extractedType.getFullyQualifiedName('.'));
667                 type= ast.newSimpleType(ast.newSimpleName(extractedType.getElementName()));
668             }
669             subRewrite.getImportRemover().registerAddedImport(extractedType.getFullyQualifiedName('.'));
670             if (type != null) {
671                 final ITypeParameter[] parameters= extractedType.getTypeParameters();
672                 if (parameters.length > 0) {
673                     final ParameterizedType parameterized= ast.newParameterizedType(type);
674                     for (int index= 0; index < parameters.length; index++)
675                         parameterized.typeArguments().add(ast.newSimpleType(ast.newSimpleName(parameters[index].getElementName())));
676                     type= parameterized;
677                 }
678             }
679             final ASTRewrite rewriter= subRewrite.getASTRewrite();
680             if (type != null && declaration instanceof TypeDeclaration) {
681                 final TypeDeclaration extended= (TypeDeclaration) declaration;
682                 final Type superClass= extended.getSuperclassType();
683                 if (superClass != null) {
684                     rewriter.replace(superClass, type, subRewrite.createCategorizedGroupDescription(RefactoringCoreMessages.ExtractSupertypeProcessor_add_supertype, SET_EXTRACT_SUPERTYPE));
685                     subRewrite.getImportRemover().registerRemovedNode(superClass);
686                 } else
687                     rewriter.set(extended, TypeDeclaration.SUPERCLASS_TYPE_PROPERTY, type, subRewrite.createCategorizedGroupDescription(RefactoringCoreMessages.ExtractSupertypeProcessor_add_supertype, SET_EXTRACT_SUPERTYPE));
688             }
689         } finally {
690             monitor.done();
691         }
692     }
693
694     /**
695      * Creates the type signature of the extracted supertype.
696      *
697      * @param targetRewrite
698      * the target compilation unit rewrite
699      * @param superType
700      * the super type, or <code>null</code> if no super type (ie.
701      * <code>java.lang.Object</code>) is available
702      * @param declaringDeclaration
703      * the declaration of the declaring type
704      * @param targetDeclaration
705      * the type declaration of the target type
706      */

707     protected final void createTypeSignature(final CompilationUnitRewrite targetRewrite, final IType superType, final AbstractTypeDeclaration declaringDeclaration, final AbstractTypeDeclaration targetDeclaration) {
708         Assert.isNotNull(targetRewrite);
709         Assert.isNotNull(declaringDeclaration);
710         Assert.isNotNull(targetDeclaration);
711         if (declaringDeclaration instanceof TypeDeclaration) {
712             final TypeDeclaration declaration= (TypeDeclaration) declaringDeclaration;
713             final Type superclassType= declaration.getSuperclassType();
714             if (superclassType != null) {
715                 Type type= null;
716                 final ITypeBinding binding= superclassType.resolveBinding();
717                 if (binding != null) {
718                     type= targetRewrite.getImportRewrite().addImport(binding, targetRewrite.getAST());
719                     targetRewrite.getImportRemover().registerAddedImports(type);
720                 }
721                 if (type != null && targetDeclaration instanceof TypeDeclaration) {
722                     final TypeDeclaration extended= (TypeDeclaration) targetDeclaration;
723                     final Type targetSuperType= extended.getSuperclassType();
724                     if (targetSuperType != null) {
725                         targetRewrite.getASTRewrite().replace(targetSuperType, type, null);
726                     } else {
727                         targetRewrite.getASTRewrite().set(extended, TypeDeclaration.SUPERCLASS_TYPE_PROPERTY, type, null);
728                     }
729                 }
730             }
731         }
732     }
733
734     /**
735      * {@inheritDoc}
736      */

737     public final RefactoringStatus createWorkingCopyLayer(final IProgressMonitor monitor) {
738         Assert.isNotNull(monitor);
739         final RefactoringStatus status= new RefactoringStatus();
740         try {
741             monitor.beginTask(RefactoringCoreMessages.ExtractSupertypeProcessor_preparing, 70);
742             status.merge(super.createWorkingCopyLayer(new SubProgressMonitor(monitor, 10)));
743             final IType declaring= getDeclaringType();
744             status.merge(createExtractedSuperType(getDeclaringSuperTypeHierarchy(new SubProgressMonitor(monitor, 10)).getSuperclass(declaring), new SubProgressMonitor(monitor, 10)));
745             if (status.hasFatalError())
746                 return status;
747             final IType extractedType= computeExtractedType(fTypeName);
748             setDestinationType(extractedType);
749             final List JavaDoc subTypes= new ArrayList JavaDoc(Arrays.asList(fTypesToExtract));
750             if (!subTypes.contains(declaring))
751                 subTypes.add(declaring);
752             final Map JavaDoc unitToTypes= new HashMap JavaDoc(subTypes.size());
753             final Set JavaDoc units= new HashSet JavaDoc(subTypes.size());
754             for (int index= 0; index < subTypes.size(); index++) {
755                 final IType type= (IType) subTypes.get(index);
756                 final ICompilationUnit unit= type.getCompilationUnit();
757                 units.add(unit);
758                 Collection JavaDoc collection= (Collection JavaDoc) unitToTypes.get(unit);
759                 if (collection == null) {
760                     collection= new ArrayList JavaDoc(2);
761                     unitToTypes.put(unit, collection);
762                 }
763                 collection.add(type);
764             }
765             final Map JavaDoc projectToUnits= new HashMap JavaDoc();
766             Collection JavaDoc collection= null;
767             IJavaProject project= null;
768             ICompilationUnit current= null;
769             for (final Iterator JavaDoc iterator= units.iterator(); iterator.hasNext();) {
770                 current= (ICompilationUnit) iterator.next();
771                 project= current.getJavaProject();
772                 collection= (Collection JavaDoc) projectToUnits.get(project);
773                 if (collection == null) {
774                     collection= new ArrayList JavaDoc();
775                     projectToUnits.put(project, collection);
776                 }
777                 collection.add(current);
778             }
779             final ITypeBinding[] extractBindings= { null};
780             final ASTParser extractParser= ASTParser.newParser(AST.JLS3);
781             extractParser.setWorkingCopyOwner(fOwner);
782             extractParser.setResolveBindings(true);
783             extractParser.setProject(project);
784             extractParser.setSource(extractedType.getCompilationUnit());
785             final CompilationUnit extractUnit= (CompilationUnit) extractParser.createAST(new SubProgressMonitor(monitor, 10));
786             if (extractUnit != null) {
787                 final AbstractTypeDeclaration extractDeclaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(extractedType, extractUnit);
788                 if (extractDeclaration != null)
789                     extractBindings[0]= extractDeclaration.resolveBinding();
790             }
791             final ASTParser parser= ASTParser.newParser(AST.JLS3);
792             final IProgressMonitor subMonitor= new SubProgressMonitor(monitor, 30);
793             try {
794                 final Set JavaDoc keySet= projectToUnits.keySet();
795                 subMonitor.beginTask("", keySet.size()); //$NON-NLS-1$
796
subMonitor.setTaskName(RefactoringCoreMessages.ExtractSupertypeProcessor_preparing);
797                 for (final Iterator JavaDoc iterator= keySet.iterator(); iterator.hasNext();) {
798                     project= (IJavaProject) iterator.next();
799                     collection= (Collection JavaDoc) projectToUnits.get(project);
800                     parser.setWorkingCopyOwner(fOwner);
801                     parser.setResolveBindings(true);
802                     parser.setProject(project);
803                     parser.setCompilerOptions(RefactoringASTParser.getCompilerOptions(project));
804                     final IProgressMonitor subsubMonitor= new SubProgressMonitor(subMonitor, 1);
805                     try {
806                         subsubMonitor.beginTask("", collection.size()); //$NON-NLS-1$
807
subsubMonitor.setTaskName(RefactoringCoreMessages.ExtractSupertypeProcessor_preparing);
808                         parser.createASTs((ICompilationUnit[]) collection.toArray(new ICompilationUnit[collection.size()]), new String JavaDoc[0], new ASTRequestor() {
809
810                             public final void acceptAST(final ICompilationUnit unit, final CompilationUnit node) {
811                                 try {
812                                     final Collection JavaDoc types= (Collection JavaDoc) unitToTypes.get(unit);
813                                     if (types != null) {
814                                         for (final Iterator JavaDoc innerIterator= types.iterator(); innerIterator.hasNext();) {
815                                             final IType currentType= (IType) innerIterator.next();
816                                             final AbstractTypeDeclaration currentDeclaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(currentType, node);
817                                             if (currentDeclaration != null)
818                                                 createModifiedSubType(unit, node, extractedType, extractBindings[0], currentDeclaration, status);
819                                         }
820                                     }
821                                 } catch (CoreException exception) {
822                                     JavaPlugin.log(exception);
823                                     status.merge(RefactoringStatus.createFatalErrorStatus(exception.getLocalizedMessage()));
824                                 } finally {
825                                     subsubMonitor.worked(1);
826                                 }
827                             }
828
829                             public final void acceptBinding(final String JavaDoc key, final IBinding binding) {
830                                 // Do nothing
831
}
832                         }, subsubMonitor);
833                     } finally {
834                         subsubMonitor.done();
835                     }
836                 }
837             } finally {
838                 subMonitor.done();
839             }
840         } catch (CoreException exception) {
841             JavaPlugin.log(exception);
842             status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
843         } finally {
844             monitor.done();
845         }
846         return status;
847     }
848
849     /**
850      * {@inheritDoc}
851      */

852     public IType[] getCandidateTypes(final RefactoringStatus status, final IProgressMonitor monitor) {
853         Assert.isNotNull(monitor);
854         if (fPossibleCandidates == null || fPossibleCandidates.length == 0) {
855             final IType declaring= getDeclaringType();
856             if (declaring != null) {
857                 try {
858                     monitor.beginTask(RefactoringCoreMessages.ExtractSupertypeProcessor_computing_possible_types, 10);
859                     final IType superType= getDeclaringSuperTypeHierarchy(new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)).getSuperclass(declaring);
860                     if (superType != null) {
861                         fPossibleCandidates= superType.newTypeHierarchy(fOwner, new SubProgressMonitor(monitor, 9, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)).getSubtypes(superType);
862                         final LinkedList JavaDoc list= new LinkedList JavaDoc(Arrays.asList(fPossibleCandidates));
863                         final Set JavaDoc names= new HashSet JavaDoc();
864                         for (final Iterator JavaDoc iterator= list.iterator(); iterator.hasNext();) {
865                             final IType type= (IType) iterator.next();
866                             if (type.isReadOnly() || type.isBinary() || type.isAnonymous() || !type.isClass() || names.contains(type.getFullyQualifiedName()))
867                                 iterator.remove();
868                             else
869                                 names.add(type.getFullyQualifiedName());
870                         }
871                         fPossibleCandidates= (IType[]) list.toArray(new IType[list.size()]);
872                     }
873                 } catch (JavaModelException exception) {
874                     JavaPlugin.log(exception);
875                 } finally {
876                     monitor.done();
877                 }
878             }
879         }
880         return fPossibleCandidates;
881     }
882
883     /**
884      * {@inheritDoc}
885      */

886     public Object JavaDoc[] getElements() {
887         return new Object JavaDoc[] { getDeclaringType()};
888     }
889
890     /**
891      * Returns the extracted type.
892      *
893      * @return the extracted type, or <code>null</code>
894      */

895     public IType getExtractedType() {
896         return getDestinationType();
897     }
898
899     /**
900      * Returns the type name.
901      *
902      * @return the type name
903      */

904     public String JavaDoc getTypeName() {
905         return fTypeName;
906     }
907
908     /**
909      * Returns the types to extract. The declaring type may or may not be
910      * contained in the result.
911      *
912      * @return the types to extract
913      */

914     public IType[] getTypesToExtract() {
915         return fTypesToExtract;
916     }
917
918     /**
919      * {@inheritDoc}
920      */

921     public RefactoringStatus initialize(final RefactoringArguments arguments) {
922         if (arguments instanceof JavaRefactoringArguments) {
923             final JavaRefactoringArguments extended= (JavaRefactoringArguments) arguments;
924             final String JavaDoc name= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_NAME);
925             if (name != null && !"".equals(name)) //$NON-NLS-1$
926
fTypeName= name;
927             else
928                 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_NAME));
929             String JavaDoc handle= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_INPUT);
930             if (handle != null) {
931                 final IJavaElement element= JDTRefactoringDescriptor.handleToElement(extended.getProject(), handle, false);
932                 if (element == null || element.getElementType() != IJavaElement.TYPE)
933                     return ScriptableRefactoring.createInputFatalStatus(element, getRefactoring().getName(), IJavaRefactorings.EXTRACT_SUPERCLASS);
934                 IType type= null;
935                 final ICompilationUnit unit= ((IType) element).getCompilationUnit();
936                 if (unit != null && unit.exists()) {
937                     try {
938                         final ICompilationUnit copy= getSharedWorkingCopy(unit, new NullProgressMonitor());
939                         final IJavaElement[] elements= copy.findElements(element);
940                         if (elements != null && elements.length == 1 && elements[0] instanceof IType && elements[0].exists())
941                             type= (IType) elements[0];
942                     } catch (JavaModelException exception) {
943                         // TODO: log exception
944
}
945                 }
946                 if (type != null)
947                     fCachedDeclaringType= type;
948                 else
949                     return ScriptableRefactoring.createInputFatalStatus(element, getRefactoring().getName(), IJavaRefactorings.EXTRACT_SUPERCLASS);
950             } else
951                 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_INPUT));
952             final String JavaDoc stubs= extended.getAttribute(ATTRIBUTE_STUBS);
953             if (stubs != null) {
954                 fCreateMethodStubs= Boolean.valueOf(stubs).booleanValue();
955             } else
956                 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_STUBS));
957             final String JavaDoc instance= extended.getAttribute(ATTRIBUTE_INSTANCEOF);
958             if (instance != null) {
959                 fInstanceOf= Boolean.valueOf(instance).booleanValue();
960             } else
961                 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_INSTANCEOF));
962             final String JavaDoc replace= extended.getAttribute(ATTRIBUTE_REPLACE);
963             if (replace != null) {
964                 fReplace= Boolean.valueOf(replace).booleanValue();
965             } else
966                 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REPLACE));
967             int extractCount= 0;
968             int abstractCount= 0;
969             int deleteCount= 0;
970             int typeCount= 0;
971             String JavaDoc value= extended.getAttribute(ATTRIBUTE_ABSTRACT);
972             if (value != null && !"".equals(value)) {//$NON-NLS-1$
973
try {
974                     abstractCount= Integer.parseInt(value);
975                 } catch (NumberFormatException JavaDoc exception) {
976                     return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_ABSTRACT));
977                 }
978             } else
979                 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_ABSTRACT));
980             value= extended.getAttribute(ATTRIBUTE_DELETE);
981             if (value != null && !"".equals(value)) {//$NON-NLS-1$
982
try {
983                     deleteCount= Integer.parseInt(value);
984                 } catch (NumberFormatException JavaDoc exception) {
985                     return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_DELETE));
986                 }
987             } else
988                 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_DELETE));
989             value= extended.getAttribute(ATTRIBUTE_EXTRACT);
990             if (value != null && !"".equals(value)) {//$NON-NLS-1$
991
try {
992                     extractCount= Integer.parseInt(value);
993                 } catch (NumberFormatException JavaDoc exception) {
994                     return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_EXTRACT));
995                 }
996             } else
997                 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_EXTRACT));
998             value= extended.getAttribute(ATTRIBUTE_TYPES);
999             if (value != null && !"".equals(value)) {//$NON-NLS-1$
1000
try {
1001                    typeCount= Integer.parseInt(value);
1002                } catch (NumberFormatException JavaDoc exception) {
1003                    return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_TYPES));
1004                }
1005            } else
1006                return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_TYPES));
1007            final RefactoringStatus status= new RefactoringStatus();
1008            List JavaDoc elements= new ArrayList JavaDoc();
1009            for (int index= 0; index < extractCount; index++) {
1010                final String JavaDoc attribute= JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (index + 1);
1011                handle= extended.getAttribute(attribute);
1012                if (handle != null && !"".equals(handle)) { //$NON-NLS-1$
1013
final IJavaElement element= JDTRefactoringDescriptor.handleToElement(fOwner, extended.getProject(), handle, false);
1014                    if (element == null || !element.exists())
1015                        status.merge(ScriptableRefactoring.createInputWarningStatus(element, getRefactoring().getName(), IJavaRefactorings.EXTRACT_SUPERCLASS));
1016                    else
1017                        elements.add(element);
1018                } else
1019                    return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, attribute));
1020            }
1021            fMembersToMove= (IMember[]) elements.toArray(new IMember[elements.size()]);
1022            elements= new ArrayList JavaDoc();
1023            for (int index= 0; index < deleteCount; index++) {
1024                final String JavaDoc attribute= JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (extractCount + index + 1);
1025                handle= extended.getAttribute(attribute);
1026                if (handle != null && !"".equals(handle)) { //$NON-NLS-1$
1027
final IJavaElement element= JDTRefactoringDescriptor.handleToElement(fOwner, extended.getProject(), handle, false);
1028                    if (element == null || !element.exists())
1029                        status.merge(ScriptableRefactoring.createInputWarningStatus(element, getRefactoring().getName(), IJavaRefactorings.EXTRACT_SUPERCLASS));
1030                    else
1031                        elements.add(element);
1032                } else
1033                    return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, attribute));
1034            }
1035            fDeletedMethods= (IMethod[]) elements.toArray(new IMethod[elements.size()]);
1036            elements= new ArrayList JavaDoc();
1037            for (int index= 0; index < abstractCount; index++) {
1038                final String JavaDoc attribute= JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (extractCount + abstractCount + index + 1);
1039                handle= extended.getAttribute(attribute);
1040                if (handle != null && !"".equals(handle)) { //$NON-NLS-1$
1041
final IJavaElement element= JDTRefactoringDescriptor.handleToElement(fOwner, extended.getProject(), handle, false);
1042                    if (element == null || !element.exists())
1043                        status.merge(ScriptableRefactoring.createInputWarningStatus(element, getRefactoring().getName(), IJavaRefactorings.EXTRACT_SUPERCLASS));
1044                    else
1045                        elements.add(element);
1046                } else
1047                    return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, attribute));
1048            }
1049            fAbstractMethods= (IMethod[]) elements.toArray(new IMethod[elements.size()]);
1050            elements= new ArrayList JavaDoc();
1051            for (int index= 0; index < typeCount; index++) {
1052                final String JavaDoc attribute= JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (extractCount + abstractCount + deleteCount + index + 1);
1053                handle= extended.getAttribute(attribute);
1054                if (handle != null && !"".equals(handle)) { //$NON-NLS-1$
1055
final IJavaElement element= JDTRefactoringDescriptor.handleToElement(fOwner, extended.getProject(), handle, false);
1056                    if (element == null || !element.exists())
1057                        status.merge(ScriptableRefactoring.createInputFatalStatus(element, getRefactoring().getName(), IJavaRefactorings.EXTRACT_SUPERCLASS));
1058                    else
1059                        elements.add(element);
1060                } else
1061                    return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, attribute));
1062            }
1063            fTypesToExtract= (IType[]) elements.toArray(new IType[elements.size()]);
1064            IJavaProject project= null;
1065            if (fMembersToMove.length > 0)
1066                project= fMembersToMove[0].getJavaProject();
1067            fSettings= JavaPreferencesSettings.getCodeGenerationSettings(project);
1068            if (!status.isOK())
1069                return status;
1070        } else
1071            return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments);
1072        return new RefactoringStatus();
1073    }
1074
1075    /**
1076     * {@inheritDoc}
1077     */

1078    protected void registerChanges(final TextEditBasedChangeManager manager) throws CoreException {
1079        try {
1080            final ICompilationUnit extractedUnit= getExtractedType().getCompilationUnit();
1081            ICompilationUnit unit= null;
1082            CompilationUnitRewrite rewrite= null;
1083            for (final Iterator JavaDoc iterator= fCompilationUnitRewrites.keySet().iterator(); iterator.hasNext();) {
1084                unit= (ICompilationUnit) iterator.next();
1085                if (unit.equals(extractedUnit)) {
1086                    rewrite= (CompilationUnitRewrite) fCompilationUnitRewrites.get(unit);
1087                    if (rewrite != null) {
1088                        CompilationUnitChange change= rewrite.createChange();
1089
1090                        if (change != null) {
1091                            final TextEdit edit= ((TextChange) change).getEdit();
1092                            if (edit != null) {
1093                                final IDocument document= new Document(fSuperSource);
1094                                try {
1095                                    edit.apply(document, TextEdit.UPDATE_REGIONS);
1096                                } catch (MalformedTreeException exception) {
1097                                    JavaPlugin.log(exception);
1098                                } catch (BadLocationException exception) {
1099                                    JavaPlugin.log(exception);
1100                                }
1101                                fSuperSource= document.get();
1102                                manager.remove(extractedUnit);
1103                            }
1104                        }
1105                    }
1106                } else {
1107                    rewrite= (CompilationUnitRewrite) fCompilationUnitRewrites.get(unit);
1108                    if (rewrite != null) {
1109                        final CompilationUnitChange layerChange= (CompilationUnitChange) fLayerChanges.get(unit.getPrimary());
1110                        final CompilationUnitChange rewriteChange= rewrite.createChange();
1111                        if (rewriteChange != null && layerChange != null) {
1112                            final MultiStateCompilationUnitChange change= new MultiStateCompilationUnitChange(rewriteChange.getName(), unit);
1113                            change.addChange(layerChange);
1114                            change.addChange(rewriteChange);
1115                            fLayerChanges.remove(unit.getPrimary());
1116                            manager.manage(unit, change);
1117                        } else if (layerChange != null) {
1118                            manager.manage(unit, layerChange);
1119                            fLayerChanges.remove(unit.getPrimary());
1120                        } else if (rewriteChange != null) {
1121                            manager.manage(unit, rewriteChange);
1122                        }
1123                    }
1124                }
1125            }
1126            for (Iterator JavaDoc iterator= fLayerChanges.entrySet().iterator(); iterator.hasNext();) {
1127                final Map.Entry JavaDoc entry= (Map.Entry JavaDoc) iterator.next();
1128                manager.manage((ICompilationUnit) entry.getKey(), (TextEditBasedChange) entry.getValue());
1129            }
1130            ICompilationUnit[] units= manager.getAllCompilationUnits();
1131            for (int index= 0; index < units.length; index++) {
1132                if (units[index].getPath().equals(extractedUnit.getPath()))
1133                    manager.remove(units[index]);
1134            }
1135        } finally {
1136            fLayerChanges.clear();
1137        }
1138    }
1139
1140    /**
1141     * Resets the changes necessary for the working copy layer.
1142     */

1143    public void resetChanges() {
1144        fLayerChanges.clear();
1145    }
1146
1147    /**
1148     * Sets the type name.
1149     *
1150     * @param name
1151     * the type name
1152     */

1153    public void setTypeName(final String JavaDoc name) {
1154        Assert.isNotNull(name);
1155        fTypeName= name;
1156    }
1157
1158    /**
1159     * Sets the types to extract. Must be a subset of
1160     * <code>getPossibleCandidates()</code>. If the declaring type is not
1161     * contained, it will automatically be added.
1162     *
1163     * @param types
1164     * the types to extract
1165     */

1166    public void setTypesToExtract(final IType[] types) {
1167        Assert.isNotNull(types);
1168        fTypesToExtract= types;
1169    }
1170}
1171
Popular Tags