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.editor.java;

import java.lang.reflect.Modifier;
import java.util.*;
import javax.jmi.reflect.InvalidObjectException;
import javax.jmi.reflect.RefPackage;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.mdr.MDRepository;
import org.netbeans.editor.Settings;
import org.netbeans.editor.SettingsChangeEvent;
import org.netbeans.editor.SettingsChangeListener;
import org.netbeans.editor.SettingsUtil;
import org.netbeans.editor.ext.ExtSettingsDefaults;
import org.netbeans.editor.ext.ExtSettingsNames;
import org.netbeans.editor.ext.java.*;
import org.netbeans.editor.ext.java.JavaCompletion.BaseField;
import org.netbeans.editor.ext.java.JavaCompletion.BaseType;
import org.netbeans.jmi.javamodel.*;
import org.netbeans.modules.javacore.ClassIndex;
import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
import org.openide.filesystems.FileObject;

public class MDRFinder implements JCFinder, SettingsChangeListener{

    /*
    static final Comparator CLASS_NAME_COMPARATOR = new DefaultClassNameComparator();
    static final Comparator INSENSITIVE_CLASS_NAME_COMPARATOR = new InsensitiveClassNameComparator();
    static final Comparator NATURAL_MEMBER_NAME_COMPARATOR = new NaturalMemberNameComparator();    
     */

    public MDRepository repository = JavaMetamodel.getDefaultRepository ();
    
    private boolean caseSensitive = false;
    
    private boolean showDeprecated = true;
    
    private boolean naturalSort = false;    
    
    private FileObject fo;
    
    private Class kitClass;

    // ..........................................................................
    
    public MDRFinder(FileObject fo, Class kitClass){
        this();
        this.fo = fo;
        this.kitClass = kitClass;
        caseSensitive = getCaseSensitive();
        showDeprecated = showDeprecated();
        naturalSort = getNaturalSort();
        Settings.addSettingsChangeListener(this);        
    }
        
    public MDRFinder(){
        super();
    }

    public void settingsChange(SettingsChangeEvent evt) {
        if (evt == null || kitClass != evt.getKitClass()) return;
        
        if (ExtSettingsNames.COMPLETION_CASE_SENSITIVE.equals((evt.getSettingName()))){
            caseSensitive = getCaseSensitive();
        }else if (ExtSettingsNames.COMPLETION_NATURAL_SORT.equals((evt.getSettingName()))){
            naturalSort = getNaturalSort();
        }else if (ExtSettingsNames.SHOW_DEPRECATED_MEMBERS.equals((evt.getSettingName()))){
            showDeprecated = showDeprecated();
        }
    }
    
    
    private boolean getCaseSensitive() {
        return SettingsUtil.getBoolean(kitClass,
            ExtSettingsNames.COMPLETION_CASE_SENSITIVE,
            ExtSettingsDefaults.defaultCompletionCaseSensitive);
    }
    
    private boolean getNaturalSort() {
        return SettingsUtil.getBoolean(kitClass,
            ExtSettingsNames.COMPLETION_NATURAL_SORT,
            ExtSettingsDefaults.defaultCompletionNaturalSort);
    }
    
    private boolean showDeprecated() {
        return SettingsUtil.getBoolean(kitClass,
            ExtSettingsNames.SHOW_DEPRECATED_MEMBERS,
            ExtSettingsDefaults.defaultShowDeprecatedMembers);
    }
    
    
    private JavaModelPackage getJavaModelPackage() {
        RefPackage extent;
        String[] extentNames = repository.getExtentNames();
        for (int i = 0; i < extentNames.length; i++) {
            extent = repository.getExtent(extentNames[i]);
            if (extent instanceof JavaModelPackage) {
                return (JavaModelPackage) extent;
            }
        }
        return null;
    }

    private JavaPackage resolvePackage(String packageName, boolean caseSensitive) {
        JavaModelPackage extent = getJavaModelPackage();
        JavaPackageClass pkgProxy = extent.getJavaPackage();
        if (extent != null) {
            if (caseSensitive) {
                return pkgProxy.resolvePackage(packageName);
            } else {
                // [TODO] implement case insensitive search
                return pkgProxy.resolvePackage(packageName);
            }
        }
        return null;
    }
    
    public JCPackage getExactPackage(String packageName) {
        
        // System.out.println ("getExactPackage: " + packageName);
        
        repository.beginTrans (false);
        try {
            JavaPackage pkg = resolvePackage(packageName, true);
            if (pkg != null) {
                return new PackageImpl (pkg);
            }
        } finally {
            repository.endTrans (false);
        }
        
        return null;
    }

    public JCClass getExactClass(String classFullName) {
        // System.out.println ("getExactClass: " + classFullName);
        JavaModelPackage extent = getJavaModelPackage();
        if (extent != null) {
            Type cls = extent.getType().resolve(classFullName);
            if (cls instanceof UnresolvedClass)
                return null; 
            return cls != null ? new ClassImpl ((JavaClass)cls) : null;
        }
        return null;
    }
    
