alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 *
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 *
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */
package org.netbeans.modules.refactoring.api;

import java.io.IOException;
import java.lang.reflect.Modifier;
import java.text.MessageFormat;
import java.util.*;
import javax.jmi.reflect.RefObject;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.jmi.javamodel.*;
import org.netbeans.modules.javacore.jmiimpl.javamodel.MethodImpl;
import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
import org.netbeans.modules.javacore.internalapi.ExternalChange;
import org.netbeans.modules.javacore.internalapi.ProgressListener;
import org.netbeans.modules.refactoring.CheckUtils;
import org.netbeans.modules.refactoring.NbAbstractRefactoring;
import org.netbeans.modules.refactoring.RenameUsageElement;
import org.netbeans.modules.refactoring.ui.RefactoringOperationListener;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataFolder;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.text.PositionBounds;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;

/**
 *
 * @author Martin Matula, Pavel Flaska, Daniel Prusa
 */
public class RenameRefactoring extends NbAbstractRefactoring implements ProgressListener {
    private final RefObject jmiObject;
    private String newName = null;
    private Collection overriddenByMethods = null; // methods that override the method to be renamed
    private Collection overridesMethods = null; // methods that are overridden by the method to be renamed
    private boolean donePreCheck = false;
    private boolean doCheckName = true;
    private FileObject originalFolder = null;
    
    /** Creates a new instance of RenameRefactoring */
    public RenameRefactoring(RefObject jmiObject) {
        this.jmiObject = jmiObject;
    }
    
    public RenameRefactoring(RefObject jmiObject, boolean doCheckName) {
        this.jmiObject = jmiObject;
        this.doCheckName = doCheckName;
    }
    
    public RenameRefactoring(RefObject jmiObject, FileObject folder) {
        this(jmiObject);
        originalFolder = folder;
    }

    public RenameRefactoring(RefObject jmiObject, boolean checkName, FileObject folder) {
        this(jmiObject, checkName);
        originalFolder = folder;
    }

    
    public Problem preCheck() {
        fireProgressListenerStart(PRE_CHECK, 4);
        try {
            Problem result = null;
            if (jmiObject instanceof Method) {
                fireProgressListenerStep();
                Method m = (Method) jmiObject;
                List argTypes = getParamTypes(m);
                fireProgressListenerStep();
                overriddenByMethods = overriddenBy(m, m.getName(), argTypes);
                fireProgressListenerStep();
                if (!overriddenByMethods.isEmpty()) {
                    String msg = new MessageFormat(getString("ERR_IsOverridden")).format(
                        new Object[] {getDefClassName(m.getDeclaringClass())}
                    );
                    result = createProblem(result, false, msg);
                }
                ClassDefinition[] par = new ClassDefinition[] {null, null};
                overridesMethods = overrides(m, m.getName(), argTypes, par);
                fireProgressListenerStep();
                if (!overridesMethods.isEmpty()) {
                    if (par[0] == null) {
                        String msg = getString ("ERR_Overrides");
                        result = createProblem(result, false, msg);
                    } else {
                        String clsName = getDefClassName(par[0]);
                        String msg = new MessageFormat(getString("ERR_Overrides_tree")).format(
                            new Object[] {clsName, getDefClassName(par[1]), clsName}
                        );
                        result = createProblem(result, true, msg);
                    }
                }
            } else if (jmiObject instanceof Field) {
                fireProgressListenerStep();
                fireProgressListenerStep();
                Field f = (Field) jmiObject;
                Field hiddenField = hides(f, f.getName());
                fireProgressListenerStep();
                fireProgressListenerStep();
                if (hiddenField != null) {
                    String msg = new MessageFormat(getString("ERR_Hides")).format(
                        new Object[] {getDefClassName(hiddenField.getDeclaringClass())}
                    );
                    result = createProblem(result, false, msg);
                }
            } else if(jmiObject instanceof JavaPackage) {
                //TODO: any prechecks?
            } else if(jmiObject instanceof Resource) {
                //any prechecks?
            } else if (!(jmiObject instanceof JavaClass)) {
                fireProgressListenerStep();
                result = createProblem(result, true, NbBundle.getMessage(RenameRefactoring.class, "ERR_RenameWrongType"));
            }

            if (result == null || !result.isFatal()) {
                donePreCheck = true;
            }

            return result;
        } finally {
            fireProgressListenerStop();
        }
    }
    
