KickJava   Java API By Example, From Geeks To Geeks.

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


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  *******************************************************************************/

11 package org.eclipse.jdt.internal.corext.refactoring.structure.constraints;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.Collections JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.HashSet JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.Set JavaDoc;
22
23 import org.eclipse.text.edits.MalformedTreeException;
24 import org.eclipse.text.edits.TextEdit;
25 import org.eclipse.text.edits.TextEditGroup;
26
27 import org.eclipse.core.runtime.Assert;
28 import org.eclipse.core.runtime.CoreException;
29 import org.eclipse.core.runtime.IProgressMonitor;
30 import org.eclipse.core.runtime.NullProgressMonitor;
31 import org.eclipse.core.runtime.SubProgressMonitor;
32
33 import org.eclipse.jface.text.BadLocationException;
34 import org.eclipse.jface.text.Document;
35 import org.eclipse.jface.text.IDocument;
36
37 import org.eclipse.ltk.core.refactoring.GroupCategory;
38 import org.eclipse.ltk.core.refactoring.GroupCategorySet;
39 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
40 import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
41
42 import org.eclipse.jdt.core.BindingKey;
43 import org.eclipse.jdt.core.ICompilationUnit;
44 import org.eclipse.jdt.core.IField;
45 import org.eclipse.jdt.core.IJavaElement;
46 import org.eclipse.jdt.core.IJavaProject;
47 import org.eclipse.jdt.core.IMember;
48 import org.eclipse.jdt.core.IMethod;
49 import org.eclipse.jdt.core.IPackageFragment;
50 import org.eclipse.jdt.core.IType;
51 import org.eclipse.jdt.core.ITypeParameter;
52 import org.eclipse.jdt.core.JavaCore;
53 import org.eclipse.jdt.core.JavaModelException;
54 import org.eclipse.jdt.core.WorkingCopyOwner;
55 import org.eclipse.jdt.core.dom.AST;
56 import org.eclipse.jdt.core.dom.ASTNode;
57 import org.eclipse.jdt.core.dom.ASTParser;
58 import org.eclipse.jdt.core.dom.ASTRequestor;
59 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
60 import org.eclipse.jdt.core.dom.ArrayType;
61 import org.eclipse.jdt.core.dom.BodyDeclaration;
62 import org.eclipse.jdt.core.dom.CastExpression;
63 import org.eclipse.jdt.core.dom.CompilationUnit;
64 import org.eclipse.jdt.core.dom.FieldDeclaration;
65 import org.eclipse.jdt.core.dom.IBinding;
66 import org.eclipse.jdt.core.dom.IMethodBinding;
67 import org.eclipse.jdt.core.dom.ITypeBinding;
68 import org.eclipse.jdt.core.dom.IVariableBinding;
69 import org.eclipse.jdt.core.dom.MethodDeclaration;
70 import org.eclipse.jdt.core.dom.QualifiedName;
71 import org.eclipse.jdt.core.dom.SimpleName;
72 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
73 import org.eclipse.jdt.core.dom.Type;
74 import org.eclipse.jdt.core.dom.TypeDeclaration;
75 import org.eclipse.jdt.core.dom.TypeParameter;
76 import org.eclipse.jdt.core.dom.VariableDeclaration;
77 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
78 import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
79 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
80 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
81 import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
82 import org.eclipse.jdt.core.formatter.CodeFormatter;
83 import org.eclipse.jdt.core.search.IJavaSearchConstants;
84 import org.eclipse.jdt.core.search.SearchMatch;
85 import org.eclipse.jdt.core.search.SearchPattern;
86
87 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
88 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
89 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
90 import org.eclipse.jdt.internal.corext.dom.NodeFinder;
91 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
92 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
93 import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory;
94 import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine2;
95 import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
96 import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;
97 import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
98 import org.eclipse.jdt.internal.corext.refactoring.structure.ImportRewriteUtil;
99 import org.eclipse.jdt.internal.corext.refactoring.tagging.ICommentProvider;
100 import org.eclipse.jdt.internal.corext.refactoring.tagging.IScriptableRefactoring;
101 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.CompilationUnitRange;
102 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType;
103 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment;
104 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
105 import org.eclipse.jdt.internal.corext.refactoring.util.TextEditBasedChangeManager;
106 import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil;
107 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
108 import org.eclipse.jdt.internal.corext.util.JdtFlags;
109 import org.eclipse.jdt.internal.corext.util.SearchUtils;
110
111 import org.eclipse.jdt.ui.CodeGeneration;
112
113 import org.eclipse.jdt.internal.ui.JavaPlugin;
114
115 /**
116  * Partial implementation of a refactoring processor solving supertype
117  * constraint models.
118  *
119  * @since 3.1
120  */

