org.eclipse.ajdt.internal.ui.refactoring.ITDRenameRefactoringProcessor.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.ajdt.internal.ui.refactoring.ITDRenameRefactoringProcessor.java

Source

/*******************************************************************************
 * Copyright (c) 2009 SpringSource and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Andrew Eisenberg - initial API and implementation
 *******************************************************************************/

package org.eclipse.ajdt.internal.ui.refactoring;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.aspectj.asm.IProgramElement.Kind;
import org.eclipse.ajdt.core.ReflectionUtils;
import org.eclipse.ajdt.core.javaelements.IntertypeElement;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
import org.eclipse.jdt.core.refactoring.descriptors.RenameJavaElementDescriptor;
import org.eclipse.jdt.core.search.FieldDeclarationMatch;
import org.eclipse.jdt.core.search.FieldReferenceMatch;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.MethodDeclarationMatch;
import org.eclipse.jdt.core.search.MethodReferenceMatch;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.internal.core.JavaElement;
import org.eclipse.jdt.internal.core.refactoring.descriptors.RefactoringSignatureDescriptorFactory;
import org.eclipse.jdt.internal.corext.refactoring.Checks;
import org.eclipse.jdt.internal.corext.refactoring.CuCollectingSearchRequestor;
import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine;
import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
import org.eclipse.jdt.internal.corext.refactoring.base.ReferencesInBinaryContext;
import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility;
import org.eclipse.jdt.internal.corext.refactoring.participants.JavaProcessors;
import org.eclipse.jdt.internal.corext.refactoring.rename.JavaRenameProcessor;
import org.eclipse.jdt.internal.corext.refactoring.rename.RenameModifications;
import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
import org.eclipse.jdt.internal.corext.util.JavaConventionsUtil;
import org.eclipse.jdt.internal.corext.util.JdtFlags;
import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
import org.eclipse.jdt.ui.JavaElementLabels;
import org.eclipse.jdt.ui.refactoring.RefactoringSaveHelper;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.RefactoringStatusContext;
import org.eclipse.ltk.core.refactoring.TextChange;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.RenameArguments;
import org.eclipse.ltk.internal.core.refactoring.Messages;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;

/**
 * @author Andrew Eisenberg
 * @created May 21, 2010
 *
 */
public class ITDRenameRefactoringProcessor extends JavaRenameProcessor {

    public static final String REFACTORING_ID = "org.eclipse.ajdt.ui.renameITD";

    // The target of the refactoring
    private IntertypeElement itd;

    // we want to rename overriders of ITD methods
    private Set<IMember> elementsToRename;

    // either itd field or method
    private Kind itdKind;

    // the mock element declared in the target type
    private IMember mockElement;

    // The ITD qualifier (may be simple type name or fully qualifed, 
    // depending on what is in the text)
    private String qualifier;

    private TextChangeManager changeManager;

    // If true, then references will be renamed as well
    private boolean updateReferences;

    // group of compilations units that contain references
    private SearchResultGroup[] references;

    public ITDRenameRefactoringProcessor(IntertypeElement itd, RefactoringStatus status) {
        this.itd = itd;
        changeManager = new TextChangeManager(true);
        updateReferences = true;
        try {
            itdKind = itd.getAJKind();
        } catch (JavaModelException e) {
            status.merge(RefactoringStatus.createFatalErrorStatus("Problem accessing the AspectJ model",
                    createErrorContext()));
        }
    }

    public ITDRenameRefactoringProcessor(JavaRefactoringArguments arguments, RefactoringStatus status) {
        RefactoringStatus initializeStatus = initialize(arguments);
        status.merge(initializeStatus);
        changeManager = new TextChangeManager(true);
        try {
            itdKind = itd.getAJKind();
        } catch (JavaModelException e) {
            status.merge(RefactoringStatus.createFatalErrorStatus("Problem accessing the AspectJ model",
                    createErrorContext()));
        }
    }