    public Problem checkParameters(String newName) {
        Problem result = null;
        
        if (!donePreCheck) {
            result = preCheck();
            if (result != null && result.isFatal()) {
                return result;
            }
        }
        
        if (getElementName((NamedElement) jmiObject).equals(newName)) {
            boolean nameNotChanged = true;
            if (jmiObject instanceof JavaClass) {
                Object comp = jmiObject.refImmediateComposite();
                if (comp instanceof Resource) {
                    String dobjName = JavaMetamodel.getManager().getDataObject((Resource)comp).getName();
                    nameNotChanged = dobjName.equals(newName);
                }
            }
            if (nameNotChanged)
                return createProblem(result, true, getString("ERR_NameNotChanged"));
        } 

        if (!Utilities.isJavaIdentifier(newName)) {
            String s = (jmiObject instanceof JavaPackage)? getString("ERR_InvalidPackage"):getString("ERR_InvalidIdentifier"); //NOI18N
            String msg = new MessageFormat(s).format(
                new Object[] {newName}
            );
            result = createProblem(result, true, msg);
            return result;
        }

        if (jmiObject instanceof JavaPackage) {
            if (doCheckName) {
                JavaPackage pckg = (JavaPackage) jmiObject;
                String fullName = pckg.getName();
                String name;
                int last = fullName.lastIndexOf('.');
                if (last > 0) {
                    name = fullName.substring(0,last+1) + newName;
                } else {
                    name = newName;
                }
                if (originalFolder != null) {
                    ClassPath projectClassPath = ClassPath.getClassPath(originalFolder, ClassPath.SOURCE);
                    if (projectClassPath.findResource(name.replace('.','/'))!=null) {
                        String msg = new MessageFormat(getString("ERR_PackageExists")).format(
                            new Object[] {newName}
                        );
                        result = createProblem(result, true, msg);
                    }
                }
            }

            this.newName = newName;
            return result;
        }

        if (jmiObject instanceof JavaClass || jmiObject instanceof Resource) {
            if (doCheckName) {
                Object ref;
                if (jmiObject instanceof Resource) {
                    ref = jmiObject;
                } else {
                    ref = jmiObject.refImmediateComposite();
                }
                if (ref instanceof Resource && !JavaMetamodel.getManager().getDataObject((Resource) ref).getName().equals(newName)) {
                    DataObject dobj = JavaMetamodel.getManager().getDataObject((Resource)ref);
                    FileObject primFile = dobj.getPrimaryFile();
                    FileObject folder = primFile.getParent();
                    FileObject[] children = folder.getChildren();
                    for (int x = 0; x < children.length; x++) {
                        if (children[x] != primFile && children[x].getName().equals(newName) && "java".equals(children[x].getExt())) { //NOI18N
                            String msg = new MessageFormat (getString ("ERR_ClassClash")).format (
                                new Object[] {newName, ((Resource) ref).getPackageName()}
                            );
                            result = createProblem(result, true, msg);
                            break;
                        }
                    } // for
                } // if
            } // if
        }

        if (!(jmiObject instanceof Resource)) {
            String msg = clashes((Feature) jmiObject, newName);
            if (msg != null) {
                result = createProblem(result, true, msg);
                return result;
            }
        }
        return result;
    }
    
