KickJava   Java API By Example, From Geeks To Geeks.

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


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.Collections JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.HashSet JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.LinkedHashSet JavaDoc;
21 import java.util.LinkedList JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.Set JavaDoc;
25
26 import org.eclipse.text.edits.MalformedTreeException;
27 import org.eclipse.text.edits.TextEdit;
28
29 import org.eclipse.core.runtime.Assert;
30 import org.eclipse.core.runtime.CoreException;
31 import org.eclipse.core.runtime.IProgressMonitor;
32 import org.eclipse.core.runtime.NullProgressMonitor;
33 import org.eclipse.core.runtime.OperationCanceledException;
34 import org.eclipse.core.runtime.SubProgressMonitor;
35
36 import org.eclipse.jface.text.BadLocationException;
37 import org.eclipse.jface.text.Document;
38 import org.eclipse.jface.text.IDocument;
39
40 import org.eclipse.ltk.core.refactoring.Change;
41 import org.eclipse.ltk.core.refactoring.GroupCategory;
42 import org.eclipse.ltk.core.refactoring.GroupCategorySet;
43 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
44 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
45 import org.eclipse.ltk.core.refactoring.RefactoringStatusContext;
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.IField;
54 import org.eclipse.jdt.core.IJavaElement;
55 import org.eclipse.jdt.core.IJavaProject;
56 import org.eclipse.jdt.core.IMember;
57 import org.eclipse.jdt.core.IMethod;
58 import org.eclipse.jdt.core.IType;
59 import org.eclipse.jdt.core.ITypeHierarchy;
60 import org.eclipse.jdt.core.ITypeParameter;
61 import org.eclipse.jdt.core.JavaCore;
62 import org.eclipse.jdt.core.JavaModelException;
63 import org.eclipse.jdt.core.Signature;
64 import org.eclipse.jdt.core.dom.AST;
65 import org.eclipse.jdt.core.dom.ASTNode;
66 import org.eclipse.jdt.core.dom.ASTParser;
67 import org.eclipse.jdt.core.dom.ASTRequestor;
68 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
69 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
70 import org.eclipse.jdt.core.dom.Block;
71 import org.eclipse.jdt.core.dom.BodyDeclaration;
72 import org.eclipse.jdt.core.dom.CompilationUnit;
73 import org.eclipse.jdt.core.dom.Expression;
74 import org.eclipse.jdt.core.dom.FieldAccess;
75 import org.eclipse.jdt.core.dom.FieldDeclaration;
76 import org.eclipse.jdt.core.dom.IBinding;
77 import org.eclipse.jdt.core.dom.IMethodBinding;
78 import org.eclipse.jdt.core.dom.ITypeBinding;
79 import org.eclipse.jdt.core.dom.Javadoc;
80 import org.eclipse.jdt.core.dom.MarkerAnnotation;
81 import org.eclipse.jdt.core.dom.MethodDeclaration;
82 import org.eclipse.jdt.core.dom.MethodInvocation;
83 import org.eclipse.jdt.core.dom.Modifier;
84 import org.eclipse.jdt.core.dom.ReturnStatement;
85 import org.eclipse.jdt.core.dom.SimpleName;
86 import org.eclipse.jdt.core.dom.SuperFieldAccess;
87 import org.eclipse.jdt.core.dom.SuperMethodInvocation;
88 import org.eclipse.jdt.core.dom.ThisExpression;
89 import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
90 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
91 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
92 import org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition;
93 import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
94 import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
95 import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
96
97 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
98 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
99 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
100 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
101 import org.eclipse.jdt.internal.corext.dom.Bindings;
102 import org.eclipse.jdt.internal.corext.dom.ModifierRewrite;
103 import org.eclipse.jdt.internal.corext.dom.NodeFinder;
104 import org.eclipse.jdt.internal.corext.refactoring.Checks;
105 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptor;
106 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
107 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
108 import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester;
109 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
110 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
111 import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange;
112 import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
113 import org.eclipse.jdt.internal.corext.refactoring.code.ScriptableRefactoring;
114 import org.eclipse.jdt.internal.corext.refactoring.rename.MethodChecks;
115 import org.eclipse.jdt.internal.corext.refactoring.reorg.SourceReferenceUtil;
116 import org.eclipse.jdt.internal.corext.refactoring.structure.constraints.SuperTypeConstraintsSolver;
117 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.CompilationUnitRange;
118 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType;
119 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ISourceConstraintVariable;
120 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeConstraintVariable;
121 import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
122 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
123 import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
124 import org.eclipse.jdt.internal.corext.refactoring.util.TextEditBasedChangeManager;
125 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
126 import org.eclipse.jdt.internal.corext.util.JdtFlags;
127 import org.eclipse.jdt.internal.corext.util.Messages;
128 import org.eclipse.jdt.internal.corext.util.Strings;
129
130 import org.eclipse.jdt.ui.CodeGeneration;
131 import org.eclipse.jdt.ui.JavaElementLabels;
132
133 import org.eclipse.jdt.internal.ui.JavaPlugin;
134 import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
135
136 /**
137  * Refactoring processor for the pull up refactoring.
138  *
139  * @since 3.2
140  */