121 public abstract class SuperTypeRefactoringProcessor extends RefactoringProcessor implements IScriptableRefactoring, ICommentProvider {
122
123     // TODO: remove
124
protected static final String JavaDoc ATTRIBUTE_INSTANCEOF= "instanceof"; //$NON-NLS-1$
125

126     // TODO: remove
127
protected static final String JavaDoc ATTRIBUTE_REPLACE= "replace"; //$NON-NLS-1$
128

129     /** The super type group category set */
130     protected static final GroupCategorySet SET_SUPER_TYPE= new GroupCategorySet(new GroupCategory("org.eclipse.jdt.internal.corext.superType", //$NON-NLS-1$
131
RefactoringCoreMessages.SuperTypeRefactoringProcessor_category_name, RefactoringCoreMessages.SuperTypeRefactoringProcessor_category_description));
132
133     /** Number of compilation units to parse at once */
134     private static final int SIZE_BATCH= 500;
135
136     /**
137      * Returns a new ast node corresponding to the given type.
138      *
139      * @param rewrite
140      * the compilation unit rewrite to use
141      * @param type
142      * the specified type
143      * @return A corresponding ast node
144      */

145     protected static ASTNode createCorrespondingNode(final CompilationUnitRewrite rewrite, final TType type) {
146         return rewrite.getImportRewrite().addImportFromSignature(new BindingKey(type.getBindingKey()).toSignature(), rewrite.getAST());
147     }
148
149     /** The comment */
150     protected String JavaDoc fComment;
151
152     /** Should type occurrences on instanceof's also be rewritten? */
153     protected boolean fInstanceOf= false;
154
155     /**
156      * The obsolete casts (element type:
157      * <code>&ltICompilationUnit, Collection&ltCastVariable2&gt&gt</code>)
158      */

159     protected Map JavaDoc fObsoleteCasts= null;
160
161     /** The working copy owner */
162     protected final WorkingCopyOwner fOwner= new WorkingCopyOwner() {
163     };
164
165     /** Should occurrences of the type be replaced by the supertype? */
166     protected boolean fReplace= false;
167
168     /** The code generation settings, or <code>null</code> */
169     protected CodeGenerationSettings fSettings;
170
171     /** The static bindings to import */
172     protected final Set JavaDoc fStaticBindings= new HashSet JavaDoc();
173
174     /** The type bindings to import */
175     protected final Set JavaDoc fTypeBindings= new HashSet JavaDoc();
176
177     /**
178      * The type occurrences (element type:
179      * <code>&ltICompilationUnit, Collection&ltIDeclaredConstraintVariable&gt&gt</code>)
180      */

181     protected Map JavaDoc fTypeOccurrences= null;
182
183     /**
184      * Creates a new supertype refactoring processor.
185      *
186      * @param settings
187      * the code generation settings, or <code>null</code>
188      */

189     protected SuperTypeRefactoringProcessor(final CodeGenerationSettings settings) {
190         fSettings= settings;
191     }
192
193     /**
194      * Adds the refactoring settings to the specified comment.
195      *
196      * @param comment
197      * the java refactoring descriptor comment
198      * @param addUseSupertype
199      * <code>true</code> to add the use supertype setting,
200      * <code>false</code> otherwise
201      */

202     protected void addSuperTypeSettings(final JDTRefactoringDescriptorComment comment, final boolean addUseSupertype) {
203         Assert.isNotNull(comment);
204         if (fReplace) {
205             if (addUseSupertype)
206                 comment.addSetting(RefactoringCoreMessages.SuperTypeRefactoringProcessor_user_supertype_setting);
207             if (fInstanceOf)
208                 comment.addSetting(RefactoringCoreMessages.SuperTypeRefactoringProcessor_use_in_instanceof_setting);
209         }
210     }
211
212     /**
213      * {@inheritDoc}
214      */

215     public boolean canEnableComment() {
216         return true;
217     }
218
219     /**
220      * Creates the super type constraint solver to solve the model.
221      *
222      * @param model
223      * the model to create a solver for
224      * @return The created super type constraint solver
225      */

226     protected abstract SuperTypeConstraintsSolver createContraintSolver(SuperTypeConstraintsModel model);
227
228     /**
229      * Creates the declarations of the new supertype members.
230      *
231      * @param sourceRewrite
232      * the source compilation unit rewrite
233      * @param targetRewrite
234      * the target rewrite
235      * @param targetDeclaration
236      * the target type declaration
237      * @throws CoreException
238      * if a buffer could not be retrieved
239      */

240     protected void createMemberDeclarations(CompilationUnitRewrite sourceRewrite, ASTRewrite targetRewrite, AbstractTypeDeclaration targetDeclaration) throws CoreException {
241         // Do nothing
242
}
243
244     /**
245      * Creates the declaration of the new supertype, excluding any comments or
246      * package declaration.
247      *
248      * @param sourceRewrite
249      * the source compilation unit rewrite
250      * @param subType
251      * the subtype
252      * @param superName
253      * the name of the supertype
254      * @param sourceDeclaration
255      * the type declaration of the source type
256      * @param buffer
257      * the string buffer containing the declaration
258      * @param isInterface
259      * <code>true</code> if the type declaration is an interface,
260      * <code>false</code> otherwise
261      * @param status
262      * the refactoring status
263      * @param monitor
264      * the progress monitor to use
265      * @throws CoreException
266      * if an error occurs
267      */

268     protected final void createTypeDeclaration(final CompilationUnitRewrite sourceRewrite, final IType subType, final String JavaDoc superName, final AbstractTypeDeclaration sourceDeclaration, final StringBuffer JavaDoc buffer, boolean isInterface, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
269         Assert.isNotNull(sourceRewrite);
270         Assert.isNotNull(subType);
271         Assert.isNotNull(superName);
272         Assert.isNotNull(sourceDeclaration);
273         Assert.isNotNull(buffer);
274         Assert.isNotNull(status);
275         Assert.isNotNull(monitor);
276         try {
277             monitor.beginTask("", 100); //$NON-NLS-1$
278
monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating);
279             final String JavaDoc delimiter= StubUtility.getLineDelimiterUsed(subType.getJavaProject());
280             if (JdtFlags.isPublic(subType)) {
281                 buffer.append(JdtFlags.VISIBILITY_STRING_PUBLIC);
282                 buffer.append(" "); //$NON-NLS-1$
283
}
284             if (isInterface)
285                 buffer.append("interface "); //$NON-NLS-1$
286
else
287                 buffer.append("class "); //$NON-NLS-1$
288
buffer.append(superName);
289             buffer.append(" {"); //$NON-NLS-1$
290
buffer.append(delimiter);
291             buffer.append(delimiter);
292             buffer.append('}');
293             final IDocument document= new Document(buffer.toString());
294             final ASTParser parser= ASTParser.newParser(AST.JLS3);
295             parser.setSource(document.get().toCharArray());
296             final CompilationUnit unit= (CompilationUnit) parser.createAST(new SubProgressMonitor(monitor, 100));
297             final ASTRewrite targetRewrite= ASTRewrite.create(unit.getAST());
298             final AbstractTypeDeclaration targetDeclaration= (AbstractTypeDeclaration) unit.types().get(0);
299             createTypeParameters(targetRewrite, subType, sourceDeclaration, targetDeclaration);
300             createMemberDeclarations(sourceRewrite, targetRewrite, targetDeclaration);
301             final TextEdit edit= targetRewrite.rewriteAST(document, subType.getJavaProject().getOptions(true));
302             try {
303                 edit.apply(document, TextEdit.UPDATE_REGIONS);
304             } catch (MalformedTreeException exception) {
305                 JavaPlugin.log(exception);
306             } catch (BadLocationException exception) {
307                 JavaPlugin.log(exception);
308             }
309             buffer.setLength(0);
310             buffer.append(document.get());
311         } finally {
312             monitor.done();
313         }
314     }
315
316     /**
317      * Creates the necessary imports for the extracted supertype.
318      *
319      * @param unit
320      * the working copy of the new supertype
321      * @param monitor
322      * the progress monitor to use
323      * @return the generated import declaration
324      * @throws CoreException
325      * if the imports could not be generated
326      */