    public Problem setParameters(String newName) {
        int steps = 0;
        if (overriddenByMethods != null)
            steps += overriddenByMethods.size();
        if (overridesMethods != null)
            steps += overridesMethods.size();
        
        fireProgressListenerStart(PARAMETERS_CHECK, 8 + 3*steps);
        
        try {
            fireProgressListenerStep();
            Problem result = checkParameters(newName);
            if (result != null && result.isFatal())
                return result;
            fireProgressListenerStep();
            String msg;
            if (jmiObject instanceof Method) {
                Method m = (Method) jmiObject;
                result = checkMethodForOverriding(m, newName, result);
                for (Iterator iter = overridesMethods.iterator(); iter.hasNext();) {
                    m = (Method) iter.next();
                    msg = clashes(m, newName);
                    if (msg != null) {
                        result = createProblem(result, true, msg);
                    }
                    result = checkMethodForOverriding(m, newName, result);
                }
                for (Iterator iter = overriddenByMethods.iterator(); iter.hasNext();) {
                    m = (Method) iter.next();
                    msg = clashes(m, newName);
                    if (msg != null) {
                        result = createProblem(result, true, msg);
                    }
                    result = checkMethodForOverriding(m, newName, result);
                }
                fireProgressListenerStep();
                fireProgressListenerStep();
            } else if (jmiObject instanceof Field) {
                Field f = (Field) jmiObject;
                fireProgressListenerStep();
                fireProgressListenerStep();
                Field hiddenField = hides(f, newName);
                fireProgressListenerStep();
                fireProgressListenerStep();
                fireProgressListenerStep();
                if (hiddenField != null) {
                    msg = new MessageFormat(getString("ERR_WillHide")).format(
                    new Object[] {getDefClassName(hiddenField.getDeclaringClass())}
                    );
                    result = createProblem(result, false, msg);
                }
            }
            
            if (result == null || !result.isFatal()) {
                this.newName = newName; // [PENDING] ???
            }
            
            return result;
        } finally {
            fireProgressListenerStop();
        }
    }
    
    private Problem checkMethodForOverriding(Method m, String newName, Problem problem) {
        List argTypes = getParamTypes(m);
        fireProgressListenerStep();
        problem = willBeOverridden(m, newName, argTypes, problem);
        fireProgressListenerStep();        
        problem = willOverride(m, newName, argTypes, problem);
        fireProgressListenerStep();
        return problem;
    }
    
    public Problem prepare(java.util.Collection elements) {
        if (newName == null) {
            return new Problem(true, getString("ERR_NameNotSet"));
        }
        
        int steps = 9;
        if (overriddenByMethods != null)
            steps += overriddenByMethods.size();
        if (overridesMethods != null)
            steps += overridesMethods.size();
        
        JavaMetamodel.getManager().getProgressSupport().addProgressListener(this);

        
        //fireProgressListenerStart(PREPARE, steps);
        
        try {
            if (jmiObject instanceof JavaPackage) {
                //fireProgressListenerStep();
                
                referencesIterator = ((NamedElement) jmiObject).getReferences().iterator();
                while (referencesIterator.hasNext()) {
                    if (cancelRequest) {
                        return null;
                    }
                    elements.add(new RenamePackageElement(jmiObject, (Element) referencesIterator.next(), newName));
                }
                DataFolder folder = originalFolder!=null ? DataFolder.findFolder(originalFolder) : getFolder(((JavaPackage)jmiObject).getName());
                if (folder != null) {
                    elements.add(new RenameDataFolder(folder, newName));
                }
                return null;
            } else {
                //fireProgressListenerStep();
                addElementsForJmiObject(elements, jmiObject);
                
                
                if (overridesMethods != null) {
                    for (Iterator iter = overridesMethods.iterator(); iter.hasNext();) {
                        if (cancelRequest) {
                            return null;
                        }
                        //fireProgressListenerStep();
                        elements.add(new RenameDOElement((RefObject) iter.next()));
                        //addElementsForJmiObject(elements, (RefObject) iter.next());
                    }
                }
                if (overriddenByMethods != null) {
                    for (Iterator iter = overriddenByMethods.iterator(); iter.hasNext();) {
                        if (cancelRequest) {
                            return null;
                        }
                        //fireProgressListenerStep();
                        elements.add(new RenameDOElement((RefObject) iter.next()));
                        //addElementsForJmiObject(elements, (RefObject) iter.next());
                    }
                }
                 
                return null;
            }
        } finally {
            referencesIterator = null;
            JavaMetamodel.getManager().getProgressSupport().removeProgressListener(this);
        }
    }
    
    private void addElementsForJmiObject(Collection elements, RefObject refObject) {
        elements.add(new RenameDOElement(refObject));
        if (refObject instanceof Method) {
            referencesIterator = ((MethodImpl) refObject).findDependencies(true, true, false).iterator();
        } else {
            referencesIterator = ((NamedElement) refObject).getReferences().iterator();
        }
        while (referencesIterator.hasNext()) {
            if (cancelRequest) {
                return;
            }
            elements.add(new RenameUsageElement(refObject, (Element) referencesIterator.next(), newName));
        }
    }
    
