1 /*******************************************************************************
2 * Copyright (c) 2000, 2012 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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.corext.refactoring.structure;
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.Collection;
16 import java.util.Comparator;
17 import java.util.HashMap;
18 import java.util.HashSet;
19 import java.util.Iterator;
20 import java.util.List;
24 import org.eclipse.core.runtime.Assert;
25 import org.eclipse.core.runtime.CoreException;
26 import org.eclipse.core.runtime.IProgressMonitor;
27 import org.eclipse.core.runtime.NullProgressMonitor;
28 import org.eclipse.core.runtime.OperationCanceledException;
29 import org.eclipse.core.runtime.SubProgressMonitor;
31 import org.eclipse.core.resources.IFile;
33 import org.eclipse.core.filebuffers.ITextFileBuffer;
35 import org.eclipse.text.edits.MalformedTreeException;
36 import org.eclipse.text.edits.TextEdit;
38 import org.eclipse.jface.text.BadLocationException;
39 import org.eclipse.jface.text.Document;
40 import org.eclipse.jface.text.IDocument;
42 import org.eclipse.ltk.core.refactoring.Change;
43 import org.eclipse.ltk.core.refactoring.GroupCategory;
44 import org.eclipse.ltk.core.refactoring.GroupCategorySet;
45 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
46 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
47 import org.eclipse.ltk.core.refactoring.TextChange;
48 import org.eclipse.ltk.core.refactoring.TextEditBasedChange;
49 import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
50 import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
51 import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
53 import org.eclipse.jdt.core.ICompilationUnit;
54 import org.eclipse.jdt.core.IField;
55 import org.eclipse.jdt.core.IJavaElement;
56 import org.eclipse.jdt.core.IJavaProject;
57 import org.eclipse.jdt.core.IMember;
58 import org.eclipse.jdt.core.IMethod;
59 import org.eclipse.jdt.core.IPackageFragment;
60 import org.eclipse.jdt.core.IType;
61 import org.eclipse.jdt.core.ITypeParameter;
62 import org.eclipse.jdt.core.JavaCore;
63 import org.eclipse.jdt.core.JavaModelException;
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.Annotation;
70 import org.eclipse.jdt.core.dom.CompilationUnit;
71 import org.eclipse.jdt.core.dom.EnumDeclaration;
72 import org.eclipse.jdt.core.dom.FieldDeclaration;
73 import org.eclipse.jdt.core.dom.IBinding;
74 import org.eclipse.jdt.core.dom.IExtendedModifier;
75 import org.eclipse.jdt.core.dom.IMethodBinding;
76 import org.eclipse.jdt.core.dom.ITypeBinding;
77 import org.eclipse.jdt.core.dom.IVariableBinding;
78 import org.eclipse.jdt.core.dom.MethodDeclaration;
79 import org.eclipse.jdt.core.dom.Modifier;
80 import org.eclipse.jdt.core.dom.NodeFinder;
81 import org.eclipse.jdt.core.dom.ParameterizedType;
82 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
83 import org.eclipse.jdt.core.dom.Type;
84 import org.eclipse.jdt.core.dom.TypeDeclaration;
85 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
86 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
87 import org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition;
88 import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
89 import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
90 import org.eclipse.jdt.core.refactoring.descriptors.ExtractInterfaceDescriptor;
91 import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
93 import org.eclipse.jdt.internal.core.refactoring.descriptors.RefactoringSignatureDescriptorFactory;
94 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
95 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
96 import org.eclipse.jdt.internal.corext.dom.Bindings;
97 import org.eclipse.jdt.internal.corext.dom.ModifierRewrite;
98 import org.eclipse.jdt.internal.corext.refactoring.Checks;
99 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
100 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
101 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil;
102 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
103 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
104 import org.eclipse.jdt.internal.corext.refactoring.changes.CreateCompilationUnitChange;
105 import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
106 import org.eclipse.jdt.internal.corext.refactoring.reorg.ASTNodeDeleteUtil;
107 import org.eclipse.jdt.internal.corext.refactoring.structure.constraints.SuperTypeConstraintsModel;
108 import org.eclipse.jdt.internal.corext.refactoring.structure.constraints.SuperTypeConstraintsSolver;
109 import org.eclipse.jdt.internal.corext.refactoring.structure.constraints.SuperTypeRefactoringProcessor;
110 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.CompilationUnitRange;
111 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType;
112 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ISourceConstraintVariable;
113 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeConstraintVariable;
114 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
115 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringFileBuffers;
116 import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
117 import org.eclipse.jdt.internal.corext.refactoring.util.TextEditBasedChangeManager;
118 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
119 import org.eclipse.jdt.internal.corext.util.JdtFlags;
120 import org.eclipse.jdt.internal.corext.util.Messages;
121 import org.eclipse.jdt.internal.corext.util.Strings;
123 import org.eclipse.jdt.ui.CodeGeneration;
124 import org.eclipse.jdt.ui.JavaElementLabels;
126 import org.eclipse.jdt.internal.ui.JavaPlugin;
127 import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
128 import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
129 import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
133 * Refactoring processor to extract interfaces.
135 public final class ExtractInterfaceProcessor extends SuperTypeRefactoringProcessor {
137 private static final String ATTRIBUTE_ABSTRACT= "abstract"; //$NON-NLS-1$
139 private static final String ATTRIBUTE_COMMENTS= "comments"; //$NON-NLS-1$
141 private static final String ATTRIBUTE_PUBLIC= "public"; //$NON-NLS-1$
143 /** The identifier of this processor */
144 public static final String IDENTIFIER= "org.eclipse.jdt.ui.extractInterfaceProcessor"; //$NON-NLS-1$
146 /** The extract interface group category set */
147 private static final GroupCategorySet SET_EXTRACT_INTERFACE= new GroupCategorySet(new GroupCategory("org.eclipse.jdt.internal.corext.extractInterface", //$NON-NLS-1$
148 RefactoringCoreMessages.ExtractInterfaceProcessor_category_name, RefactoringCoreMessages.ExtractInterfaceProcessor_category_description));
151 * Is the specified member extractable from the type?
155 * @return <code>true</code> if the member is extractable,
156 * <code>false</code> otherwise
157 * @throws JavaModelException
160 protected static boolean isExtractableMember(final IMember member) throws JavaModelException {
161 Assert.isNotNull(member);
162 switch (member.getElementType()) {
163 case IJavaElement.METHOD:
164 return JdtFlags.isPublic(member) && !JdtFlags.isStatic(member) && !((IMethod) member).isConstructor();
165 case IJavaElement.FIELD:
166 return JdtFlags.isPublic(member) && JdtFlags.isStatic(member) && JdtFlags.isFinal(member) && !JdtFlags.isEnum(member);
172 /** Should extracted methods be declared as abstract? */
173 private boolean fAbstract= true;
175 /** Should override annotations be generated? */
176 private boolean fAnnotations= false;
178 /** The text edit based change manager */
179 private TextEditBasedChangeManager fChangeManager= null;
181 /** Should comments be generated? */
182 private boolean fComments= true;
184 /** The members to extract */
185 private IMember[] fMembers= null;
187 /** Should extracted methods be declared as public? */
188 private boolean fPublic= true;
190 /** The subtype where to extract the supertype */
191 private IType fSubType;
193 /** The supertype name */
194 private String fSuperName;
196 /** The source of the new supertype */
197 private String fSuperSource= null;
200 * Creates a new extract interface processor.
203 * the type where to extract the supertype, or <code>null</code>
204 * if invoked by scripting
206 * the code generation settings, or <code>null</code> if
207 * invoked by scripting
209 public ExtractInterfaceProcessor(final IType type, final CodeGenerationSettings settings) {
212 if (fSubType != null)
213 fSuperName= fSubType.getElementName();
217 * Creates a new extract interface processor from refactoring arguments.
220 * the refactoring arguments
222 * the resulting status
224 public ExtractInterfaceProcessor(JavaRefactoringArguments arguments, RefactoringStatus status) {
226 RefactoringStatus initializeStatus= initialize(arguments);
227 status.merge(initializeStatus);
231 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#checkFinalConditions(org.eclipse.core.runtime.IProgressMonitor,org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext)
234 public final RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, final CheckConditionsContext context) throws CoreException, OperationCanceledException {
235 Assert.isNotNull(monitor);
236 Assert.isNotNull(context);
237 final RefactoringStatus status= new RefactoringStatus();
238 fChangeManager= new TextEditBasedChangeManager();
240 monitor.beginTask("", 1); //$NON-NLS-1$
241 monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_checking);
242 status.merge(Checks.checkIfCuBroken(fSubType));
243 if (!status.hasError()) {
244 if (fSubType.isBinary() || fSubType.isReadOnly() || !fSubType.exists())
245 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_no_binary, JavaStatusContext.create(fSubType)));
246 else if (fSubType.isAnonymous())
247 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_no_anonymous, JavaStatusContext.create(fSubType)));
248 else if (fSubType.isAnnotation())
249 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_no_annotation, JavaStatusContext.create(fSubType)));
251 status.merge(checkSuperType());
252 if (!status.hasFatalError()) {
253 if (!status.hasFatalError()) {
254 fChangeManager= createChangeManager(new SubProgressMonitor(monitor, 1), status);
255 if (!status.hasFatalError()) {
256 Checks.addModifiedFilesToChecker(ResourceUtil.getFiles(fChangeManager.getAllCompilationUnits()), context);
269 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor)
272 public final RefactoringStatus checkInitialConditions(final IProgressMonitor monitor) throws CoreException, OperationCanceledException {
273 Assert.isNotNull(monitor);
274 final RefactoringStatus status= new RefactoringStatus();
276 monitor.beginTask("", 1); //$NON-NLS-1$
277 monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_checking);
278 status.merge(Checks.checkIfCuBroken(fSubType));
287 * Checks whether the supertype clashes with existing types.
289 * @return the status of the condition checking
290 * @throws JavaModelException
293 protected final RefactoringStatus checkSuperType() throws JavaModelException {
294 final IPackageFragment fragment= fSubType.getPackageFragment();
295 final IType type= Checks.findTypeInPackage(fragment, fSuperName);
296 if (type != null && type.exists()) {
297 if (fragment.isDefaultPackage())
298 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.ExtractInterfaceProcessor_existing_default_type, BasicElementLabels.getJavaElementName(fSuperName)));
300 String packageLabel= JavaElementLabels.getElementLabel(fragment, JavaElementLabels.ALL_DEFAULT);
301 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.ExtractInterfaceProcessor_existing_type, new String[] { BasicElementLabels.getJavaElementName(fSuperName), packageLabel }));
304 return new RefactoringStatus();
308 * Checks whether the type name is valid.
312 * @return the status of the condition checking
314 public final RefactoringStatus checkTypeName(final String name) {
315 Assert.isNotNull(name);
317 final RefactoringStatus result= Checks.checkTypeName(name, fSubType);
318 if (result.hasFatalError())
320 final String unitName= JavaModelUtil.getRenamedCUName(fSubType.getCompilationUnit(), name);
321 result.merge(Checks.checkCompilationUnitName(unitName, fSubType));
322 if (result.hasFatalError())
324 final IPackageFragment fragment= fSubType.getPackageFragment();
325 if (fragment.getCompilationUnit(unitName).exists()) {
326 result.addFatalError(Messages.format(RefactoringCoreMessages.ExtractInterfaceProcessor_existing_compilation_unit, new String[] { BasicElementLabels.getResourceName(unitName), JavaElementLabels.getElementLabel(fragment, JavaElementLabels.ALL_DEFAULT) }));
329 result.merge(checkSuperType());
331 } catch (JavaModelException exception) {
332 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error);
337 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#createChange(org.eclipse.core.runtime.IProgressMonitor)
340 public final Change createChange(final IProgressMonitor monitor) throws CoreException, OperationCanceledException {
341 Assert.isNotNull(monitor);
343 monitor.beginTask("", 1); //$NON-NLS-1$
344 monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating);
345 final Map<String, String> arguments= new HashMap<String, String>();
346 String project= null;
347 final IJavaProject javaProject= fSubType.getJavaProject();
348 if (javaProject != null)
349 project= javaProject.getElementName();
350 int flags= JavaRefactoringDescriptor.JAR_MIGRATION | JavaRefactoringDescriptor.JAR_REFACTORING | RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE;
352 if (fSubType.isLocal() || fSubType.isAnonymous())
353 flags|= JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
354 } catch (JavaModelException exception) {
355 JavaPlugin.log(exception);
357 final IPackageFragment fragment= fSubType.getPackageFragment();
358 final ICompilationUnit cu= fragment.getCompilationUnit(JavaModelUtil.getRenamedCUName(fSubType.getCompilationUnit(), fSuperName));
359 final IType type= cu.getType(fSuperName);
360 final String description= Messages.format(RefactoringCoreMessages.ExtractInterfaceProcessor_description_descriptor_short, BasicElementLabels.getJavaElementName(fSuperName));
361 final String header= Messages.format(RefactoringCoreMessages.ExtractInterfaceProcessor_descriptor_description, new String[] { JavaElementLabels.getElementLabel(type, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getElementLabel(fSubType, JavaElementLabels.ALL_FULLY_QUALIFIED) });
362 final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header);
363 comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractInterfaceProcessor_refactored_element_pattern, JavaElementLabels.getElementLabel(type, JavaElementLabels.ALL_FULLY_QUALIFIED)));
364 final String[] settings= new String[fMembers.length];
365 for (int index= 0; index < settings.length; index++)
366 settings[index]= JavaElementLabels.getElementLabel(fMembers[index], JavaElementLabels.ALL_FULLY_QUALIFIED);
367 comment.addSetting(JDTRefactoringDescriptorComment.createCompositeSetting(RefactoringCoreMessages.ExtractInterfaceProcessor_extracted_members_pattern, settings));
368 addSuperTypeSettings(comment, true);
369 final ExtractInterfaceDescriptor descriptor= RefactoringSignatureDescriptorFactory.createExtractInterfaceDescriptor(project, description, comment.asString(), arguments, flags);
370 arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT, JavaRefactoringDescriptorUtil.elementToHandle(project, fSubType));
371 arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME, fSuperName);
372 for (int index= 0; index < fMembers.length; index++)
373 arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_ELEMENT + (index + 1), JavaRefactoringDescriptorUtil.elementToHandle(project, fMembers[index]));
374 arguments.put(ATTRIBUTE_ABSTRACT, Boolean.valueOf(fAbstract).toString());
375 arguments.put(ATTRIBUTE_COMMENTS, Boolean.valueOf(fComments).toString());
376 arguments.put(ATTRIBUTE_PUBLIC, Boolean.valueOf(fPublic).toString());
377 arguments.put(ATTRIBUTE_REPLACE, Boolean.valueOf(fReplace).toString());
378 arguments.put(ATTRIBUTE_INSTANCEOF, Boolean.valueOf(fInstanceOf).toString());
379 final DynamicValidationRefactoringChange change= new DynamicValidationRefactoringChange(descriptor, RefactoringCoreMessages.ExtractInterfaceRefactoring_name, fChangeManager.getAllChanges());
380 final IFile file= ResourceUtil.getFile(fSubType.getCompilationUnit());
381 if (fSuperSource != null && fSuperSource.length() > 0)
382 change.add(new CreateCompilationUnitChange(fSubType.getPackageFragment().getCompilationUnit(JavaModelUtil.getRenamedCUName(fSubType.getCompilationUnit(), fSuperName)), fSuperSource, file.getCharset(false)));
391 * Creates the text change manager for this processor.
394 * the progress monitor to display progress
396 * the refactoring status
397 * @return the created text change manager
398 * @throws JavaModelException
399 * if the method declaration could not be found
400 * @throws CoreException
401 * if the changes could not be generated
403 protected final TextEditBasedChangeManager createChangeManager(final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException, CoreException {
404 Assert.isNotNull(status);
405 Assert.isNotNull(monitor);
407 monitor.beginTask("", 300); //$NON-NLS-1$
408 monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating);
410 final TextEditBasedChangeManager manager= new TextEditBasedChangeManager();
411 final CompilationUnitRewrite sourceRewrite= new CompilationUnitRewrite(fSubType.getCompilationUnit());
412 final AbstractTypeDeclaration declaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(fSubType, sourceRewrite.getRoot());
413 if (declaration != null) {
414 createTypeSignature(sourceRewrite, declaration, status, new SubProgressMonitor(monitor, 20));
415 final IField[] fields= getExtractedFields(fSubType.getCompilationUnit());
416 if (fields.length > 0)
417 ASTNodeDeleteUtil.markAsDeleted(fields, sourceRewrite, sourceRewrite.createCategorizedGroupDescription(RefactoringCoreMessages.ExtractInterfaceProcessor_remove_field_label, SET_EXTRACT_INTERFACE));
418 if (fSubType.isInterface()) {
419 final IMethod[] methods= getExtractedMethods(fSubType.getCompilationUnit());
420 if (methods.length > 0)
421 ASTNodeDeleteUtil.markAsDeleted(methods, sourceRewrite, sourceRewrite.createCategorizedGroupDescription(RefactoringCoreMessages.ExtractInterfaceProcessor_remove_method_label, SET_EXTRACT_INTERFACE));
423 final String name= JavaModelUtil.getRenamedCUName(fSubType.getCompilationUnit(), fSuperName);
424 final ICompilationUnit original= fSubType.getPackageFragment().getCompilationUnit(name);
425 final ICompilationUnit copy= getSharedWorkingCopy(original.getPrimary(), new SubProgressMonitor(monitor, 20));
426 fSuperSource= createTypeSource(copy, fSubType, fSuperName, sourceRewrite, declaration, status, new SubProgressMonitor(monitor, 40));
427 if (fSuperSource != null) {
428 copy.getBuffer().setContents(fSuperSource);
429 JavaModelUtil.reconcile(copy);
431 final Set<String> replacements= new HashSet<String>();
433 rewriteTypeOccurrences(manager, sourceRewrite, copy, replacements, status, new SubProgressMonitor(monitor, 220));
434 createMethodComments(sourceRewrite, replacements);
435 manager.manage(fSubType.getCompilationUnit(), sourceRewrite.createChange(true));
444 * @see org.eclipse.jdt.internal.corext.refactoring.structure.constraints.SuperTypeRefactoringProcessor#createContraintSolver(org.eclipse.jdt.internal.corext.refactoring.structure.constraints.SuperTypeConstraintsModel)
447 protected final SuperTypeConstraintsSolver createContraintSolver(final SuperTypeConstraintsModel model) {
448 return new ExtractInterfaceConstraintsSolver(model, fSuperName);
452 * Creates a target field declaration.
454 * @param sourceRewrite
455 * the source compilation unit rewrite
456 * @param targetRewrite
458 * @param targetDeclaration
459 * the target type declaration
461 * the source variable declaration fragment
462 * @throws CoreException
463 * if a buffer could not be retrieved
465 protected final void createFieldDeclaration(final CompilationUnitRewrite sourceRewrite, final ASTRewrite targetRewrite, final AbstractTypeDeclaration targetDeclaration, final VariableDeclarationFragment fragment) throws CoreException {
466 Assert.isNotNull(targetDeclaration);
467 Assert.isNotNull(sourceRewrite);
468 Assert.isNotNull(targetRewrite);
469 Assert.isNotNull(fragment);
470 final FieldDeclaration field= (FieldDeclaration) fragment.getParent();
471 ImportRewriteUtil.collectImports(fSubType.getJavaProject(), field, fTypeBindings, fStaticBindings, false);
472 final ASTRewrite rewrite= ASTRewrite.create(field.getAST());
473 final ITrackedNodePosition position= rewrite.track(field);
474 final ListRewrite rewriter= rewrite.getListRewrite(field, FieldDeclaration.FRAGMENTS_PROPERTY);
475 VariableDeclarationFragment current= null;
476 for (final Iterator<VariableDeclarationFragment> iterator= field.fragments().iterator(); iterator.hasNext();) {
477 current= iterator.next();
478 if (!current.getName().getIdentifier().equals(fragment.getName().getIdentifier()))
479 rewriter.remove(current, null);
481 final ICompilationUnit unit= sourceRewrite.getCu();
482 final ITextFileBuffer buffer= RefactoringFileBuffers.acquire(unit);
484 final IDocument document= new Document(buffer.getDocument().get());
486 rewrite.rewriteAST(document, unit.getJavaProject().getOptions(true)).apply(document, TextEdit.UPDATE_REGIONS);
487 targetRewrite.getListRewrite(targetDeclaration, targetDeclaration.getBodyDeclarationsProperty()).insertFirst(targetRewrite.createStringPlaceholder(normalizeText(document.get(position.getStartPosition(), position.getLength())), ASTNode.FIELD_DECLARATION), null);
488 } catch (MalformedTreeException exception) {
489 JavaPlugin.log(exception);
490 } catch (BadLocationException exception) {
491 JavaPlugin.log(exception);
494 RefactoringFileBuffers.release(unit);
502 protected final void createMemberDeclarations(final CompilationUnitRewrite sourceRewrite, final ASTRewrite targetRewrite, final AbstractTypeDeclaration targetDeclaration) throws CoreException {
503 Assert.isNotNull(sourceRewrite);
504 Assert.isNotNull(targetRewrite);
505 Assert.isNotNull(targetDeclaration);
506 Arrays.sort(fMembers, new Comparator<IMember>() {
508 public final int compare(final IMember first, final IMember second) {
510 return first.getSourceRange().getOffset() - second.getSourceRange().getOffset();
511 } catch (JavaModelException exception) {
512 return first.hashCode() - second.hashCode();
516 fTypeBindings.clear();
517 fStaticBindings.clear();
518 if (fMembers.length > 0) {
519 IMember member= null;
520 for (int index= fMembers.length - 1; index >= 0; index--) {
521 member= fMembers[index];
522 if (member instanceof IField) {
523 createFieldDeclaration(sourceRewrite, targetRewrite, targetDeclaration, ASTNodeSearchUtil.getFieldDeclarationFragmentNode((IField) member, sourceRewrite.getRoot()));
524 } else if (member instanceof IMethod) {
525 createMethodDeclaration(sourceRewrite, targetRewrite, targetDeclaration, ASTNodeSearchUtil.getMethodDeclarationNode((IMethod) member, sourceRewrite.getRoot()));
532 * Creates the method comment for the specified declaration.
534 * @param sourceRewrite
535 * the compilation unit rewrite
537 * the method declaration
538 * @param replacements
539 * the set of variable binding keys of formal parameters which
542 * <code>true</code> if javadoc comments are processed,
543 * <code>false</code> otherwise
544 * @throws CoreException
547 protected final void createMethodComment(final CompilationUnitRewrite sourceRewrite, final MethodDeclaration declaration, final Set<String> replacements, final boolean javadoc) throws CoreException {
548 Assert.isNotNull(sourceRewrite);
549 Assert.isNotNull(declaration);
550 Assert.isNotNull(replacements);
551 final IMethodBinding binding= declaration.resolveBinding();
552 if (binding != null) {
553 IVariableBinding variable= null;
554 SingleVariableDeclaration argument= null;
555 final IPackageFragment fragment= fSubType.getPackageFragment();
556 final String string= fragment.isDefaultPackage() ? fSuperName : fragment.getElementName() + "." + fSuperName; //$NON-NLS-1$
557 final ITypeBinding[] bindings= binding.getParameterTypes();
558 final String[] names= new String[bindings.length];
559 for (int offset= 0; offset < names.length; offset++) {
560 argument= (SingleVariableDeclaration) declaration.parameters().get(offset);
561 variable= argument.resolveBinding();
562 if (variable != null) {
563 if (replacements.contains(variable.getKey()))
564 names[offset]= string;
566 if (binding.isVarargs() && bindings[offset].isArray() && offset == names.length - 1)
567 names[offset]= Bindings.getFullyQualifiedName(bindings[offset].getElementType());
569 names[offset]= Bindings.getFullyQualifiedName(bindings[offset]);
573 final String comment= CodeGeneration.getMethodComment(fSubType.getCompilationUnit(), fSubType.getElementName(), declaration, false, binding.getName(), string, names, StubUtility.getLineDelimiterUsed(fSubType.getJavaProject()));
574 if (comment != null) {
575 final ASTRewrite rewrite= sourceRewrite.getASTRewrite();
576 if (declaration.getJavadoc() != null) {
577 rewrite.replace(declaration.getJavadoc(), rewrite.createStringPlaceholder(comment, ASTNode.JAVADOC), sourceRewrite.createCategorizedGroupDescription(RefactoringCoreMessages.ExtractInterfaceProcessor_rewrite_comment, SET_EXTRACT_INTERFACE));
578 } else if (javadoc) {
579 rewrite.set(declaration, MethodDeclaration.JAVADOC_PROPERTY, rewrite.createStringPlaceholder(comment, ASTNode.JAVADOC), sourceRewrite.createCategorizedGroupDescription(RefactoringCoreMessages.ExtractInterfaceProcessor_add_comment, SET_EXTRACT_INTERFACE));
586 * Creates the method annotations and comments of the extracted methods in
589 * @param sourceRewrite
590 * the source compilation unit rewrite
591 * @param replacements
592 * the set of variable binding keys of formal parameters which
594 * @throws CoreException
597 protected final void createMethodComments(final CompilationUnitRewrite sourceRewrite, final Set<String> replacements) throws CoreException {
598 Assert.isNotNull(sourceRewrite);
599 Assert.isNotNull(replacements);
600 if (fMembers.length > 0 && (fAnnotations || fComments)) {
601 IJavaProject project= fSubType.getJavaProject();
602 boolean annotations= fAnnotations && !JavaModelUtil.isVersionLessThan(project.getOption(JavaCore.COMPILER_SOURCE, true), JavaCore.VERSION_1_6);
603 boolean javadoc= project.getOption(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, true).equals(JavaCore.ENABLED);
604 IMember member= null;
605 for (int index= 0; index < fMembers.length; index++) {
606 member= fMembers[index];
607 if (member instanceof IMethod) {
608 MethodDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode((IMethod) member, sourceRewrite.getRoot());
610 ASTRewrite rewrite= sourceRewrite.getASTRewrite();
611 AST ast= rewrite.getAST();
612 Annotation marker= ast.newMarkerAnnotation();
613 marker.setTypeName(ast.newSimpleName("Override")); //$NON-NLS-1$
614 rewrite.getListRewrite(declaration, MethodDeclaration.MODIFIERS2_PROPERTY).insertFirst(marker, null);
617 createMethodComment(sourceRewrite, declaration, replacements, javadoc);
624 * Creates a target method declaration.
626 * @param sourceRewrite
627 * the source compilation unit rewrite
628 * @param targetRewrite
630 * @param targetDeclaration
631 * the target type declaration
633 * the source method declaration
634 * @throws CoreException
635 * if a buffer could not be retrieved
637 protected final void createMethodDeclaration(final CompilationUnitRewrite sourceRewrite, final ASTRewrite targetRewrite, final AbstractTypeDeclaration targetDeclaration, final MethodDeclaration declaration) throws CoreException {
638 Assert.isNotNull(targetDeclaration);
639 Assert.isNotNull(sourceRewrite);
640 Assert.isNotNull(targetRewrite);
641 Assert.isNotNull(declaration);
642 ImportRewriteUtil.collectImports(fSubType.getJavaProject(), declaration, fTypeBindings, fStaticBindings, true);
643 ASTRewrite rewrite= ASTRewrite.create(declaration.getAST());
644 ITrackedNodePosition position= rewrite.track(declaration);
645 if (declaration.getBody() != null)
646 rewrite.remove(declaration.getBody(), null);
647 ListRewrite list= rewrite.getListRewrite(declaration, declaration.getModifiersProperty());
648 boolean publicFound= false;
649 boolean abstractFound= false;
650 Annotation annotation= null;
651 for (IExtendedModifier extended : (List<IExtendedModifier>) declaration.modifiers()) {
652 if (!extended.isAnnotation()) {
653 Modifier modifier= (Modifier) extended;
654 if (fPublic && modifier.getKeyword().equals(Modifier.ModifierKeyword.PUBLIC_KEYWORD)) {
658 if (fAbstract && modifier.getKeyword().equals(Modifier.ModifierKeyword.ABSTRACT_KEYWORD)) {
662 list.remove(modifier, null);
663 } else if (extended.isAnnotation()) {
664 annotation= (Annotation) extended;
665 ITypeBinding binding= annotation.resolveTypeBinding();
666 if (binding.getQualifiedName().equals("java.lang.Override") || ! Bindings.isClassOrRuntimeAnnotation(binding)) //$NON-NLS-1$
667 list.remove(annotation, null);
670 ModifierRewrite rewriter= ModifierRewrite.create(rewrite, declaration);
671 if (fPublic && !publicFound)
672 rewriter.setVisibility(Modifier.PUBLIC, null);
673 if (fAbstract && !abstractFound)
674 rewriter.setModifiers(Modifier.ABSTRACT, 0, null);
676 for (SingleVariableDeclaration param : (List<SingleVariableDeclaration>) declaration.parameters()) {
677 ListRewrite modifierRewrite= rewrite.getListRewrite(param, SingleVariableDeclaration.MODIFIERS2_PROPERTY);
678 for (IExtendedModifier extended : (List<IExtendedModifier>) param.modifiers()) {
679 if (!extended.isAnnotation()) {
680 Modifier modifier= (Modifier) extended;
681 modifierRewrite.remove(modifier, null);
682 } else if (extended.isAnnotation()) {
683 annotation= (Annotation) extended;
684 ITypeBinding binding= annotation.resolveTypeBinding();
685 if (! Bindings.isClassOrRuntimeAnnotation(binding))
686 modifierRewrite.remove(annotation, null);
691 ICompilationUnit unit= sourceRewrite.getCu();
692 ITextFileBuffer buffer= RefactoringFileBuffers.acquire(unit);
694 IDocument document= new Document(buffer.getDocument().get());
696 rewrite.rewriteAST(document, unit.getJavaProject().getOptions(true)).apply(document, TextEdit.UPDATE_REGIONS);
697 targetRewrite.getListRewrite(targetDeclaration, targetDeclaration.getBodyDeclarationsProperty()).insertFirst(targetRewrite.createStringPlaceholder(normalizeText(document.get(position.getStartPosition(), position.getLength())), ASTNode.METHOD_DECLARATION), null);
698 } catch (MalformedTreeException exception) {
699 JavaPlugin.log(exception);
700 } catch (BadLocationException exception) {
701 JavaPlugin.log(exception);
704 RefactoringFileBuffers.release(unit);
709 * Creates the new signature of the source type.
712 * the source compilation unit rewrite
714 * the type declaration
716 * the refactoring status
718 * the progress monitor to use
719 * @throws JavaModelException
720 * if the type parameters cannot be retrieved
722 protected final void createTypeSignature(final CompilationUnitRewrite rewrite, final AbstractTypeDeclaration declaration, final RefactoringStatus status, final IProgressMonitor monitor) throws JavaModelException {
723 Assert.isNotNull(rewrite);
724 Assert.isNotNull(declaration);
725 Assert.isNotNull(status);
726 Assert.isNotNull(monitor);
728 monitor.beginTask("", 1); //$NON-NLS-1$
729 monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating);
730 final AST ast= declaration.getAST();
731 final ITypeParameter[] parameters= fSubType.getTypeParameters();
732 Type type= ast.newSimpleType(ast.newSimpleName(fSuperName));
733 if (parameters.length > 0) {
734 final ParameterizedType parameterized= ast.newParameterizedType(type);
735 for (int index= 0; index < parameters.length; index++)
736 parameterized.typeArguments().add(ast.newSimpleType(ast.newSimpleName(parameters[index].getElementName())));
739 final ASTRewrite rewriter= rewrite.getASTRewrite();
740 if (declaration instanceof TypeDeclaration)
741 rewriter.getListRewrite(declaration, TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY).insertLast(type, rewrite.createCategorizedGroupDescription(RefactoringCoreMessages.ExtractInterfaceProcessor_add_super_interface, SET_EXTRACT_INTERFACE));
742 else if (declaration instanceof EnumDeclaration)
743 rewriter.getListRewrite(declaration, EnumDeclaration.SUPER_INTERFACE_TYPES_PROPERTY).insertLast(type, rewrite.createCategorizedGroupDescription(RefactoringCoreMessages.ExtractInterfaceProcessor_add_super_interface, SET_EXTRACT_INTERFACE));
751 * Should extracted methods be declared as abstract?
753 * @return <code>true</code> if the should be declared as abstract,
754 * <code>false</code> otherwise
756 public final boolean getAbstract() {
761 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#getElements()
764 public final Object[] getElements() {
765 return new Object[] { fSubType };
769 * Returns the list of extractable members from the type.
771 * @return the list of extractable members
772 * @throws JavaModelException
775 public final IMember[] getExtractableMembers() throws JavaModelException {
776 final List<IJavaElement> list= new ArrayList<IJavaElement>();
777 IJavaElement[] children= fSubType.getChildren();
778 for (int index= 0; index < children.length; index++) {
779 if (children[index] instanceof IMember && isExtractableMember((IMember) children[index]))
780 list.add(children[index]);
782 final IMember[] members= new IMember[list.size()];
783 list.toArray(members);
788 * Returns the extracted fields from the compilation unit.
791 * the compilation unit
792 * @return the extracted fields
794 protected final IField[] getExtractedFields(final ICompilationUnit unit) {
795 Assert.isNotNull(unit);
796 final List<IJavaElement> list= new ArrayList<IJavaElement>();
797 for (int index= 0; index < fMembers.length; index++) {
798 if (fMembers[index] instanceof IField) {
799 final IJavaElement element= JavaModelUtil.findInCompilationUnit(unit, fMembers[index]);
800 if (element instanceof IField)
804 final IField[] fields= new IField[list.size()];
805 list.toArray(fields);
810 * Returns the extracted methods from the compilation unit.
813 * the compilation unit
814 * @return the extracted methods
816 protected final IMethod[] getExtractedMethods(final ICompilationUnit unit) {
817 Assert.isNotNull(unit);
818 final List<IJavaElement> list= new ArrayList<IJavaElement>();
819 for (int index= 0; index < fMembers.length; index++) {
820 if (fMembers[index] instanceof IMethod) {
821 final IJavaElement element= JavaModelUtil.findInCompilationUnit(unit, fMembers[index]);
822 if (element instanceof IMethod)
826 final IMethod[] methods= new IMethod[list.size()];
827 list.toArray(methods);
832 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#getIdentifier()
835 public final String getIdentifier() {
840 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#getProcessorName()
843 public final String getProcessorName() {
844 return RefactoringCoreMessages.ExtractInterfaceProcessor_name;
848 * Should extracted methods be declared as public?
850 * @return <code>true</code> if the should be declared as public,
851 * <code>false</code> otherwise
853 public final boolean getPublic() {
858 * Returns the type where to extract an interface.
860 * @return the type where to extract an interface
862 public final IType getType() {
867 * Returns the new interface name.
869 * @return the new interface name
871 public final String getTypeName() {
876 * Should override annotations be generated?
878 * @return <code>true</code> if annotations should be generated, <code>false</code> otherwise
880 public final boolean isAnnotations() {
884 private RefactoringStatus initialize(JavaRefactoringArguments extended) {
885 String handle= extended.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT);
886 if (handle != null) {
887 final IJavaElement element= JavaRefactoringDescriptorUtil.handleToElement(extended.getProject(), handle, false);
888 if (element == null || !element.exists() || element.getElementType() != IJavaElement.TYPE)
889 return JavaRefactoringDescriptorUtil.createInputFatalStatus(element, getProcessorName(), IJavaRefactorings.EXTRACT_INTERFACE);
891 fSubType= (IType) element;
893 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT));
894 final String name= extended.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME);
897 final RefactoringStatus status= checkTypeName(name);
898 if (status.hasError())
901 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME));
902 final String deferred= extended.getAttribute(ATTRIBUTE_ABSTRACT);
903 if (deferred != null) {
904 fAbstract= Boolean.valueOf(deferred).booleanValue();
906 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_ABSTRACT));
907 final String comment= extended.getAttribute(ATTRIBUTE_COMMENTS);
908 if (comment != null) {
909 fComments= Boolean.valueOf(comment).booleanValue();
911 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_COMMENTS));
912 final String instance= extended.getAttribute(ATTRIBUTE_INSTANCEOF);
913 if (instance != null) {
914 fInstanceOf= Boolean.valueOf(instance).booleanValue();
916 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_INSTANCEOF));
917 final String visibility= extended.getAttribute(ATTRIBUTE_PUBLIC);
918 if (visibility != null) {
919 fPublic= Boolean.valueOf(visibility).booleanValue();
921 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_PUBLIC));
922 final String replace= extended.getAttribute(ATTRIBUTE_REPLACE);
923 if (replace != null) {
924 fReplace= Boolean.valueOf(replace).booleanValue();
926 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REPLACE));
928 final List<IJavaElement> elements= new ArrayList<IJavaElement>();
929 String attribute= JavaRefactoringDescriptorUtil.ATTRIBUTE_ELEMENT + count;
930 final RefactoringStatus status= new RefactoringStatus();
931 while ((handle= extended.getAttribute(attribute)) != null) {
932 final IJavaElement element= JavaRefactoringDescriptorUtil.handleToElement(extended.getProject(), handle, false);
933 if (element == null || !element.exists())
934 status.merge(JavaRefactoringDescriptorUtil.createInputWarningStatus(element, getProcessorName(), IJavaRefactorings.EXTRACT_INTERFACE));
936 elements.add(element);
938 attribute= JavaRefactoringDescriptorUtil.ATTRIBUTE_ELEMENT + count;
940 fMembers= elements.toArray(new IMember[elements.size()]);
941 fSettings= JavaPreferencesSettings.getCodeGenerationSettings(fSubType.getJavaProject());
944 return new RefactoringStatus();
948 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#isApplicable()
951 public final boolean isApplicable() throws CoreException {
952 return Checks.isAvailable(fSubType) && !fSubType.isBinary() && !fSubType.isReadOnly() && !fSubType.isAnnotation() && !fSubType.isAnonymous();
956 * Should comments be generated?
958 * @return <code>true</code> if comments should be generated,
959 * <code>false</code> otherwise
961 public final boolean isComments() {
966 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#loadParticipants(org.eclipse.ltk.core.refactoring.RefactoringStatus,org.eclipse.ltk.core.refactoring.participants.SharableParticipants)
969 public final RefactoringParticipant[] loadParticipants(final RefactoringStatus status, final SharableParticipants sharedParticipants) throws CoreException {
970 return new RefactoringParticipant[0];
974 * Normalizes the indentation of the specified text.
977 * the text to normalize
978 * @return the normalized text
979 * @throws JavaModelException
982 protected final String normalizeText(final String code) throws JavaModelException {
983 Assert.isNotNull(code);
984 final String[] lines= Strings.convertIntoLines(code);
985 final IJavaProject project= fSubType.getJavaProject();
986 Strings.trimIndentation(lines, project, false);
987 return Strings.concatenate(lines, StubUtility.getLineDelimiterUsed(project));
991 * Resets the environment.
993 protected void resetEnvironment() {
995 resetWorkingCopies();
1002 protected final void rewriteTypeOccurrences(final TextEditBasedChangeManager manager, final ASTRequestor requestor, final CompilationUnitRewrite rewrite, final ICompilationUnit unit, final CompilationUnit node, final Set<String> replacements, final IProgressMonitor monitor) throws CoreException {
1004 monitor.beginTask("", 100); //$NON-NLS-1$
1005 monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating);
1006 CompilationUnitRewrite currentRewrite= null;
1007 final boolean isSubUnit= rewrite.getCu().equals(unit.getPrimary());
1009 currentRewrite= rewrite;
1011 currentRewrite= new CompilationUnitRewrite(unit, node);
1012 final Collection<ITypeConstraintVariable> collection= fTypeOccurrences.get(unit);
1013 if (collection != null && !collection.isEmpty()) {
1014 final IProgressMonitor subMonitor= new SubProgressMonitor(monitor, 100);
1016 subMonitor.beginTask("", collection.size() * 10); //$NON-NLS-1$
1017 subMonitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating);
1018 TType estimate= null;
1019 ISourceConstraintVariable variable= null;
1020 ITypeConstraintVariable constraint= null;
1021 for (final Iterator<ITypeConstraintVariable> iterator= collection.iterator(); iterator.hasNext();) {
1022 variable= iterator.next();
1023 if (variable instanceof ITypeConstraintVariable) {
1024 constraint= (ITypeConstraintVariable) variable;
1025 estimate= (TType) constraint.getData(SuperTypeConstraintsSolver.DATA_TYPE_ESTIMATE);
1026 if (estimate != null) {
1027 final CompilationUnitRange range= constraint.getRange();
1029 rewriteTypeOccurrence(range, estimate, requestor, currentRewrite, node, replacements, currentRewrite.createCategorizedGroupDescription(RefactoringCoreMessages.SuperTypeRefactoringProcessor_update_type_occurrence, SET_SUPER_TYPE));
1031 final ASTNode result= NodeFinder.perform(node, range.getSourceRange());
1033 rewriteTypeOccurrence(estimate, currentRewrite, result, currentRewrite.createCategorizedGroupDescription(RefactoringCoreMessages.SuperTypeRefactoringProcessor_update_type_occurrence, SET_SUPER_TYPE));
1035 subMonitor.worked(10);
1044 final TextChange change= currentRewrite.createChange(true);
1046 manager.manage(unit, change);
1054 * Creates the necessary text edits to replace the subtype occurrences by a
1058 * the text change manager
1059 * @param sourceRewrite
1060 * the compilation unit of the subtype (not in working copy mode)
1062 * the compilation unit of the supertype (in working copy mode)
1063 * @param replacements
1064 * the set of variable binding keys of formal parameters which
1067 * the refactoring status
1069 * the progress monitor to display progress
1070 * @throws CoreException
1071 * if an error occurs
1073 protected final void rewriteTypeOccurrences(final TextEditBasedChangeManager manager, final CompilationUnitRewrite sourceRewrite, final ICompilationUnit superUnit, final Set<String> replacements, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
1074 Assert.isNotNull(manager);
1075 Assert.isNotNull(sourceRewrite);
1076 Assert.isNotNull(superUnit);
1077 Assert.isNotNull(replacements);
1078 Assert.isNotNull(status);
1079 Assert.isNotNull(monitor);
1081 monitor.beginTask("", 300); //$NON-NLS-1$
1082 monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating);
1083 final ICompilationUnit subUnit= getSharedWorkingCopy(fSubType.getCompilationUnit().getPrimary(), new SubProgressMonitor(monitor, 20));
1084 final ITextFileBuffer buffer= RefactoringFileBuffers.acquire(fSubType.getCompilationUnit());
1085 final ASTRewrite rewrite= sourceRewrite.getASTRewrite();
1087 final IDocument document= new Document(buffer.getDocument().get());
1089 rewrite.rewriteAST(document, fSubType.getJavaProject().getOptions(true)).apply(document, TextEdit.UPDATE_REGIONS);
1090 } catch (MalformedTreeException exception) {
1091 JavaPlugin.log(exception);
1092 } catch (BadLocationException exception) {
1093 JavaPlugin.log(exception);
1095 subUnit.getBuffer().setContents(document.get());
1097 RefactoringFileBuffers.release(fSubType.getCompilationUnit());
1099 JavaModelUtil.reconcile(subUnit);
1100 final IJavaProject project= subUnit.getJavaProject();
1101 final ASTParser parser= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
1102 parser.setWorkingCopyOwner(fOwner);
1103 parser.setResolveBindings(true);
1104 parser.setProject(project);
1105 parser.setCompilerOptions(RefactoringASTParser.getCompilerOptions(project));
1106 parser.createASTs(new ICompilationUnit[] { subUnit}, new String[0], new ASTRequestor() {
1109 public final void acceptAST(final ICompilationUnit unit, final CompilationUnit node) {
1111 final IType subType= (IType) JavaModelUtil.findInCompilationUnit(unit, fSubType);
1112 final AbstractTypeDeclaration subDeclaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(subType, node);
1113 if (subDeclaration != null) {
1114 final ITypeBinding subBinding= subDeclaration.resolveBinding();
1115 if (subBinding != null) {
1117 ITypeBinding superBinding= null;
1118 final ITypeBinding[] superBindings= subBinding.getInterfaces();
1119 for (int index= 0; index < superBindings.length; index++) {
1120 name= superBindings[index].getName();
1121 if (name.startsWith(fSuperName) && superBindings[index].getTypeArguments().length == subBinding.getTypeParameters().length)
1122 superBinding= superBindings[index];
1124 if (superBinding != null) {
1125 solveSuperTypeConstraints(unit, node, subType, subBinding, superBinding, new SubProgressMonitor(monitor, 80), status);
1126 if (!status.hasFatalError()) {
1127 rewriteTypeOccurrences(manager, this, sourceRewrite, unit, node, replacements, status, new SubProgressMonitor(monitor, 200));
1128 if (manager.containsChangesIn(superUnit)) {
1129 final TextEditBasedChange change= manager.get(superUnit);
1130 if (change instanceof TextChange) {
1131 final TextEdit edit= ((TextChange) change).getEdit();
1133 final IDocument document= new Document(superUnit.getBuffer().getContents());
1135 edit.apply(document, TextEdit.UPDATE_REGIONS);
1136 } catch (MalformedTreeException exception) {
1137 JavaPlugin.log(exception);
1138 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error));
1139 } catch (BadLocationException exception) {
1140 JavaPlugin.log(exception);
1141 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error));
1143 fSuperSource= document.get();
1144 manager.remove(superUnit);
1152 } catch (JavaModelException exception) {
1153 JavaPlugin.log(exception);
1154 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error));
1159 public final void acceptBinding(final String key, final IBinding binding) {
1162 }, new NullProgressMonitor());
1169 * Determines whether extracted methods should be declared as abstract.
1172 * <code>true</code> to declare them public, <code>false</code>
1175 public final void setAbstract(final boolean declare) {
1180 * Determines whether override annotations should be generated.
1182 * @param annotations <code>true</code> to generate override annotations, <code>false</code> otherwise
1184 public final void setAnnotations(final boolean annotations) {
1185 fAnnotations= annotations;
1189 * Determines whether comments should be generated.
1192 * <code>true</code> to generate comments, <code>false</code>
1195 public final void setComments(final boolean comments) {
1196 fComments= comments;
1200 * Sets the members to be extracted.
1203 * the members to be extracted
1204 * @throws JavaModelException
1205 * if an error occurs
1207 public final void setExtractedMembers(final IMember[] members) throws JavaModelException {
1212 * Determines whether extracted methods should be declared as public.
1215 * <code>true</code> to declare them public, <code>false</code>
1218 public final void setPublic(final boolean declare) {
1223 * Sets the new interface name.
1226 * the new interface name
1228 public final void setTypeName(final String name) {
1229 Assert.isNotNull(name);