edu.illinois.compositerefactorings.steps.CreateNewSuperclassCommandHandler.java Source code

Java tutorial

Introduction

Here is the source code for edu.illinois.compositerefactorings.steps.CreateNewSuperclassCommandHandler.java

Source

/**
 * Copyright (c) 2008-2012 University of Illinois at Urbana-Champaign.
 * 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
 */

package edu.illinois.compositerefactorings.steps;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil;
import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.ltk.core.refactoring.CheckConditionsOperation;
import org.eclipse.ltk.core.refactoring.PerformRefactoringOperation;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.internal.ui.refactoring.RefactoringStatusDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.handlers.HandlerUtil;

import edu.illinois.compositerefactorings.messages.CompositeRefactoringsMessages;
import edu.illinois.compositerefactorings.refactorings.createnewtoplevelsuperclass.CreateNewTopLevelSuperClassDescriptor;
import edu.illinois.compositerefactorings.refactorings.createnewtoplevelsuperclass.CreateNewTopLevelSuperClassRefactoring;

@SuppressWarnings("restriction")
public class CreateNewSuperclassCommandHandler extends AbstractHandler {

    @SuppressWarnings("serial")
    public static class InvalidSelectionException extends Exception {

        public InvalidSelectionException(String message) {
            super(message);
        }

    }

    //   private static Set<String> fullyQualifiedName(List<IType> types) {
    //      Set<String> fullyQualifiedNames= new HashSet<String>();
    //      for (IType type : types) {
    //         fullyQualifiedNames.add(type.getFullyQualifiedName());
    //      }
    //      return fullyQualifiedNames;
    //   }

    @Override
    public Object execute(ExecutionEvent event) throws ExecutionException {
        // See http://wiki.bioclipse.net/index.php?title=How_to_add_menus_and_actions&oldid=4857
        Shell shell = HandlerUtil.getActiveShell(event);
        IEditorPart editorPart = HandlerUtil.getActiveEditor(event);
        ISelection selection = HandlerUtil.getCurrentSelection(event);
        try {
            List<IType> selectedTypes = getSelectedTypes(editorPart, selection);
            CreateNewTopLevelSuperClassRefactoring refactoring = createRefactoring(selectedTypes);
            IProgressMonitor monitor = new NullProgressMonitor();
            RefactoringStatus status = checkRefactoring(selectedTypes, refactoring, monitor);
            if (status.isOK() || choseToProceed(shell, status)) {
                performRefactoring(refactoring, monitor);
                openNewSuperClass(selectedTypes);
            }
        } catch (JavaModelException e) {
            throw new ExecutionException("Unexpected selection", e);
        } catch (CoreException e) {
            throw new ExecutionException("Refactoring object creation failed.", e);
        } catch (InvalidSelectionException e) {
            MessageDialog.openError(shell, "Unavailable Refactoring", e.getMessage());
        }
        return null;
    }

    private static void openNewSuperClass(List<IType> selectedTypes) throws JavaModelException, PartInitException {
        JavaUI.openInEditor(findNewType(selectedTypes.get(0)));
    }

    private static void performRefactoring(CreateNewTopLevelSuperClassRefactoring refactoring,
            IProgressMonitor monitor) throws CoreException {
        PerformRefactoringOperation operation = new PerformRefactoringOperation(refactoring,
                CheckConditionsOperation.INITIAL_CONDITONS);
        operation.run(monitor);
    }

    private static RefactoringStatus checkRefactoring(List<IType> selectedTypes,
            CreateNewTopLevelSuperClassRefactoring refactoring, IProgressMonitor monitor) throws CoreException {
        RefactoringStatus status = new RefactoringStatus();
        status.merge(refactoring.checkInitialConditions(monitor));
        status.merge(refactoring.checkFinalConditions(monitor));
        //      I (Mohsen) disabled the following check because it is too expensive.
        //      status.merge(areSelectedTypesCompatible(refactoring, selectedTypes, monitor));
        return status;
    }

    private static CreateNewTopLevelSuperClassRefactoring createRefactoring(List<IType> selectedTypes)
            throws CoreException {
        CreateNewTopLevelSuperClassDescriptor descriptor = createRefactoringDescriptor(selectedTypes);
        CreateNewTopLevelSuperClassRefactoring refactoring = (CreateNewTopLevelSuperClassRefactoring) descriptor
                .createRefactoringContext(new RefactoringStatus()).getRefactoring();
        return refactoring;
    }