    private DataFolder getFolder(String name) {
        FileObject fo = classPath.findResource(name.replace('.','/'));
        if (fo == null)
            return null;
        return DataFolder.findFolder(fo);
    }
    
    private Collection overriddenBy(Method method, String name, List argTypes) {
        if (!isVirtual(method))
            return Collections.EMPTY_LIST;

        Collection result = new HashSet();
        ClassDefinition jc = method.getDeclaringClass();
        LinkedList subtypes = new LinkedList();
        addSubtypes(jc, subtypes);
        while (subtypes.size() > 0) {
            jc = (ClassDefinition) subtypes.removeFirst();
            if (jc instanceof UnresolvedClass) {
                continue;
            }
            Method m = jc.getMethod(name, argTypes, false);
            if ((m != null) && isVirtual(m)) {
                result.add(m);
            }
            addSubtypes(jc, subtypes);
        }
        return result;
    }
    
    private Collection overrides(Method method, String name, List argTypes, ClassDefinition[] cls_par) {
        if (!isVirtual(method))
            return Collections.EMPTY_LIST;

        ClassDefinition javaClass = method.getDeclaringClass ();
        LinkedList supertypes = new LinkedList ();
        Collection result = new HashSet();
        Method last = null;

        supertypes.addAll (javaClass.getInterfaces());
        ClassDefinition jc = javaClass.getSuperClass ();
        if (jc != null)
            supertypes.add (jc);
        while (supertypes.size () > 0) {
            jc = (ClassDefinition) supertypes.removeFirst ();
            if (jc instanceof UnresolvedClass) {
                continue;
            }
            Method m = jc.getMethod (name, argTypes, false);
            if ((m != null) && isVirtual(m)) {
                result.add(m);
                last = m;                
            }
            supertypes.addAll (jc.getInterfaces ());
            jc = jc.getSuperClass ();
            if (jc != null) {
                supertypes.add (jc);
            }
        }
        
        if (last != null) {
            ClassDefinition cd = last.getDeclaringClass();
            ClassDefinition implementor = findDifferentSubtype((JavaClass) cd, name, argTypes, javaClass);
            if (implementor != null) {
                cls_par[0] = cd;
                cls_par[1] = implementor;
            }
        }
        return result;
    }        
    
    private ClassDefinition findDifferentSubtype(JavaClass baseClass, String name, List argTypes, ClassDefinition subtype) {
        Set supertypes = new HashSet();
        LinkedList subtypes = new LinkedList();
        ClassDefinition jc = baseClass;
        
        collectSupertypes(supertypes, subtype);
        addSubtypes(jc, subtypes);
        while (subtypes.size() > 0) {
            jc = (ClassDefinition) subtypes.removeFirst();
            if (jc instanceof UnresolvedClass) {
                continue;
            }
            if (supertypes.contains(jc)) {
                continue;
            } else if (jc.getMethod(name, argTypes, false) != null) {
                return jc;
            }
            addSubtypes(jc, subtypes);
        }
        return null;
    }

    private void collectSupertypes(Set supertypes, ClassDefinition jc) {
        if (jc == null)
            return;
        supertypes.add(jc);
        collectSupertypes(supertypes, jc.getSuperClass());
        for (Iterator iter = jc.getInterfaces().iterator(); iter.hasNext();) {
            collectSupertypes(supertypes, (ClassDefinition)iter.next());
        }
    }
    
    private boolean isVirtual(Feature feature) {
        int mod = feature.getModifiers ();
        return ((mod & Modifier.PROTECTED) > 0) || ((mod & Modifier.PUBLIC) > 0);
    }
    
    private boolean isStatic(Feature feature) {
        return (feature.getModifiers () & Modifier.STATIC) > 0;
    }
    
    private int getAccessLevel(Feature f) {
        int mod = f.getModifiers();
        if ((mod & Modifier.PUBLIC) > 0)
            return 3;
        if ((mod & Modifier.PROTECTED) > 0)
            return 2;
        if ((mod & Modifier.PRIVATE) > 0)
            return 0;
        return 1;
    }
    
    private Method isOverridden(Method method, String name, List argTypes) {
        if (!isVirtual(method))
            return null;

        ClassDefinition jc = method.getDeclaringClass();
        LinkedList subtypes = new LinkedList();
        addSubtypes(jc, subtypes);
        while (subtypes.size() > 0) {
            jc = (ClassDefinition) subtypes.removeFirst();
            if (jc instanceof UnresolvedClass) {
                continue;
            }
            Method m = jc.getMethod(name, argTypes, false);
            if ((m != null) && isVirtual(m))
                return m;
            addSubtypes(jc, subtypes);
        }
        return null;
    }