327     protected final String JavaDoc createTypeImports(final ICompilationUnit unit, final IProgressMonitor monitor) throws CoreException {
328         Assert.isNotNull(unit);
329         Assert.isNotNull(monitor);
330         try {
331             monitor.beginTask("", 100); //$NON-NLS-1$
332
monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating);
333             final ImportRewrite rewrite= StubUtility.createImportRewrite(unit, true);
334             ITypeBinding type= null;
335             for (final Iterator JavaDoc iterator= fTypeBindings.iterator(); iterator.hasNext();) {
336                 type= (ITypeBinding) iterator.next();
337                 if (type.isTypeVariable()) {
338                     final ITypeBinding[] bounds= type.getTypeBounds();
339                     for (int index= 0; index < bounds.length; index++)
340                         rewrite.addImport(bounds[index]);
341                 }
342                 rewrite.addImport(type);
343             }
344             IBinding binding= null;
345             for (final Iterator JavaDoc iterator= fStaticBindings.iterator(); iterator.hasNext();) {
346                 binding= (IBinding) iterator.next();
347                 rewrite.addStaticImport(binding);
348             }
349             final IDocument document= new Document();
350             try {
351                 rewrite.rewriteImports(new SubProgressMonitor(monitor, 100)).apply(document);
352             } catch (MalformedTreeException exception) {
353                 JavaPlugin.log(exception);
354             } catch (BadLocationException exception) {
355                 JavaPlugin.log(exception);
356             } catch (CoreException exception) {
357                 JavaPlugin.log(exception);
358             }
359             fTypeBindings.clear();
360             fStaticBindings.clear();
361             return document.get();
362         } finally {
363             monitor.done();
364         }
365     }
366
367     /**
368      * Creates the type parameters of the new supertype.
369      *
370      * @param targetRewrite
371      * the target compilation unit rewrite
372      * @param subType
373      * the subtype
374      * @param sourceDeclaration
375      * the type declaration of the source type
376      * @param targetDeclaration
377      * the type declaration of the target type
378      */

379     protected final void createTypeParameters(final ASTRewrite targetRewrite, final IType subType, final AbstractTypeDeclaration sourceDeclaration, final AbstractTypeDeclaration targetDeclaration) {
380         Assert.isNotNull(targetRewrite);
381         Assert.isNotNull(sourceDeclaration);
382         Assert.isNotNull(targetDeclaration);
383         if (sourceDeclaration instanceof TypeDeclaration) {
384             TypeParameter parameter= null;
385             final ListRewrite rewrite= targetRewrite.getListRewrite(targetDeclaration, TypeDeclaration.TYPE_PARAMETERS_PROPERTY);
386             for (final Iterator JavaDoc iterator= ((TypeDeclaration) sourceDeclaration).typeParameters().iterator(); iterator.hasNext();) {
387                 parameter= (TypeParameter) iterator.next();
388                 rewrite.insertLast(ASTNode.copySubtree(targetRewrite.getAST(), parameter), null);
389                 ImportRewriteUtil.collectImports(subType.getJavaProject(), sourceDeclaration, fTypeBindings, fStaticBindings, false);
390             }
391         }
392     }
393
394     /**
395      * Creates the source for the new compilation unit containing the supertype.
396      *
397      * @param copy
398      * the working copy of the new supertype
399      * @param subType
400      * the subtype
401      * @param superName
402      * the name of the supertype
403      * @param sourceRewrite
404      * the source compilation unit rewrite
405      * @param declaration
406      * the type declaration
407      * @param status
408      * the refactoring status
409      * @param monitor
410      * the progress monitor to display progress
411      * @return the source of the new compilation unit, or <code>null</code>
412      * @throws CoreException
413      * if an error occurs
414      */

415     protected final String JavaDoc createTypeSource(final ICompilationUnit copy, final IType subType, final String JavaDoc superName, final CompilationUnitRewrite sourceRewrite, final AbstractTypeDeclaration declaration, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
416         Assert.isNotNull(copy);
417         Assert.isNotNull(subType);
418         Assert.isNotNull(superName);
419         Assert.isNotNull(sourceRewrite);
420         Assert.isNotNull(declaration);
421         Assert.isNotNull(status);
422         Assert.isNotNull(monitor);
423         String JavaDoc source= null;
424         try {
425             monitor.beginTask("", 100); //$NON-NLS-1$
426
monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating);
427             final String JavaDoc delimiter= StubUtility.getLineDelimiterUsed(subType.getJavaProject());
428             String JavaDoc typeComment= null;
429             String JavaDoc fileComment= null;
430             if (fSettings.createComments) {
431                 final ITypeParameter[] parameters= subType.getTypeParameters();
432                 final String JavaDoc[] names= new String JavaDoc[parameters.length];
433                 for (int index= 0; index < parameters.length; index++)
434                     names[index]= parameters[index].getElementName();
435                 typeComment= CodeGeneration.getTypeComment(copy, superName, names, delimiter);
436                 fileComment= CodeGeneration.getFileComment(copy, delimiter);
437             }
438             final StringBuffer JavaDoc buffer= new StringBuffer JavaDoc(64);
439             createTypeDeclaration(sourceRewrite, subType, superName, declaration, buffer, true, status, new SubProgressMonitor(monitor, 40));
440             final String JavaDoc imports= createTypeImports(copy, new SubProgressMonitor(monitor, 60));
441             source= createTypeTemplate(copy, imports, fileComment, typeComment, buffer.toString());
442             if (source == null) {
443                 if (!subType.getPackageFragment().isDefaultPackage()) {
444                     if (imports.length() > 0)
445                         buffer.insert(0, imports);
446                     buffer.insert(0, "package " + subType.getPackageFragment().getElementName() + ";"); //$NON-NLS-1$//$NON-NLS-2$
447
}
448                 source= buffer.toString();
449             }
450             final IDocument document= new Document(source);
451             final TextEdit edit= CodeFormatterUtil.format2(CodeFormatter.K_COMPILATION_UNIT, source, 0, delimiter, copy.getJavaProject().getOptions(true));
452             if (edit != null) {
453                 try {
454                     edit.apply(document, TextEdit.UPDATE_REGIONS);
455                 } catch (MalformedTreeException exception) {
456                     JavaPlugin.log(exception);
457                     status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error));
458                 } catch (BadLocationException exception) {
459                     JavaPlugin.log(exception);
460                     status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error));
461                 }
462                 source= document.get();
463             }
464         } finally {
465             monitor.done();
466         }
467         return source;
468     }
469
470     /**
471      * Creates the type template based on the code generation settings.
472      *
473      * @param unit
474      * the working copy for the new supertype
475      * @param imports
476      * the generated imports declaration
477      * @param fileComment
478      * the file comment
479      * @param comment
480      * the type comment
481      * @param content
482      * the type content
483      * @return a template for the supertype, or <code>null</code>
484      * @throws CoreException
485      * if the template could not be evaluated
486      */

487     protected final String JavaDoc createTypeTemplate(final ICompilationUnit unit, final String JavaDoc imports, String JavaDoc fileComment, final String JavaDoc comment, final String JavaDoc content) throws CoreException {
488         Assert.isNotNull(unit);
489         Assert.isNotNull(imports);
490         Assert.isNotNull(content);
491         final IPackageFragment fragment= (IPackageFragment) unit.getParent();
492         final StringBuffer JavaDoc buffer= new StringBuffer JavaDoc();
493         final String JavaDoc delimiter= StubUtility.getLineDelimiterUsed(unit.getJavaProject());
494         if (!fragment.isDefaultPackage()) {
495             buffer.append("package " + fragment.getElementName() + ";"); //$NON-NLS-1$ //$NON-NLS-2$
496
buffer.append(delimiter);
497             buffer.append(delimiter);
498         }
499         if (imports.length() > 0)
500             buffer.append(imports);
501
502         return StubUtility.getCompilationUnitContent(unit, buffer.toString(), fileComment, comment, content, delimiter);
503     }
504
505     /**
506      * {@inheritDoc}
507      */