141 public class PullUpRefactoringProcessor extends HierarchyProcessor {
142
143     /**
144      * AST node visitor which performs the actual mapping.
145      */

146     private static class PullUpAstNodeMapper extends TypeVariableMapper {
147
148         /** Are we in an anonymous class declaration? */
149         private boolean fAnonymousClassDeclaration= false;
150
151         /** The source compilation unit rewrite to use */
152         private final CompilationUnitRewrite fSourceRewriter;
153
154         /** The super reference type */
155         private final IType fSuperReferenceType;
156
157         /** The target compilation unit rewrite to use */
158         private final CompilationUnitRewrite fTargetRewriter;
159
160         /** Are we in a type declaration statement? */
161         private boolean fTypeDeclarationStatement= false;
162
163         /** The binding of the enclosing method */
164         private final IMethodBinding fEnclosingMethod;
165
166         /**
167          * Creates a new pull up ast node mapper.
168          *
169          * @param sourceRewriter
170          * the source compilation unit rewrite to use
171          * @param targetRewriter
172          * the target compilation unit rewrite to use
173          * @param rewrite
174          * the AST rewrite to use
175          * @param type
176          * the super reference type
177          * @param mapping
178          * the type variable mapping
179          * @param enclosing the binding of the enclosing method
180          */

181         public PullUpAstNodeMapper(final CompilationUnitRewrite sourceRewriter, final CompilationUnitRewrite targetRewriter, final ASTRewrite rewrite, final IType type, final TypeVariableMaplet[] mapping, final IMethodBinding enclosing) {
182             super(rewrite, mapping);
183             Assert.isNotNull(rewrite);
184             Assert.isNotNull(type);
185             fSourceRewriter= sourceRewriter;
186             fTargetRewriter= targetRewriter;
187             fSuperReferenceType= type;
188             fEnclosingMethod= enclosing;
189         }
190
191         public final void endVisit(final AnonymousClassDeclaration node) {
192             fAnonymousClassDeclaration= false;
193             super.endVisit(node);
194         }
195
196         public final void endVisit(final TypeDeclarationStatement node) {
197             fTypeDeclarationStatement= false;
198             super.endVisit(node);
199         }
200
201         public final boolean visit(final AnonymousClassDeclaration node) {
202             fAnonymousClassDeclaration= true;
203             return super.visit(node);
204         }
205
206         public final boolean visit(final SuperFieldAccess node) {
207             if (!fAnonymousClassDeclaration && !fTypeDeclarationStatement) {
208                 final AST ast= node.getAST();
209                 final FieldAccess access= ast.newFieldAccess();
210                 access.setExpression(ast.newThisExpression());
211                 access.setName(ast.newSimpleName(node.getName().getIdentifier()));
212                 fRewrite.replace(node, access, null);
213                 if (!fSourceRewriter.getCu().equals(fTargetRewriter.getCu()))
214                     fSourceRewriter.getImportRemover().registerRemovedNode(node);
215                 return true;
216             }
217             return false;
218         }
219
220         public final boolean visit(final SuperMethodInvocation node) {
221             if (!fAnonymousClassDeclaration && !fTypeDeclarationStatement) {
222                 final IBinding superBinding= node.getName().resolveBinding();
223                 if (superBinding instanceof IMethodBinding) {
224                     final IMethodBinding extended= (IMethodBinding) superBinding;
225                     if (fEnclosingMethod != null && fEnclosingMethod.overrides(extended))
226                         return true;
227                     final ITypeBinding declaringBinding= extended.getDeclaringClass();
228                     if (declaringBinding != null) {
229                         final IType type= (IType) declaringBinding.getJavaElement();
230                         if (!fSuperReferenceType.equals(type))
231                             return true;
232                     }
233                 }
234                 final AST ast= node.getAST();
235                 final ThisExpression expression= ast.newThisExpression();
236                 final MethodInvocation invocation= ast.newMethodInvocation();
237                 final SimpleName simple= ast.newSimpleName(node.getName().getIdentifier());
238                 invocation.setName(simple);
239                 invocation.setExpression(expression);
240                 final List JavaDoc arguments= (List JavaDoc) node.getStructuralProperty(SuperMethodInvocation.ARGUMENTS_PROPERTY);
241                 if (arguments != null && arguments.size() > 0) {
242                     final ListRewrite rewriter= fRewrite.getListRewrite(invocation, MethodInvocation.ARGUMENTS_PROPERTY);
243                     rewriter.insertLast(rewriter.createCopyTarget((ASTNode) arguments.get(0), (ASTNode) arguments.get(arguments.size() - 1)), null);
244                 }
245                 fRewrite.replace(node, invocation, null);
246                 if (!fSourceRewriter.getCu().equals(fTargetRewriter.getCu()))
247                     fSourceRewriter.getImportRemover().registerRemovedNode(node);
248                 return true;
249             }
250             return false;
251         }
252
253         public final boolean visit(final TypeDeclarationStatement node) {
254             fTypeDeclarationStatement= true;
255             return super.visit(node);
256         }
257     }
258
259     protected static final String JavaDoc ATTRIBUTE_ABSTRACT= "abstract"; //$NON-NLS-1$
260

261     protected static final String JavaDoc ATTRIBUTE_DELETE= "delete"; //$NON-NLS-1$
262

263     protected static final String JavaDoc ATTRIBUTE_PULL= "pull"; //$NON-NLS-1$
264

265     protected static final String JavaDoc ATTRIBUTE_STUBS= "stubs"; //$NON-NLS-1$
266

267     private static final String JavaDoc IDENTIFIER= "org.eclipse.jdt.ui.pullUpProcessor"; //$NON-NLS-1$
268

269     /** The pull up group category set */
270     private static final GroupCategorySet SET_PULL_UP= new GroupCategorySet(new GroupCategory("org.eclipse.jdt.internal.corext.pullUp", //$NON-NLS-1$
271
RefactoringCoreMessages.PullUpRefactoring_category_name, RefactoringCoreMessages.PullUpRefactoring_category_description));
272
273     private static void addMatchingMember(final Map JavaDoc mapping, final IMember key, final IMember matchingMember) {
274         Set JavaDoc matchingSet;
275         if (mapping.containsKey(key)) {
276             matchingSet= (Set JavaDoc) mapping.get(key);
277         } else {
278             matchingSet= new HashSet JavaDoc();
279             mapping.put(key, matchingSet);
280         }
281         Assert.isTrue(!matchingSet.contains(matchingMember));
282         matchingSet.add(matchingMember);
283     }
284
285     private static Block createMethodStub(final MethodDeclaration method, final AST ast) {
286         final Block body= ast.newBlock();
287         final Expression expression= ASTNodeFactory.newDefaultExpression(ast, method.getReturnType2(), method.getExtraDimensions());
288         if (expression != null) {
289             final ReturnStatement returnStatement= ast.newReturnStatement();
290             returnStatement.setExpression(expression);
291             body.statements().add(returnStatement);
292         }
293         return body;
294     }
295
296     private static Set JavaDoc getEffectedSubTypes(final ITypeHierarchy hierarchy, final IType type) throws JavaModelException {
297          IType[] types= null;
298          final boolean isInterface= type.isInterface();
299         if (isInterface) {
300              final Collection JavaDoc remove= new ArrayList JavaDoc();
301              final List JavaDoc list= new ArrayList JavaDoc(Arrays.asList(hierarchy.getSubtypes(type)));
302              for (final Iterator JavaDoc iterator= list.iterator(); iterator.hasNext();) {
303                 final IType element= (IType) iterator.next();
304                 if (element.isInterface())
305                     remove.add(element);
306             }
307              list.removeAll(remove);
308              types= (IType[]) list.toArray(new IType[list.size()]);
309          } else
310              types= hierarchy.getSubclasses(type);
311         final Set JavaDoc result= new HashSet JavaDoc();
312         for (int index= 0; index < types.length; index++) {
313             if (!isInterface && JdtFlags.isAbstract(types[index]))
314                 result.addAll(getEffectedSubTypes(hierarchy, types[index]));
315             else
316                 result.add(types[index]);
317         }
318         return result;
319     }
320
321     private static IMember[] getMembers(final IMember[] members, final int type) {
322         final List JavaDoc list= Arrays.asList(JavaElementUtil.getElementsOfType(members, type));
323         return (IMember[]) list.toArray(new IMember[list.size()]);
324     }
325
326     private static void mergeMaps(final Map JavaDoc result, final Map JavaDoc map) {
327         for (final Iterator JavaDoc iter= result.keySet().iterator(); iter.hasNext();) {
328             final IMember key= (IMember) iter.next();
329             if (map.containsKey(key)) {
330                 final Set JavaDoc resultSet= (Set JavaDoc) result.get(key);
331                 final Set JavaDoc mapSet= (Set JavaDoc) map.get(key);
332                 resultSet.addAll(mapSet);
333             }
334         }
335     }
336
337     private static void upgradeMap(final Map JavaDoc result, final Map JavaDoc map) {
338         for (final Iterator JavaDoc iter= map.keySet().iterator(); iter.hasNext();) {
339             final IMember key= (IMember) iter.next();
340             if (!result.containsKey(key)) {
341                 final Set JavaDoc mapSet= (Set JavaDoc) map.get(key);
342                 final Set JavaDoc resultSet= new HashSet JavaDoc(mapSet);
343                 result.put(key, resultSet);
344             }
345         }
346     }
347
348     /** The methods to be declared abstract */
349     protected IMethod[] fAbstractMethods= new IMethod[0];
350
351     /** The cached supertype hierarchy of the declaring type */
352     private ITypeHierarchy fCachedDeclaringSuperTypeHierarchy;
353
354     /** The cached type hierarchy of the destination type */
355     private ITypeHierarchy fCachedDestinationTypeHierarchy;
356
357     /** The cached set of skipped supertypes */
358     private Set JavaDoc fCachedSkippedSuperTypes;
359
360     /** The map of compilation units to compilation unit rewrites */
361     protected Map JavaDoc fCompilationUnitRewrites;
362
363     /** Should method stubs be generated in subtypes? */
364     protected boolean fCreateMethodStubs= true;
365
366     /** The methods to be deleted in subtypes */
367     protected IMethod[] fDeletedMethods= new IMethod[0];
368
369     /** The destination type */
370     protected IType fDestinationType;
371
372     /**
373      * Creates a new pull up refactoring processor.
374      *
375      * @param members
376      * the members to pull up, or <code>null</code> if invoked by
377      * scripting
378      * @param settings
379      * the code generation settings, or <code>null</code> if
380      * invoked by scripting
381      */

382     public PullUpRefactoringProcessor(final IMember[] members, final CodeGenerationSettings settings) {
383         this(members, settings, false);
384     }
385
386     /**
387      * Creates a new pull up refactoring processor.
388      *
389      * @param members
390      * the members to pull up, or <code>null</code> if invoked by
391      * scripting
392      * @param settings
393      * the code generation settings, or <code>null</code> if
394      * invoked by scripting
395      * @param layer
396      * <code>true</code> to create a working copy layer,
397      * <code>false</code> otherwise
398      */

399     protected PullUpRefactoringProcessor(final IMember[] members, final CodeGenerationSettings settings, final boolean layer) {
400         super(members, settings, layer);
401         if (members != null) {
402             final IType type= RefactoringAvailabilityTester.getTopLevelType(fMembersToMove);
403             try {
404                 if (type != null && RefactoringAvailabilityTester.getPullUpMembers(type).length != 0) {
405                     fCachedDeclaringType= RefactoringAvailabilityTester.getTopLevelType(fMembersToMove);
406                     fMembersToMove= new IMember[0];
407                 }
408             } catch (JavaModelException exception) {
409                 JavaPlugin.log(exception);
410             }
411         }
412     }
413
414     private void addAllRequiredPullableMembers(final List JavaDoc queue, final IMember member, final IProgressMonitor monitor) throws JavaModelException {
415         Assert.isNotNull(queue);
416         Assert.isNotNull(member);
417         Assert.isNotNull(monitor);
418         SubProgressMonitor sub= null;
419         try {
420             monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_calculating_required, 3);
421             final IMethod[] requiredMethods= ReferenceFinderUtil.getMethodsReferencedIn(new IJavaElement[] { member}, fOwner, new SubProgressMonitor(monitor, 1));
422             sub= new SubProgressMonitor(monitor, 1);
423             boolean isStatic= false;
424             try {
425                 sub.beginTask(RefactoringCoreMessages.PullUpRefactoring_calculating_required, requiredMethods.length);
426                 isStatic= JdtFlags.isStatic(member);
427                 for (int index= 0; index < requiredMethods.length; index++) {
428                     final IMethod requiredMethod= requiredMethods[index];
429                     if (isStatic && !JdtFlags.isStatic(requiredMethod))
430                         continue;
431                     if (isRequiredPullableMember(queue, requiredMethod) && !(MethodChecks.isVirtual(requiredMethod) && isAvailableInDestination(requiredMethod, new SubProgressMonitor(sub, 1))))
432                         queue.add(requiredMethod);
433                 }
434             } finally {
435                 sub.done();
436             }
437             final IField[] requiredFields= ReferenceFinderUtil.getFieldsReferencedIn(new IJavaElement[] { member}, fOwner, new SubProgressMonitor(monitor, 1));
438             sub= new SubProgressMonitor(monitor, 1);
439             try {
440                 sub.beginTask(RefactoringCoreMessages.PullUpRefactoring_calculating_required, requiredFields.length);
441                 isStatic= JdtFlags.isStatic(member);
442                 for (int index= 0; index < requiredFields.length; index++) {
443                     final IField requiredField= requiredFields[index];
444                     if (isStatic && !JdtFlags.isStatic(requiredField))
445                         continue;
446                     if (isRequiredPullableMember(queue, requiredField))
447                         queue.add(requiredField);
448                 }
449             } finally {
450                 sub.done();
451             }
452             final IType[] requiredTypes= ReferenceFinderUtil.getTypesReferencedIn(new IJavaElement[] { member}, fOwner, new SubProgressMonitor(monitor, 1));
453             sub= new SubProgressMonitor(monitor, 1);
454             try {
455                 sub.beginTask(RefactoringCoreMessages.PullUpRefactoring_calculating_required, requiredMethods.length);
456                 isStatic= JdtFlags.isStatic(member);
457                 for (int index= 0; index < requiredTypes.length; index++) {
458                     final IType requiredType= requiredTypes[index];
459                     if (isStatic && !JdtFlags.isStatic(requiredType))
460                         continue;
461                     if (isRequiredPullableMember(queue, requiredType))
462                         queue.add(requiredType);
463                 }
464             } finally {
465                 sub.done();
466             }
467         } finally {
468             monitor.done();
469         }
470     }
471
472     private void addMethodStubForAbstractMethod(final IMethod sourceMethod, final CompilationUnit declaringCuNode, final AbstractTypeDeclaration typeToCreateStubIn, final ICompilationUnit newCu, final CompilationUnitRewrite rewriter, final Map JavaDoc adjustments, final IProgressMonitor monitor, final RefactoringStatus status) throws CoreException {
473         final MethodDeclaration methodToCreateStubFor= ASTNodeSearchUtil.getMethodDeclarationNode(sourceMethod, declaringCuNode);
474         final AST ast= rewriter.getRoot().getAST();
475         final MethodDeclaration newMethod= ast.newMethodDeclaration();
476         newMethod.setBody(createMethodStub(methodToCreateStubFor, ast));
477         newMethod.setConstructor(false);
478         newMethod.setExtraDimensions(methodToCreateStubFor.getExtraDimensions());
479         newMethod.modifiers().addAll(ASTNodeFactory.newModifiers(ast, getModifiersWithUpdatedVisibility(sourceMethod, JdtFlags.clearFlag(Modifier.NATIVE | Modifier.ABSTRACT, methodToCreateStubFor.getModifiers()), adjustments, new SubProgressMonitor(monitor, 1), false, status)));
480         newMethod.setName(((SimpleName) ASTNode.copySubtree(ast, methodToCreateStubFor.getName())));
481         final TypeVariableMaplet[] mapping= TypeVariableUtil.composeMappings(TypeVariableUtil.subTypeToSuperType(getDeclaringType(), getDestinationType()), TypeVariableUtil.superTypeToInheritedType(getDestinationType(), ((IType) typeToCreateStubIn.resolveBinding().getJavaElement())));
482         copyReturnType(rewriter.getASTRewrite(), getDeclaringType().getCompilationUnit(), methodToCreateStubFor, newMethod, mapping);
483         copyParameters(rewriter.getASTRewrite(), getDeclaringType().getCompilationUnit(), methodToCreateStubFor, newMethod, mapping);
484         copyThrownExceptions(methodToCreateStubFor, newMethod);
485         newMethod.setJavadoc(createJavadocForStub(typeToCreateStubIn.getName().getIdentifier(), methodToCreateStubFor, newMethod, newCu, rewriter.getASTRewrite()));
486         ImportRewriteUtil.addImports(rewriter, newMethod, new HashMap JavaDoc(), new HashMap JavaDoc(), false);
487         rewriter.getASTRewrite().getListRewrite(typeToCreateStubIn, typeToCreateStubIn.getBodyDeclarationsProperty()).insertAt(newMethod, ASTNodes.getInsertionIndex(newMethod, typeToCreateStubIn.bodyDeclarations()), rewriter.createCategorizedGroupDescription(RefactoringCoreMessages.PullUpRefactoring_add_method_stub, SET_PULL_UP));
488     }
489
490     private void addNecessaryMethodStubs(final List JavaDoc effected, final CompilationUnit root, final CompilationUnitRewrite unitRewriter, final Map JavaDoc adjustments, final IProgressMonitor monitor, final RefactoringStatus status) throws CoreException {
491         final IType declaringType= getDeclaringType();
492         final IMethod[] methods= getAbstractMethods();
493         try {
494             monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, effected.size());
495             for (final Iterator JavaDoc iter= effected.iterator(); iter.hasNext();) {
496                 final IType type= (IType) iter.next();
497                 if (type.equals(declaringType))
498                     continue;
499                 final AbstractTypeDeclaration declaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(type, unitRewriter.getRoot());
500                 final ICompilationUnit unit= type.getCompilationUnit();
501                 final IProgressMonitor subMonitor= new SubProgressMonitor(monitor, 1);
502                 try {
503                     subMonitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, methods.length);
504                     for (int j= 0; j < methods.length; j++) {
505                         final IMethod method= methods[j];
506                         if (null == JavaModelUtil.findMethod(method.getElementName(), method.getParameterTypes(), method.isConstructor(), type)) {
507                             addMethodStubForAbstractMethod(method, root, declaration, unit, unitRewriter, adjustments, new SubProgressMonitor(subMonitor, 1), status);
508                         }
509                     }
510                     subMonitor.done();
511                 } finally {
512                     subMonitor.done();
513                 }
514             }
515         } finally {
516             monitor.done();
517         }
518     }
519
520     protected boolean canBeAccessedFrom(final IMember member, final IType target, final ITypeHierarchy hierarchy) throws JavaModelException {
521         if (super.canBeAccessedFrom(member, target, hierarchy)) {
522             if (target.isInterface())
523                 return true;
524             if (target.equals(member.getDeclaringType()))
525                 return true;
526             if (target.equals(member))
527                 return true;
528             if (member instanceof IMethod) {
529                 final IMethod method= (IMethod) member;
530                 final IMethod stub= target.getMethod(method.getElementName(), method.getParameterTypes());
531                 if (stub.exists())
532                     return true;
533             }
534             if (member.getDeclaringType() == null) {
535                 if (!(member instanceof IType))
536                     return false;
537                 if (JdtFlags.isPublic(member))
538                     return true;
539                 if (!JdtFlags.isPackageVisible(member))
540                     return false;
541                 if (JavaModelUtil.isSamePackage(((IType) member).getPackageFragment(), target.getPackageFragment()))
542                     return true;
543                 final IType type= member.getDeclaringType();
544                 if (type != null)
545                     return hierarchy.contains(type);
546                 return false;
547             }
548             final IType declaringType= member.getDeclaringType();
549             if (!canBeAccessedFrom(declaringType, target, hierarchy))
550                 return false;
551             if (declaringType.equals(getDeclaringType()))
552                 return false;
553             return true;
554         }
555         return false;
556     }
557
558     private RefactoringStatus checkAccessedFields(final IProgressMonitor monitor, final ITypeHierarchy hierarchy) throws JavaModelException {
559         monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking_referenced_elements, 2);
560         final RefactoringStatus result= new RefactoringStatus();
561
562         final List JavaDoc pulledUpList= Arrays.asList(fMembersToMove);
563         final List JavaDoc deletedList= Arrays.asList(getMembersToDelete(new SubProgressMonitor(monitor, 1)));
564         final IField[] accessedFields= ReferenceFinderUtil.getFieldsReferencedIn(fMembersToMove, fOwner, new SubProgressMonitor(monitor, 1));
565
566         final IType destination= getDestinationType();
567         for (int i= 0; i < accessedFields.length; i++) {
568             final IField field= accessedFields[i];
569             if (!field.exists())
570                 continue;
571
572             boolean isAccessible= pulledUpList.contains(field) || deletedList.contains(field) || canBeAccessedFrom(field, destination, hierarchy) || Flags.isEnum(field.getFlags());
573             if (!isAccessible) {
574                 final String JavaDoc message= Messages.format(RefactoringCoreMessages.PullUpRefactoring_field_not_accessible, new String JavaDoc[] { JavaElementLabels.getTextLabel(field, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getTextLabel(destination, JavaElementLabels.ALL_FULLY_QUALIFIED)});
575                 result.addError(message, JavaStatusContext.create(field));
576             } else if (getSkippedSuperTypes(new SubProgressMonitor(monitor, 1)).contains(field.getDeclaringType())) {
577                 final String JavaDoc message= Messages.format(RefactoringCoreMessages.PullUpRefactoring_field_cannot_be_accessed, new String JavaDoc[] { JavaElementLabels.getTextLabel(field, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getTextLabel(destination, JavaElementLabels.ALL_FULLY_QUALIFIED)});
578                 result.addError(message, JavaStatusContext.create(field));
579             }
580         }
581         monitor.done();
582         return result;
583     }
584
585     private RefactoringStatus checkAccessedMethods(final IProgressMonitor monitor, final ITypeHierarchy hierarchy) throws JavaModelException {
586         monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking_referenced_elements, 2);
587         final RefactoringStatus result= new RefactoringStatus();
588
589         final List JavaDoc pulledUpList= Arrays.asList(fMembersToMove);
590         final List JavaDoc declaredAbstractList= Arrays.asList(fAbstractMethods);
591         final List JavaDoc deletedList= Arrays.asList(getMembersToDelete(new SubProgressMonitor(monitor, 1)));
592         final IMethod[] accessedMethods= ReferenceFinderUtil.getMethodsReferencedIn(fMembersToMove, fOwner, new SubProgressMonitor(monitor, 1));
593
594         final IType destination= getDestinationType();
595         for (int index= 0; index < accessedMethods.length; index++) {
596             final IMethod method= accessedMethods[index];
597             if (!method.exists())
598                 continue;
599             boolean isAccessible= pulledUpList.contains(method) || deletedList.contains(method) || declaredAbstractList.contains(method) || canBeAccessedFrom(method, destination, hierarchy);
600             if (!isAccessible) {
601                 final String JavaDoc message= Messages.format(RefactoringCoreMessages.PullUpRefactoring_method_not_accessible, new String JavaDoc[] { JavaElementLabels.getTextLabel(method, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getTextLabel(destination, JavaElementLabels.ALL_FULLY_QUALIFIED)});
602                 result.addError(message, JavaStatusContext.create(method));
603             } else if (getSkippedSuperTypes(new SubProgressMonitor(monitor, 1)).contains(method.getDeclaringType())) {
604                 final String JavaDoc[] keys= { JavaElementLabels.getTextLabel(method, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getTextLabel(destination, JavaElementLabels.ALL_FULLY_QUALIFIED)};
605                 final String JavaDoc message= Messages.format(RefactoringCoreMessages.PullUpRefactoring_method_cannot_be_accessed, keys);
606                 result.addError(message, JavaStatusContext.create(method));
607             }
608         }
609         monitor.done();
610         return result;
611     }
612
613     private RefactoringStatus checkAccessedTypes(final IProgressMonitor monitor, final ITypeHierarchy hierarchy) throws JavaModelException {
614         final RefactoringStatus result= new RefactoringStatus();
615         final IType[] accessedTypes= getTypesReferencedInMovedMembers(monitor);
616         final IType destination= getDestinationType();
617         final List JavaDoc pulledUpList= Arrays.asList(fMembersToMove);
618         for (int index= 0; index < accessedTypes.length; index++) {
619             final IType type= accessedTypes[index];
620             if (!type.exists())
621                 continue;
622
623             if (!canBeAccessedFrom(type, destination, hierarchy) && !pulledUpList.contains(type)) {
624                 final String JavaDoc message= Messages.format(RefactoringCoreMessages.PullUpRefactoring_type_not_accessible, new String JavaDoc[] { JavaElementLabels.getTextLabel(type, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getTextLabel(destination, JavaElementLabels.ALL_FULLY_QUALIFIED)});
625                 result.addError(message, JavaStatusContext.create(type));
626             }
627         }
628         monitor.done();
629         return result;
630     }
631
632     private RefactoringStatus checkAccesses(final IProgressMonitor monitor) throws JavaModelException {
633         final RefactoringStatus result= new RefactoringStatus();
634         try {
635             monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking_referenced_elements, 4);
636             final ITypeHierarchy hierarchy= getDestinationType().newSupertypeHierarchy(fOwner, new SubProgressMonitor(monitor, 1));
637             result.merge(checkAccessedTypes(new SubProgressMonitor(monitor, 1), hierarchy));
638             result.merge(checkAccessedFields(new SubProgressMonitor(monitor, 1), hierarchy));
639             result.merge(checkAccessedMethods(new SubProgressMonitor(monitor, 1), hierarchy));
640         } finally {
641             monitor.done();
642         }
643         return result;
644     }
645
646     private void checkAccessModifiers(final RefactoringStatus result, final Set JavaDoc notDeletedMembersInSubtypes) throws JavaModelException {
647         if (fDestinationType.isInterface())
648             return;
649         final List JavaDoc toDeclareAbstract= Arrays.asList(fAbstractMethods);
650         for (final Iterator JavaDoc iter= notDeletedMembersInSubtypes.iterator(); iter.hasNext();) {
651             final IMember member= (IMember) iter.next();
652             if (member.getElementType() == IJavaElement.METHOD && !toDeclareAbstract.contains(member)) {
653                 final IMethod method= ((IMethod) member);
654                 if (method.getDeclaringType().getPackageFragment().equals(fDestinationType.getPackageFragment())) {
655                     if (JdtFlags.isPrivate(method))
656                         result.addError(Messages.format(RefactoringCoreMessages.PullUpRefactoring_lower_default_visibility, new String JavaDoc[] { JavaElementLabels.getTextLabel(method, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getTextLabel(method.getDeclaringType(), JavaElementLabels.ALL_FULLY_QUALIFIED)}), JavaStatusContext.create(method));
657                 } else if (!JdtFlags.isPublic(method) && !JdtFlags.isProtected(method))
658                     result.addError(Messages.format(RefactoringCoreMessages.PullUpRefactoring_lower_protected_visibility, new String JavaDoc[] { JavaElementLabels.getTextLabel(method, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getTextLabel(method.getDeclaringType(), JavaElementLabels.ALL_FULLY_QUALIFIED)}), JavaStatusContext.create(method));
659             }
660         }
661     }
662
663     protected RefactoringStatus checkDeclaringSuperTypes(final IProgressMonitor monitor) throws JavaModelException {
664         final RefactoringStatus result= new RefactoringStatus();
665         if (getCandidateTypes(result, monitor).length == 0 && !result.hasFatalError()) {
666             final String JavaDoc msg= Messages.format(RefactoringCoreMessages.PullUpRefactoring_not_this_type, new String JavaDoc[] { JavaElementLabels.getTextLabel(getDeclaringType(), JavaElementLabels.ALL_FULLY_QUALIFIED)});
667             return RefactoringStatus.createFatalErrorStatus(msg);
668         }
669         return result;
670     }
671
672     protected RefactoringStatus checkDeclaringType(final IProgressMonitor monitor) throws JavaModelException {
673         final RefactoringStatus status= super.checkDeclaringType(monitor);
674         if (JavaModelUtil.getFullyQualifiedName(getDeclaringType()).equals("java.lang.Object")) //$NON-NLS-1$
675
status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PullUpRefactoring_no_java_lang_Object));
676         status.merge(checkDeclaringSuperTypes(monitor));
677         return status;
678     }
679
680     private void checkFieldTypes(final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException {
681         final Map JavaDoc mapping= getMatchingMembers(getDestinationTypeHierarchy(monitor), getDestinationType(), true);
682         for (int i= 0; i < fMembersToMove.length; i++) {
683             if (fMembersToMove[i].getElementType() != IJavaElement.FIELD)
684                 continue;
685             final IField field= (IField) fMembersToMove[i];
686             final String JavaDoc type= Signature.toString(field.getTypeSignature());
687             Assert.isTrue(mapping.containsKey(field));
688             for (final Iterator JavaDoc iter= ((Set JavaDoc) mapping.get(field)).iterator(); iter.hasNext();) {
689                 final IField matchingField= (IField) iter.next();
690                 if (field.equals(matchingField))
691                     continue;
692                 if (type.equals(Signature.toString(matchingField.getTypeSignature())))
693                     continue;
694                 final String JavaDoc[] keys= { JavaElementLabels.getTextLabel(matchingField, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getTextLabel(matchingField.getDeclaringType(), JavaElementLabels.ALL_FULLY_QUALIFIED)};
695                 final String JavaDoc message= Messages.format(RefactoringCoreMessages.PullUpRefactoring_different_field_type, keys);
696                 final RefactoringStatusContext context= JavaStatusContext.create(matchingField.getCompilationUnit(), matchingField.getSourceRange());
697                 status.addError(message, context);
698             }
699         }
700     }
701
702     /**
703      * {@inheritDoc}
704      */

705     public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, final CheckConditionsContext context) throws CoreException, OperationCanceledException {
706         try {
707             monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, 12);
708             clearCaches();
709
710             final RefactoringStatus result= new RefactoringStatus();
711             result.merge(createWorkingCopyLayer(new SubProgressMonitor(monitor, 4)));
712             if (result.hasFatalError())
713                 return result;
714             if (monitor.isCanceled())
715                 throw new OperationCanceledException();
716             result.merge(checkGenericDeclaringType(new SubProgressMonitor(monitor, 1)));
717             result.merge(checkFinalFields(new SubProgressMonitor(monitor, 1)));
718             if (monitor.isCanceled())
719                 throw new OperationCanceledException();
720             result.merge(checkAccesses(new SubProgressMonitor(monitor, 1)));
721             result.merge(checkMembersInTypeAndAllSubtypes(new SubProgressMonitor(monitor, 2)));
722             result.merge(checkIfSkippingOverElements(new SubProgressMonitor(monitor, 1)));
723             if (monitor.isCanceled())
724                 throw new OperationCanceledException();
725             if (!JdtFlags.isAbstract(getDestinationType()) && getAbstractMethods().length > 0)
726                 result.merge(checkConstructorCalls(getDestinationType(), new SubProgressMonitor(monitor, 1)));
727             else
728                 monitor.worked(1);
729             if (result.hasFatalError())
730                 return result;
731             fCompilationUnitRewrites= new HashMap JavaDoc(3);
732             result.merge(checkProjectCompliance(getCompilationUnitRewrite(fCompilationUnitRewrites, getDeclaringType().getCompilationUnit()), getDestinationType(), fMembersToMove));
733             fChangeManager= createChangeManager(new SubProgressMonitor(monitor, 1), result);
734             result.merge(Checks.validateModifiesFiles(ResourceUtil.getFiles(fChangeManager.getAllCompilationUnits()), getRefactoring().getValidationContext()));
735             return result;
736         } finally {
737             monitor.done();
738         }
739     }
740
741     private RefactoringStatus checkFinalFields(final IProgressMonitor monitor) throws JavaModelException {
742         final RefactoringStatus result= new RefactoringStatus();
743         monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, fMembersToMove.length);
744         for (int index= 0; index < fMembersToMove.length; index++) {
745             final IMember member= fMembersToMove[index];
746             if (member.getElementType() == IJavaElement.FIELD) {
747                 if (!JdtFlags.isStatic(member)) {
748                     if (JdtFlags.isFinal(member)) {
749                         final RefactoringStatusContext context= JavaStatusContext.create(member);
750                         result.addWarning(RefactoringCoreMessages.PullUpRefactoring_final_fields, context);
751                     } else if (getDestinationType().isInterface()) {
752                         final RefactoringStatusContext context= JavaStatusContext.create(member);
753                         result.addWarning(RefactoringCoreMessages.PullUpRefactoring_non_final_pull_up_to_interface, context);
754                     }
755                 }
756             }
757             monitor.worked(1);
758             if (monitor.isCanceled())
759                 throw new OperationCanceledException();
760         }
761         monitor.done();
762         return result;
763     }
764
765     private RefactoringStatus checkGenericDeclaringType(final SubProgressMonitor monitor) throws JavaModelException {
766         Assert.isNotNull(monitor);
767
768         final RefactoringStatus status= new RefactoringStatus();
769         try {
770             final IMember[] pullables= getMembersToMove();
771             monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, pullables.length);
772
773             final IType declaring= getDeclaringType();
774             final ITypeParameter[] parameters= declaring.getTypeParameters();
775             if (parameters.length > 0) {
776                 final TypeVariableMaplet[] mapping= TypeVariableUtil.subTypeToInheritedType(declaring);
777                 IMember member= null;
778                 int length= 0;
779                 for (int index= 0; index < pullables.length; index++) {
780                     member= pullables[index];
781                     final String JavaDoc[] unmapped= TypeVariableUtil.getUnmappedVariables(mapping, declaring, member);
782                     length= unmapped.length;
783                     switch (length) {
784                         case 0:
785                             break;
786                         case 1:
787                             status.addError(Messages.format(RefactoringCoreMessages.PullUpRefactoring_Type_variable_not_available, new String JavaDoc[] { unmapped[0], declaring.getSuperclassName()}), JavaStatusContext.create(member));
788                             break;
789                         case 2:
790                             status.addError(Messages.format(RefactoringCoreMessages.PullUpRefactoring_Type_variable2_not_available, new String JavaDoc[] { unmapped[0], unmapped[1], declaring.getSuperclassName()}), JavaStatusContext.create(member));
791                             break;
792                         case 3:
793                             status.addError(Messages.format(RefactoringCoreMessages.PullUpRefactoring_Type_variable3_not_available, new String JavaDoc[] { unmapped[0], unmapped[1], unmapped[2], declaring.getSuperclassName()}), JavaStatusContext.create(member));
794                             break;
795                         default:
796                             status.addError(Messages.format(RefactoringCoreMessages.PullUpRefactoring_Type_variables_not_available, new String JavaDoc[] { declaring.getSuperclassName()}), JavaStatusContext.create(member));
797                     }
798                     monitor.worked(1);
799                     if (monitor.isCanceled())
800                         throw new OperationCanceledException();
801                 }
802             }
803         } finally {
804             monitor.done();
805         }
806         return status;
807     }
808
809     private RefactoringStatus checkIfDeclaredIn(final IMember element, final IType type) throws JavaModelException {
810         if (element instanceof IMethod)
811             return checkIfMethodDeclaredIn((IMethod) element, type);
812         else if (element instanceof IField)
813             return checkIfFieldDeclaredIn((IField) element, type);
814         else if (element instanceof IType)
815             return checkIfTypeDeclaredIn((IType) element, type);
816         Assert.isTrue(false);
817         return null;
818     }
819
820     private RefactoringStatus checkIfFieldDeclaredIn(final IField iField, final IType type) {
821         final IField fieldInType= type.getField(iField.getElementName());
822         if (!fieldInType.exists())
823             return null;
824         final String JavaDoc[] keys= { JavaElementLabels.getTextLabel(fieldInType, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getTextLabel(type, JavaElementLabels.ALL_FULLY_QUALIFIED)};
825         final String JavaDoc msg= Messages.format(RefactoringCoreMessages.PullUpRefactoring_Field_declared_in_class, keys);
826         final RefactoringStatusContext context= JavaStatusContext.create(fieldInType);
827         return RefactoringStatus.createWarningStatus(msg, context);
828     }
829
830     private RefactoringStatus checkIfMethodDeclaredIn(final IMethod iMethod, final IType type) throws JavaModelException {
831         final IMethod methodInType= JavaModelUtil.findMethod(iMethod.getElementName(), iMethod.getParameterTypes(), iMethod.isConstructor(), type);
832         if (methodInType == null || !methodInType.exists())
833             return null;
834         final String JavaDoc[] keys= { JavaElementLabels.getTextLabel(methodInType, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getTextLabel(type, JavaElementLabels.ALL_FULLY_QUALIFIED)};
835         final String JavaDoc msg= Messages.format(RefactoringCoreMessages.PullUpRefactoring_Method_declared_in_class, keys);
836         final RefactoringStatusContext context= JavaStatusContext.create(methodInType);
837         return RefactoringStatus.createWarningStatus(msg, context);
838     }
839
840     private RefactoringStatus checkIfSkippingOverElements(final IProgressMonitor monitor) throws JavaModelException {
841         monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, 1);
842         try {
843             final Set JavaDoc skippedTypes= getSkippedSuperTypes(new SubProgressMonitor(monitor, 1));
844             final IType[] skipped= (IType[]) skippedTypes.toArray(new IType[skippedTypes.size()]);
845             final RefactoringStatus result= new RefactoringStatus();
846             for (int i= 0; i < fMembersToMove.length; i++) {
847                 final IMember element= fMembersToMove[i];
848                 for (int j= 0; j < skipped.length; j++) {
849                     result.merge(checkIfDeclaredIn(element, skipped[j]));
850                 }
851             }
852             return result;
853         } finally {
854             monitor.done();
855         }
856     }
857
858     private RefactoringStatus checkIfTypeDeclaredIn(final IType iType, final IType type) {
859         final IType typeInType= type.getType(iType.getElementName());
860         if (!typeInType.exists())
861             return null;
862         final String JavaDoc[] keys= { JavaElementLabels.getTextLabel(typeInType, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getTextLabel(type, JavaElementLabels.ALL_FULLY_QUALIFIED)};
863         final String JavaDoc msg= Messages.format(RefactoringCoreMessages.PullUpRefactoring_Type_declared_in_class, keys);
864         final RefactoringStatusContext context= JavaStatusContext.create(typeInType);
865         return RefactoringStatus.createWarningStatus(msg, context);
866     }
867
868     /**
869      * {@inheritDoc}
870      */

871     public RefactoringStatus checkInitialConditions(final IProgressMonitor monitor) throws CoreException, OperationCanceledException {
872         try {
873             monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, 1);
874             final RefactoringStatus status= new RefactoringStatus();
875             status.merge(checkDeclaringType(new SubProgressMonitor(monitor, 1)));
876             if (status.hasFatalError())
877                 return status;
878             status.merge(checkIfMembersExist());
879             if (status.hasFatalError())
880                 return status;
881             return status;
882         } finally {
883             monitor.done();
884         }
885     }
886
887     private void checkMembersInDestinationType(final RefactoringStatus status, final Set JavaDoc set) throws JavaModelException {
888         final IMember[] destinationMembers= getCreatedDestinationMembers();
889         final List JavaDoc list= new ArrayList JavaDoc(destinationMembers.length);
890         list.addAll(Arrays.asList(destinationMembers));
891         list.addAll(set);
892         list.removeAll(Arrays.asList(fDeletedMethods));
893         final IMember[] members= (IMember[]) list.toArray(new IMember[list.size()]);
894         status.merge(MemberCheckUtil.checkMembersInDestinationType(members, getDestinationType()));
895     }
896
897     private RefactoringStatus checkMembersInTypeAndAllSubtypes(final IProgressMonitor monitor) throws JavaModelException {
898         final RefactoringStatus result= new RefactoringStatus();
899         monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, 3);
900         final Set JavaDoc notDeletedMembers= getNotDeletedMembers(new SubProgressMonitor(monitor, 1));
901         final Set JavaDoc notDeletedMembersInTargetType= new HashSet JavaDoc();
902         final Set JavaDoc notDeletedMembersInSubtypes= new HashSet JavaDoc();
903         for (final Iterator JavaDoc iter= notDeletedMembers.iterator(); iter.hasNext();) {
904             final IMember member= (IMember) iter.next();
905             if (getDestinationType().equals(member.getDeclaringType()))
906                 notDeletedMembersInTargetType.add(member);
907             else
908                 notDeletedMembersInSubtypes.add(member);
909         }
910         checkMembersInDestinationType(result, notDeletedMembersInTargetType);
911         checkAccessModifiers(result, notDeletedMembersInSubtypes);
912         checkMethodReturnTypes(new SubProgressMonitor(monitor, 1), result, notDeletedMembersInSubtypes);
913         checkFieldTypes(new SubProgressMonitor(monitor, 1), result);
914         monitor.done();
915         return result;
916     }
917
918     private void checkMethodReturnTypes(final IProgressMonitor monitor, final RefactoringStatus status, final Set JavaDoc notDeletedMembersInSubtypes) throws JavaModelException {
919         final Map JavaDoc mapping= getMatchingMembers(getDestinationTypeHierarchy(monitor), getDestinationType(), true);
920         final IMember[] members= getCreatedDestinationMembers();
921         for (int i= 0; i < members.length; i++) {
922             if (members[i].getElementType() != IJavaElement.METHOD)
923                 continue;
924             final IMethod method= (IMethod) members[i];
925             if (mapping.containsKey(method)) {
926                 final Set JavaDoc set= (Set JavaDoc) mapping.get(method);
927                 if (set != null) {
928                     final String JavaDoc returnType= Signature.toString(Signature.getReturnType(method.getSignature()).toString());
929                     for (final Iterator JavaDoc iter= set.iterator(); iter.hasNext();) {
930                         final IMethod matchingMethod= (IMethod) iter.next();
931                         if (method.equals(matchingMethod))
932                             continue;
933                         if (!notDeletedMembersInSubtypes.contains(matchingMethod))
934                             continue;
935                         if (returnType.equals(Signature.toString(Signature.getReturnType(matchingMethod.getSignature()).toString())))
936                             continue;
937                         final String JavaDoc[] keys= { JavaElementLabels.getTextLabel(matchingMethod, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getTextLabel(matchingMethod.getDeclaringType(), JavaElementLabels.ALL_FULLY_QUALIFIED)};
938                         final String JavaDoc message= Messages.format(RefactoringCoreMessages.PullUpRefactoring_different_method_return_type, keys);
939                         final RefactoringStatusContext context= JavaStatusContext.create(matchingMethod.getCompilationUnit(), matchingMethod.getNameRange());
940                         status.addError(message, context);
941                     }
942                 }
943             }
944         }
945     }
946
947     protected void clearCaches() {
948         super.clearCaches();
949         fCachedMembersReferences.clear();
950         fCachedDestinationTypeHierarchy= null;
951         fCachedDeclaringSuperTypeHierarchy= null;
952     }
953
954     private void copyBodyOfPulledUpMethod(final CompilationUnitRewrite sourceRewrite, final CompilationUnitRewrite targetRewrite, final IMethod method, final MethodDeclaration oldMethod, final MethodDeclaration newMethod, final TypeVariableMaplet[] mapping, final IProgressMonitor monitor) throws JavaModelException {
955         final Block body= oldMethod.getBody();
956         if (body == null) {
957             newMethod.setBody(null);
958             return;
959         }
960         try {
961             final IDocument document= new Document(method.getCompilationUnit().getBuffer().getContents());
962             final ASTRewrite rewrite= ASTRewrite.create(body.getAST());
963             final ITrackedNodePosition position= rewrite.track(body);
964             body.accept(new PullUpAstNodeMapper(sourceRewrite, targetRewrite, rewrite, getDeclaringSuperTypeHierarchy(monitor).getSuperclass(getDeclaringType()), mapping, oldMethod.resolveBinding()));
965             rewrite.rewriteAST(document, method.getJavaProject().getOptions(true)).apply(document, TextEdit.NONE);
966             String JavaDoc content= document.get(position.getStartPosition(), position.getLength());
967             final String JavaDoc[] lines= Strings.convertIntoLines(content);
968             Strings.trimIndentation(lines, method.getJavaProject(), false);
969             content= Strings.concatenate(lines, StubUtility.getLineDelimiterUsed(method));
970             newMethod.setBody((Block) targetRewrite.getASTRewrite().createStringPlaceholder(content, ASTNode.BLOCK));
971         } catch (MalformedTreeException exception) {
972             JavaPlugin.log(exception);
973         } catch (BadLocationException exception) {
974             JavaPlugin.log(exception);
975         }
976     }
977
978     private void createAbstractMethod(final IMethod sourceMethod, final CompilationUnitRewrite sourceRewriter, final CompilationUnit declaringCuNode, final AbstractTypeDeclaration destination, final TypeVariableMaplet[] mapping, final CompilationUnitRewrite targetRewrite, final Map JavaDoc adjustments, final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException {
979         final MethodDeclaration oldMethod= ASTNodeSearchUtil.getMethodDeclarationNode(sourceMethod, declaringCuNode);
980         if (JavaModelUtil.is50OrHigher(sourceMethod.getJavaProject()) && (fSettings.overrideAnnotation || JavaCore.ERROR.equals(sourceMethod.getJavaProject().getOption(JavaCore.COMPILER_PB_MISSING_OVERRIDE_ANNOTATION, true)))) {
981             final MarkerAnnotation annotation= sourceRewriter.getAST().newMarkerAnnotation();
982             annotation.setTypeName(sourceRewriter.getAST().newSimpleName("Override")); //$NON-NLS-1$
983
sourceRewriter.getASTRewrite().getListRewrite(oldMethod, MethodDeclaration.MODIFIERS2_PROPERTY).insertFirst(annotation, sourceRewriter.createCategorizedGroupDescription(RefactoringCoreMessages.PullUpRefactoring_add_override_annotation, SET_PULL_UP));
984         }
985         final MethodDeclaration newMethod= targetRewrite.getAST().newMethodDeclaration();
986         newMethod.setBody(null);
987         newMethod.setConstructor(false);
988         newMethod.setExtraDimensions(oldMethod.getExtraDimensions());
989         newMethod.setJavadoc(null);
990         int modifiers= getModifiersWithUpdatedVisibility(sourceMethod, Modifier.ABSTRACT | JdtFlags.clearFlag(Modifier.NATIVE | Modifier.FINAL, sourceMethod.getFlags()), adjustments, monitor, false, status);
991         if (oldMethod.isVarargs())
992             modifiers&= ~Flags.AccVarargs;
993         newMethod.modifiers().addAll(ASTNodeFactory.newModifiers(targetRewrite.getAST(), modifiers));
994         newMethod.setName(((SimpleName) ASTNode.copySubtree(targetRewrite.getAST(), oldMethod.getName())));
995         copyReturnType(targetRewrite.getASTRewrite(), getDeclaringType().getCompilationUnit(), oldMethod, newMethod, mapping);
996         copyParameters(targetRewrite.getASTRewrite(), getDeclaringType().getCompilationUnit(), oldMethod, newMethod, mapping);
997         copyThrownExceptions(oldMethod, newMethod);
998         ImportRewriteUtil.addImports(targetRewrite, newMethod, new HashMap JavaDoc(), new HashMap JavaDoc(), false);
999         targetRewrite.getASTRewrite().getListRewrite(destination, destination.getBodyDeclarationsProperty()).insertAt(newMethod, ASTNodes.getInsertionIndex(newMethod, destination.bodyDeclarations()), targetRewrite.createCategorizedGroupDescription(RefactoringCoreMessages.PullUpRefactoring_add_abstract_method, SET_PULL_UP));
1000    }
1001
1002    /**
1003     * {@inheritDoc}
1004     */

1005    public Change createChange(final IProgressMonitor monitor) throws CoreException, OperationCanceledException {
1006        try {
1007            final Map JavaDoc arguments= new HashMap JavaDoc();
1008            String JavaDoc project= null;
1009            final IType declaring= getDeclaringType();
1010            final IJavaProject javaProject= declaring.getJavaProject();
1011            if (javaProject != null)
1012                project= javaProject.getElementName();
1013            int flags= JavaRefactoringDescriptor.JAR_MIGRATION | JavaRefactoringDescriptor.JAR_REFACTORING | RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE;
1014            try {
1015                if (declaring.isLocal() || declaring.isAnonymous())
1016                    flags|= JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
1017            } catch (JavaModelException exception) {
1018                JavaPlugin.log(exception);
1019            }
1020            final String JavaDoc description= fMembersToMove.length == 1 ? Messages.format(RefactoringCoreMessages.PullUpRefactoring_descriptor_description_short, new String JavaDoc[] { fMembersToMove[0].getElementName(), fDestinationType.getElementName()}) : Messages.format(RefactoringCoreMessages.PullUpRefactoring_descriptor_description_short_multiple, fDestinationType.getElementName());
1021            final String JavaDoc header= fMembersToMove.length == 1 ? Messages.format(RefactoringCoreMessages.PullUpRefactoring_descriptor_description_full, new String JavaDoc[] { JavaElementLabels.getElementLabel(fMembersToMove[0], JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getElementLabel(declaring, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getElementLabel(fDestinationType, JavaElementLabels.ALL_FULLY_QUALIFIED)}) : Messages.format(RefactoringCoreMessages.PullUpRefactoring_descriptor_description, new String JavaDoc[] { JavaElementLabels.getElementLabel(declaring, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getElementLabel(fDestinationType, JavaElementLabels.ALL_FULLY_QUALIFIED)});
1022            final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header);
1023            comment.addSetting(Messages.format(RefactoringCoreMessages.MoveStaticMembersProcessor_target_element_pattern, JavaElementLabels.getElementLabel(fDestinationType, JavaElementLabels.ALL_FULLY_QUALIFIED)));
1024            addSuperTypeSettings(comment, true);
1025            final JDTRefactoringDescriptor descriptor= new JDTRefactoringDescriptor(IJavaRefactorings.PULL_UP, project, description, comment.asString(), arguments, flags);
1026            arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_INPUT, descriptor.elementToHandle(fDestinationType));
1027            arguments.put(ATTRIBUTE_REPLACE, Boolean.valueOf(fReplace).toString());
1028            arguments.put(ATTRIBUTE_INSTANCEOF, Boolean.valueOf(fInstanceOf).toString());
1029            arguments.put(ATTRIBUTE_STUBS, Boolean.valueOf(fCreateMethodStubs).toString());
1030            arguments.put(ATTRIBUTE_PULL, new Integer JavaDoc(fMembersToMove.length).toString());
1031            for (int offset= 0; offset < fMembersToMove.length; offset++)
1032                arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (offset + 1), descriptor.elementToHandle(fMembersToMove[offset]));
1033            arguments.put(ATTRIBUTE_DELETE, new Integer JavaDoc(fDeletedMethods.length).toString());
1034            for (int offset= 0; offset < fDeletedMethods.length; offset++)
1035                arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (offset + fMembersToMove.length + 1), descriptor.elementToHandle(fDeletedMethods[offset]));
1036            arguments.put(ATTRIBUTE_ABSTRACT, new Integer JavaDoc(fAbstractMethods.length).toString());
1037            for (int offset= 0; offset < fAbstractMethods.length; offset++)
1038                arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (offset + fMembersToMove.length + fDeletedMethods.length + 1), descriptor.elementToHandle(fAbstractMethods[offset]));
1039            return new DynamicValidationRefactoringChange(descriptor, RefactoringCoreMessages.PullUpRefactoring_Pull_Up, fChangeManager.getAllChanges());
1040        } finally {
1041            monitor.done();
1042            clearCaches();
1043        }
1044    }
1045
1046    private TextEditBasedChangeManager createChangeManager(final IProgressMonitor monitor, final RefactoringStatus status) throws CoreException {
1047        Assert.isNotNull(monitor);
1048        Assert.isNotNull(status);
1049        try {
1050            monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, 24);
1051            final ICompilationUnit source= getDeclaringType().getCompilationUnit();
1052            final IType destination= getDestinationType();
1053            final ICompilationUnit target= destination.getCompilationUnit();
1054            final CompilationUnitRewrite sourceRewriter= getCompilationUnitRewrite(fCompilationUnitRewrites, source);
1055            final CompilationUnitRewrite targetRewriter= getCompilationUnitRewrite(fCompilationUnitRewrites, target);
1056            final Map JavaDoc deleteMap= createMembersToDeleteMap(new SubProgressMonitor(monitor, 1));
1057            final Map JavaDoc effectedMap= createEffectedTypesMap(new SubProgressMonitor(monitor, 1));
1058            final ICompilationUnit[] units= getAffectedCompilationUnits(new SubProgressMonitor(monitor, 1));
1059            ICompilationUnit unit= null;
1060            CompilationUnitRewrite rewrite= null;
1061            final Map JavaDoc adjustments= new HashMap JavaDoc();
1062            MemberVisibilityAdjustor adjustor= null;
1063            final IProgressMonitor sub= new SubProgressMonitor(monitor, 1);
1064            try {
1065                sub.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, units.length * 11);
1066                for (int index= 0; index < units.length; index++) {
1067                    unit= units[index];
1068                    if (!(source.equals(unit) || target.equals(unit) || deleteMap.containsKey(unit) || effectedMap.containsKey(unit))) {
1069                        sub.worked(10);
1070                        continue;
1071                    }
1072                    rewrite= getCompilationUnitRewrite(fCompilationUnitRewrites, unit);
1073                    if (deleteMap.containsKey(unit)) {
1074                        LinkedList JavaDoc list= new LinkedList JavaDoc((List JavaDoc) deleteMap.get(unit));
1075                        if (destination.isInterface()) {
1076                            for (final Iterator JavaDoc iterator= list.iterator(); iterator.hasNext();) {
1077                                final IMember member= (IMember) iterator.next();
1078                                if (member instanceof IMethod)
1079                                    iterator.remove();
1080                            }
1081                        }
1082                        deleteDeclarationNodes(sourceRewriter, sourceRewriter.getCu().equals(targetRewriter.getCu()), rewrite, list, SET_PULL_UP);
1083                    }
1084                    final CompilationUnit root= sourceRewriter.getRoot();
1085                    if (unit.equals(target)) {
1086                        final ASTRewrite rewriter= rewrite.getASTRewrite();
1087                        if (!JdtFlags.isAbstract(destination) && !destination.isInterface() && getAbstractMethods().length > 0) {
1088                            final AbstractTypeDeclaration declaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(destination, rewrite.getRoot());
1089                            ModifierRewrite.create(rewriter, declaration).setModifiers(declaration.getModifiers() | Modifier.ABSTRACT, rewrite.createCategorizedGroupDescription(RefactoringCoreMessages.PullUpRefactoring_make_target_abstract, SET_PULL_UP));
1090                        }
1091                        final TypeVariableMaplet[] mapping= TypeVariableUtil.subTypeToSuperType(getDeclaringType(), destination);
1092                        final IProgressMonitor subsub= new SubProgressMonitor(sub, 1);
1093                        final AbstractTypeDeclaration declaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(destination, rewrite.getRoot());
1094                        fMembersToMove= JavaElementUtil.sortByOffset(fMembersToMove);
1095                        subsub.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, fMembersToMove.length);
1096                        IMember member= null;
1097                        for (int offset= fMembersToMove.length - 1; offset >= 0; offset--) {
1098                            member= fMembersToMove[offset];
1099                            adjustor= new MemberVisibilityAdjustor(destination, member);
1100                            adjustor.setRewrite(sourceRewriter.getASTRewrite(), root);
1101
1102                            // TW: set to error if bug 78387 is fixed
1103
adjustor.setFailureSeverity(RefactoringStatus.WARNING);
1104
1105                            adjustor.setOwner(fOwner);
1106                            adjustor.setRewrites(fCompilationUnitRewrites);
1107                            adjustor.setStatus(status);
1108                            adjustor.setAdjustments(adjustments);
1109                            adjustor.adjustVisibility(new SubProgressMonitor(subsub, 1));
1110                            adjustments.remove(member);
1111                            if (member instanceof IField) {
1112                                final VariableDeclarationFragment oldField= ASTNodeSearchUtil.getFieldDeclarationFragmentNode((IField) member, root);
1113                                if (oldField != null) {
1114                                    int flags= getModifiersWithUpdatedVisibility(member, member.getFlags(), adjustments, new SubProgressMonitor(subsub, 1), true, status);
1115                                    if (destination.isInterface())
1116                                        flags|= Flags.AccFinal;
1117                                    final FieldDeclaration newField= createNewFieldDeclarationNode(rewriter, root, (IField) member, oldField, mapping, new SubProgressMonitor(subsub, 1), status, flags);
1118                                    rewriter.getListRewrite(declaration, declaration.getBodyDeclarationsProperty()).insertAt(newField, ASTNodes.getInsertionIndex(newField, declaration.bodyDeclarations()), rewrite.createCategorizedGroupDescription(RefactoringCoreMessages.HierarchyRefactoring_add_member, SET_PULL_UP));
1119                                    ImportRewriteUtil.addImports(rewrite, oldField.getParent(), new HashMap JavaDoc(), new HashMap JavaDoc(), false);
1120                                }
1121                            } else if (member instanceof IMethod) {
1122                                final MethodDeclaration oldMethod= ASTNodeSearchUtil.getMethodDeclarationNode((IMethod) member, root);
1123                                if (oldMethod != null) {
1124                                    if (JdtFlags.isStatic(member) && fDestinationType.isInterface())
1125                                        status.merge(RefactoringStatus.createErrorStatus(Messages.format(RefactoringCoreMessages.PullUpRefactoring_moving_static_method_to_interface, new String JavaDoc[] { JavaElementLabels.getTextLabel(member, JavaElementLabels.ALL_FULLY_QUALIFIED)}), JavaStatusContext.create(member)));
1126                                    final MethodDeclaration newMethod= createNewMethodDeclarationNode(sourceRewriter, rewrite, ((IMethod) member), oldMethod, root, mapping, adjustments, new SubProgressMonitor(subsub, 1), status);
1127                                    rewriter.getListRewrite(declaration, declaration.getBodyDeclarationsProperty()).insertAt(newMethod, ASTNodes.getInsertionIndex(newMethod, declaration.bodyDeclarations()), rewrite.createCategorizedGroupDescription(RefactoringCoreMessages.HierarchyRefactoring_add_member, SET_PULL_UP));
1128                                    ImportRewriteUtil.addImports(rewrite, oldMethod, new HashMap JavaDoc(), new HashMap JavaDoc(), false);
1129                                }
1130                            } else if (member instanceof IType) {
1131                                final AbstractTypeDeclaration oldType= ASTNodeSearchUtil.getAbstractTypeDeclarationNode((IType) member, root);
1132                                if (oldType != null) {
1133                                    final BodyDeclaration newType= createNewTypeDeclarationNode(((IType) member), oldType, root, mapping, rewriter);
1134                                    rewriter.getListRewrite(declaration, declaration.getBodyDeclarationsProperty()).insertAt(newType, ASTNodes.getInsertionIndex(newType, declaration.bodyDeclarations()), rewrite.createCategorizedGroupDescription(RefactoringCoreMessages.HierarchyRefactoring_add_member, SET_PULL_UP));
1135                                    ImportRewriteUtil.addImports(rewrite, oldType, new HashMap JavaDoc(), new HashMap JavaDoc(), false);
1136                                }
1137                            } else
1138                                Assert.isTrue(false);
1139                            subsub.worked(1);
1140                        }
1141                        subsub.done();
1142                        for (int offset= 0; offset < fAbstractMethods.length; offset++)
1143                            createAbstractMethod(fAbstractMethods[offset], sourceRewriter, root, declaration, mapping, rewrite, adjustments, new SubProgressMonitor(sub, 1), status);
1144                    } else
1145                        sub.worked(2);
1146                    if (unit.equals(sourceRewriter.getCu())) {
1147                        final IProgressMonitor subsub= new SubProgressMonitor(sub, 1);
1148                        subsub.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, fAbstractMethods.length * 2);
1149                        IMethod method= null;
1150                        for (int offset= 0; offset < fAbstractMethods.length; offset++) {
1151                            method= fAbstractMethods[offset];
1152                            adjustor= new MemberVisibilityAdjustor(destination, method);
1153                            adjustor.setRewrite(sourceRewriter.getASTRewrite(), root);
1154                            adjustor.setRewrites(fCompilationUnitRewrites);
1155
1156                            // TW: set to error if bug 78387 is fixed
1157
adjustor.setFailureSeverity(RefactoringStatus.WARNING);
1158
1159                            adjustor.setOwner(fOwner);
1160                            adjustor.setStatus(status);
1161                            adjustor.setAdjustments(adjustments);
1162                            if (needsVisibilityAdjustment(method, false, new SubProgressMonitor(subsub, 1), status))
1163                                adjustments.put(method, new MemberVisibilityAdjustor.OutgoingMemberVisibilityAdjustment(method, Modifier.ModifierKeyword.PROTECTED_KEYWORD, RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_method_warning, new String JavaDoc[] { MemberVisibilityAdjustor.getLabel(method), RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_protected}), JavaStatusContext.create(method))));
1164                        }
1165                    } else
1166                        sub.worked(2);
1167                    if (effectedMap.containsKey(unit))
1168                        addNecessaryMethodStubs((List JavaDoc) effectedMap.get(unit), root, rewrite, adjustments, new SubProgressMonitor(sub, 2), status);
1169                    if (sub.isCanceled())
1170                        throw new OperationCanceledException();
1171                }
1172            } finally {
1173                sub.done();
1174            }
1175            if (adjustor != null && !adjustments.isEmpty())
1176                adjustor.rewriteVisibility(new SubProgressMonitor(monitor, 1));
1177            final TextEditBasedChangeManager manager= new TextEditBasedChangeManager();
1178            if (fReplace) {
1179                final Set JavaDoc set= fCompilationUnitRewrites.keySet();
1180                for (final Iterator JavaDoc iterator= set.iterator(); iterator.hasNext();) {
1181                    unit= (ICompilationUnit) iterator.next();
1182                    rewrite= (CompilationUnitRewrite) fCompilationUnitRewrites.get(unit);
1183                    if (rewrite != null) {
1184                        final CompilationUnitChange change= rewrite.createChange(false, null);
1185                        if (change != null)
1186                            manager.manage(unit, change);
1187                    }
1188                }
1189                TextEdit edit= null;
1190                TextEditBasedChange change= null;
1191                final Map JavaDoc workingcopies= new HashMap JavaDoc();
1192                final IProgressMonitor subMonitor= new SubProgressMonitor(monitor, 1);
1193                try {
1194                    subMonitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, set.size());
1195                    for (final Iterator JavaDoc iterator= set.iterator(); iterator.hasNext();) {
1196                        unit= (ICompilationUnit) iterator.next();
1197                        change= manager.get(unit);
1198                        if (change instanceof TextChange) {
1199                            edit= ((TextChange) change).getEdit();
1200                            if (edit != null) {
1201                                final ICompilationUnit copy= createWorkingCopy(unit, edit, status, new SubProgressMonitor(monitor, 1));
1202                                if (copy != null)
1203                                    workingcopies.put(unit, copy);
1204                            }
1205                        }
1206                    }
1207                    final ICompilationUnit current= (ICompilationUnit) workingcopies.get(sourceRewriter.getCu());
1208                    if (current != null)
1209                        rewriteTypeOccurrences(manager, sourceRewriter, current, new HashSet JavaDoc(), status, new SubProgressMonitor(monitor, 16));
1210                } finally {
1211                    subMonitor.done();
1212                    ICompilationUnit[] cus= manager.getAllCompilationUnits();
1213                    for (int index= 0; index < cus.length; index++) {
1214                        CompilationUnitChange current= (CompilationUnitChange) manager.get(cus[index]);
1215                        if (change != null && current.getEdit() == null)
1216                            manager.remove(cus[index]);
1217                    }
1218                }
1219            }
1220            registerChanges(manager);
1221            return manager;
1222        } finally {
1223            fCompilationUnitRewrites.clear();
1224            monitor.done();
1225        }
1226    }
1227
1228    private Map JavaDoc createEffectedTypesMap(final IProgressMonitor monitor) throws JavaModelException {
1229        if (!(fCreateMethodStubs && getAbstractMethods().length > 0))
1230            return new HashMap JavaDoc(0);
1231        final Set JavaDoc effected= getEffectedSubTypes(getDestinationTypeHierarchy(monitor), getDestinationType());
1232        final Map JavaDoc result= new HashMap JavaDoc();
1233        for (final Iterator JavaDoc iterator= effected.iterator(); iterator.hasNext();) {
1234            final IType type= (IType) iterator.next();
1235            final ICompilationUnit unit= type.getCompilationUnit();
1236            if (!result.containsKey(unit))
1237                result.put(unit, new ArrayList JavaDoc(1));
1238            ((List JavaDoc) result.get(unit)).add(type);
1239        }
1240        return result;
1241    }
1242
1243    private Javadoc createJavadocForStub(final String JavaDoc enclosingTypeName, final MethodDeclaration oldMethod, final MethodDeclaration newMethodNode, final ICompilationUnit cu, final ASTRewrite rewrite) throws CoreException {
1244        if (fSettings.createComments) {
1245            final IMethodBinding binding= oldMethod.resolveBinding();
1246            if (binding != null) {
1247                final ITypeBinding[] params= binding.getParameterTypes();
1248                final String JavaDoc fullTypeName= JavaModelUtil.getFullyQualifiedName(getDestinationType());
1249                final String JavaDoc[] fullParamNames= new String JavaDoc[params.length];
1250                for (int i= 0; i < fullParamNames.length; i++) {
1251                    fullParamNames[i]= Bindings.getFullyQualifiedName(params[i]);
1252                }
1253                final String JavaDoc comment= CodeGeneration.getMethodComment(cu, enclosingTypeName, newMethodNode, false, binding.getName(), fullTypeName, fullParamNames, StubUtility.getLineDelimiterUsed(cu));
1254                return (Javadoc) rewrite.createStringPlaceholder(comment, ASTNode.JAVADOC);
1255            }
1256        }
1257        return null;
1258    }
1259
1260    private Map JavaDoc createMembersToDeleteMap(final IProgressMonitor monitor) throws JavaModelException {
1261        final IMember[] membersToDelete= getMembersToDelete(monitor);
1262        final Map JavaDoc result= new HashMap JavaDoc();
1263        for (int i= 0; i < membersToDelete.length; i++) {
1264            final IMember member= membersToDelete[i];
1265            final ICompilationUnit cu= member.getCompilationUnit();
1266            if (!result.containsKey(cu))
1267                result.put(cu, new ArrayList JavaDoc(1));
1268            ((List JavaDoc) result.get(cu)).add(member);
1269        }
1270        return result;
1271    }
1272
1273    private MethodDeclaration createNewMethodDeclarationNode(final CompilationUnitRewrite sourceRewrite, final CompilationUnitRewrite targetRewrite, final IMethod sourceMethod, final MethodDeclaration oldMethod, final CompilationUnit declaringCuNode, final TypeVariableMaplet[] mapping, final Map JavaDoc adjustments, final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException {
1274        final ASTRewrite rewrite= targetRewrite.getASTRewrite();
1275        final AST ast= rewrite.getAST();
1276        final MethodDeclaration newMethod= ast.newMethodDeclaration();
1277        if (!getDestinationType().isInterface())
1278            copyBodyOfPulledUpMethod(sourceRewrite, targetRewrite, sourceMethod, oldMethod, newMethod, mapping, monitor);
1279        newMethod.setConstructor(oldMethod.isConstructor());
1280        newMethod.setExtraDimensions(oldMethod.getExtraDimensions());
1281        copyJavadocNode(rewrite, sourceMethod, oldMethod, newMethod);
1282        int modifiers= getModifiersWithUpdatedVisibility(sourceMethod, sourceMethod.getFlags(), adjustments, monitor, true, status);
1283        if (oldMethod.isVarargs())
1284            modifiers&= ~Flags.AccVarargs;
1285        copyAnnotations(oldMethod, newMethod);
1286        newMethod.modifiers().addAll(ASTNodeFactory.newModifiers(ast, modifiers));
1287        newMethod.setName(((SimpleName) ASTNode.copySubtree(ast, oldMethod.getName())));
1288        copyReturnType(rewrite, getDeclaringType().getCompilationUnit(), oldMethod, newMethod, mapping);
1289        copyParameters(rewrite, getDeclaringType().getCompilationUnit(), oldMethod, newMethod, mapping);
1290        copyThrownExceptions(oldMethod, newMethod);
1291        copyTypeParameters(oldMethod, newMethod);
1292        return newMethod;
1293    }
1294
1295    private BodyDeclaration createNewTypeDeclarationNode(final IType type, final AbstractTypeDeclaration oldType, final CompilationUnit declaringCuNode, final TypeVariableMaplet[] mapping, final ASTRewrite rewrite) throws JavaModelException {
1296        final ICompilationUnit declaringCu= getDeclaringType().getCompilationUnit();
1297        if (!JdtFlags.isPublic(type) && !JdtFlags.isProtected(type)) {
1298            if (mapping.length > 0)
1299                return createPlaceholderForTypeDeclaration(oldType, declaringCu, mapping, rewrite, true);
1300
1301            return createPlaceholderForProtectedTypeDeclaration(oldType, declaringCuNode, declaringCu, rewrite, true);
1302        }
1303        if (mapping.length > 0)
1304            return createPlaceholderForTypeDeclaration(oldType, declaringCu, mapping, rewrite, true);
1305
1306        return createPlaceholderForTypeDeclaration(oldType, declaringCu, rewrite, true);
1307    }
1308
1309    private ICompilationUnit createWorkingCopy(final ICompilationUnit unit, final TextEdit edit, final RefactoringStatus status, final IProgressMonitor monitor) {
1310        try {
1311            monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, 1);
1312            final ICompilationUnit copy= getSharedWorkingCopy(unit.getPrimary(), new SubProgressMonitor(monitor, 1));
1313            final IDocument document= new Document(unit.getBuffer().getContents());
1314            edit.apply(document, TextEdit.UPDATE_REGIONS);
1315            copy.getBuffer().setContents(document.get());
1316            JavaModelUtil.reconcile(copy);
1317            return copy;
1318        } catch (JavaModelException exception) {
1319            status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error));
1320        } catch (MalformedTreeException exception) {
1321            status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error));
1322        } catch (BadLocationException exception) {
1323            status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error));
1324        } finally {
1325            monitor.done();
1326        }
1327        return null;
1328    }
1329
1330    /**
1331     * Creates a working copy layer if necessary.
1332     *
1333     * @param monitor
1334     * the progress monitor to use
1335     * @return a status describing the outcome of the operation
1336     */