    private Problem willBeOverridden(Method method, String name, List argTypes, Problem problem) {
        int accessLevel = getAccessLevel(method);
        if (accessLevel == 0)
            return null;
                
        boolean isStatic = isStatic(method);
        boolean isFinal = (method.getModifiers() & Modifier.FINAL) > 0;
        Method temp = null;
        ClassDefinition jc = method.getDeclaringClass();
        LinkedList subtypes = new LinkedList();
        addSubtypes(jc, subtypes);
        while (subtypes.size() > 0) {
            jc = (ClassDefinition) subtypes.removeFirst();
            if (jc instanceof UnresolvedClass) {
                continue;
            }
            Method m = jc.getMethod(name, argTypes, false);
            if (m != null) {
                if (temp == null)
                    temp = m;
                if (isFinal) {
                    String msg = new MessageFormat(getString("ERR_WillBeOverridden_final")).format(
                        new Object[] {
                            method.getName(),
                            getDefClassName(method.getDeclaringClass()),
                            m.getName(),
                            getDefClassName(m.getDeclaringClass())
                        }
                    );
                    return createProblem(problem, true, msg);
                }
                if (getAccessLevel(m) < accessLevel) {
                    String msg = new MessageFormat(getString("ERR_WillBeOverridden_access")).format(
                        new Object[] {
                            method.getName(),
                            getDefClassName(method.getDeclaringClass()),
                            m.getName(),
                            getDefClassName(m.getDeclaringClass())
                        }
                    );
                    return createProblem(problem, true, msg);
                }
                if (isStatic != isStatic(m)) {
                    String msg = new MessageFormat(getString("ERR_WillBeOverridden_static")).format(
                        new Object[] {
                            isStatic ? getString("LBL_static") : getString("LBL_instance"),
                            method.getName(),
                            getDefClassName(method.getDeclaringClass()),
                            isStatic(m) ? getString("LBL_static") : getString("LBL_instance"),
                            m.getName(),
                            getDefClassName(m.getDeclaringClass())
                        }
                    );
                    return createProblem(problem, true, msg);
                }
            } else {
                addSubtypes(jc, subtypes);
            }
        }
        if (temp != null) {
            String msg = new MessageFormat(getString("ERR_WillBeOverridden")).format(
                new Object[] {
                    method.getName(),
                    getDefClassName(method.getDeclaringClass()),
                    temp.getName(),
                    getDefClassName(temp.getDeclaringClass())
                }
            );
            return createProblem(problem, false, msg);
        } else {
            return problem;
        }
    }
    
    private Problem willOverride(Method method, String name, List argTypes, Problem problem) {
        int accessLevel = getAccessLevel(method);
        boolean isStatic = isStatic(method);        
        Method temp = null;
        ClassDefinition jc = method.getDeclaringClass ();
        LinkedList supertypes = new LinkedList ();

        supertypes.addAll (jc.getInterfaces());
        jc = jc.getSuperClass ();
        if (jc != null)
            supertypes.add (jc);
        while (supertypes.size () > 0) {
            jc = (ClassDefinition) supertypes.removeFirst ();
            if (jc instanceof UnresolvedClass) {
                continue;
            }
            Method m = jc.getMethod (name, argTypes, false);
            if (m != null) {
                if (temp == null)
                    temp = m;
                if ((m.getModifiers() & Modifier.FINAL) > 0) {
                    String msg = new MessageFormat(getString("ERR_WillOverride_final")).format(
                        new Object[] {
                            method.getName(),
                            getDefClassName(method.getDeclaringClass()),
                            m.getName(),
                            getDefClassName(m.getDeclaringClass())
                        }
                    );
                    return createProblem(problem, true, msg);
                }
                if (getAccessLevel(m) > accessLevel) {
                    String msg = new MessageFormat(getString("ERR_WillOverride_access")).format(
                        new Object[] {
                            method.getName(),
                            getDefClassName(method.getDeclaringClass()),
                            m.getName(),
                            getDefClassName(m.getDeclaringClass())
                        }
                    );
                    return createProblem(problem, true, msg);
                }
                if (isStatic != isStatic(m)) {
                    String msg = new MessageFormat(getString("ERR_WillOverride_static")).format(
                        new Object[] {
                            isStatic ? getString("LBL_static") : getString("LBL_instance"),
                            method.getName(),
                            getDefClassName(method.getDeclaringClass()),
                            isStatic(m) ? getString("LBL_static") : getString("LBL_instance"),
                            m.getName(),
                            getDefClassName(m.getDeclaringClass())
                        }
                    );
                    return createProblem(problem, true, msg);
                }
            } else {
                supertypes.addAll (jc.getInterfaces ());
                jc = jc.getSuperClass ();
                if (jc != null)
                    supertypes.add (jc);
            }
        } // while
        if (temp != null) {
            String msg = new MessageFormat(getString("ERR_WillOverride")).format(
                new Object[] {
                    method.getName(),
                    getDefClassName(method.getDeclaringClass()),
                    temp.getName(),
                    getDefClassName(temp.getDeclaringClass())
                }
            );
            return createProblem(problem, false, msg);
        } else {
            return problem;
        }
    }
    