    private RefactoringStatus initialize(JavaRefactoringArguments extended) {
        final String handle = extended.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT);
        if (handle != null) {
            final IJavaElement element = JavaRefactoringDescriptorUtil.handleToElement(extended.getProject(),
                    handle, false);
            if (element == null || !element.exists() || !(element instanceof IntertypeElement)) {
                return JavaRefactoringDescriptorUtil.createInputFatalStatus(element, getProcessorName(),
                        IJavaRefactorings.RENAME_FIELD);
            } else {
                itd = (IntertypeElement) element;
            }
        } else {
            return RefactoringStatus.createFatalErrorStatus(
                    Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
                            JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT));
        }
        final String name = extended.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME);
        if (name != null && !"".equals(name)) { //$NON-NLS-1$
            setNewElementName(name);
        } else {
            return RefactoringStatus.createFatalErrorStatus(
                    Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
                            JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME));
        }
        final String references = extended.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_REFERENCES);
        if (references != null) {
            updateReferences = Boolean.valueOf(references).booleanValue();
        } else {
            return RefactoringStatus.createFatalErrorStatus(
                    Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
                            JavaRefactoringDescriptorUtil.ATTRIBUTE_REFERENCES));
        }
        return new RefactoringStatus();
    }

    public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
            throws CoreException, OperationCanceledException {
        checkCanceled(pm);
        mockElement = itd.createMockDeclaration();

        if (mockElement == null) {
            return RefactoringStatus.createFatalErrorStatus(
                    "AspectJ model not available for this ITD, do a full project build and try again.",
                    createErrorContext());
        }
        qualifier = itd.getElementName().substring(0,
                itd.getElementName().length() - mockElement.getElementName().length());
        if (qualifier == null || qualifier.length() == 0) {
            return RefactoringStatus.createFatalErrorStatus("Invalid ITD qualifier", createErrorContext());
        }

        RefactoringStatus result = Checks.checkAvailability(itd);
        if (result.hasFatalError()) {
            return result;
        }
        result.merge(Checks.checkIfCuBroken(itd));
        checkCanceled(pm);
        return result;
    }

    private RefactoringStatusContext createErrorContext() {
        return JavaStatusContext.create(itd);
    }

    protected RefactoringStatus doCheckFinalConditions(IProgressMonitor pm, CheckConditionsContext context)
            throws CoreException, OperationCanceledException {
        try {
            pm.beginTask("", 18); //$NON-NLS-1$
            pm.setTaskName(RefactoringCoreMessages.RenameFieldRefactoring_checking);
            RefactoringStatus result = new RefactoringStatus();

            // cannot rename if current AJCU is broken
            result.merge(Checks.checkIfCuBroken(itd));
            if (result.hasFatalError()) {
                return result;
            }
            checkCanceled(pm);

            // ensure new name is OK 
            result.merge(checkNewElementName(getNewElementName()));
            pm.worked(1);

            // field specific checks 
            if (itdKind == Kind.INTER_TYPE_FIELD) {
                result.merge(checkEnclosingHierarchy((IField) mockElement));
                result.merge(checkNestedHierarchy(mockElement.getDeclaringType()));
            }
            checkCanceled(pm);
            pm.worked(1);
            pm.worked(1);

            if (updateReferences) {
                pm.setTaskName(RefactoringCoreMessages.RenameFieldRefactoring_searching);
                // find all occurrences of renamed element.  This will include the declaration
                // original declaration as well as declarations and references of ripple 
                // methods if ITD Method decl.
                references = getOccurrences(new SubProgressMonitor(pm, 3), result);
                pm.setTaskName(RefactoringCoreMessages.RenameFieldRefactoring_checking);
            } else {
                // currently, no way to disable updateReferences, so this will never be hit
                references = new SearchResultGroup[0];
                pm.worked(3);
            }
            checkCanceled(pm);

            if (updateReferences) {
                // warn if any compilation units are broken
                result.merge(analyzeAffectedCompilationUnits());
                // check renaming of ripple methods
                result.merge(checkRelatedElements());
            } else {
                Checks.checkCompileErrorsInAffectedFile(result, itd.getResource());
            }
            checkCanceled(pm);

            // create all changes
            result.merge(createChanges(new SubProgressMonitor(pm, 10)));
            if (result.hasFatalError())
                return result;

            return result;
        } finally {
            pm.done();
        }
    }

    private RefactoringStatus createChanges(IProgressMonitor pm) throws CoreException {
        pm.beginTask(RefactoringCoreMessages.RenameFieldRefactoring_checking, 10);
        RefactoringStatus result = new RefactoringStatus();
        changeManager.clear();

        addOccurrenceUpdates(new SubProgressMonitor(pm, 1));
        // can't do this since AspectJ does not do reconcling
        //            result.merge(analyzeRenameChanges(new SubProgressMonitor(pm, 2)));
        if (result.hasFatalError())
            return result;

        pm.done();
        return result;
    }

    private void addDeclarationUpdate(IMember member) throws CoreException {
        ISourceRange nameRange = member.getNameRange();
        TextEdit textEdit = new ReplaceEdit(nameRange.getOffset(), nameRange.getLength(),
                extractRawITDName(getNewElementName()));
        ICompilationUnit cu = member.getCompilationUnit();
        String groupName = itdKind == Kind.INTER_TYPE_FIELD
                ? RefactoringCoreMessages.RenameFieldRefactoring_Update_field_declaration
                : RefactoringCoreMessages.RenameMethodRefactoring_update_declaration;

        addTextEdit(changeManager.get(cu), groupName, textEdit);
    }

    private void addTextEdit(TextChange change, String groupName, TextEdit textEdit) {
        TextChangeCompatibility.addTextEdit(change, groupName, textEdit);
    }

    private SearchResultGroup[] getOccurrences(IProgressMonitor pm, RefactoringStatus status) throws CoreException {

        String binaryRefsDescription = Messages.format(
                RefactoringCoreMessages.ReferencesInBinaryContext_ref_in_binaries_description,
                BasicElementLabels.getJavaElementName(getCurrentElementName()));
        ReferencesInBinaryContext binaryRefs = new ReferencesInBinaryContext(binaryRefsDescription);

        // must include ripple methods if this is an ITD method
        initializeElementsToRename(new SubProgressMonitor(pm, 1), binaryRefs);
        pm.setTaskName(RefactoringCoreMessages.RenameMethodRefactoring_taskName_searchingForReferences);

        SearchResultGroup[] result = RefactoringSearchEngine.search(createSearchPattern(), createRefactoringScope(),
                new CuCollectingSearchRequestor(binaryRefs), pm, status);
        binaryRefs.addErrorIfNecessary(status);

        return result;
    }

    /**
     * Checks the ripple methods to make sure they can validly be renamed.
     */
    private RefactoringStatus checkRelatedElements() throws CoreException {
        RefactoringStatus result = new RefactoringStatus();
        if (itdKind == Kind.INTER_TYPE_FIELD) {
            return result;
        }
        for (IMember member : elementsToRename) {
            if (!(member instanceof IMethod)) {
                result.merge(RefactoringStatus.createErrorStatus("Related element is not a method.",
                        JavaStatusContext.create(member)));
            }
            IMethod method = (IMethod) member;

            result.merge(Checks.checkIfConstructorName(method, getNewElementName(),
                    method.getDeclaringType().getElementName()));

            String[] msgData = new String[] { BasicElementLabels.getJavaElementName(method.getElementName()),
                    BasicElementLabels.getJavaElementName(method.getDeclaringType().getFullyQualifiedName('.')) };
            if (!method.exists()) {
                result.addFatalError(
                        Messages.format(RefactoringCoreMessages.RenameMethodRefactoring_not_in_model, msgData));
                continue;
            }
            if (method.isBinary())
                result.addFatalError(
                        Messages.format(RefactoringCoreMessages.RenameMethodRefactoring_no_binary, msgData));
            if (method.isReadOnly())
                result.addFatalError(
                        Messages.format(RefactoringCoreMessages.RenameMethodRefactoring_no_read_only, msgData));
            if (JdtFlags.isNative(method))
                result.addError(
                        Messages.format(RefactoringCoreMessages.RenameMethodRefactoring_no_native_1, msgData));
        }
        return result;
    }

    private IJavaSearchScope createRefactoringScope() throws CoreException {
        return RefactoringScopeFactory.create(itd, true, false);
    }

    private SearchPattern createSearchPattern() {
        HashSet<IMember> members = new HashSet<IMember>(elementsToRename);
        IMember[] ms = (IMember[]) members.toArray(new IMethod[members.size()]);
        return RefactoringSearchEngine.createOrPattern(ms, IJavaSearchConstants.ALL_OCCURRENCES);
    }

    private void addOccurrenceUpdates(IProgressMonitor pm) throws CoreException {
        pm.beginTask("", references.length); //$NON-NLS-1$
        String editName = itdKind == Kind.INTER_TYPE_FIELD
                ? RefactoringCoreMessages.RenameFieldRefactoring_Update_field_reference
                : RefactoringCoreMessages.RenameMethodRefactoring_update_occurrence;
        for (int i = 0; i < references.length; i++) {

            ICompilationUnit cu = references[i].getCompilationUnit();
            if (cu == null) {
                continue;
            }
            SearchMatch[] matches = references[i].getSearchResults();
            for (int j = 0; j < matches.length; j++) {
                if (matches[j] instanceof MethodReferenceMatch) {
                    addTextEdit(changeManager.get(cu), editName, createTextChange(matches[j]));
                } else if (matches[j] instanceof MethodDeclarationMatch) {
                    addDeclarationUpdate((IMember) matches[j].getElement());
                } else if (matches[j] instanceof FieldReferenceMatch) {
                    addTextEdit(changeManager.get(cu), editName, createTextChange(matches[j]));
                } else if (matches[j] instanceof FieldDeclarationMatch) {
                    addDeclarationUpdate((IMember) matches[j].getElement());
                }
                pm.worked(1);
            }
        }
    }

    private TextEdit createTextChange(SearchMatch match) {
        String rawITDName = extractRawITDName(itd.getElementName());
        return new ReplaceEdit(match.getOffset(), rawITDName.length(), extractRawITDName(getNewElementName()));
    }

    /*
     * (non java-doc)
     * Analyzes all compilation units in which type is referenced
     */
    private RefactoringStatus analyzeAffectedCompilationUnits() throws CoreException {
        RefactoringStatus result = new RefactoringStatus();
        references = Checks.excludeCompilationUnits(references, result);
        if (result.hasFatalError())
            return result;

        result.merge(Checks.checkCompileErrorsInAffectedFiles(references));
        return result;
    }

    private RefactoringStatus checkNestedHierarchy(IType type) throws CoreException {
        IType[] nestedTypes = type.getTypes();
        if (nestedTypes == null)
            return null;
        RefactoringStatus result = new RefactoringStatus();
        for (int i = 0; i < nestedTypes.length; i++) {
            IField otherField = nestedTypes[i].getField(getNewElementName());
            if (otherField.exists()) {
                String msg = Messages.format(RefactoringCoreMessages.RenameFieldRefactoring_hiding,
                        new String[] { BasicElementLabels.getJavaElementName(itd.getElementName()),
                                BasicElementLabels.getJavaElementName(getNewElementName()),
                                BasicElementLabels.getJavaElementName(nestedTypes[i].getFullyQualifiedName('.')) });
                result.addWarning(msg, JavaStatusContext.create(otherField));
            }
            result.merge(checkNestedHierarchy(nestedTypes[i]));
        }
        return result;
    }

    private RefactoringStatus checkEnclosingHierarchy(IField field) {
        IType current = field.getDeclaringType();
        if (Checks.isTopLevel(current))
            return null;
        RefactoringStatus result = new RefactoringStatus();
        while (current != null) {
            IField otherField = current.getField(getNewElementName());
            if (otherField.exists()) {
                String msg = Messages.format(RefactoringCoreMessages.RenameFieldRefactoring_hiding2,
                        new String[] { BasicElementLabels.getJavaElementName(getNewElementName()),
                                BasicElementLabels.getJavaElementName(current.getFullyQualifiedName('.')),
                                BasicElementLabels.getJavaElementName(otherField.getElementName()) });
                result.addWarning(msg, JavaStatusContext.create(otherField));
            }
            current = current.getDeclaringType();
        }
        return result;
    }

    /**
     * first check to make sure that the qualifier has not changed, then perform
     * checks for either a method or a field
     */
    public RefactoringStatus checkNewElementName(String newName) throws CoreException {
        RefactoringStatus status = new RefactoringStatus();
        status.merge(checkITDQualifier(newName));
        if (status.getSeverity() != RefactoringStatus.OK) {
            return status;
        }

        if (Checks.isAlreadyNamed(itd, newName)) {
            status.addFatalError(RefactoringCoreMessages.RenameMethodRefactoring_same_name, createErrorContext());
        }

        String rawName = extractRawITDName(newName);
        status.merge(Checks.checkName(rawName, JavaConventionsUtil.validateMethodName(rawName, itd)));
        if (status.isOK() && !Checks.startsWithLowerCase(rawName))
            status = RefactoringStatus.createWarningStatus(RefactoringCoreMessages.Checks_method_names_lowercase);

        if (itdKind == Kind.INTER_TYPE_FIELD) {
            if (mockElement.getDeclaringType().getField(rawName).exists())
                status.addError(RefactoringCoreMessages.RenameFieldRefactoring_field_already_defined,
                        JavaStatusContext.create(mockElement.getDeclaringType().getField(rawName)));
        }
        return status;
    }

    private String extractRawITDName(String newName) {
        String[] split = newName.split("\\.");
        return split.length > 1 ? split[split.length - 1] : newName;
    }

    private RefactoringStatus checkITDQualifier(String newName) {
        if (!newName.startsWith(qualifier)) {
            return RefactoringStatus.createFatalErrorStatus("ITD qualifier may not be changed during rename.",
                    createErrorContext());
        }
        return new RefactoringStatus();
    }

    protected RenameModifications computeRenameModifications() throws CoreException {
        RenameModifications result = new RenameModifications();
        RenameArguments args = new RenameArguments(getNewElementName(), getUpdateReferences());
        for (IMember element : elementsToRename) {
            if (element instanceof IMethod) {
                result.rename((IMethod) element, args);
            } else if (element instanceof IField) {
                // shouldn't happen since ITDs do not implement IField
                result.rename((IField) element, args);
            }
        }
        return result;
    }

    private void initializeElementsToRename(IProgressMonitor pm, ReferencesInBinaryContext binaryRefs)
            throws CoreException {
        if (elementsToRename == null && itdKind == Kind.INTER_TYPE_METHOD) {
            IMethod[] rippleMethods = RippleMethodFinder2.getRelatedMethods(itd, binaryRefs, pm, null);
            elementsToRename = new HashSet<IMember>(Arrays.asList(rippleMethods));
            elementsToRename.add(itd);
        } else {
            elementsToRename = Collections.singleton((IMember) itd);
        }
    }

    protected String[] getAffectedProjectNatures() throws CoreException {
        return JavaProcessors.computeAffectedNatures(itd);
    }

    protected IFile[] getChangedFiles() throws CoreException {
        return ResourceUtil.getFiles(changeManager.getAllCompilationUnits());
    }

    public int getSaveMode() {
        return RefactoringSaveHelper.SAVE_REFACTORING;
    }

    private void checkCanceled(IProgressMonitor pm) {
        if (pm.isCanceled()) {
            throw new OperationCanceledException();
        }
    }

    public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
        try {
            final TextChange[] changes = changeManager.getAllChanges();
            final List<TextChange> list = new ArrayList<TextChange>(changes.length);
            list.addAll(Arrays.asList(changes));
            return new DynamicValidationRefactoringChange(createDescriptor(), "Rename Intertype Declaration",
                    (Change[]) list.toArray(new Change[list.size()]));
        } finally {
            pm.done();
        }
    }

    private RenameJavaElementDescriptor createDescriptor() {
        String project = null;
        IJavaProject javaProject = itd.getJavaProject();
        if (javaProject != null)
            project = javaProject.getElementName();
        int flags = RefactoringDescriptor.STRUCTURAL_CHANGE;
        try {
            if (!Flags.isPrivate(itd.getFlags()))
                flags |= RefactoringDescriptor.MULTI_CHANGE;
        } catch (JavaModelException exception) {
        }
        final String description = Messages.format("Rename intertype declaration ''{0}''",
                BasicElementLabels.getJavaElementName(itd.getElementName()));
        final String header = Messages.format("Rename intertype declaration ''{0}'' to ''{1}''",
                new String[] { JavaElementLabels.getTextLabel(itd, JavaElementLabels.ALL_FULLY_QUALIFIED),
                        BasicElementLabels.getJavaElementName(getNewElementName()) });
        final String comment = new JDTRefactoringDescriptorComment(project, this, header).asString();
        // must start with an invalid refactoring ID since the constructor does a legality check.`
        final RenameJavaElementDescriptor descriptor = RefactoringSignatureDescriptorFactory
                .createRenameJavaElementDescriptor(IJavaRefactorings.RENAME_METHOD);
        ReflectionUtils.setPrivateField(RefactoringDescriptor.class, "fRefactoringId", descriptor, REFACTORING_ID);
        descriptor.setProject(project);
        descriptor.setDescription(description);
        descriptor.setComment(comment);
        descriptor.setFlags(flags);
        descriptor.setJavaElement(itd);
        descriptor.setNewName(getNewElementName());
        descriptor.setUpdateReferences(updateReferences);
        return descriptor;
    }

    public Object[] getElements() {
        return new Object[] { itd };
    }

    public String getIdentifier() {
        return "org.eclipse.ajdt.ui.refactoring.rename.itd";
    }

    public String getProcessorName() {
        return "Rename an Intertype Declaration";
    }

    public boolean isApplicable() throws CoreException {
        return itdKind == Kind.INTER_TYPE_FIELD || itdKind == Kind.INTER_TYPE_METHOD;
    }

    public String getCurrentElementName() {
        return itd.getElementName();
    }

    public Object getNewElement() throws CoreException {
        return new Object[] { IntertypeElement.create(itd.getJemDelimeter(), (JavaElement) itd.getParent(),
                getNewElementName(), itd.getParameterTypes()) };
    }

    public final void setUpdateReferences(boolean update) {
        updateReferences = update;
    }

    public boolean getUpdateReferences() {
        return updateReferences;
    }

}