508     protected void finalize() throws Throwable JavaDoc {
509         resetWorkingCopies();
510     }
511
512     /**
513      * {@inheritDoc}
514      */

515     public final String JavaDoc getComment() {
516         return fComment;
517     }
518
519     /**
520      * Returns the field which corresponds to the specified variable declaration
521      * fragment
522      *
523      * @param fragment
524      * the variable declaration fragment
525      * @return the corresponding field
526      * @throws JavaModelException
527      * if an error occurs
528      */

529     protected final IField getCorrespondingField(final VariableDeclarationFragment fragment) throws JavaModelException {
530         final IBinding binding= fragment.getName().resolveBinding();
531         if (binding instanceof IVariableBinding) {
532             final IVariableBinding variable= (IVariableBinding) binding;
533             if (variable.isField()) {
534                 final ICompilationUnit unit= RefactoringASTParser.getCompilationUnit(fragment);
535                 final IJavaElement element= unit.getElementAt(fragment.getStartPosition());
536                 if (element instanceof IField)
537                     return (IField) element;
538             }
539         }
540         return null;
541     }
542
543     /**
544      * Computes the compilation units of fields referencing the specified type
545      * occurrences.
546      *
547      * @param units
548      * the compilation unit map (element type:
549      * <code>&ltIJavaProject, Set&ltICompilationUnit&gt&gt</code>)
550      * @param nodes
551      * the ast nodes representing the type occurrences
552      * @throws JavaModelException
553      * if an error occurs
554      */

555     protected final void getFieldReferencingCompilationUnits(final Map JavaDoc units, final ASTNode[] nodes) throws JavaModelException {
556         ASTNode node= null;
557         IField field= null;
558         IJavaProject project= null;
559         for (int index= 0; index < nodes.length; index++) {
560             node= nodes[index];
561             project= RefactoringASTParser.getCompilationUnit(node).getJavaProject();
562             if (project != null) {
563                 final List JavaDoc fields= getReferencingFields(node, project);
564                 for (int offset= 0; offset < fields.size(); offset++) {
565                     field= (IField) fields.get(offset);
566                     Set JavaDoc set= (Set JavaDoc) units.get(project);
567                     if (set == null) {
568                         set= new HashSet JavaDoc();
569                         units.put(project, set);
570                     }
571                     final ICompilationUnit unit= field.getCompilationUnit();
572                     if (unit != null)
573                         set.add(unit);
574                 }
575             }
576         }
577     }
578
579     /**
580      * Computes the compilation units of methods referencing the specified type
581      * occurrences.
582      *
583      * @param units
584      * the compilation unit map (element type:
585      * <code>&ltIJavaProject, Set&ltICompilationUnit&gt&gt</code>)
586      * @param nodes
587      * the ast nodes representing the type occurrences
588      * @throws JavaModelException
589      * if an error occurs
590      */

591     protected final void getMethodReferencingCompilationUnits(final Map JavaDoc units, final ASTNode[] nodes) throws JavaModelException {
592         ASTNode node= null;
593         IMethod method= null;
594         IJavaProject project= null;
595         for (int index= 0; index < nodes.length; index++) {
596             node= nodes[index];
597             project= RefactoringASTParser.getCompilationUnit(node).getJavaProject();
598             if (project != null) {
599                 method= getReferencingMethod(node);
600                 if (method != null) {
601                     Set JavaDoc set= (Set JavaDoc) units.get(project);
602                     if (set == null) {
603                         set= new HashSet JavaDoc();
604                         units.put(project, set);
605                     }
606                     final ICompilationUnit unit= method.getCompilationUnit();
607                     if (unit != null)
608                         set.add(unit);
609                 }
610             }
611         }
612     }
613
614     /**
615      * Computes the compilation units referencing the subtype to replace.
616      *
617      * @param type
618      * the subtype
619      * @param monitor
620      * the progress monitor to use
621      * @param status
622      * the refactoring status
623      * @return the referenced compilation units (element type:
624      * <code>&ltIJavaProject, Collection&ltSearchResultGroup&gt&gt</code>)
625      * @throws JavaModelException
626      * if an error occurs
627      */