    private Method overrides(Method method, String name, List argTypes, boolean findFinal) {
        Method res = null;
        if (!isVirtual(method))
            return null;

        ClassDefinition jc = method.getDeclaringClass ();
        LinkedList supertypes = new LinkedList ();

        supertypes.addAll (jc.getInterfaces());
        jc = jc.getSuperClass ();
        if (jc != null)
            supertypes.add (jc);
        while (supertypes.size () > 0) {
            jc = (ClassDefinition) supertypes.removeFirst ();
            if (jc instanceof UnresolvedClass) {
                continue;
            }
            Method m = jc.getMethod (name, argTypes, false);
            if ((m != null) && isVirtual(m)) {
                if ((m.getModifiers () & Modifier.FINAL) > 0) {
                    res = m;
                    break;
                } else if (res == null) {
                    res = m;
                    if (!findFinal)
                        break;
                }
            }
            supertypes.addAll (jc.getInterfaces ());
            jc = jc.getSuperClass ();
            if (jc != null)
                supertypes.add (jc);
        }        
        return res;
    }

    private Field hides (Field field, String name) {
        if (!isVirtual(field))
            return null;

        ClassDefinition jc = field.getDeclaringClass ();
        jc = jc.getSuperClass ();
        while (jc != null) {
            Field f = jc.getField (name, false);
            if ((f != null) && isVirtual(f))
                return f;
            jc = jc.getSuperClass ();
        }
        return null;
    }

    private String clashes(Feature feature, String newName) {
        ClassDefinition dc = feature.getDeclaringClass ();
        if (feature instanceof JavaClass) {
            if (dc != null) {
                Iterator iter = dc.getFeatures ().iterator ();
                while (iter.hasNext ()) {
                    Object obj = iter.next();
                    if (!(obj instanceof JavaClass))
                        continue;
                    JavaClass nestedClass = (JavaClass) obj;
                    if (nestedClass.getSimpleName ().equals (newName)) {
                        return new MessageFormat (getString ("ERR_InnerClassClash")).format (
                            new Object[] {newName, getDefClassName(dc)}
                        );
                    }
                } // while
            } else {
                Resource resource = (Resource)feature.refImmediateComposite();
                DataObject dobj = JavaMetamodel.getManager().getDataObject(resource);
                FileObject primFile = dobj.getPrimaryFile();
                FileObject folder = primFile.getParent();
                FileObject[] children = folder.getChildren();
                for (int x = 0; x < children.length; x++) {
                    if (children[x] != primFile && children[x].getName().equals(newName) && "java".equals(children[x].getExt())) { //NOI18N
                        return new MessageFormat (getString ("ERR_ClassClash")).format (
                            new Object[] {newName, resource.getPackageName()}
                        );
                    }
                }
            }
        } else if (feature instanceof Method) {
            List params = getParamTypes ((Method) feature);
            if (CheckUtils.getMethod (dc, newName, params) != null) {
                return new MessageFormat (getString ("ERR_MethodClash")).format (
                    new Object[] {newName, getDefClassName(dc)}
                );
            } // if
        } else if (feature instanceof Field) {
            if (CheckUtils.getField (dc, newName) != null) {
                return new MessageFormat (getString ("ERR_FieldClash")).format (
                    new Object[] {newName, getDefClassName(dc)}
                );
            } // if
        }
        return null;
    }
    