    private static List<IType> getSelectedTypes(IEditorPart editorPart, ISelection selection)
            throws InvalidSelectionException, JavaModelException {
        List<IType> selectedTypes;
        if (selection instanceof ITextSelection) {
            selectedTypes = getSelectedTypes(editorPart, (ITextSelection) selection);
        } else if (selection instanceof IStructuredSelection) {
            selectedTypes = getSelectedTypes((IStructuredSelection) selection);
        } else {
            throw new InvalidSelectionException("Unexpected kind of selection");
        }
        return selectedTypes;
    }

    //   private static RefactoringStatus areSelectedTypesCompatible(CreateNewTopLevelSuperClassRefactoring refactoring, List<IType> selectedTypes, IProgressMonitor monitor) {
    //      RefactoringStatus status= new RefactoringStatus();
    //      List<IType> possibleTypes= Arrays.asList(refactoring.getCandidateTypes(monitor));
    //      if (!fullyQualifiedName(possibleTypes).containsAll(fullyQualifiedName(selectedTypes))) {
    //         status.merge(RefactoringStatus.createErrorStatus("The selected types belong to different class hierarchies."));
    //      }
    //      return status;
    //   }

    private boolean choseToProceed(Shell shell, RefactoringStatus status) {
        return new RefactoringStatusDialog(status, shell, "Refactoring Problems", false).open() == Window.OK;
    }

    // See http://publib.boulder.ibm.com/infocenter/iadthelp/v6r0/index.jsp?topic=/org.eclipse.jdt.doc.isv/guide/jdt_api_open_editor.htm
    private static IType findNewType(IType firstSelectedType) {
        return firstSelectedType.getPackageFragment()
                .getCompilationUnit("Super" + firstSelectedType.getElementName() + JavaModelUtil.DEFAULT_CU_SUFFIX)
                .findPrimaryType();
    }

    public static List<IType> getSelectedTypes(IEditorPart editorPart, ITextSelection selection)
            throws InvalidSelectionException, JavaModelException {
        CompilationUnitEditor editor;
        if (editorPart instanceof CompilationUnitEditor) {
            editor = (CompilationUnitEditor) editorPart;
        } else {
            throw new InvalidSelectionException("The active editor is not for editing Java compilation units.");
        }
        IType selectedType = SelectionConverter.getTypeAtOffset(editor);
        if (selectedType != null) {
            return Arrays.asList(selectedType);
        } else {
            throw new InvalidSelectionException("No Java types were selected.");
        }
    }

    private static List<IType> getSelectedTypes(IStructuredSelection selection)
            throws JavaModelException, InvalidSelectionException {
        List<IType> selectedTypes = new ArrayList<IType>();
        for (Object selectionElement : selection.toList()) {
            selectedTypes.add(extractTypeFromSelection(selectionElement));
        }
        return selectedTypes;
    }

    // See org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester.getSingleSelectedType(IStructuredSelection)
    private static IType extractTypeFromSelection(Object selectionElement)
            throws JavaModelException, InvalidSelectionException {
        if (selectionElement instanceof IType)
            return (IType) selectionElement;
        if (selectionElement instanceof ICompilationUnit) {
            final ICompilationUnit unit = (ICompilationUnit) selectionElement;
            if (unit.exists()) {
                return JavaElementUtil.getMainType(unit);
            }
        }
        throw new InvalidSelectionException(selectionElement + " is not a Java type.");
    }

    private static String typeNames(List<IType> types) {
        StringBuilder sb = new StringBuilder();
        for (Iterator<IType> iterator = types.iterator(); iterator.hasNext();) {
            IType type = (IType) iterator.next();
            sb.append(type.getElementName());
            if (iterator.hasNext()) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    public static CreateNewTopLevelSuperClassDescriptor createRefactoringDescriptor(List<IType> types) {
        IJavaProject javaProject = types.get(0).getJavaProject();
        String description = MessageFormat
                .format(CompositeRefactoringsMessages.CreateNewTopLevelSuperClass_description, typeNames(types));
        Map<String, String> arguments = new HashMap<String, String>();
        arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT,
                JavaRefactoringDescriptorUtil.elementToHandle(javaProject.getElementName(), types.get(0)));
        org.eclipse.jdt.internal.core.refactoring.descriptors.JavaRefactoringDescriptorUtil.setJavaElementArray(
                arguments, CreateNewTopLevelSuperClassDescriptor.ATTRIBUTE_TYPES,
                JavaRefactoringDescriptorUtil.ATTRIBUTE_ELEMENT, javaProject.getElementName(),
                types.toArray(new IType[] {}), 1);
        arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME, "Super" + types.get(0).getElementName());
        CreateNewTopLevelSuperClassDescriptor descriptor = new CreateNewTopLevelSuperClassDescriptor(
                javaProject.getElementName(), description, null, arguments,
                RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE);
        return descriptor;
    }

}