org.eclipse.che.jdt.refactoring.session.RenameLinkedModeRefactoringSession.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.che.jdt.refactoring.session.RenameLinkedModeRefactoringSession.java

Source

/*******************************************************************************
 * Copyright (c) 2012-2015 Codenvy, S.A.
 * 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:
 *   Codenvy, S.A. - initial API and implementation
 *******************************************************************************/

package org.eclipse.che.jdt.refactoring.session;

import org.eclipse.che.ide.ext.java.shared.dto.LinkedModeModel;
import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangeCreationResult;
import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangeInfo;
import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringResult;
import org.eclipse.che.jdt.refactoring.DtoConverter;
import org.eclipse.che.jdt.refactoring.RefactoringException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
import org.eclipse.jdt.core.refactoring.descriptors.RenameJavaElementDescriptor;
import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder;
import org.eclipse.jdt.internal.corext.refactoring.rename.RenamingNameSuggestor;
import org.eclipse.jdt.ui.SharedASTProvider;
import org.eclipse.jdt.ui.refactoring.RenameSupport;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.PerformChangeOperation;
import org.eclipse.ltk.core.refactoring.RefactoringCore;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import static org.eclipse.che.ide.ext.java.server.dto.DtoServerImpls.LinkedModeModelImpl;
import static org.eclipse.che.ide.ext.java.server.dto.DtoServerImpls.LinkedPositionGroupImpl;
import static org.eclipse.che.ide.ext.java.server.dto.DtoServerImpls.RegionImpl;

/**
 * The class contains methods for the refactoring that uses the linked editor.
 *
 * @author Evgen Vidolob
 * @author Valeriy Svydenko
 */
public class RenameLinkedModeRefactoringSession extends RefactoringSession {
    private final IJavaElement element;
    private final ICompilationUnit compilationUnit;
    private final int offset;
    private String fOriginalName;

    public RenameLinkedModeRefactoringSession(IJavaElement element, ICompilationUnit compilationUnit, int offset) {
        super(null);
        this.element = element;
        this.compilationUnit = compilationUnit;
        this.offset = offset;
    }

    @Override
    public ChangeCreationResult createChange() throws RefactoringException {
        return super.createChange();
    }

    @Override
    public Change getChange() {
        return super.getChange();
    }

    @Override
    public RefactoringResult apply() {
        throw new UnsupportedOperationException("apply isn't supported on RenameLinkedModeRefactoringSession");
    }

    public LinkedModeModel getModel() {
        CompilationUnit root = SharedASTProvider.getAST(compilationUnit, SharedASTProvider.WAIT_YES, null);

        LinkedPositionGroupImpl group = new LinkedPositionGroupImpl();
        ASTNode selectedNode = NodeFinder.perform(root, offset, 0);
        if (!(selectedNode instanceof SimpleName)) {
            return null;
        }
        SimpleName nameNode = (SimpleName) selectedNode;

        fOriginalName = nameNode.getIdentifier();
        final int pos = nameNode.getStartPosition();
        ASTNode[] sameNodes = LinkedNodeFinder.findByNode(root, nameNode);

        //TODO: copied from LinkedNamesAssistProposal#apply(..):
        // sort for iteration order, starting with the node @ offset
        Arrays.sort(sameNodes, new Comparator<ASTNode>() {
            public int compare(ASTNode o1, ASTNode o2) {
                return rank(o1) - rank(o2);
            }

            /**
             * Returns the absolute rank of an <code>ASTNode</code>. Nodes
             * preceding <code>pos</code> are ranked last.
             *
             * @param node the node to compute the rank for
             * @return the rank of the node with respect to the invocation offset
             */
            private int rank(ASTNode node) {
                int relativeRank = node.getStartPosition() + node.getLength() - pos;
                if (relativeRank < 0)
                    return Integer.MAX_VALUE + relativeRank;
                else
                    return relativeRank;
            }
        });
        for (int i = 0; i < sameNodes.length; i++) {
            ASTNode elem = sameNodes[i];
            RegionImpl position = new RegionImpl();
            position.setOffset(elem.getStartPosition());
            position.setLength(elem.getLength());
            group.addPositions(position);
        }
        LinkedModeModelImpl model = new LinkedModeModelImpl();
        model.addGroups(group);
        return model;

    }

