edu.illinois.compositerefactorings.refactorings.MemberCheckUtil.java Source code

Java tutorial

Introduction

Here is the source code for edu.illinois.compositerefactorings.refactorings.MemberCheckUtil.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2011 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package edu.illinois.compositerefactorings.refactorings;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.corext.refactoring.Checks;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Messages;
import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.RefactoringStatusContext;

/**
 * {@link org.eclipse.jdt.internal.corext.refactoring.structure.MemberCheckUtil}
 */
@SuppressWarnings("restriction")
public class MemberCheckUtil {

    private MemberCheckUtil() {
        //static only
    }

    public static RefactoringStatus checkMembersInDestinationType(IMember[] members, IType destinationType)
            throws JavaModelException {
        RefactoringStatus result = new RefactoringStatus();
        for (int i = 0; i < members.length; i++) {
            if (members[i].getElementType() == IJavaElement.METHOD)
                checkMethodInType(destinationType, result, (IMethod) members[i]);
            else if (members[i].getElementType() == IJavaElement.FIELD)
                checkFieldInType(destinationType, result, (IField) members[i]);
            else if (members[i].getElementType() == IJavaElement.TYPE)
                checkTypeInType(destinationType, result, (IType) members[i]);
        }
        return result;
    }

    private static void checkMethodInType(IType destinationType, RefactoringStatus result, IMethod method)
            throws JavaModelException {
        IMethod[] destinationTypeMethods = destinationType.getMethods();
        IMethod found = findMethod(method, destinationTypeMethods);
        if (found != null) {
            RefactoringStatusContext context = JavaStatusContext.create(destinationType.getCompilationUnit(),
                    found.getSourceRange());
            String message = Messages.format(RefactoringCoreMessages.MemberCheckUtil_signature_exists,
                    new String[] { BasicElementLabels.getJavaElementName(method.getElementName()),
                            getQualifiedLabel(destinationType) });
            result.addError(message, context);
        } else {
            IMethod similar = Checks.findMethod(method, destinationType);
            if (similar != null) {
                String message = Messages.format(RefactoringCoreMessages.MemberCheckUtil_same_param_count,
                        new String[] { BasicElementLabels.getJavaElementName(method.getElementName()),
                                getQualifiedLabel(destinationType) });
                RefactoringStatusContext context = JavaStatusContext.create(destinationType.getCompilationUnit(),
                        similar.getSourceRange());
                result.addWarning(message, context);
            }
        }
    }

    private static void checkFieldInType(IType destinationType, RefactoringStatus result, IField field)
            throws JavaModelException {
        IField destinationTypeField = destinationType.getField(field.getElementName());
        if (!destinationTypeField.exists())
            return;
        String message = Messages.format(RefactoringCoreMessages.MemberCheckUtil_field_exists,
                new String[] { BasicElementLabels.getJavaElementName(field.getElementName()),
                        getQualifiedLabel(destinationType) });
        RefactoringStatusContext context = JavaStatusContext.create(destinationType.getCompilationUnit(),
                destinationTypeField.getSourceRange());
        result.addError(message, context);
    }

    private static void checkTypeInType(IType destinationType, RefactoringStatus result, IType type)
            throws JavaModelException {
        String typeName = type.getElementName();
        IType destinationTypeType = destinationType.getType(typeName);
        if (destinationTypeType.exists()) {
            String message = Messages.format(RefactoringCoreMessages.MemberCheckUtil_type_name_conflict0,
                    new String[] { BasicElementLabels.getJavaElementName(typeName),
                            getQualifiedLabel(destinationType) });
            RefactoringStatusContext context = JavaStatusContext.create(destinationType.getCompilationUnit(),
                    destinationTypeType.getNameRange());
            result.addError(message, context);
        } else {
            //need to check the hierarchy of enclosing and enclosed types
            if (destinationType.getElementName().equals(typeName)) {
                String message = Messages.format(RefactoringCoreMessages.MemberCheckUtil_type_name_conflict1,
                        getQualifiedLabel(type));
                RefactoringStatusContext context = JavaStatusContext.create(destinationType.getCompilationUnit(),
                        destinationType.getNameRange());
                result.addError(message, context);
            }
            if (typeNameExistsInEnclosingTypeChain(destinationType, typeName)) {
                String message = Messages.format(RefactoringCoreMessages.MemberCheckUtil_type_name_conflict2,
                        getQualifiedLabel(type));
                RefactoringStatusContext context = JavaStatusContext.create(destinationType.getCompilationUnit(),
                        destinationType.getNameRange());
                result.addError(message, context);
            }
            checkHierarchyOfEnclosedTypes(destinationType, result, type);
        }
    }

    private static void checkHierarchyOfEnclosedTypes(IType destinationType, RefactoringStatus result, IType type)
            throws JavaModelException {
        IType[] enclosedTypes = getAllEnclosedTypes(type);
        for (int i = 0; i < enclosedTypes.length; i++) {
            IType enclosedType = enclosedTypes[i];
            if (destinationType.getElementName().equals(enclosedType.getElementName())) {
                String message = Messages.format(RefactoringCoreMessages.MemberCheckUtil_type_name_conflict3,
                        new String[] { getQualifiedLabel(enclosedType), getQualifiedLabel(type) });
                RefactoringStatusContext context = JavaStatusContext.create(destinationType.getCompilationUnit(),
                        destinationType.getNameRange());
                result.addError(message, context);
            }
            if (typeNameExistsInEnclosingTypeChain(destinationType, enclosedType.getElementName())) {
                String message = Messages.format(RefactoringCoreMessages.MemberCheckUtil_type_name_conflict4,
                        new String[] { getQualifiedLabel(enclosedType), getQualifiedLabel(type) });
                RefactoringStatusContext context = JavaStatusContext.create(destinationType.getCompilationUnit(),
                        destinationType.getNameRange());
                result.addError(message, context);
            }
        }
    }

    private static String getQualifiedLabel(IType enclosedType) {
        return BasicElementLabels.getJavaElementName(enclosedType.getFullyQualifiedName('.'));
    }

    private static IType[] getAllEnclosedTypes(IType type) throws JavaModelException {
        List<IType> result = new ArrayList<IType>(2);
        IType[] directlyEnclosed = type.getTypes();
        result.addAll(Arrays.asList(directlyEnclosed));
        for (int i = 0; i < directlyEnclosed.length; i++) {
            IType enclosedType = directlyEnclosed[i];
            result.addAll(Arrays.asList(getAllEnclosedTypes(enclosedType)));
        }
        return result.toArray(new IType[result.size()]);
    }

    private static boolean typeNameExistsInEnclosingTypeChain(IType type, String typeName) {
        IType enclosing = type.getDeclaringType();
        while (enclosing != null) {
            if (enclosing.getElementName().equals(typeName))
                return true;
            enclosing = enclosing.getDeclaringType();
        }
        return false;
    }

    /**
     * Finds a method in a list of methods. Compares methods by signature
     * (only SimpleNames of types), and not by the declaring type.
     * @param method the method to find
     * @param allMethods the methods to look at
     * @return The found method or <code>null</code>, if nothing found
     * @throws JavaModelException
     */
    public static IMethod findMethod(IMethod method, IMethod[] allMethods) throws JavaModelException {
        String name = method.getElementName();
        String[] paramTypes = method.getParameterTypes();
        boolean isConstructor = method.isConstructor();

        for (int i = 0; i < allMethods.length; i++) {
            if (JavaModelUtil.isSameMethodSignature(name, paramTypes, isConstructor, allMethods[i]))
                return allMethods[i];
        }
        return null;
    }
}