    public List findPackages(String name, boolean exactMatch, boolean subPackages) {
        
        // System.out.println("findPackages: " + name);
        
        ArrayList ret = new ArrayList ();
        
        repository.beginTrans (false);
        try {
            
            if (exactMatch) {
                JCPackage pkg = getExactPackage (name);
                if (pkg != null) {
                    ret.add (pkg);
                }
            } else {
                int index = name.lastIndexOf('.');
                String prefix = index > 0 ? name.substring(0, index) : "";
                JavaPackage pkg = resolvePackage(prefix, caseSensitive);
                if (pkg != null) {
                    Collection subpackages = pkg.getSubPackages();
                    ArrayList list = new ArrayList();
                    for (Iterator it = subpackages.iterator(); it.hasNext();) {
                        JavaPackage subPackage = (JavaPackage) it.next();
                        String spName = caseSensitive ? subPackage.getName() : subPackage.getName().toUpperCase();
                        String csName = caseSensitive ? name : name.toUpperCase();
                        if (spName.startsWith(csName)) {
                            list.add(subPackage);
                        }
                    }
                    for (Iterator iter = list.iterator (); iter.hasNext ();) {
                        JavaPackage javaPkg = (JavaPackage) iter.next ();
                        ret.add (new PackageImpl (javaPkg));
                    }
                }
            } // else
            
            if (subPackages) {
                int size = ret.size ();                
                for (int x = 0; x < size; x++) {
                    PackageImpl pkgImpl = (PackageImpl) ret.get(x);
                    addSubPackages(ret, pkgImpl.javaPackage);
                }
            }
            
        } finally {
            repository.endTrans (false);
        }                
        return ret;
    }

    /** Find classes by name and possibly in some package
    * @param pkg package where the classes should be searched for. It can be null
    * @param exactMatch whether the given name is the exact requested name
    *   of the class or not.
    * @return list of the matching classes
    */
    public List findClasses(JCPackage pkg, String name, boolean exactMatch) {
        
        // System.out.println("findClasses: " + (pkg == null ? "null" : pkg.getName ()) + " " + name);
        
        List ret = new ArrayList();

        repository.beginTrans (false);
        try {
            JavaMetamodel.getManager();
            ArrayList classes = new ArrayList();
            String clsName = (pkg == null ? "" : pkg.getName() + '.') + name;
            if (fo == null){
                // [TODO] rewrite to use a meaningful classpath
                ClassPath cp = JavaMetamodel.getManager().getClassPath();
                FileObject[] cpRoots = cp.getRoots();
                for (int i = 0; i < cpRoots.length; i++) {
                    ClassIndex ci = ClassIndex.getIndex(JavaMetamodel.getManager().getJavaExtent(cpRoots[i]));
                    if (ci == null) continue;
                    if (pkg == null) {
                        if (exactMatch) {
                            classes.addAll(ci.getClassesBySimpleName(name, caseSensitive));
                        } else {
                            classes.addAll(ci.getClassesBySNPrefix(name, caseSensitive));
                        }
                    } else {
                        if (exactMatch) {
                            JavaClass cls = ci.getClassByFqn(name);
                            if (cls != null) {
                                classes.add(cls);
                            }
                        } else {
                            classes.addAll(ci.getClassesByFQNPrefix(clsName));
                        }
                    }
               }
            }else{
                ClassIndex ci = ClassIndex.getIndex(JavaMetamodel.getManager().getJavaExtent(fo));
                if (ci != null){
                    if (pkg == null) {
                        if (exactMatch) {
                            classes.addAll(ci.getClassesBySimpleName(name, caseSensitive));
                        } else {
                            classes.addAll(ci.getClassesBySNPrefix(name, caseSensitive));
                        }
                    } else {
                        if (exactMatch) {
                            JavaClass cls = ci.getClassByFqn(name);
                            if (cls != null) {
                                classes.add(cls);
                            }
                        } else {
                            classes.addAll(ci.getClassesByFQNPrefix(clsName));
                        }
                    }
                }
            }
            for (Iterator it = classes.iterator(); it.hasNext();) {
                ret.add(new ClassImpl((JavaClass) it.next()));
            }
            Collections.sort(ret, naturalSort ? JCBaseFinder.INSENSITIVE_CLASS_NAME_COMPARATOR : JCBaseFinder.CLASS_NAME_COMPARATOR);
        } finally {
            repository.endTrans (false);
        }
        
        return ret;
    }