1337    protected RefactoringStatus createWorkingCopyLayer(IProgressMonitor monitor) {
1338        try {
1339            monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, 1);
1340            ICompilationUnit unit= getDeclaringType().getCompilationUnit();
1341            if (fLayer)
1342                unit= unit.findWorkingCopy(fOwner);
1343            resetWorkingCopies(unit);
1344            return new RefactoringStatus();
1345        } finally {
1346            monitor.done();
1347        }
1348    }
1349
1350    private IMethod[] getAbstractMethods() throws JavaModelException {
1351        final IMethod[] toDeclareAbstract= fAbstractMethods;
1352        final IMethod[] abstractPulledUp= getAbstractMethodsToPullUp();
1353        final Set JavaDoc result= new LinkedHashSet JavaDoc(toDeclareAbstract.length + abstractPulledUp.length + fMembersToMove.length);
1354        if (fDestinationType.isInterface()) {
1355            for (int i= 0; i < fMembersToMove.length; i++) {
1356                if (fMembersToMove[i].getElementType() == IJavaElement.METHOD) {
1357                    result.add(fMembersToMove[i]);
1358                }
1359            }
1360        }
1361        result.addAll(Arrays.asList(toDeclareAbstract));
1362        result.addAll(Arrays.asList(abstractPulledUp));
1363        return (IMethod[]) result.toArray(new IMethod[result.size()]);
1364    }
1365
1366    private IMethod[] getAbstractMethodsToPullUp() throws JavaModelException {
1367        final List JavaDoc result= new ArrayList JavaDoc(fMembersToMove.length);
1368        for (int i= 0; i < fMembersToMove.length; i++) {
1369            final IMember member= fMembersToMove[i];
1370            if (member instanceof IMethod && JdtFlags.isAbstract(member))
1371                result.add(member);
1372        }
1373        return (IMethod[]) result.toArray(new IMethod[result.size()]);
1374    }
1375
1376    public IMember[] getAdditionalRequiredMembersToPullUp(final IProgressMonitor monitor) throws JavaModelException {
1377        final IMember[] members= getCreatedDestinationMembers();
1378        monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_calculating_required, members.length);// not
1379
final List JavaDoc queue= new ArrayList JavaDoc(members.length);
1380        queue.addAll(Arrays.asList(members));
1381        if (queue.isEmpty())
1382            return new IMember[0];
1383        int i= 0;
1384        IMember current;
1385        do {
1386            current= (IMember) queue.get(i);
1387            addAllRequiredPullableMembers(queue, current, new SubProgressMonitor(monitor, 1));
1388            i++;
1389            if (queue.size() == i)
1390                current= null;
1391        } while (current != null);
1392        queue.removeAll(Arrays.asList(members));// report only additional
1393
return (IMember[]) queue.toArray(new IMember[queue.size()]);
1394    }
1395
1396    private ICompilationUnit[] getAffectedCompilationUnits(final IProgressMonitor monitor) throws JavaModelException {
1397        final IType[] allSubtypes= getDestinationTypeHierarchy(monitor).getAllSubtypes(getDestinationType());
1398        final Set JavaDoc result= new HashSet JavaDoc(allSubtypes.length);
1399        for (int i= 0; i < allSubtypes.length; i++) {
1400            result.add(allSubtypes[i].getCompilationUnit());
1401        }
1402        result.add(getDestinationType().getCompilationUnit());
1403        return (ICompilationUnit[]) result.toArray(new ICompilationUnit[result.size()]);
1404    }
1405
1406    public IType[] getCandidateTypes(final RefactoringStatus status, final IProgressMonitor monitor) throws JavaModelException {
1407        final IType declaring= getDeclaringType();
1408        final IType[] superTypes= declaring.newSupertypeHierarchy(fOwner, monitor).getAllSupertypes(declaring);
1409        final List JavaDoc list= new ArrayList JavaDoc(superTypes.length);
1410        int binary= 0;
1411        for (int index= 0; index < superTypes.length; index++) {
1412            final IType type= superTypes[index];
1413            if (type != null && type.exists() && !type.isReadOnly() && !type.isBinary() && !"java.lang.Object".equals(type.getFullyQualifiedName())) { //$NON-NLS-1$
1414
list.add(type);
1415            } else {
1416                if (type != null && type.isBinary()) {
1417                    binary++;
1418                }
1419            }
1420        }
1421        if (superTypes.length == 1 && superTypes[0].getFullyQualifiedName().equals("java.lang.Object")) //$NON-NLS-1$
1422
status.addFatalError(RefactoringCoreMessages.PullUPRefactoring_not_java_lang_object);
1423        else if (superTypes.length == binary)
1424            status.addFatalError(RefactoringCoreMessages.PullUPRefactoring_no_all_binary);
1425
1426        Collections.reverse(list);
1427        return (IType[]) list.toArray(new IType[list.size()]);
1428    }
1429
1430    protected CompilationUnitRewrite getCompilationUnitRewrite(final Map JavaDoc rewrites, final ICompilationUnit unit) {
1431        Assert.isNotNull(rewrites);
1432        Assert.isNotNull(unit);
1433        CompilationUnitRewrite rewrite= (CompilationUnitRewrite) rewrites.get(unit);
1434        if (rewrite == null) {
1435            rewrite= new CompilationUnitRewrite(fOwner, unit);
1436            rewrites.put(unit, rewrite);
1437        }
1438        return rewrite;
1439    }
1440
1441    private IMember[] getCreatedDestinationMembers() {
1442        final List JavaDoc result= new ArrayList JavaDoc(fMembersToMove.length + fAbstractMethods.length);
1443        result.addAll(Arrays.asList(fMembersToMove));
1444        result.addAll(Arrays.asList(fAbstractMethods));
1445        return (IMember[]) result.toArray(new IMember[result.size()]);
1446    }
1447
1448    public boolean getCreateMethodStubs() {
1449        return fCreateMethodStubs;
1450    }
1451
1452    public ITypeHierarchy getDeclaringSuperTypeHierarchy(final IProgressMonitor monitor) throws JavaModelException {
1453        try {
1454            if (fCachedDeclaringSuperTypeHierarchy != null)
1455                return fCachedDeclaringSuperTypeHierarchy;
1456            fCachedDeclaringSuperTypeHierarchy= getDeclaringType().newSupertypeHierarchy(fOwner, monitor);
1457            return fCachedDeclaringSuperTypeHierarchy;
1458        } finally {
1459            monitor.done();
1460        }
1461    }
1462
1463    public IType getDestinationType() {
1464        return fDestinationType;
1465    }
1466
1467    public ITypeHierarchy getDestinationTypeHierarchy(final IProgressMonitor monitor) throws JavaModelException {
1468        try {
1469            if (fCachedDestinationTypeHierarchy != null && fCachedDestinationTypeHierarchy.getType().equals(getDestinationType()))
1470                return fCachedDestinationTypeHierarchy;
1471            fCachedDestinationTypeHierarchy= getDestinationType().newTypeHierarchy(fOwner, monitor);
1472            return fCachedDestinationTypeHierarchy;
1473        } finally {
1474            monitor.done();
1475        }
1476    }
1477
1478    /**
1479     * {@inheritDoc}
1480     */