628     protected final Map JavaDoc getReferencingCompilationUnits(final IType type, final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException {
629         try {
630             monitor.beginTask("", 100); //$NON-NLS-1$
631
monitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
632             final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2();
633             engine.setOwner(fOwner);
634             engine.setFiltering(true, true);
635             engine.setStatus(status);
636             engine.setScope(RefactoringScopeFactory.create(type));
637             engine.setPattern(SearchPattern.createPattern(type, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE));
638             engine.searchPattern(new SubProgressMonitor(monitor, 100));
639             return engine.getAffectedProjects();
640         } finally {
641             monitor.done();
642         }
643     }
644
645     /**
646      * Returns the fields which reference the specified ast node.
647      *
648      * @param node
649      * the ast node
650      * @param project
651      * the java project
652      * @return the referencing fields
653      * @throws JavaModelException
654      * if an error occurs
655      */

656     protected final List JavaDoc getReferencingFields(final ASTNode node, final IJavaProject project) throws JavaModelException {
657         List JavaDoc result= Collections.EMPTY_LIST;
658         if (node instanceof Type) {
659             final BodyDeclaration parent= (BodyDeclaration) ASTNodes.getParent(node, BodyDeclaration.class);
660             if (parent instanceof FieldDeclaration) {
661                 final List JavaDoc fragments= ((FieldDeclaration) parent).fragments();
662                 result= new ArrayList JavaDoc(fragments.size());
663                 VariableDeclarationFragment fragment= null;
664                 for (final Iterator JavaDoc iterator= fragments.iterator(); iterator.hasNext();) {
665                     fragment= (VariableDeclarationFragment) iterator.next();
666                     final IField field= getCorrespondingField(fragment);
667                     if (field != null)
668                         result.add(field);
669                 }
670             }
671         }
672         return result;
673     }
674
675     /**
676      * Returns the method which references the specified ast node.
677      *
678      * @param node
679      * the ast node
680      * @return the referencing method
681      * @throws JavaModelException
682      * if an error occurs
683      */

684     protected final IMethod getReferencingMethod(final ASTNode node) throws JavaModelException {
685         if (node instanceof Type) {
686             final BodyDeclaration parent= (BodyDeclaration) ASTNodes.getParent(node, BodyDeclaration.class);
687             if (parent instanceof MethodDeclaration) {
688                 final IMethodBinding binding= ((MethodDeclaration) parent).resolveBinding();
689                 if (binding != null) {
690                     final ICompilationUnit unit= RefactoringASTParser.getCompilationUnit(node);
691                     final IJavaElement element= unit.getElementAt(node.getStartPosition());
692                     if (element instanceof IMethod)
693                         return (IMethod) element;
694                 }
695             }
696         }
697         return null;
698     }
699
700     protected ICompilationUnit getSharedWorkingCopy(final ICompilationUnit unit, final IProgressMonitor monitor) throws JavaModelException {
701         try {
702             ICompilationUnit copy= unit.findWorkingCopy(fOwner);
703             if (copy == null)
704                 copy= unit.getWorkingCopy(fOwner, monitor);
705             return copy;
706         } finally {
707             monitor.done();
708         }
709     }
710
711     /**
712      * Returns whether type occurrences in instanceof's should be rewritten.
713      *
714      * @return <code>true</code> if they are rewritten, <code>false</code>
715      * otherwise
716      */

717     public final boolean isInstanceOf() {
718         return fInstanceOf;
719     }
720
721     /**
722      * Should occurrences of the subtype be replaced by the supertype?
723      *
724      * @return <code>true</code> if the subtype should be replaced,
725      * <code>false</code> otherwise
726      */

727     public final boolean isReplace() {
728         return fReplace;
729     }
730
731     /**
732      * Performs the first pass of processing the affected compilation units.
733      *
734      * @param creator
735      * the constraints creator to use
736      * @param units
737      * the compilation unit map (element type:
738      * <code>&ltIJavaProject, Set&ltICompilationUnit&gt&gt</code>)
739      * @param groups
740      * the search result group map (element type:
741      * <code>&ltICompilationUnit, SearchResultGroup&gt</code>)
742      * @param unit
743      * the compilation unit of the subtype
744      * @param node
745      * the compilation unit node of the subtype
746      * @param monitor
747      * the progress monitor to use
748      */

749     protected final void performFirstPass(final SuperTypeConstraintsCreator creator, final Map JavaDoc units, final Map JavaDoc groups, final ICompilationUnit unit, final CompilationUnit node, final IProgressMonitor monitor) {
750         try {
751             monitor.beginTask("", 100); //$NON-NLS-1$
752
monitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
753             node.accept(creator);
754             monitor.worked(20);
755             final SearchResultGroup group= (SearchResultGroup) groups.get(unit);
756             if (group != null) {
757                 final ASTNode[] nodes= ASTNodeSearchUtil.getAstNodes(group.getSearchResults(), node);
758                 try {
759                     getMethodReferencingCompilationUnits(units, nodes);
760                     monitor.worked(40);
761                     getFieldReferencingCompilationUnits(units, nodes);
762                     monitor.worked(40);
763                 } catch (JavaModelException exception) {
764                     JavaPlugin.log(exception);
765                 }
766             }
767         } finally {
768             monitor.done();
769         }
770     }
771
772     /**
773      * Performs the second pass of processing the affected compilation units.
774      *
775      * @param creator
776      * the constraints creator to use
777      * @param unit
778      * the compilation unit of the subtype
779      * @param node
780      * the compilation unit node of the subtype
781      * @param monitor
782      * the progress monitor to use
783      */

784     protected final void performSecondPass(final SuperTypeConstraintsCreator creator, final ICompilationUnit unit, final CompilationUnit node, final IProgressMonitor monitor) {
785         try {
786             monitor.beginTask("", 20); //$NON-NLS-1$
787
monitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
788             node.accept(creator);
789             monitor.worked(20);
790         } finally {
791             monitor.done();
792         }
793     }
794
795     /**
796      * Resets the working copies.
797      */

798     protected void resetWorkingCopies() {
799         final ICompilationUnit[] units= JavaCore.getWorkingCopies(fOwner);
800         for (int index= 0; index < units.length; index++) {
801             final ICompilationUnit unit= units[index];
802             try {
803                 unit.discardWorkingCopy();
804             } catch (Exception JavaDoc exception) {
805                 // Do nothing
806
}
807         }
808     }
809
810     /**
811      * Resets the working copies.
812      *
813      * @param unit
814      * the compilation unit to discard
815      */

816     protected void resetWorkingCopies(final ICompilationUnit unit) {
817         final ICompilationUnit[] units= JavaCore.getWorkingCopies(fOwner);
818         for (int index= 0; index < units.length; index++) {
819             if (!units[index].equals(unit)) {
820                 try {
821                     units[index].discardWorkingCopy();
822                 } catch (Exception JavaDoc exception) {
823                     // Do nothing
824
}
825             } else {
826                 try {
827                     units[index].getBuffer().setContents(unit.getPrimary().getBuffer().getContents());
828                     JavaModelUtil.reconcile(units[index]);
829                 } catch (JavaModelException exception) {
830                     JavaPlugin.log(exception);
831                 }
832             }
833         }
834     }
835
836     /**
837      * Creates the necessary text edits to replace the subtype occurrence by a
838      * supertype.
839      *
840      * @param range
841      * the compilation unit range
842      * @param estimate
843      * the type estimate
844      * @param requestor
845      * the ast requestor to use
846      * @param rewrite
847      * the compilation unit rewrite to use
848      * @param copy
849      * the compilation unit node of the working copy ast
850      * @param replacements
851      * the set of variable binding keys of formal parameters which
852      * must be replaced
853      * @param group
854      * the text edit group to use
855      */

856     protected final void rewriteTypeOccurrence(final CompilationUnitRange range, final TType estimate, final ASTRequestor requestor, final CompilationUnitRewrite rewrite, final CompilationUnit copy, final Set JavaDoc replacements, final TextEditGroup group) {
857         ASTNode node= null;
858         IBinding binding= null;
859         final CompilationUnit target= rewrite.getRoot();
860         node= NodeFinder.perform(copy, range.getSourceRange());
861         if (node != null) {
862             node= ASTNodes.getNormalizedNode(node).getParent();
863             if (node instanceof VariableDeclaration) {
864                 binding= ((VariableDeclaration) node).resolveBinding();
865                 node= target.findDeclaringNode(binding.getKey());
866                 if (node instanceof SingleVariableDeclaration) {
867                     rewriteTypeOccurrence(estimate, rewrite, ((SingleVariableDeclaration) node).getType(), group);
868                     if (node.getParent() instanceof MethodDeclaration) {
869                         binding= ((VariableDeclaration) node).resolveBinding();
870                         if (binding != null)
871                             replacements.add(binding.getKey());
872                     }
873                 }
874             } else if (node instanceof VariableDeclarationStatement) {
875                 binding= ((VariableDeclaration) ((VariableDeclarationStatement) node).fragments().get(0)).resolveBinding();
876                 node= target.findDeclaringNode(binding.getKey());
877                 if (node instanceof VariableDeclarationFragment)
878                     rewriteTypeOccurrence(estimate, rewrite, ((VariableDeclarationStatement) ((VariableDeclarationFragment) node).getParent()).getType(), group);
879             } else if (node instanceof MethodDeclaration) {
880                 binding= ((MethodDeclaration) node).resolveBinding();
881                 node= target.findDeclaringNode(binding.getKey());
882                 if (node instanceof MethodDeclaration)
883                     rewriteTypeOccurrence(estimate, rewrite, ((MethodDeclaration) node).getReturnType2(), group);
884             } else if (node instanceof FieldDeclaration) {
885                 binding= ((VariableDeclaration) ((FieldDeclaration) node).fragments().get(0)).resolveBinding();
886                 node= target.findDeclaringNode(binding.getKey());
887                 if (node instanceof VariableDeclarationFragment) {
888                     node= node.getParent();
889                     if (node instanceof FieldDeclaration)
890                         rewriteTypeOccurrence(estimate, rewrite, ((FieldDeclaration) node).getType(), group);
891                 }
892             } else if (node instanceof ArrayType) {
893                 final ASTNode type= node;
894                 while (node != null && !(node instanceof MethodDeclaration) && !(node instanceof VariableDeclarationFragment))
895                     node= node.getParent();
896                 if (node != null) {
897                     final int delta= node.getStartPosition() + node.getLength() - type.getStartPosition();
898                     if (node instanceof MethodDeclaration)
899                         binding= ((MethodDeclaration) node).resolveBinding();
900                     else if (node instanceof VariableDeclarationFragment)
901                         binding= ((VariableDeclarationFragment) node).resolveBinding();
902                     if (binding != null) {
903                         node= target.findDeclaringNode(binding.getKey());
904                         if (node instanceof MethodDeclaration || node instanceof VariableDeclarationFragment) {
905                             node= NodeFinder.perform(target, node.getStartPosition() + node.getLength() - delta, 0);
906                             if (node instanceof SimpleName)
907                                 rewriteTypeOccurrence(estimate, rewrite, node, group);
908                         }
909                     }
910                 }
911             } else if (node instanceof QualifiedName) {
912                 final ASTNode name= node;
913                 while (node != null && !(node instanceof MethodDeclaration) && !(node instanceof VariableDeclarationFragment))
914                     node= node.getParent();
915                 if (node != null) {
916                     final int delta= node.getStartPosition() + node.getLength() - name.getStartPosition();
917                     if (node instanceof MethodDeclaration)
918                         binding= ((MethodDeclaration) node).resolveBinding();
919                     else if (node instanceof VariableDeclarationFragment)
920                         binding= ((VariableDeclarationFragment) node).resolveBinding();
921                     if (binding != null) {
922                         node= target.findDeclaringNode(binding.getKey());
923                         if (node instanceof SimpleName || node instanceof MethodDeclaration || node instanceof VariableDeclarationFragment) {
924                             node= NodeFinder.perform(target, node.getStartPosition() + node.getLength() - delta, 0);
925                             if (node instanceof SimpleName)
926                                 rewriteTypeOccurrence(estimate, rewrite, node, group);
927                         }
928                     }
929                 }
930             } else if (node instanceof CastExpression) {
931                 final ASTNode expression= node;
932                 while (node != null && !(node instanceof MethodDeclaration))
933                     node= node.getParent();
934                 if (node != null) {
935                     final int delta= node.getStartPosition() + node.getLength() - expression.getStartPosition();
936                     binding= ((MethodDeclaration) node).resolveBinding();
937                     node= target.findDeclaringNode(binding.getKey());
938                     if (node instanceof MethodDeclaration) {
939                         node= NodeFinder.perform(target, node.getStartPosition() + node.getLength() - delta, 0);
940                         if (node instanceof CastExpression)
941                             rewriteTypeOccurrence(estimate, rewrite, ((CastExpression) node).getType(), group);
942                     }
943                 }
944             }
945         }
946     }
947
948     /**
949      * Creates the necessary text edits to replace the subtype occurrence by a
950      * supertype.
951      *
952      * @param estimate
953      * the type estimate
954      * @param rewrite
955      * the ast rewrite to use
956      * @param node
957      * the ast node to rewrite
958      * @param group
959      * the text edit group to use
960      */

961     protected final void rewriteTypeOccurrence(final TType estimate, final CompilationUnitRewrite rewrite, final ASTNode node, final TextEditGroup group) {
962         rewrite.getImportRemover().registerRemovedNode(node);
963         rewrite.getASTRewrite().replace(node, createCorrespondingNode(rewrite, estimate), group);
964     }
965
966     /**
967      * Creates the necessary text edits to replace the subtype occurrence by a
968      * supertype.
969      *
970      * @param manager
971      * the text change manager to use
972      * @param requestor
973      * the ast requestor to use
974      * @param rewrite
975      * the compilation unit rewrite of the subtype (not in working
976      * copy mode)
977      * @param unit
978      * the compilation unit
979      * @param node
980      * the compilation unit node
981      * @param replacements
982      * the set of variable binding keys of formal parameters which
983      * must be replaced
984      * @param monitor
985      * the progress monitor to use
986      * @throws CoreException
987      * if the change could not be generated
988      */

989     protected abstract void rewriteTypeOccurrences(TextEditBasedChangeManager manager, ASTRequestor requestor, CompilationUnitRewrite rewrite, ICompilationUnit unit, CompilationUnit node, Set JavaDoc replacements, IProgressMonitor monitor) throws CoreException;
990
991     /**
992      * Creates the necessary text edits to replace the subtype occurrences by a
993      * supertype.
994      *
995      * @param manager
996      * the text change manager to use
997      * @param sourceRewrite
998      * the compilation unit rewrite of the subtype (not in working
999      * copy mode)
1000     * @param sourceRequestor
1001     * the ast requestor of the subtype, or <code>null</code>
1002     * @param subUnit
1003     * the compilation unit of the subtype, or <code>null</code>
1004     * @param subNode
1005     * the compilation unit node of the subtype, or <code>null</code>
1006     * @param replacements
1007     * the set of variable binding keys of formal parameters which
1008     * must be replaced
1009     * @param status
1010     * the refactoring status
1011     * @param monitor
1012     * the progress monitor to use
1013     */

1014    protected final void rewriteTypeOccurrences(final TextEditBasedChangeManager manager, final ASTRequestor sourceRequestor, final CompilationUnitRewrite sourceRewrite, final ICompilationUnit subUnit, final CompilationUnit subNode, final Set JavaDoc replacements, final RefactoringStatus status, final IProgressMonitor monitor) {
1015        try {
1016            monitor.beginTask("", 300); //$NON-NLS-1$
1017
monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating);
1018            if (fTypeOccurrences != null) {
1019                final Set JavaDoc units= new HashSet JavaDoc(fTypeOccurrences.keySet());
1020                if (subUnit != null)
1021                    units.remove(subUnit);
1022                final Map JavaDoc projects= new HashMap JavaDoc();
1023                Collection JavaDoc collection= null;
1024                IJavaProject project= null;
1025                ICompilationUnit current= null;
1026                for (final Iterator JavaDoc iterator= units.iterator(); iterator.hasNext();) {
1027                    current= (ICompilationUnit) iterator.next();
1028                    project= current.getJavaProject();
1029                    collection= (Collection JavaDoc) projects.get(project);
1030                    if (collection == null) {
1031                        collection= new ArrayList JavaDoc();
1032                        projects.put(project, collection);
1033                    }
1034                    collection.add(current);
1035                }
1036                final ASTParser parser= ASTParser.newParser(AST.JLS3);
1037                final IProgressMonitor subMonitor= new SubProgressMonitor(monitor, 320);
1038                try {
1039                    final Set JavaDoc keySet= projects.keySet();
1040                    subMonitor.beginTask("", keySet.size() * 100); //$NON-NLS-1$
1041
subMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
1042                    for (final Iterator JavaDoc iterator= keySet.iterator(); iterator.hasNext();) {
1043                        project= (IJavaProject) iterator.next();
1044                        collection= (Collection JavaDoc) projects.get(project);
1045                        parser.setWorkingCopyOwner(fOwner);
1046                        parser.setResolveBindings(true);
1047                        parser.setProject(project);
1048                        parser.setCompilerOptions(RefactoringASTParser.getCompilerOptions(project));
1049                        final IProgressMonitor subsubMonitor= new SubProgressMonitor(subMonitor, 100);
1050                        try {
1051                            subsubMonitor.beginTask("", collection.size() * 100 + 200); //$NON-NLS-1$
1052
subsubMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
1053                            parser.createASTs((ICompilationUnit[]) collection.toArray(new ICompilationUnit[collection.size()]), new String JavaDoc[0], new ASTRequestor() {
1054
1055                                public final void acceptAST(final ICompilationUnit unit, final CompilationUnit node) {
1056                                    final IProgressMonitor subsubsubMonitor= new SubProgressMonitor(subsubMonitor, 100);
1057                                    try {
1058                                        subsubsubMonitor.beginTask("", 100); //$NON-NLS-1$
1059
subsubsubMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
1060                                        if (sourceRewrite != null)
1061                                            rewriteTypeOccurrences(manager, this, sourceRewrite, unit, node, replacements, new SubProgressMonitor(subsubsubMonitor, 100));
1062                                    } catch (CoreException exception) {
1063                                        status.merge(RefactoringStatus.createFatalErrorStatus(exception.getLocalizedMessage()));
1064                                    } finally {
1065                                        subsubsubMonitor.done();
1066                                    }
1067                                }
1068
1069                                public final void acceptBinding(final String JavaDoc key, final IBinding binding) {
1070                                    // Do nothing
1071
}
1072                            }, new SubProgressMonitor(subsubMonitor, 200));
1073                        } finally {
1074                            subsubMonitor.done();
1075                        }
1076                    }
1077                    try {
1078                        if (subUnit != null && subNode != null && sourceRewrite != null && sourceRequestor != null)
1079                            rewriteTypeOccurrences(manager, sourceRequestor, sourceRewrite, subUnit, subNode, replacements, new SubProgressMonitor(subMonitor, 20));
1080                    } catch (CoreException exception) {
1081                        status.merge(RefactoringStatus.createFatalErrorStatus(exception.getLocalizedMessage()));
1082                    }
1083                } finally {
1084                    subMonitor.done();
1085                }
1086            }
1087        } finally {
1088            monitor.done();
1089        }
1090    }
1091
1092    /**
1093     * {@inheritDoc}
1094     */