    /**
     * Make rename operation.
     * @param newName the name which will be applied
     * @return result of the rename operation
     * @throws CoreException if an error occurs while creating the refactoring instance
     * @throws InvocationTargetException if an error occurred while executing the
     * operation.
     * @throws InterruptedException if the operation has been canceled by the
     * user.
     */
    public RefactoringResult doRename(String newName)
            throws CoreException, InvocationTargetException, InterruptedException {
        if (fOriginalName.equals(newName)) {
            return DtoConverter.toRefactoringResultDto(new RefactoringStatus());
        }
        RenameSupport renameSupport = undoAndCreateRenameSupport(newName);
        if (renameSupport == null)
            return DtoConverter.toRefactoringResultDto(
                    RefactoringStatus.createFatalErrorStatus("Can't create rename refactoring"));

        RefactoringResult refactoringResult = DtoConverter.toRefactoringResultDto(renameSupport.perform());

        PerformChangeOperation operation = renameSupport.getfPerformChangeOperation();
        if (operation == null) {
            return refactoringResult;
        }
        CompositeChange operationChange = (CompositeChange) operation.getUndoChange();
        Change[] changes = operationChange.getChildren();

        List<ChangeInfo> changesInfo = new ArrayList<>();
        prepareChangesInfo(changes, changesInfo);

        refactoringResult.setChanges(changesInfo);

        return refactoringResult;
    }

    private RenameSupport undoAndCreateRenameSupport(String newName) throws CoreException {

        if (newName.length() == 0)
            return null;

        RenameJavaElementDescriptor descriptor = createRenameDescriptor(element, newName);
        return RenameSupport.create(descriptor);
    }