    String getElementName (NamedElement elem) {
        if (elem instanceof JavaClass) {
            return ((JavaClass) elem).getSimpleName();
        } else {
            return elem.getName();
        }
    }
    
    String getDefClassName(ClassDefinition cd) {
        if (cd instanceof JavaClass) {
            return ((JavaClass) cd).getName();
        } else {
            return "";
        }
    }
    
    private List getParamTypes(Method method) {
        List types = new LinkedList ();
        Iterator iter = method.getParameters ().iterator ();
        while (iter.hasNext ())
            types.add (getRealType(((Parameter) iter.next ()).getType ()));
        return types;
    }
    
    private static Type getRealType(Type type) {
        if (type instanceof ParameterizedType) {
            return ((ParameterizedType) type).getDefinition();
        }
        return type;
    }

    private void addSubtypes(ClassDefinition cd, List list) {
        if (!(cd instanceof JavaClass)) {
            return;
        }
        JavaClass jc = (JavaClass) cd;
        Collection subtypes = null;
        if (jc.isInterface()) {            
            subtypes = jc.getImplementors();
        } else {
            subtypes = jc.getSubClasses();            
        }
        list.addAll(subtypes);        
    }
    
    private static final String getString(String key) {
        return NbBundle.getMessage(RenameRefactoring.class, key);
    }
    
    public void start(org.netbeans.modules.javacore.internalapi.ProgressEvent event) {
        fireProgressListenerStart(event.getOperationType(), event.getCount());
    }
    
    public void step(org.netbeans.modules.javacore.internalapi.ProgressEvent event) {
        fireProgressListenerStep();
    }
    
    public void stop(org.netbeans.modules.javacore.internalapi.ProgressEvent event) {
        fireProgressListenerStop();
    }
    
    public void setClassPath() {
        if (jmiObject instanceof Method) {
            Collection c = ((MethodImpl) jmiObject).getOverridenMethods();
            if (!c.isEmpty()) {
                setClassPath(c);
                return;
            }
        }
        setClassPath((Element) jmiObject);
    }

    // RenameDOElement ..........................................................
    private class RenameDOElement implements RefactoringElement, ExternalChange {
        private boolean enabled = true;
        private final String text;
        private PositionBounds bounds = null;
        private String oldName = null;
        private Resource res = null;
        private RefObject refObject;
        
        private int status;
        
        public RenameDOElement(RefObject refObject) {
            this.refObject = refObject;
            Object o;
            if (refObject instanceof Resource) {
                o = refObject;
            } else {
                o = refObject.refImmediateComposite();
            }
            if (o instanceof Resource) res = (Resource) o;
            String bundleName;
            if (refObject instanceof Resource) {
                bundleName = "LBL_RenameClassDO";
            } else {
                bundleName = refObject instanceof JavaClass ? (isResourceClass() ? "LBL_RenameClassDO" : "LBL_RenameClass") : (refObject instanceof Method ? "LBL_RenameMethod" : "LBL_RenameField"); //NOI18N
            }
            text = MessageFormat.format(NbBundle.getMessage(RenameRefactoring.class, bundleName), new Object[] {newName});
            
            if (!(refObject instanceof ClassMember)) {
                status = RefactoringElement.NORMAL;
            } else {
                if (JavaMetamodel.getManager().isElementGuarded((ClassMember)refObject)) {
                    status = RefactoringElement.GUARDED;
                } else {
                    status = RefactoringElement.NORMAL;
                }
            }
        }
        
        /**
         * Tests, if the renamed object should cause resource rename. Checks
         * if the object is java class. Then it checks for resource. If the
         * resource exists and resource name is the same as the name of class
         * is the same as the name of resource, it returns true. In all other
         * cases it returns false.
         *
         * @return  true, if the renamed object should cause resource rename
         */
         private boolean isResourceClass() { //todo (#pf): try to find out better name for this method.
            if (res == null || !(refObject instanceof JavaClass))
                return false;
            int classCount = 0;
            for (Iterator iter = res.getClassifiers().iterator(); iter.hasNext(); ) {
                if (iter.next() instanceof JavaClass) {
                    classCount++;
                }
            }
            if (classCount == 1) {
                return true;
            }
            String relativeResName = res.getName();
            String javaClassName = ((JavaClass) refObject).getSimpleName();
            int begin = relativeResName.lastIndexOf('/') + 1;
            if (begin < 0) begin = 0;
            int end = relativeResName.lastIndexOf('.');
            if (javaClassName.equals(relativeResName.substring(begin, end)))
                return true;
            else
                return false;
        }
        