1095    public final void setComment(final String JavaDoc comment) {
1096        fComment= comment;
1097    }
1098
1099    /**
1100     * Determines whether type occurrences in instanceof's should be rewritten.
1101     *
1102     * @param rewrite
1103     * <code>true</code> to rewrite them, <code>false</code>
1104     * otherwise
1105     */

1106    public final void setInstanceOf(final boolean rewrite) {
1107        fInstanceOf= rewrite;
1108    }
1109
1110    /**
1111     * Determines whether occurrences of the subtype should be replaced by the
1112     * supertype.
1113     *
1114     * @param replace
1115     * <code>true</code> to replace occurrences where possible,
1116     * <code>false</code> otherwise
1117     */

1118    public final void setReplace(final boolean replace) {
1119        fReplace= replace;
1120    }
1121
1122    /**
1123     * Solves the supertype constraints to replace subtype by a supertype.
1124     *
1125     * @param subUnit
1126     * the compilation unit of the subtype, or <code>null</code>
1127     * @param subNode
1128     * the compilation unit node of the subtype, or <code>null</code>
1129     * @param subType
1130     * the java element of the subtype
1131     * @param subBinding
1132     * the type binding of the subtype to replace
1133     * @param superBinding
1134     * the type binding of the supertype to use as replacement
1135     * @param monitor
1136     * the progress monitor to use
1137     * @param status
1138     * the refactoring status
1139     * @throws JavaModelException
1140     * if an error occurs
1141     */