    /** Find fields by name in a given class.
    * @param cls class which is searched for the fields.
    * @param name start of the name of the field
    * @param exactMatch whether the given name of the field is exact
    * @param staticOnly whether search for the static fields only
    * @return list of the matching fields
    */
    public List findFields(JCClass cls, String name, boolean exactMatch,
            boolean staticOnly, boolean inspectOuterClasses) {
                
        // System.out.println("findFields: " + cls.getFullName ());
        
        TreeSet ts = naturalSort ? new TreeSet(JCBaseFinder.NATURAL_MEMBER_NAME_COMPARATOR) : new TreeSet();
        
        repository.beginTrans (false);
        try {
            JavaClass jc = null;
            if (cls instanceof ClassImpl) {
                jc = ((ClassImpl) cls).javaSource;
            } else {
                JavaModelPackage p = getJavaModelPackage();
                if (p != null) {
                    Object o = p.getType().resolve(cls.getFullName());
                    if (o instanceof JavaClass) {
                        jc = (JavaClass) o;
                    } else {
                        jc = (JavaClass) p.getType().resolve("java.lang.Object"); //NOI18N 
                    }
                }
            }
            if (jc == null) {
                return new ArrayList ();
            }
            List clsList = getClassList(jc);
            String pkgName = cls.getPackageName();
            HashSet ifaces = new HashSet(); // The set for temporal storage of all implemented interfaces

            JavaClass tempClass;

            for (int i = clsList.size() - 1; i >= 0; i--) {
                tempClass = (JavaClass) clsList.get (i);

                // remember all the interfaces along the way through hierarchy
                if (tempClass.isInterface()) {
                    ifaces.add(tempClass); //bugfix of #19615
                }            
                ifaces.addAll(tempClass.getInterfaces());

                String pName = getPackageName(jc);
                boolean difPkg = !pName.equals(pkgName);
                List outerList = (i == 0 && inspectOuterClasses && cls.getName().indexOf('.') >= 0)
                                 ? getOuterClasses(tempClass) : null;
                int outerInd = (outerList != null) ? (outerList.size() - 1) : -1;
                do {
                    if (outerInd >= 0) {
                        tempClass = (JavaClass)outerList.get(outerInd--);
                    }
                    Iterator iter = tempClass.getFeatures().iterator ();
                    while (iter.hasNext ()) {
                        Feature feature = (Feature) iter.next();
                        if (!(feature instanceof Field)) continue;
                        Field fld = (Field) feature;
                        int mods = fld.getModifiers();
                        if ((staticOnly && (mods & Modifier.STATIC) == 0)
                                || ((mods & Modifier.PRIVATE) != 0)//(i > 0 && (mods & Modifier.PRIVATE) != 0) - #46851
                                || (difPkg && (mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0)
                                || ((outerInd >-1) && ((jc.getModifiers() & Modifier.STATIC) != 0 ) && ((mods & Modifier.STATIC) == 0))
                           ) {
                            continue;
                        }
                        if (exactMatch) {
                            if (!fld.getName().equals(name)) {
                                continue;
                            }
                        } else {
                            if (!startsWith(fld.getName(), name)) {
                                continue;
                            }
                        }

                        boolean isLocal = jc.equals(tempClass) && outerInd == -1;
                        // [PENDING]
                        // if (showDeprecated || !JCUtilities.isDeprecated(fld)){
                            ts.add(new FieldImpl(fld, isLocal));
                        // }

                    } // while
                } while (outerInd >= 0);
            } // while
            // add ALL known fields from interfaces, ALL as they are public static
            for( Iterator it = ifaces.iterator(); it.hasNext(); ) {
                tempClass = (JavaClass) it.next ();            
                Iterator fieldsIter = tempClass.getFeatures().iterator ();
                while (fieldsIter.hasNext ()) {
                    Object tmp = fieldsIter.next();
                    if (!(tmp instanceof Field)) continue;
                    Field fld = (Field) tmp;
                    if( exactMatch ? !fld.getName().equals(name)
                                   : !startsWith(fld.getName(), name) ) continue;

                    // [PENDING]
                    // if (showDeprecated || !JCUtilities.isDeprecated(fld)){
                        ts.add(new FieldImpl (fld));
                    // }
                }            
            }

            if (staticOnly){
                if((exactMatch && "class".equals(name)) || (!exactMatch && startsWith("class", name))){ //NOI18N
                    JCField field = new BaseField(JavaCompletion.CLASS_CLASS, "class", //NOI18N
                    JavaCompletion.CLASS_TYPE, Modifier.PUBLIC);
                    ts.add(field);
                }
            }
            
            if (cls == JavaCompletion.OBJECT_CLASS_ARRAY) {
                ts.add(new BaseField(JavaCompletion.INT_CLASS, "length", JavaCompletion.INT_TYPE, Modifier.PUBLIC)); // NOI18N
            }

        } finally {
            repository.endTrans (false);
        }
        
        return new ArrayList(ts);        
    }

    
    /** Find methods by name in a given class.
    * @param cls class which is searched for the methods.
    * @param name start of the name of the method
    * @param exactMatch whether the given name of the method is exact
    * @param staticOnly whether search for the static methods only
    * @return list of the matching methods
    */
    public List findMethods(JCClass cls, String name, boolean exactMatch, 
                            boolean staticOnly, boolean inspectOuterClasses) {
                                
        // System.out.println("findMethods: " + cls.getName ());

        TreeSet ts = naturalSort ? new TreeSet(JCBaseFinder.NATURAL_MEMBER_NAME_COMPARATOR) : new TreeSet();
        
       repository.beginTrans (false);
       try {
        
            JavaClass jc = null;
            if (cls instanceof ClassImpl) {
                jc = ((ClassImpl) cls).javaSource;
            } else {
                JavaModelPackage p = getJavaModelPackage();
                if (p != null) {
                    Object o = p.getType().resolve(cls.getFullName());
                    if (o instanceof JavaClass) {
                        jc = (JavaClass) o;
                    } else {
                        jc = (JavaClass) p.getType().resolve("java.lang.Object"); //NOI18N
                    }                 
                }
            }
            if (jc == null) {
                return new LinkedList ();
            }
            
            List clsList = getClassList(jc);
            String pkgName = cls.getPackageName();

            for (int i = clsList.size() - 1; i >= 0; i--) {
                JavaClass tempCls = (JavaClass) clsList.get(i);
                if (tempCls != null) {
                    String tempName = getPackageName(tempCls);
                    boolean difPkg = !tempName.equals(pkgName);
                    List outerList = (i == 0 && inspectOuterClasses && (tempCls.getDeclaringClass () != null))
                                     ? getOuterClasses(tempCls) : null;
                    int outerInd = (outerList != null) ? (outerList.size() - 1) : -1;
                    do {
                        if (outerInd >= 0) {
                            tempCls = (JavaClass)outerList.get(outerInd--);
                        }

                        Iterator methodsIter = tempCls.getFeatures().iterator ();
                        while (methodsIter.hasNext ()) {          
                            Object tmp = methodsIter.next();
                            if (!(tmp instanceof Method)) continue;
                            Method mtd = (Method) tmp;
                            int mods = mtd.getModifiers();
                            if ((staticOnly && (mods & Modifier.STATIC) == 0)
                                    || ((mods & Modifier.PRIVATE) != 0)//(i > 0 && (mods & Modifier.PRIVATE) != 0) - #46851
                                    || (difPkg && (mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0)
                                    || ((outerInd >-1) && ((jc.getModifiers() & Modifier.STATIC) != 0 ) && ((mods & Modifier.STATIC) == 0))
                               ) {
                                continue;
                            }
                            if (exactMatch) {
                                if (!mtd.getName().equals(name)) {
                                    continue;
                                }
                            } else { // match begining
                                if (!startsWith(mtd.getName(), name)) {
                                    continue;
                                }
                            }

                            boolean isLocal = jc.equals(tempCls) && outerInd == -1;
                            
                            // override the method from superclass (throwing exceptions could differ)
                            MethodImpl mtdImpl = new MethodImpl (mtd, isLocal);
                            if (ts.contains(mtdImpl)) 
                                ts.remove(mtdImpl);

                            // [PENDING]
                            // if (showDeprecated || !JCUtilities.isDeprecated(mtd)){
                                ts.add(mtdImpl);
                            // }
                        }
                    } while (outerInd >= 0);
                }
            }
        } finally {
            repository.endTrans (false);
        }
            
        return new ArrayList(ts);
    }

    private void addSubPackages (List list, JavaPackage pkg) {
        Iterator iter = pkg.getSubPackages ().iterator ();
        while (iter.hasNext ()) {
            JavaPackage p = (JavaPackage) iter.next ();
            list.add (new PackageImpl (p));
            addSubPackages (list, p);
        }
    }
    
    private List getClassListForList(List classes) {
        Iterator interfacesIt=classes.iterator();
        List ret = new ArrayList ();
        
        while(interfacesIt.hasNext()) {
            ret.addAll(getClassList((JavaClass)interfacesIt.next()));
        }
        return ret;
    }
    
    private List getClassList(JavaClass jc) {
        List ret = new ArrayList ();
        if (jc != null) {
            ret.add(jc);
            if (jc.isInterface()) {                
                ret.addAll(getClassListForList(jc.getInterfaces()));
                // #16252 it is legal to call methods for java.lang.Object from an interface
                JavaClass objectClass = (JavaClass)getJavaModelPackage().getType().resolve("java.lang.Object"); // NOI18N
                if (objectClass != null)
                    ret.add(objectClass); // [PENDING] ???
            } else {
                JavaClass superClass = jc.getSuperClass();
                if (superClass != null)
                    ret.addAll(getClassList(superClass));
                if (Modifier.isAbstract(jc.getModifiers())) {
                    // in the case of abstract implementor of interface
                    ret.addAll(getClassListForList(jc.getInterfaces()));
                } // if
            } // else
        }
        return ret;
    }    
    
    /** Get outer classes to search
    * the fields and methods there. The original class is added
    * as the first member of the resulting list.
    */
    private List getOuterClasses(JavaClass jc) {        
        ArrayList outers = new ArrayList();
        outers.add(jc);
        while (jc != null) {
            jc = (JavaClass) jc.getDeclaringClass ();
            if (jc != null) {
                // [PENDING] check for deprecated classes ...
                // if (showDeprecated || !JCUtilities.isDeprecated(cls)) 
                outers.add (jc);
            }
        }
        return outers;
    }
    
    //......................................
    public Iterator getClasses () {
        return null;
    }
    
    public boolean append(JCClassProvider cp) {
        return true;
    }

    public void reset() {
    }

    public boolean notifyAppend(JCClass c, boolean appendFinished) {
        return false;
    }
    //......................................
    
    public void setCaseSensitive(boolean sensitive){
        caseSensitive = sensitive;
    }

    public void setNaturalSort(boolean sort){
        naturalSort = sort;        
    }
    
    public void setShowDeprecated(boolean deprecated){
        showDeprecated = deprecated;
    }
    
    public boolean getShowDeprecated(){
        return showDeprecated;
    }
    
    private boolean startsWith(String theString, String prefix){
        return caseSensitive ? theString.startsWith(prefix) :
            theString.toLowerCase().startsWith(prefix.toLowerCase());
    }

    public JCClass createJCClass (JavaClass jc) {
        if (jc != null)
            return new ClassImpl (jc);
        else {
            throw new NullPointerException();
//            // [PENDING] incorrect for innerclasses
//            String pkgName, name;
//            String fullName = desc.getDescriptor ();
//            int index = fullName.lastIndexOf ('.');
//            if (index > -1) {
//                name = fullName.substring (index + 1);
//                pkgName = fullName.substring (0, index);
//            } else {
//                name = fullName;
//                pkgName = "";
//            }
//            return new SimpleClass (name, pkgName);
        }
    }
    
    public JCType createJCType (Type desc) {
        if (desc instanceof PrimitiveType) {
            PrimitiveTypeKind kind = ((PrimitiveType) desc).getKind ();
            if (PrimitiveTypeKindEnum.BOOLEAN.equals(kind))
                return JavaCompletion.BOOLEAN_TYPE;
            if (PrimitiveTypeKindEnum.INT.equals(kind))
                return JavaCompletion.INT_TYPE;
            if (PrimitiveTypeKindEnum.CHAR.equals (kind))
                return JavaCompletion.CHAR_TYPE;
            if (PrimitiveTypeKindEnum.BYTE.equals (kind))
                return JavaCompletion.BYTE_TYPE;
            if (PrimitiveTypeKindEnum.SHORT.equals (kind))
                return JavaCompletion.SHORT_TYPE;
            if (PrimitiveTypeKindEnum.LONG.equals (kind))
                return JavaCompletion.LONG_TYPE;
            if (PrimitiveTypeKindEnum.FLOAT.equals (kind))
                return JavaCompletion.FLOAT_TYPE;
            if (PrimitiveTypeKindEnum.DOUBLE.equals (kind))
                return JavaCompletion.DOUBLE_TYPE;
            if (PrimitiveTypeKindEnum.VOID.equals (kind))
                return JavaCompletion.VOID_TYPE;
            return JavaCompletion.INVALID_TYPE;
        } else if (desc instanceof JavaClass) {
            return new BaseType (createJCClass ((JavaClass) desc), 0);
        } else {
            int depth = 0;
            while (desc instanceof Array) {
                depth++;
                desc = ((Array) desc).getType ();
            }
            return new BaseType (createJCType (desc).getClazz (), depth);
        }
    }
    
    // --------------------------------------------------------------------------
    // --------------------------------------------------------------------------
    
    // PackageImpl ..............................................................
    public  class PackageImpl implements JCPackage {

        JavaPackage javaPackage;

        public PackageImpl (JavaPackage javaPackage) {
            this.javaPackage = javaPackage;
        }

        /** Get full name of this package */
        public final String getName() {
            try {
                return javaPackage.getName ();
            } catch (InvalidObjectException e) {
                return "";
            }
        }

        public String getLastName() {
            String name = getName ();
            return name.substring (name.lastIndexOf('.') + 1);            
        }

        /** Get classes contained in this package */
        public JCClass[] getClasses() {
            repository.beginTrans (false);
            try {
                Collection coll = new ArrayList();
                if (fo == null){
                    // [TODO] MaM - rewrite to use a meaningful classpath
                    ClassPath cp = JavaMetamodel.getManager().getClassPath();
                    FileObject[] cpRoots = cp.getRoots();
                    for (int i = 0; i < cpRoots.length; i++) {
                        ClassIndex ci = ClassIndex.getIndex(JavaMetamodel.getManager().getJavaExtent(cpRoots[i]));
                        if (ci == null) continue;
                        coll.addAll(ci.getClassesByFQNPrefix(javaPackage.getName() + '.'));
                    }
                }else{
                    ClassIndex ci = ClassIndex.getIndex(JavaMetamodel.getManager().getJavaExtent(fo));
                    if (ci != null){
                        coll.addAll(ci.getClassesByFQNPrefix(javaPackage.getName() + '.'));
                    }
                }
                JCClass [] res = new JCClass [coll.size ()];
                Iterator iter = coll.iterator ();
                for (int x = 0; iter.hasNext (); x++) {
                    res [x] = new ClassImpl ((JavaClass) iter.next ());
                }
                return res;
            } catch (InvalidObjectException e) {
                return new JCClass [0];
            } finally {
                repository.endTrans (false);
            }
        }

        public void setClasses(JCClass[] classes) {
            // [PENDING]
        }

        public int getDotCount() {
            int dotCnt = 0;
            int i = 0;
            do {
                dotCnt++;
                i = getName ().indexOf('.', i) + 1;
            } while (i > 0);
            return dotCnt;
        }

        public int compareTo(Object o) {
            if (this == o) {
                return 0;
            }
            JCPackage p = (JCPackage)o;
            return getName ().compareTo(p.getName());
        }

        public int hashCode() {
            return javaPackage.hashCode();
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o instanceof JCPackage) {
                return getName ().equals(((JCPackage)o).getName());
            }
            if (o instanceof String) {
                return getName ().equals((String)o);
            }
            return false;
        }

        public String toString() {
            return getName ();
        }

    } // PackageImpl
    
    private static String getPackageName(JavaClass source) {
        if (source instanceof UnresolvedClass) {
            String name = source.getName();
            int index = name.lastIndexOf('.');
            return index < 0 ? "" : name.substring(0, index);
        } else {
            org.netbeans.jmi.javamodel.Resource resource = source.getResource();
            String result = null;
            if (resource != null) {
                result = resource.getPackageName();
            }
            if (result == null) {
                result = "";
            }
            return result;
        }
    }

    // ClassImpl ................................................................
    public class ClassImpl implements JCClass {

        private final JavaClass javaSource;
        private final String stringValue;
        private final String packageName;
        private final String fullName;
        private final String className;
        
        public ClassImpl (JavaClass source) {
            String temp, pkgName;
            javaSource = source;
            repository.beginTrans(false);
            try {
                temp = source.getName();
                pkgName = MDRFinder.getPackageName(source);
            } catch (InvalidObjectException e) {
                temp = pkgName = "";
            } finally {
                repository.endTrans();
            }
            fullName = temp;
            packageName = pkgName;            
            if (pkgName.length() != 0) {
                pkgName += "."; // NOI18N
            }
            int pkgNameLength = pkgName.length ();
            
            // #35721: check lenghts before the substring is obtained            
            if (pkgNameLength > temp.length ()) {
                /*
                System.out.println("MDRFinder.ClassImpl: incosistency detected");
                System.out.println("  fullName: \"" + fullName + "\"   packageName: \"" + packageName + "\"");
                 */
                className = "";
            } else {
                className = temp.substring(pkgNameLength);
            }
            stringValue = pkgName + className.replace('.', '$');
        }        

        public final String getName() {
            return className;
        }

        public final String getPackageName() {
            return packageName;
        }

        public String getFullName() {
            return fullName;
        }

        // [PENDING] ???
        public int getTagOffset() {
            return -1;
        }

        public boolean isInterface() {
            try {
                return javaSource.isInterface ();
            } catch (InvalidObjectException e) {
                return false;
            }
        }

        public int getModifiers() {
            try {
                return javaSource.getModifiers ();
            } catch (InvalidObjectException e) {
                return 0;
            }
        }

        public JCClass getSuperclass() {
            try {
                JavaClass superDesc = javaSource.getSuperClass();
                return superDesc != null ? createJCClass (superDesc) : null;
            } catch (InvalidObjectException e) {
                return null;
            }
        }

        public JCClass[] getInterfaces() {
            repository.beginTrans (false);
            try {
                Collection coll = javaSource.getInterfaces ();
                JCClass [] superinterfaces = new JCClass [coll.size ()];
                Iterator iter = coll.iterator ();
                for (int x = 0; iter.hasNext (); x++) {
                    JavaClass inter = (JavaClass) iter.next ();                    
                    superinterfaces [x] = createJCClass(inter);
                }
                return superinterfaces;
            } catch (InvalidObjectException e) {
                return new JCClass [0];
            } finally {
                repository.endTrans (false);
            }
        }

        public JCField[] getFields() {
            repository.beginTrans (false);
            try {
                Collection coll = javaSource.getFeatures();
                ArrayList fields = new ArrayList(coll.size());
                for (Iterator iter = coll.iterator(); iter.hasNext ();) {
                    Object temp = iter.next();
                    if (temp instanceof Field) {
                        fields.add(new FieldImpl ((Field) temp));
                    }
                }
                return (JCField[]) fields.toArray(new JCField[fields.size()]);
            } catch (InvalidObjectException e) {
                return new JCField [0];
            } finally {
                repository.endTrans (false);
            }
        }

        public JCConstructor[] getConstructors() {
            repository.beginTrans (false);
            try {
                Collection coll = javaSource.getFeatures();
                ArrayList constr = new ArrayList(coll.size());
                for (Iterator iter = coll.iterator(); iter.hasNext ();) {
                    Object temp = iter.next();
                    if (temp instanceof Constructor) {
                        constr.add(new ConstructorImpl ((Constructor) temp));
                    }
                }
                return (JCConstructor[]) constr.toArray(new JCConstructor[constr.size()]);
            } catch (InvalidObjectException e) {
                return new JCConstructor [0];
            } finally {
                repository.endTrans (false);
            }
        }

        public JCMethod[] getMethods() {
            repository.beginTrans (false);
            try {
                Collection coll = javaSource.getFeatures();
                ArrayList fields = new ArrayList(coll.size());
                for (Iterator iter = coll.iterator(); iter.hasNext ();) {
                    Object temp = iter.next();
                    if (temp instanceof Method) {
                        fields.add(new MethodImpl ((Method) temp));
                    }
                }
                return (JCMethod[]) fields.toArray(new JCMethod[fields.size()]);
            } catch (InvalidObjectException e) {
                return new JCMethod [0];
            } finally {
                repository.endTrans (false);
            }
        }

        public int compareTo(Object o) {
            if (this == o) {
                return 0;
            }
            JCClass c = (JCClass)o;

            int order = getPackageName ().compareTo(c.getPackageName());
            if (order == 0) {
                order = getName ().compareTo(c.getName());
            }
            return order;
        }

        public int hashCode() {
            return getName ().hashCode() ^ getPackageName ().hashCode();
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o instanceof JCClass) {
                JCClass c = (JCClass)o;
                return getName ().equals(c.getName()) && getPackageName ().equals(c.getPackageName());
            }
            return false;
        }

        public String toString() {
            return stringValue;
        }

    } // ClassImpl