    /**
     * Creates a rename descriptor.
     *
     * @param javaElement element to rename
     * @param newName new name
     * @return a rename descriptor with current settings as used in the refactoring dialogs
     * @throws JavaModelException if an error occurs while accessing the element
     */
    private RenameJavaElementDescriptor createRenameDescriptor(IJavaElement javaElement, String newName)
            throws JavaModelException {
        String contributionId;
        // see RefactoringExecutionStarter#createRenameSupport(..):
        int elementType = javaElement.getElementType();
        switch (elementType) {
        case IJavaElement.JAVA_PROJECT:
            contributionId = IJavaRefactorings.RENAME_JAVA_PROJECT;
            break;
        case IJavaElement.PACKAGE_FRAGMENT_ROOT:
            contributionId = IJavaRefactorings.RENAME_SOURCE_FOLDER;
            break;
        case IJavaElement.PACKAGE_FRAGMENT:
            contributionId = IJavaRefactorings.RENAME_PACKAGE;
            break;
        case IJavaElement.COMPILATION_UNIT:
            contributionId = IJavaRefactorings.RENAME_COMPILATION_UNIT;
            break;
        case IJavaElement.TYPE:
            contributionId = IJavaRefactorings.RENAME_TYPE;
            break;
        case IJavaElement.METHOD:
            final IMethod method = (IMethod) javaElement;
            if (method.isConstructor())
                return createRenameDescriptor(method.getDeclaringType(), newName);
            else
                contributionId = IJavaRefactorings.RENAME_METHOD;
            break;
        case IJavaElement.FIELD:
            IField field = (IField) javaElement;
            if (field.isEnumConstant())
                contributionId = IJavaRefactorings.RENAME_ENUM_CONSTANT;
            else
                contributionId = IJavaRefactorings.RENAME_FIELD;
            break;
        case IJavaElement.TYPE_PARAMETER:
            contributionId = IJavaRefactorings.RENAME_TYPE_PARAMETER;
            break;
        case IJavaElement.LOCAL_VARIABLE:
            contributionId = IJavaRefactorings.RENAME_LOCAL_VARIABLE;
            break;
        default:
            return null;
        }

        RenameJavaElementDescriptor descriptor = (RenameJavaElementDescriptor) RefactoringCore
                .getRefactoringContribution(contributionId).createDescriptor();
        descriptor.setJavaElement(javaElement);
        descriptor.setNewName(newName);
        if (elementType != IJavaElement.PACKAGE_FRAGMENT_ROOT)
            descriptor.setUpdateReferences(true);

        //        IDialogSettings javaSettings= JavaPlugin.getDefault().getDialogSettings();
        //        IDialogSettings refactoringSettings= javaSettings.getSection(RefactoringWizardPage.REFACTORING_SETTINGS); //TODO: undocumented API
        //        if (refactoringSettings == null) {
        //            refactoringSettings= javaSettings.addNewSection(RefactoringWizardPage.REFACTORING_SETTINGS);
        //        }

        switch (elementType) {
        case IJavaElement.METHOD:
        case IJavaElement.FIELD:
            descriptor.setDeprecateDelegate(
                    /*refactoringSettings.getBoolean(DelegateUIHelper.DELEGATE_DEPRECATION)*/false);
            descriptor
                    .setKeepOriginal(/*refactoringSettings.getBoolean(DelegateUIHelper.DELEGATE_UPDATING)*/ false);
        }
        switch (elementType) {
        case IJavaElement.TYPE:
            //         case IJavaElement.COMPILATION_UNIT: // TODO
            descriptor.setUpdateSimilarDeclarations(
                    /*refactoringSettings.getBoolean(RenameRefactoringWizard.TYPE_UPDATE_SIMILAR_ELEMENTS)*/ false);
            int strategy;
            try {
                strategy = 1; //refactoringSettings.getInt(RenameRefactoringWizard.TYPE_SIMILAR_MATCH_STRATEGY);
            } catch (NumberFormatException e) {
                strategy = RenamingNameSuggestor.STRATEGY_EXACT;
            }
            descriptor.setMatchStrategy(strategy);
        }
        switch (elementType) {
        case IJavaElement.PACKAGE_FRAGMENT:
            descriptor.setUpdateHierarchy(
                    /*refactoringSettings.getBoolean(RenameRefactoringWizard.PACKAGE_RENAME_SUBPACKAGES)*/true);
        }
        switch (elementType) {
        case IJavaElement.PACKAGE_FRAGMENT:
        case IJavaElement.TYPE:
            String fileNamePatterns = /*refactoringSettings.get(RenameRefactoringWizard.QUALIFIED_NAMES_PATTERNS)*/"*";
            if (fileNamePatterns != null && fileNamePatterns.length() != 0) {
                descriptor.setFileNamePatterns(fileNamePatterns);
                boolean updateQualifiedNames = /*refactoringSettings.getBoolean(RenameRefactoringWizard.UPDATE_QUALIFIED_NAMES)*/false;
                descriptor.setUpdateQualifiedNames(updateQualifiedNames);
                //                    fShowPreview|= updateQualifiedNames;
            }
        }
        switch (elementType) {
        case IJavaElement.PACKAGE_FRAGMENT:
        case IJavaElement.TYPE:
        case IJavaElement.FIELD:
            boolean updateTextualOccurrences = false; //refactoringSettings.getBoolean(RenameRefactoringWizard.UPDATE_TEXTUAL_MATCHES);
            descriptor.setUpdateTextualOccurrences(updateTextualOccurrences);
            //                fShowPreview|= updateTextualOccurrences;
        }
        switch (elementType) {
        case IJavaElement.FIELD:
            descriptor.setRenameGetters(
                    /*refactoringSettings.getBoolean(RenameRefactoringWizard.FIELD_RENAME_GETTER)*/false);
            descriptor.setRenameSetters(
                    /*refactoringSettings.getBoolean(RenameRefactoringWizard.FIELD_RENAME_SETTER)*/false);
        }
        return descriptor;
    }
}