1142    protected final void solveSuperTypeConstraints(final ICompilationUnit subUnit, final CompilationUnit subNode, final IType subType, final ITypeBinding subBinding, final ITypeBinding superBinding, final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException {
1143        Assert.isNotNull(subType);
1144        Assert.isNotNull(subBinding);
1145        Assert.isNotNull(superBinding);
1146        Assert.isNotNull(monitor);
1147        Assert.isNotNull(status);
1148        int level= 3;
1149        TypeEnvironment environment= new TypeEnvironment();
1150        final SuperTypeConstraintsModel model= new SuperTypeConstraintsModel(environment, environment.create(subBinding), environment.create(superBinding));
1151        final SuperTypeConstraintsCreator creator= new SuperTypeConstraintsCreator(model, fInstanceOf);
1152        try {
1153            monitor.beginTask("", 300); //$NON-NLS-1$
1154
monitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
1155            final Map JavaDoc firstPass= getReferencingCompilationUnits(subType, new SubProgressMonitor(monitor, 100), status);
1156            final Map JavaDoc secondPass= new HashMap JavaDoc();
1157            IJavaProject project= null;
1158            Collection JavaDoc collection= null;
1159            try {
1160                final ASTParser parser= ASTParser.newParser(AST.JLS3);
1161                Object JavaDoc element= null;
1162                ICompilationUnit current= null;
1163                SearchResultGroup group= null;
1164                SearchMatch[] matches= null;
1165                final Map JavaDoc groups= new HashMap JavaDoc();
1166                for (final Iterator JavaDoc outer= firstPass.keySet().iterator(); outer.hasNext();) {
1167                    project= (IJavaProject) outer.next();
1168                    if (level == 3 && !JavaModelUtil.is50OrHigher(project))
1169                        level= 2;
1170                    collection= (Collection JavaDoc) firstPass.get(project);
1171                    if (collection != null) {
1172                        for (final Iterator JavaDoc inner= collection.iterator(); inner.hasNext();) {
1173                            group= (SearchResultGroup) inner.next();
1174                            matches= group.getSearchResults();
1175                            for (int index= 0; index < matches.length; index++) {
1176                                element= matches[index].getElement();
1177                                if (element instanceof IMember) {
1178                                    current= ((IMember) element).getCompilationUnit();
1179                                    if (current != null)
1180                                        groups.put(current, group);
1181                                }
1182                            }
1183                        }
1184                    }
1185                }
1186                Set JavaDoc units= null;
1187                final Set JavaDoc processed= new HashSet JavaDoc();
1188                if (subUnit != null)
1189                    processed.add(subUnit);
1190                model.beginCreation();
1191                IProgressMonitor subMonitor= new SubProgressMonitor(monitor, 120);
1192                try {
1193                    final Set JavaDoc keySet= firstPass.keySet();
1194                    subMonitor.beginTask("", keySet.size() * 100); //$NON-NLS-1$
1195
subMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
1196                    for (final Iterator JavaDoc outer= keySet.iterator(); outer.hasNext();) {
1197                        project= (IJavaProject) outer.next();
1198                        collection= (Collection JavaDoc) firstPass.get(project);
1199                        if (collection != null) {
1200                            units= new HashSet JavaDoc(collection.size());
1201                            for (final Iterator JavaDoc inner= collection.iterator(); inner.hasNext();) {
1202                                group= (SearchResultGroup) inner.next();
1203                                matches= group.getSearchResults();
1204                                for (int index= 0; index < matches.length; index++) {
1205                                    element= matches[index].getElement();
1206                                    if (element instanceof IMember) {
1207                                        current= ((IMember) element).getCompilationUnit();
1208                                        if (current != null)
1209                                            units.add(current);
1210                                    }
1211                                }
1212                            }
1213                            final List JavaDoc batches= new ArrayList JavaDoc(units);
1214                            final int size= batches.size();
1215                            final int iterations= ((size - 1) / SIZE_BATCH) + 1;
1216                            final IProgressMonitor subsubMonitor= new SubProgressMonitor(subMonitor, 100);
1217                            try {
1218                                subsubMonitor.beginTask("", iterations * 100); //$NON-NLS-1$
1219
subsubMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
1220                                final Map JavaDoc options= RefactoringASTParser.getCompilerOptions(project);
1221                                for (int index= 0; index < iterations; index++) {
1222                                    final List JavaDoc iteration= batches.subList(index * SIZE_BATCH, Math.min(size, (index + 1) * SIZE_BATCH));
1223                                    parser.setWorkingCopyOwner(fOwner);
1224                                    parser.setResolveBindings(true);
1225                                    parser.setProject(project);
1226                                    parser.setCompilerOptions(options);
1227                                    final IProgressMonitor subsubsubMonitor= new SubProgressMonitor(subsubMonitor, 100);
1228                                    try {
1229                                        final int count= iteration.size();
1230                                        subsubsubMonitor.beginTask("", count * 100); //$NON-NLS-1$
1231
subsubsubMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
1232                                        parser.createASTs((ICompilationUnit[]) iteration.toArray(new ICompilationUnit[count]), new String JavaDoc[0], new ASTRequestor() {
1233
1234                                            public final void acceptAST(final ICompilationUnit unit, final CompilationUnit node) {
1235                                                if (!processed.contains(unit)) {
1236                                                    performFirstPass(creator, secondPass, groups, unit, node, new SubProgressMonitor(subsubsubMonitor, 100));
1237                                                    processed.add(unit);
1238                                                } else
1239                                                    subsubsubMonitor.worked(100);
1240                                            }
1241
1242                                            public final void acceptBinding(final String JavaDoc key, final IBinding binding) {
1243                                                // Do nothing
1244
}
1245                                        }, new NullProgressMonitor());
1246                                    } finally {
1247                                        subsubsubMonitor.done();
1248                                    }
1249                                }
1250                            } finally {
1251                                subsubMonitor.done();
1252                            }
1253                        }
1254                    }
1255                } finally {
1256                    firstPass.clear();
1257                    subMonitor.done();
1258                }
1259                if (subUnit != null && subNode != null)
1260                    performFirstPass(creator, secondPass, groups, subUnit, subNode, new SubProgressMonitor(subMonitor, 20));
1261                subMonitor= new SubProgressMonitor(monitor, 100);
1262                try {
1263                    final Set JavaDoc keySet= secondPass.keySet();
1264                    subMonitor.beginTask("", keySet.size() * 100); //$NON-NLS-1$
1265
subMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
1266                    for (final Iterator JavaDoc iterator= keySet.iterator(); iterator.hasNext();) {
1267                        project= (IJavaProject) iterator.next();
1268                        if (level == 3 && !JavaModelUtil.is50OrHigher(project))
1269                            level= 2;
1270                        collection= (Collection JavaDoc) secondPass.get(project);
1271                        if (collection != null) {
1272                            parser.setWorkingCopyOwner(fOwner);
1273                            parser.setResolveBindings(true);
1274                            parser.setProject(project);
1275                            parser.setCompilerOptions(RefactoringASTParser.getCompilerOptions(project));
1276                            final IProgressMonitor subsubMonitor= new SubProgressMonitor(subMonitor, 100);
1277                            try {
1278                                subsubMonitor.beginTask("", collection.size() * 100); //$NON-NLS-1$
1279
subsubMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
1280                                parser.createASTs((ICompilationUnit[]) collection.toArray(new ICompilationUnit[collection.size()]), new String JavaDoc[0], new ASTRequestor() {
1281
1282                                    public final void acceptAST(final ICompilationUnit unit, final CompilationUnit node) {
1283                                        if (!processed.contains(unit))
1284                                            performSecondPass(creator, unit, node, new SubProgressMonitor(subsubMonitor, 100));
1285                                        else
1286                                            subsubMonitor.worked(100);
1287                                    }
1288
1289                                    public final void acceptBinding(final String JavaDoc key, final IBinding binding) {
1290                                        // Do nothing
1291
}
1292                                }, new NullProgressMonitor());
1293                            } finally {
1294                                subsubMonitor.done();
1295                            }
1296                        }
1297                    }
1298                } finally {
1299                    secondPass.clear();
1300                    subMonitor.done();
1301                }
1302            } finally {
1303                model.endCreation();
1304                model.setCompliance(level);
1305            }
1306            final SuperTypeConstraintsSolver solver= createContraintSolver(model);
1307            solver.solveConstraints();
1308            fTypeOccurrences= solver.getTypeOccurrences();
1309            fObsoleteCasts= solver.getObsoleteCasts();
1310        } finally {
1311            monitor.done();
1312        }
1313    }
1314}
1315
Popular Tags