        public String getDisplayText() {
            return text;
        }
        
        public Element getJavaElement() {
            return (Element) refObject;
        }
        
        public PositionBounds getPosition() {
            if (bounds == null) {
                if (!(refObject instanceof Resource)) {
                    bounds = getPositionBounds(refObject);
                }
            }
            return bounds;
        }
        
        public int getStatus() {
            return status;
        }
        
        public String getText() {
            return getDisplayText();
        }
        
        public boolean isEnabled() {
            return enabled;
        }
        
        public void performChange() {
            if (refObject instanceof Resource) {
                 JavaMetamodel.getManager().registerExtChange(this);
            } else {
                Feature obj = (Feature) refObject;
                if (obj instanceof JavaClass) {
                    oldName = ((JavaClass) obj).getSimpleName();
                    if (isResourceClass()) {
                        JavaMetamodel.getManager().registerExtChange(this);
                    }
                    ((JavaClass) obj).setSimpleName(newName);
                } else {
                    oldName = obj.getName();
                    obj.setName(newName);
                }
            }
        }
        
        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }
        
        private void doRename() {
            try {
                DataObject dobj = JavaMetamodel.getManager().getDataObject(res);
                oldName = dobj.getName();
                RefactoringOperationListener.removeOperationalListener();
                dobj.rename(newName);  
                RefactoringOperationListener.addOperationalListener();
            } catch (DataObjectNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        
        public void performExternalChange () {
            doRename();
        }
        
        public void undoExternalChange() {
           if (oldName == null) return;
            String temp = newName;
            newName = oldName;
            oldName = temp; 
            doRename();
            newName = temp; 
        }

        
    } // RenameDOElement

    // RenamePackageElement ..........................................................
    private class RenamePackageElement extends RenameUsageElement {
        private String oldName = null;

        public RenamePackageElement(RefObject jmiObject, Element feature, String newName) {
                super(jmiObject, feature, newName);
        }
        
        public void performChange() {
            MultipartId mpi = (MultipartId) feature;
            oldName = mpi.getName();
            mpi.setName(newName);
        }
        
    } // RenamePackageElement
    
    // RenameDataFolder ..........................................................
    private class RenameDataFolder implements RefactoringElement, ExternalChange {
        private boolean enabled = true;
        private final String text;
        private PositionBounds bounds = null;
        private String oldName = null;
        private DataFolder folder = null;
        
        public RenameDataFolder(DataFolder folder, String name) {
            newName = name; 
            this.folder = folder;
            text = MessageFormat.format(NbBundle.getMessage(RenameRefactoring.class, "LBL_RenameFolder"), new Object[] {folder.getName(), newName});
        }
        
        public String getDisplayText() {
            return text;
        }
        
        public Element getJavaElement() {
            return (Element) jmiObject;
        }
        
        public PositionBounds getPosition() {
            if (bounds == null) {
                bounds = getPositionBounds(jmiObject);
            }
            return bounds;
        }
        
        public int getStatus() {
            return NORMAL;
        }
        
        public String getText() {
            return getDisplayText();
        }
        
        public boolean isEnabled() {
            return enabled;
        }
        
        public void performChange() {
             JavaMetamodel.getManager().registerExtChange(this);
        }
        
        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }
        
        private void doRename() {
            oldName = folder.getName();
            try {
                RefactoringOperationListener.removeOperationalListener();
                folder.rename(newName);
                RefactoringOperationListener.addOperationalListener();
            } catch (java.io.IOException e) {
                throw new RuntimeException(e);
            }
        }
        
        public void performExternalChange () {
            doRename();
        }
        
        public void undoExternalChange() {
            if (oldName == null) return;
            String temp = newName;
            newName = oldName;
            oldName = temp; 
            doRename();
            newName = temp; 
        }
        
    } // RenameDataFolder
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.