    /*
    // TypeImpl .................................................................
    public static class TypeImpl implements JCType {

        protected JCClass clazz;

        protected int arrayDepth;

        public TypeImpl (JCClass clazz, int arrayDepth) {
            this.clazz = clazz;
            this.arrayDepth = arrayDepth;
            if (arrayDepth < 0) {
                throw new IllegalArgumentException("Array depth " + arrayDepth + " < 0."); // NOI18N
            }
        }

        public JCClass getClazz() {
            return clazz;
        }

        public int getArrayDepth() {
            return arrayDepth;
        }

        public String format(boolean useFullName) {
            StringBuffer sb = new StringBuffer(useFullName ? getClazz().getFullName()
                                               : getClazz().getName());
            int ad = arrayDepth;
            while (ad > 0) {
                sb.append("[]"); // NOI18N
                ad--;
            }
            return sb.toString();
        }

        public int compareTo(Object o) {
            if (this == o) {
                return 0;
            }
            JCType t = (JCType)o;
            int order = clazz.compareTo(t.getClazz());
            if (order == 0) {
                order = arrayDepth - t.getArrayDepth();
            }
            return order;
        }

        public int hashCode() {
            return clazz.hashCode() + arrayDepth;
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o instanceof JCType) {
                JCType t = (JCType)o;
                return clazz.equals(t.getClazz()) && arrayDepth == t.getArrayDepth();
            }
            return false;
        }

        public String toString() {
            StringBuffer sb = new StringBuffer(clazz.toString());
            int ad = arrayDepth;
            while (ad > 0) {
                sb.append("[]"); // NOI18N
                ad--;
            }
            return sb.toString();
        }

    } // TypeImpl
     */