1481    public Object JavaDoc[] getElements() {
1482        return fMembersToMove;
1483    }
1484
1485    /**
1486     * {@inheritDoc}
1487     */

1488    public String JavaDoc getIdentifier() {
1489        return IDENTIFIER;
1490    }
1491
1492    public IMember[] getMatchingElements(final IProgressMonitor monitor, final boolean includeAbstract) throws JavaModelException {
1493        try {
1494            final Set JavaDoc result= new HashSet JavaDoc();
1495            final IType destination= getDestinationType();
1496            final Map JavaDoc matching= getMatchingMembers(getDestinationTypeHierarchy(monitor), getDestinationType(), includeAbstract);
1497            for (final Iterator JavaDoc iterator= matching.keySet().iterator(); iterator.hasNext();) {
1498                final IMember key= (IMember) iterator.next();
1499                Assert.isTrue(!key.getDeclaringType().equals(destination));
1500                result.addAll((Set JavaDoc) matching.get(key));
1501            }
1502            return (IMember[]) result.toArray(new IMember[result.size()]);
1503        } finally {
1504            monitor.done();
1505        }
1506    }
1507
1508    private Map JavaDoc getMatchingMembers(final ITypeHierarchy hierarchy, final IType type, final boolean includeAbstract) throws JavaModelException {
1509        final Map JavaDoc result= new HashMap JavaDoc();
1510        result.putAll(getMatchingMembersMapping(type));
1511        final IType[] subTypes= hierarchy.getAllSubtypes(type);
1512        for (int i= 0; i < subTypes.length; i++) {
1513            final Map JavaDoc map= getMatchingMembersMapping(subTypes[i]);
1514            mergeMaps(result, map);
1515            upgradeMap(result, map);
1516        }
1517        if (includeAbstract)
1518            return result;
1519
1520        for (int i= 0; i < fAbstractMethods.length; i++) {
1521            if (result.containsKey(fAbstractMethods[i]))
1522                result.remove(fAbstractMethods[i]);
1523        }
1524        return result;
1525    }
1526
1527    private Map JavaDoc getMatchingMembersMapping(final IType initial) throws JavaModelException {
1528        final Map JavaDoc result= new HashMap JavaDoc();
1529        final IMember[] members= getCreatedDestinationMembers();
1530        for (int i= 0; i < members.length; i++) {
1531            final IMember member= members[i];
1532            if (member instanceof IMethod) {
1533                final IMethod method= (IMethod) member;
1534                final IMethod found= MemberCheckUtil.findMethod(method, initial.getMethods());
1535                if (found != null)
1536                    addMatchingMember(result, method, found);
1537            } else if (member instanceof IField) {
1538                final IField field= (IField) member;
1539                final IField found= initial.getField(field.getElementName());
1540                if (found.exists())
1541                    addMatchingMember(result, field, found);
1542            } else if (member instanceof IType) {
1543                final IType type= (IType) member;
1544                final IType found= initial.getType(type.getElementName());
1545                if (found.exists())
1546                    addMatchingMember(result, type, found);
1547            } else
1548                Assert.isTrue(false);
1549        }
1550
1551        return result;
1552    }
1553
1554    private IMember[] getMembersToDelete(final IProgressMonitor monitor) throws JavaModelException {
1555        try {
1556            final IMember[] typesToDelete= getMembers(fMembersToMove, IJavaElement.TYPE);
1557            final IMember[] matchingElements= getMatchingElements(monitor, false);
1558            final IMember[] matchingFields= getMembers(matchingElements, IJavaElement.FIELD);
1559            return JavaElementUtil.merge(JavaElementUtil.merge(matchingFields, typesToDelete), fDeletedMethods);
1560        } finally {
1561            monitor.done();
1562        }
1563    }
1564
1565    private int getModifiersWithUpdatedVisibility(final IMember member, final int modifiers, final Map JavaDoc adjustments, final IProgressMonitor monitor, final boolean considerReferences, final RefactoringStatus status) throws JavaModelException {
1566        if (needsVisibilityAdjustment(member, considerReferences, monitor, status)) {
1567            final MemberVisibilityAdjustor.OutgoingMemberVisibilityAdjustment adjustment= new MemberVisibilityAdjustor.OutgoingMemberVisibilityAdjustment(member, Modifier.ModifierKeyword.PROTECTED_KEYWORD, RefactoringStatus.createWarningStatus(Messages.format(MemberVisibilityAdjustor.getMessage(member), new String JavaDoc[] { MemberVisibilityAdjustor.getLabel(member), MemberVisibilityAdjustor.getLabel(Modifier.ModifierKeyword.PROTECTED_KEYWORD)})));
1568            adjustment.setNeedsRewriting(false);
1569            adjustments.put(member, adjustment);
1570            return JdtFlags.clearAccessModifiers(modifiers) | Modifier.PROTECTED;
1571        }
1572        if (getDestinationType().isInterface()) {
1573            final int flags= JdtFlags.clearAccessModifiers(modifiers) | Modifier.PUBLIC;
1574            if (member instanceof IMethod)
1575                return JdtFlags.clearFlag(Modifier.STATIC, flags);
1576            return flags;
1577        }
1578        return modifiers;
1579    }
1580
1581    private Set JavaDoc getNotDeletedMembers(final IProgressMonitor monitor) throws JavaModelException {
1582        final Set JavaDoc matchingSet= new HashSet JavaDoc();
1583        monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, 2);
1584        matchingSet.addAll(Arrays.asList(getMatchingElements(new SubProgressMonitor(monitor, 1), true)));
1585        matchingSet.removeAll(Arrays.asList(getMembersToDelete(new SubProgressMonitor(monitor, 1))));
1586        monitor.done();
1587        return matchingSet;
1588    }
1589
1590    /**
1591     * {@inheritDoc}
1592     */

1593    public String JavaDoc getProcessorName() {
1594        return RefactoringCoreMessages.PullUpRefactoring_Pull_Up;
1595    }
1596
1597    public IMember[] getPullableMembersOfDeclaringType() {
1598        try {
1599            return RefactoringAvailabilityTester.getPullUpMembers(getDeclaringType());
1600        } catch (JavaModelException e) {
1601            return new IMember[0];
1602        }
1603    }
1604
1605    // skipped super classes are those declared in the hierarchy between the
1606
// declaring type of the selected members
1607
// and the target type
1608
private Set JavaDoc getSkippedSuperTypes(final IProgressMonitor monitor) throws JavaModelException {
1609        monitor.beginTask(RefactoringCoreMessages.PullUpRefactoring_checking, 1);
1610        try {
1611            if (fCachedSkippedSuperTypes != null && getDestinationTypeHierarchy(new SubProgressMonitor(monitor, 1)).getType().equals(getDestinationType()))
1612                return fCachedSkippedSuperTypes;
1613            final ITypeHierarchy hierarchy= getDestinationTypeHierarchy(new SubProgressMonitor(monitor, 1));
1614            fCachedSkippedSuperTypes= new HashSet JavaDoc(2);
1615            IType current= hierarchy.getSuperclass(getDeclaringType());
1616            while (current != null && !current.equals(getDestinationType())) {
1617                fCachedSkippedSuperTypes.add(current);
1618                current= hierarchy.getSuperclass(current);
1619            }
1620            return fCachedSkippedSuperTypes;
1621        } finally {
1622            monitor.done();
1623        }
1624    }
1625
1626    /**
1627     * {@inheritDoc}
1628     */