    // ParameterImpl ............................................................
    public  class ParameterImpl implements JCParameter {

        private Parameter param;

        public ParameterImpl (Parameter param) {
            this.param = param;
        }

        public String getName() {
            try {
                return param.getName ();
            } catch (InvalidObjectException e) {
                return "";
            }
        }

        public JCType getType() {
            try {
                return createJCType (param.getType ());
            } catch (InvalidObjectException e) {
                return JavaCompletion.INVALID_TYPE;
            }    
        }

        public int compareTo(Object o) {
            if (this == o) {
                return 0;
            }
            JCParameter p = (JCParameter)o;
            return getType ().compareTo(p.getType()); // only by type
        }

        public int hashCode() {
            return getType ().hashCode() ^ getName ().hashCode();
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o instanceof JCParameter) {
                JCParameter p = (JCParameter)o;
                return getType ().equals(p.getType()); // only by type
            }
            return false;
        }

        public String toString() {
            return getType ().toString() + ' ' + getName ();
        }

    } // ParameterImpl

    // FieldImpl ................................................................
    public  class FieldImpl implements JCField {

        private Field field;
        private int localFlag;

        public FieldImpl (Field field, boolean isLocal) {
            this.field = field;
            this.localFlag = isLocal ? JavaCompletion.LOCAL_MEMBER_BIT : 0;
        }
        
        public FieldImpl (Field field) {
            this.field = field;
            this.localFlag = 0;
        }

        public String getName() {
            try {
                return field.getName ();
            } catch (InvalidObjectException e) {
                return "";
            }
        }

        public JCType getType() {
            try {
                return createJCType (field.getType ());
            } catch (InvalidObjectException e) {
                return JavaCompletion.INVALID_TYPE;
            }    
        }
        
        public int getModifiers() {
            try {
                return field.getModifiers () | localFlag;
            } catch (InvalidObjectException e) {
                return 0;
            }
        }

        public JCClass getClazz() {
            try {
                return new ClassImpl ((JavaClass) field.getDeclaringClass ());
            } catch (InvalidObjectException e) {
                return JavaCompletion.NULL_CLASS; // [PENDING]
            }
        }

        public int getTagOffset() {
            return 0; // [PENDING]
        }

        public int compareTo(Object o) {
            if (this == o) {
                return 0;
            }
            JCField f = (JCField)o;
            
            if (this == o)
                return 0;
            int order = getType ().compareTo(f.getType());            
            if (order == 0) {
                order = getName ().compareTo(f.getName());
            }
            return order;
        }

        public int hashCode() {
            return getType ().hashCode() ^ getName ().hashCode() ^ getModifiers ();
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o instanceof JCField) {
                JCField p = (JCField)o;
                return getName ().equals(p.getName()) && getType ().equals(p.getType());
            }
            return false;
        }

        public String toString() {
            return Modifier.toString(getModifiers ()) + ' ' + getType() + ' ' + getName();
        }

    } // FieldImpl

    // ConstructorImpl ..........................................................
    public  class ConstructorImpl implements JCConstructor {

        private CallableFeature constr;
        
        public ConstructorImpl (CallableFeature constr) {
            this.constr = constr;    
        }

        public JCClass getClazz() {
            try {
                return new ClassImpl ((JavaClass) constr.getDeclaringClass ());
            } catch (InvalidObjectException e) {
                return JavaCompletion.NULL_CLASS; // [PENDING]
            }
        }

        public int getTagOffset() {
            return 0; // [PENDING]
        }

        public int getModifiers() {
            try {
                return constr.getModifiers ();
            } catch (InvalidObjectException e) {
                return 0;
            }
        }

        public JCParameter[] getParameters() {
            repository.beginTrans (false);
            try {
                Collection coll = constr.getParameters ();
                JCParameter [] params = new JCParameter [coll.size ()];
                Iterator iter = coll.iterator ();
                for (int x = 0; iter.hasNext (); x++) {                    
                    params [x] = new ParameterImpl ((Parameter) iter.next ());
                }
                return params;
            } catch (InvalidObjectException e) {
                return new JCParameter [0];
            } finally {
                repository.endTrans (false);
            }
        }

        public JCClass[] getExceptions() {
            repository.beginTrans (false);
            try {
                Collection coll = constr.getExceptions ();
                JCClass [] exs = new JCClass [coll.size ()];
                Iterator iter = coll.iterator ();
                for (int x = 0; iter.hasNext (); x++) {
                    JavaClass exSource = (JavaClass) iter.next ();
                    exs [x] = createJCClass (exSource);
                }
                return exs;
            } catch (InvalidObjectException e) {
                return new JCClass [0];
            } finally {
                repository.endTrans (false);
            }
        }

        /** This implementation expects
        * that only the constructors inside one class will
        * be compared.
        */
        public int compareTo(Object o) {
            if (this == o) {
                return 0;
            }
            JCConstructor c = (JCConstructor)o;
            int order = 0;
            JCParameter[] mp = c.getParameters();
            JCParameter[] parameters = getParameters();
            int commonCnt = Math.min(parameters.length, mp.length);
            for (int i = 0; i < commonCnt; i++) {
                order = parameters[i].compareTo(mp[i]);
                if (order != 0) {
                    return order;
                }
            }
            order = parameters.length - mp.length;
            return order;
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o instanceof JCConstructor) {
                return (compareTo(o) == 0);
            }
            return false;
        }

        public int hashCode() {
            JCParameter[] parameters = getParameters();
            int h = 0;
            for (int i = 0; i < parameters.length; i++) {
                h ^= parameters[i].hashCode();
            }
            return h;
        }

        String toString(String returnTypeName, String methodName) {
            StringBuffer sb = new StringBuffer(Modifier.toString(getModifiers ()));
            sb.append(' ');
            sb.append(returnTypeName);
            sb.append(methodName);
            // Add parameters
            sb.append('(');
            JCParameter[] parameters = getParameters();
            int cntM1 = parameters.length - 1;
            for (int i = 0; i <= cntM1; i++) {
                sb.append(parameters[i].toString());
                if (i < cntM1) {
                    sb.append(", "); // NOI18N
                }
            }
            sb.append(')');
            // Add exceptions
            JCClass [] exceptions = getExceptions ();
            cntM1 = exceptions.length - 1;
            if (cntM1 >= 0) {
                sb.append(" throws "); // NOI18N
                for (int i = 0; i <= cntM1; i++) {
                    sb.append(exceptions[i].toString());
                    if (i < cntM1) {
                        sb.append(", "); // NOI18N
                    }
                }
            }
            return sb.toString();
        }

        public String toString() {
            return toString("", getClazz().getName()); // NOI18N
        }

    }  // ConstructorImpl

    // MethodImpl ...............................................................
    public  class MethodImpl extends ConstructorImpl implements JCMethod {

        private Method method;
        private int localFlag;

        public MethodImpl (Method method, boolean isLocal) {
            this (method);
            this.method = method;
            this.localFlag = isLocal ? JavaCompletion.LOCAL_MEMBER_BIT : 0;
        }
        
        public MethodImpl (Method method) {
            super (method);
            this.method = method;
            this.localFlag = 0;
        }

        public String getName() {
            try {
                return method.getName ();
            } catch (InvalidObjectException e) {
                return "";
            }
        }

        public int getModifiers() {
            try {
                return method.getModifiers () | localFlag;
            } catch (InvalidObjectException e) {
                return 0;
            }
        }
        
        public JCType getReturnType() {
            try {
                return createJCType (method.getType ());
            } catch (InvalidObjectException e) {
                return JavaCompletion.INVALID_TYPE;
            }    
        }
        
        public int compareTo(Object o) {
            if (this == o) {
                return 0;
            }
            JCMethod m = (JCMethod)o;
            int order = getName ().compareTo(m.getName());
            if (order == 0) {
                order = super.compareTo(o);
            }
            return order;
        }

        public int hashCode() {
            return getName ().hashCode() ^ super.hashCode();
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o instanceof JCMethod) {
                return (compareTo(o) == 0);
            }
            return false;
        }

        public String toString() {
            String rtn = getReturnType().toString();
            return toString((rtn.length() > 0) ? rtn + ' ' : "", getName ()); // NOI18N
        }

    } // MethodImpl    
    
}
... 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.