1629    public RefactoringStatus initialize(final RefactoringArguments arguments) {
1630        if (arguments instanceof JavaRefactoringArguments) {
1631            final JavaRefactoringArguments extended= (JavaRefactoringArguments) arguments;
1632            String JavaDoc handle= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_INPUT);
1633            if (handle != null) {
1634                final IJavaElement element= JDTRefactoringDescriptor.handleToElement(extended.getProject(), handle, false);
1635                if (element == null || !element.exists() || element.getElementType() != IJavaElement.TYPE)
1636                    return ScriptableRefactoring.createInputFatalStatus(element, getRefactoring().getName(), IJavaRefactorings.PULL_UP);
1637                else
1638                    fDestinationType= (IType) element;
1639            } else
1640                return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_INPUT));
1641            final String JavaDoc stubs= extended.getAttribute(ATTRIBUTE_STUBS);
1642            if (stubs != null) {
1643                fCreateMethodStubs= Boolean.valueOf(stubs).booleanValue();
1644            } else
1645                return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_STUBS));
1646            final String JavaDoc instance= extended.getAttribute(ATTRIBUTE_INSTANCEOF);
1647            if (instance != null) {
1648                fInstanceOf= Boolean.valueOf(instance).booleanValue();
1649            } else
1650                return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_INSTANCEOF));
1651            final String JavaDoc replace= extended.getAttribute(ATTRIBUTE_REPLACE);
1652            if (replace != null) {
1653                fReplace= Boolean.valueOf(replace).booleanValue();
1654            } else
1655                return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REPLACE));
1656            int pullCount= 0;
1657            int abstractCount= 0;
1658            int deleteCount= 0;
1659            String JavaDoc value= extended.getAttribute(ATTRIBUTE_ABSTRACT);
1660            if (value != null && !"".equals(value)) {//$NON-NLS-1$
1661
try {
1662                    abstractCount= Integer.parseInt(value);
1663                } catch (NumberFormatException JavaDoc exception) {
1664                    return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_ABSTRACT));
1665                }
1666            } else
1667                return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_ABSTRACT));
1668            value= extended.getAttribute(ATTRIBUTE_DELETE);
1669            if (value != null && !"".equals(value)) {//$NON-NLS-1$
1670
try {
1671                    deleteCount= Integer.parseInt(value);
1672                } catch (NumberFormatException JavaDoc exception) {
1673                    return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_DELETE));
1674                }
1675            } else
1676                return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_DELETE));
1677            value= extended.getAttribute(ATTRIBUTE_PULL);
1678            if (value != null && !"".equals(value)) {//$NON-NLS-1$
1679
try {
1680                    pullCount= Integer.parseInt(value);
1681                } catch (NumberFormatException JavaDoc exception) {
1682                    return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_PULL));
1683                }
1684            } else
1685                return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_PULL));
1686            final RefactoringStatus status= new RefactoringStatus();
1687            List JavaDoc elements= new ArrayList JavaDoc();
1688            for (int index= 0; index < pullCount; index++) {
1689                final String JavaDoc attribute= JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (index + 1);
1690                handle= extended.getAttribute(attribute);
1691                if (handle != null && !"".equals(handle)) { //$NON-NLS-1$
1692
final IJavaElement element= JDTRefactoringDescriptor.handleToElement(extended.getProject(), handle, false);
1693                    if (element == null || !element.exists())
1694                        status.merge(ScriptableRefactoring.createInputWarningStatus(element, getRefactoring().getName(), IJavaRefactorings.PULL_UP));
1695                    else
1696                        elements.add(element);
1697                } else
1698                    return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, attribute));
1699            }
1700            fMembersToMove= (IMember[]) elements.toArray(new IMember[elements.size()]);
1701            elements= new ArrayList JavaDoc();
1702            for (int index= 0; index < deleteCount; index++) {
1703                final String JavaDoc attribute= JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (pullCount + index + 1);
1704                handle= extended.getAttribute(attribute);
1705                if (handle != null && !"".equals(handle)) { //$NON-NLS-1$
1706
final IJavaElement element= JDTRefactoringDescriptor.handleToElement(extended.getProject(), handle, false);
1707                    if (element == null || !element.exists())
1708                        status.merge(ScriptableRefactoring.createInputWarningStatus(element, getRefactoring().getName(), IJavaRefactorings.PULL_UP));
1709                    else
1710                        elements.add(element);
1711                } else
1712                    return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, attribute));
1713            }
1714            fDeletedMethods= (IMethod[]) elements.toArray(new IMethod[elements.size()]);
1715            elements= new ArrayList JavaDoc();
1716            for (int index= 0; index < abstractCount; index++) {
1717                final String JavaDoc attribute= JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (pullCount + abstractCount + index + 1);
1718                handle= extended.getAttribute(attribute);
1719                if (handle != null && !"".equals(handle)) { //$NON-NLS-1$
1720
final IJavaElement element= JDTRefactoringDescriptor.handleToElement(extended.getProject(), handle, false);
1721                    if (element == null || !element.exists())
1722                        status.merge(ScriptableRefactoring.createInputWarningStatus(element, getRefactoring().getName(), IJavaRefactorings.PULL_UP));
1723                    else
1724                        elements.add(element);
1725                } else
1726                    return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, attribute));
1727            }
1728            fAbstractMethods= (IMethod[]) elements.toArray(new IMethod[elements.size()]);
1729            IJavaProject project= null;
1730            if (fMembersToMove.length > 0)
1731                project= fMembersToMove[0].getJavaProject();
1732            fSettings= JavaPreferencesSettings.getCodeGenerationSettings(project);
1733            if (!status.isOK())
1734                return status;
1735        } else
1736            return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments);
1737        return new RefactoringStatus();
1738    }
1739
1740    /**
1741     * {@inheritDoc}
1742     */

1743    public boolean isApplicable() throws CoreException {
1744        return RefactoringAvailabilityTester.isPullUpAvailable(fMembersToMove);
1745    }
1746
1747    private boolean isAvailableInDestination(final IMethod method, final IProgressMonitor monitor) throws JavaModelException {
1748        try {
1749            final IType destination= getDestinationType();
1750            final IMethod first= JavaModelUtil.findMethod(method.getElementName(), method.getParameterTypes(), false, destination);
1751            if (first != null && MethodChecks.isVirtual(first))
1752                return true;
1753            final ITypeHierarchy hierarchy= getDestinationTypeHierarchy(monitor);
1754            final IMethod found= JavaModelUtil.findMethodInHierarchy(hierarchy, destination, method.getElementName(), method.getParameterTypes(), false);
1755            return found != null && MethodChecks.isVirtual(found);
1756        } finally {
1757            monitor.done();
1758        }
1759    }
1760
1761    private boolean isRequiredPullableMember(final List JavaDoc queue, final IMember member) throws JavaModelException {
1762        final IType declaring= member.getDeclaringType();
1763        if (declaring == null) // not a member
1764
return false;
1765        return declaring.equals(getDeclaringType()) && !queue.contains(member) && RefactoringAvailabilityTester.isPullUpAvailable(member);
1766    }
1767
1768    protected void registerChanges(final TextEditBasedChangeManager manager) throws CoreException {
1769        ICompilationUnit unit= null;
1770        CompilationUnitRewrite rewrite= null;
1771        for (final Iterator JavaDoc iterator= fCompilationUnitRewrites.keySet().iterator(); iterator.hasNext();) {
1772            unit= (ICompilationUnit) iterator.next();
1773            rewrite= (CompilationUnitRewrite) fCompilationUnitRewrites.get(unit);
1774            if (rewrite != null) {
1775                final CompilationUnitChange change= rewrite.createChange();
1776                if (change != null)
1777                    manager.manage(unit, change);
1778            }
1779        }
1780    }
1781
1782    /**
1783     * Resets the environment before the first wizard page becomes visible.
1784     */

1785    public void resetEnvironment() {
1786        ICompilationUnit unit= getDeclaringType().getCompilationUnit();
1787        if (fLayer)
1788            unit= unit.findWorkingCopy(fOwner);
1789        resetWorkingCopies(unit);
1790    }
1791
1792    /**
1793     * {@inheritDoc}
1794     */

1795    protected void rewriteTypeOccurrences(final TextEditBasedChangeManager manager, final ASTRequestor requestor, final CompilationUnitRewrite rewrite, final ICompilationUnit unit, final CompilationUnit node, final Set JavaDoc replacements, final IProgressMonitor monitor) throws CoreException {
1796        try {
1797            monitor.beginTask("", 100); //$NON-NLS-1$
1798
monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating);
1799            CompilationUnitRewrite currentRewrite= null;
1800            final CompilationUnitRewrite existingRewrite= (CompilationUnitRewrite) fCompilationUnitRewrites.get(unit.getPrimary());
1801            final boolean isTouched= existingRewrite != null;
1802            if (isTouched)
1803                currentRewrite= existingRewrite;
1804            else
1805                currentRewrite= new CompilationUnitRewrite(unit, node);
1806            final Collection JavaDoc collection= (Collection JavaDoc) fTypeOccurrences.get(unit);
1807            if (collection != null && !collection.isEmpty()) {
1808                final IProgressMonitor subMonitor= new SubProgressMonitor(monitor, 100);
1809                try {
1810                    subMonitor.beginTask("", collection.size() * 10); //$NON-NLS-1$
1811
subMonitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating);
1812                    TType estimate= null;
1813                    ISourceConstraintVariable variable= null;
1814                    ITypeConstraintVariable constraint= null;
1815                    for (final Iterator JavaDoc iterator= collection.iterator(); iterator.hasNext();) {
1816                        variable= (ISourceConstraintVariable) iterator.next();
1817                        if (variable instanceof ITypeConstraintVariable) {
1818                            constraint= (ITypeConstraintVariable) variable;
1819                            estimate= (TType) constraint.getData(SuperTypeConstraintsSolver.DATA_TYPE_ESTIMATE);
1820                            if (estimate != null) {
1821                                final CompilationUnitRange range= constraint.getRange();
1822                                if (isTouched)
1823                                    rewriteTypeOccurrence(range, estimate, requestor, currentRewrite, node, replacements, currentRewrite.createCategorizedGroupDescription(RefactoringCoreMessages.SuperTypeRefactoringProcessor_update_type_occurrence, SET_SUPER_TYPE));
1824                                else {
1825                                    final ASTNode result= NodeFinder.perform(node, range.getSourceRange());
1826                                    if (result != null)
1827                                        rewriteTypeOccurrence(estimate, currentRewrite, result, currentRewrite.createCategorizedGroupDescription(RefactoringCoreMessages.SuperTypeRefactoringProcessor_update_type_occurrence, SET_SUPER_TYPE));
1828                                }
1829                                subMonitor.worked(10);
1830                            }
1831                        }
1832                    }
1833                } finally {
1834                    subMonitor.done();
1835                }
1836            }
1837            if (!isTouched) {
1838                final TextChange change= currentRewrite.createChange();
1839                if (change != null)
1840                    manager.manage(unit, change);
1841            }
1842        } finally {
1843            monitor.done();
1844        }
1845    }
1846
1847    protected void rewriteTypeOccurrences(final TextEditBasedChangeManager manager, final CompilationUnitRewrite sourceRewrite, final ICompilationUnit copy, final Set JavaDoc replacements, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
1848        try {
1849            monitor.beginTask("", 100); //$NON-NLS-1$
1850
monitor.setTaskName(RefactoringCoreMessages.PullUpRefactoring_checking);
1851            final IType declaring= getDeclaringType();
1852            final IJavaProject project= declaring.getJavaProject();
1853            final ASTParser parser= ASTParser.newParser(AST.JLS3);
1854            parser.setWorkingCopyOwner(fOwner);
1855            parser.setResolveBindings(true);
1856            parser.setProject(project);
1857            parser.setCompilerOptions(RefactoringASTParser.getCompilerOptions(project));
1858            parser.createASTs(new ICompilationUnit[] { copy}, new String JavaDoc[0], new ASTRequestor() {
1859
1860                public final void acceptAST(final ICompilationUnit unit, final CompilationUnit node) {
1861                    try {
1862                        final IType subType= (IType) JavaModelUtil.findInCompilationUnit(unit, declaring);
1863                        final AbstractTypeDeclaration subDeclaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(subType, node);
1864                        if (subDeclaration != null) {
1865                            final ITypeBinding subBinding= subDeclaration.resolveBinding();
1866                            if (subBinding != null) {
1867                                String JavaDoc name= null;
1868                                ITypeBinding superBinding= null;
1869                                final ITypeBinding[] superBindings= Bindings.getAllSuperTypes(subBinding);
1870                                for (int index= 0; index < superBindings.length; index++) {
1871                                    name= superBindings[index].getName();
1872                                    if (name.startsWith(fDestinationType.getElementName()))
1873                                        superBinding= superBindings[index];
1874                                }
1875                                if (superBinding != null) {
1876                                    solveSuperTypeConstraints(unit, node, subType, subBinding, superBinding, new SubProgressMonitor(monitor, 80), status);
1877                                    if (!status.hasFatalError())
1878                                        rewriteTypeOccurrences(manager, this, sourceRewrite, unit, node, replacements, status, new SubProgressMonitor(monitor, 120));
1879                                }
1880                            }
1881                        }
1882                    } catch (JavaModelException exception) {
1883                        JavaPlugin.log(exception);
1884                        status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error));
1885                    }
1886                }
1887
1888                public final void acceptBinding(final String JavaDoc key, final IBinding binding) {
1889                    // Do nothing
1890
}
1891            }, new NullProgressMonitor());
1892        } finally {
1893            monitor.done();
1894        }
1895    }
1896
1897    /**
1898     * Sets the methods to declare abstract.
1899     *
1900     * @param methods
1901     * the methods to declare abstract
1902     */

1903    public void setAbstractMethods(final IMethod[] methods) {
1904        Assert.isNotNull(methods);
1905        fAbstractMethods= methods;
1906    }
1907
1908    /**
1909     * Determines whether to create method stubs for non-implemented abstract
1910     * methods.
1911     *
1912     * @param create
1913     * <code>true</code> to create stubs, <code>false</code>
1914     * otherwise
1915     */

1916    public void setCreateMethodStubs(final boolean create) {
1917        fCreateMethodStubs= create;
1918    }
1919
1920    /**
1921     * Sets the methods to delete
1922     *
1923     * @param methods
1924     * the methods to delete
1925     */

1926    public void setDeletedMethods(final IMethod[] methods) {
1927        Assert.isNotNull(methods);
1928        fDeletedMethods= methods;
1929    }
1930
1931    /**
1932     * Sets the destination type.
1933     *
1934     * @param type
1935     * the destination type
1936     */

1937    public void setDestinationType(final IType type) {
1938        Assert.isNotNull(type);
1939        if (!type.equals(fDestinationType))
1940            fCachedDestinationTypeHierarchy= null;
1941        fDestinationType= type;
1942    }
1943
1944    /**
1945     * Sets the members to move.
1946     *
1947     * @param members
1948     * the members to move
1949     */

1950    public void setMembersToMove(final IMember[] members) {
1951        Assert.isNotNull(members);
1952        fMembersToMove= (IMember[]) SourceReferenceUtil.sortByOffset(members);
1953    }
1954}
1955
Popular Tags