|
What this is
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-2000 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.editor.ext.java; import java.io.File; import java.io.FileFilter; import java.util.List; import java.util.ArrayList; import java.util.Iterator; import java.util.TreeSet; import java.lang.reflect.Modifier; import java.lang.reflect.Method; import java.lang.reflect.Field; import java.lang.reflect.Constructor; import org.netbeans.editor.TokenID; import org.netbeans.editor.ext.java.JavaCompletion; /** * Java completion utilities * * @author Miloslav Metelka * @version 1.00 */ public class JCUtilities { private static final int javaTokenIDsLength = JavaTokenContext.context.getTokenIDs().length; private static final boolean[][] primitivesAssignable = new boolean[javaTokenIDsLength][]; private static final JCClass[][] primitivesCommonClass = new JCClass[javaTokenIDsLength][]; static { int[] typeIDs = new int[] { JavaTokenContext.BOOLEAN_ID, JavaTokenContext.BYTE_ID, JavaTokenContext.CHAR_ID, JavaTokenContext.DOUBLE_ID, JavaTokenContext.FLOAT_ID, JavaTokenContext.INT_ID, JavaTokenContext.LONG_ID, JavaTokenContext.SHORT_ID, JavaTokenContext.VOID_ID }; boolean[][] assignVals = new boolean[][] { new boolean[] { true, false, false, false, false, false, false, false, false}, // boolean new boolean[] { false, true, false, true, true, true, true, true, false}, // byte new boolean[] { false, false, true, true, true, true, true, false, false}, // char new boolean[] { false, false, false, true, false, false, false, false, false}, // double new boolean[] { false, false, false, true, true, false, false, false, false}, // float new boolean[] { false, false, false, true, true, true, true, false, false}, // int new boolean[] { false, false, false, true, true, false, true, false, false}, // long new boolean[] { false, false, false, true, true, true, true, true, false}, // short new boolean[] { false, false, false, false, false, false, false, false, true} // void }; JCClass[][] classesVals = new JCClass[][] { new JCClass[] { JavaCompletion.BOOLEAN_CLASS, null, null, null, null, null, null, null, null}, // boolean new JCClass[] { null, JavaCompletion.BYTE_CLASS, JavaCompletion.INT_CLASS, JavaCompletion.DOUBLE_CLASS, JavaCompletion.FLOAT_CLASS, JavaCompletion.INT_CLASS, JavaCompletion.LONG_CLASS, JavaCompletion.INT_CLASS, null}, // byte new JCClass[] { null, JavaCompletion.INT_CLASS, JavaCompletion.CHAR_CLASS, JavaCompletion.DOUBLE_CLASS, JavaCompletion.FLOAT_CLASS, JavaCompletion.INT_CLASS, JavaCompletion.LONG_CLASS, JavaCompletion.INT_CLASS, null}, // char new JCClass[] { null, JavaCompletion.DOUBLE_CLASS, JavaCompletion.DOUBLE_CLASS, JavaCompletion.DOUBLE_CLASS, JavaCompletion.DOUBLE_CLASS, JavaCompletion.DOUBLE_CLASS, JavaCompletion.DOUBLE_CLASS, JavaCompletion.DOUBLE_CLASS, null}, // double new JCClass[] { null, JavaCompletion.FLOAT_CLASS, JavaCompletion.FLOAT_CLASS, JavaCompletion.DOUBLE_CLASS, JavaCompletion.FLOAT_CLASS, JavaCompletion.FLOAT_CLASS, JavaCompletion.FLOAT_CLASS, JavaCompletion.FLOAT_CLASS, null}, // float new JCClass[] { null, JavaCompletion.INT_CLASS, JavaCompletion.INT_CLASS, JavaCompletion.DOUBLE_CLASS, JavaCompletion.FLOAT_CLASS, JavaCompletion.INT_CLASS, JavaCompletion.LONG_CLASS, JavaCompletion.INT_CLASS, null}, // int new JCClass[] { null, JavaCompletion.LONG_CLASS, JavaCompletion.LONG_CLASS, JavaCompletion.DOUBLE_CLASS, JavaCompletion.FLOAT_CLASS, JavaCompletion.LONG_CLASS, JavaCompletion.LONG_CLASS, JavaCompletion.LONG_CLASS, null}, // long new JCClass[] { null, JavaCompletion.INT_CLASS, JavaCompletion.INT_CLASS, JavaCompletion.DOUBLE_CLASS, JavaCompletion.FLOAT_CLASS, JavaCompletion.INT_CLASS, JavaCompletion.LONG_CLASS, JavaCompletion.SHORT_CLASS, null}, // short new JCClass[] { null, null, null, null, null, null, null, null, JavaCompletion.VOID_CLASS} // void }; for (int i = 0; i < typeIDs.length; i++) { primitivesAssignable[typeIDs[i]] = new boolean[javaTokenIDsLength]; primitivesCommonClass[typeIDs[i]] = new JCClass[javaTokenIDsLength]; for (int j = 0; j < typeIDs.length; j++) { primitivesAssignable[typeIDs[i]][typeIDs[j]] = assignVals[i][j]; primitivesCommonClass[typeIDs[i]][typeIDs[j]] = classesVals[i][j]; } } } private static boolean stringEqual(String s1, String s2) { return (s1 == null) ? (s2 == null) : s1.equals(s2); } private static boolean classEqual(JCClass c1, JCClass c2) { return (c1 == null) ? (c2 == null) : c1.equals(c2); } private static boolean typeEqual(JCType t1, JCType t2) { return (t1 == null) ? (t2 == null) : classEqual(t1.getClazz(), t2.getClazz()) && (t1.getArrayDepth() == t2.getArrayDepth()); } private static boolean parameterEqual(JCParameter p1, JCParameter p2) { return (p1 == null) ? (p2 == null) : typeEqual(p1.getType(), p2.getType()) && stringEqual(p1.getName(), p2.getName()); } private static boolean constructorEqual(JCConstructor c1, JCConstructor c2) { return (c1 == null) ? (c2 == null) : (c1.getClazz().equals(c2.getClazz()) // mustn't be null && c1.getModifiers() == c2.getModifiers() && parameterArrayEqual(c1.getParameters(), c2.getParameters()) && classArrayEqual(c1.getExceptions(), c2.getExceptions()) ); } private static boolean parameterArrayEqual(JCParameter[] pa1, JCParameter[] pa2) { if (pa1.length != pa2.length) { return false; } for (int i = pa1.length - 1; i >= 0; i--) { if (!parameterEqual(pa1[i], pa2[i])) { return false; } } return true; } private static boolean classArrayEqual(JCClass[] ca1, JCClass[] ca2) { if (ca1.length != ca2.length) { return false; } for (int i = ca1.length - 1; i >= 0; i--) { if (!classEqual(ca1[i], ca2[i])) { return false; } } return true; } private static boolean fieldArraysEqual(JCField[] fa1, JCField[] fa2) { if (fa1.length != fa2.length) { return false; } for (int i = fa1.length - 1; i >= 0; i--) { JCField f1 = fa1[i]; JCField f2 = fa2[i]; if (!parameterEqual(f1, f2) || !f1.getClazz().equals(f2.getClazz()) // mustn't be null || (f1.getModifiers() != f2.getModifiers()) ) { return false; } } return true; } private static boolean constructorArrayEqual(JCConstructor[] ca1, JCConstructor[] ca2) { if (ca1.length != ca2.length) { return false; } for (int i = ca1.length - 1; i >= 0; i--) { if (!constructorEqual(ca1[i], ca2[i])) { return false; } } return true; } private static boolean methodArraysEqual(JCMethod[] ma1, JCMethod[] ma2) { if (ma1.length != ma2.length) { return false; } for (int i = ma1.length - 1; i >= 0; i--) { JCMethod m1 = ma1[i]; JCMethod m2 = ma2[i]; if (!constructorEqual(m1, m2) || !stringEqual(m1.getName(), m2.getName()) || !typeEqual(m1.getReturnType(), m2.getReturnType()) ) { return false ; } } return true; } public static boolean equal(JCClass c1, JCClass c2) { if (c1 == null && c2 == null) { // both null return true; } if (c1 == null || c2 == null) { // one of them is null, but not both return false; } if (!c1.equals(c2) || c1.isInterface() != c2.isInterface() || c1.getModifiers() != c2.getModifiers() || !classEqual(c1.getSuperclass(), c2.getSuperclass()) ) { return false; } if (!fieldArraysEqual(c1.getFields(), c2.getFields()) || !constructorArrayEqual(c1.getConstructors(), c2.getConstructors()) || !methodArraysEqual(c1.getMethods(), c2.getMethods()) || !classArrayEqual(c1.getInterfaces(), c2.getInterfaces()) ) { return false; } return true; } private static boolean isDeprecated(int mods){ return ((mods & JavaCompletion.DEPRECATED_BIT) != 0) ? true : false; } public static boolean isDeprecated(Object o){ if (o instanceof JCClass){ return isDeprecated(((JCClass)o).getModifiers()); }else if (o instanceof JCConstructor){ return isDeprecated(((JCConstructor)o).getModifiers()); }else if (o instanceof JCField){ return isDeprecated(((JCField)o).getModifiers()); } return false; } public static String dumpClass(JCClass c) { StringBuffer sb = new StringBuffer(); sb.append(Modifier.toString(c.getModifiers())); sb.append(c.isInterface() ? " interface " : " class "); // NOI18N sb.append(c); sb.append(" extends "); // NOI18N sb.append(c.getSuperclass()); // Add implemented interfaces JCClass[] ifcs = c.getInterfaces(); int cntM1 = ifcs.length - 1; if (cntM1 >= 0) { sb.append(" implements "); // NOI18N for (int i = 0; i <= cntM1; i++) { sb.append(ifcs[i].toString()); if (i < cntM1) { sb.append(", "); // NOI18N } } } sb.append('\n'); String indentStr = " "; // NOI18N // Add fields JCField[] flds = c.getFields(); if (flds.length > 0) { sb.append("FIELDS:\n"); // NOI18N for (int i = 0; i < flds.length; i++) { sb.append(indentStr); sb.append(flds[i]); sb.append('\n'); } } // Add constructors JCConstructor[] cons = c.getConstructors(); if (cons.length > 0) { sb.append("CONSTRUCTORS:\n"); // NOI18N for (int i = 0; i < cons.length; i++) { sb.append(indentStr); sb.append(cons[i]); sb.append('\n'); } } // Add methods JCMethod[] mtds = c.getMethods(); if (mtds.length > 0) { sb.append("METHODS:\n"); // NOI18N for (int i = 0; i < mtds.length; i++) { sb.append(indentStr); sb.append(mtds[i]); sb.append('\n'); } } return sb.toString(); } public static JCClass getExactClass(JCFinder finder, String name, String pkgName) { return finder.getExactClass((pkgName.length() != 0) ? (pkgName + "." + name) : name); // NOI18N } /** Get the sorted constructor list for the given class. */ public static List getConstructors(JCClass cls) { return getConstructors(cls, true); } /** Get the sorted constructor list for the given class. * If offerDeprecated is false, then deprecated constructors will not be retreived. */ public static List getConstructors(JCClass cls, boolean offerDeprecated) { TreeSet ts = new TreeSet(); JCConstructor[] constructors = cls.getConstructors(); for (int i = constructors.length - 1; i >= 0; i--) { if (offerDeprecated || !isDeprecated(constructors[i])) ts.add(constructors[i]); } // #32241 if (constructors.length == 0){ ts.add(new JavaCompletion.BaseConstructor(cls, Modifier.PUBLIC, JavaCompletion.EMPTY_PARAMETERS, JavaCompletion.EMPTY_CLASSES)); } return new ArrayList(ts); } /** Get all the interfaces the class/interface * implements/extends. */ public static List getAllInterfaces(JCFinder finder, JCClass cls) { return getAllInterfaces(finder, cls, true); } /** Get all the interfaces the class/interface * implements/extends. * @param offerDeprecated if true deprecated classes will be returned also */ public static List getAllInterfaces(JCFinder finder, JCClass cls, boolean offerDeprecated) { ArrayList ret = new ArrayList(); collectInterfaces(finder, cls, ret, offerDeprecated); return ret; } /** Accumulate the subinterfaces recursively */ private static void collectInterfaces(JCFinder finder, JCClass cls, ArrayList clsList, boolean offerDeprecated) { JCClass[] ifcs = cls.getInterfaces(); if (ifcs != null) { for (int i = 0; i < ifcs.length; i++) { if (clsList.contains(ifcs[i])) continue; if (offerDeprecated || !isDeprecated(ifcs[i])){ clsList.add(ifcs[i]); } cls = finder.getExactClass(ifcs[i].getFullName()); if (cls != null) { collectInterfaces(finder, cls, clsList, offerDeprecated); // recurse implemented interfaces } } } } /** Get the list containing the given class and all its superclasses. */ public static List getSuperclasses(JCFinder finder, JCClass cls) { ArrayList clsList = new ArrayList(); cls = finder.getExactClass(cls.getFullName()); if (cls != null) { cls = cls.getSuperclass(); } while (cls != null && clsList.indexOf(cls) < 0) { clsList.add(cls); cls = finder.getExactClass(cls.getFullName()); if (cls != null) { cls = cls.getSuperclass(); } } return clsList; } public static JCClass createSimpleClass(Class c) { if (c == null || c.getName() == null) { return JavaCompletion.INVALID_CLASS; } return createSimpleClassImpl(c.getName()); } private static JCClass createSimpleClassImpl(String className) { int dotInd = className.lastIndexOf('.'); return JavaCompletion.getSimpleClass(className.replace('$', '.'), (dotInd >= 0) ? dotInd : 0); } public static JavaCompletion.BaseType createType(Class c) { if (c == null) { return JavaCompletion.INVALID_TYPE; } String className = c.getName(); int arrayDepth = 0; while (className.length() > 0 && className.charAt(0) == '[') { arrayDepth++; className = className.substring(1); } if (arrayDepth > 0) { switch (className.charAt(0)) { case 'L': className = className.substring(1, className.length() - 1); break; case 'B': className = "byte"; // NOI18N break; case 'C': className = "char"; // NOI18N break; case 'D': className = "double"; // NOI18N break; case 'F': className = "float"; // NOI18N break; case 'I': className = "int"; // NOI18N break; case 'J': className = "long"; // NOI18N break; case 'S': className = "short"; // NOI18N break; case 'Z': className = "boolean"; // NOI18N break; } } return new JavaCompletion.BaseType( createSimpleClassImpl(className), arrayDepth ); } public static List getClassList(List classNames, boolean storeDeclaredClasses, int classLevel, int fieldLevel, int methodLevel) { ArrayList l = new ArrayList(); Iterator i = classNames.iterator(); while (i.hasNext()) { String name = (String)i.next(); Class c = null; try { c = Class.forName(name); } catch (ClassNotFoundException e) { System.err.println("Class '" + name + "' not found."); // NOI18N } catch ( ThreadDeath td ) { throw td; } catch (Throwable t) { System.err.println("Exception thrown during class rebuild:"); // NOI18N t.printStackTrace(); if (t instanceof OutOfMemoryError) throw (OutOfMemoryError) t; } if (c != null) { l.addAll(createClassList(c, storeDeclaredClasses, classLevel, fieldLevel, methodLevel)); } } return l; } private static String strip(String name, String baseName, String suffix) { int startInd = 0; int endStrip = 0; if (name.startsWith(baseName)) { startInd = baseName.length(); } if (name.endsWith(suffix)) { endStrip = suffix.length(); } return name.substring(startInd, name.length() - endStrip); } private static String separatorToDot(String s) { return s.replace(File.separatorChar, '.'); } private static List createClassList(Class c, boolean storeDeclaredClasses, int classLevel, int fieldLevel, int methodLevel) { ArrayList cL = new ArrayList(); if (c == null) { return cL; } if (JavaCompletion.getLevel(c.getModifiers()) >= classLevel) { cL.add(new BaseJCClass(c, classLevel, fieldLevel, methodLevel)); } // possibly store declared classes subclasses if (storeDeclaredClasses) { try { Class[] dC = c.getDeclaredClasses(); for (int i = 0; i < dC.length; i++) { if (JavaCompletion.getLevel(dC[i].getModifiers()) >= classLevel) { cL.addAll(createClassList(dC[i], storeDeclaredClasses, classLevel, fieldLevel, methodLevel)); } } } catch (SecurityException e) { // can't access declared classes e.printStackTrace(); } } return cL; } public static List getClassNameList(String packageDirName) { File packageDir = new File(packageDirName); List classNames = new ArrayList(); packageDirName += File.separator; // to strip begining if (packageDir.exists()) { getClassListFromSourcesRec(classNames, packageDirName, packageDir); } return classNames; } private static void getClassListFromSourcesRec(final List l, final String packageDirName, File curDir) { curDir.listFiles( new FileFilter() { public boolean accept(File f) { if (f.isDirectory()) { getClassListFromSourcesRec(l, packageDirName, f); } if (f.getName().endsWith(".java")) { // NOI18N l.add(separatorToDot(strip(f.getAbsolutePath(), packageDirName, ".java"))); // NOI18N } return false; } } ); } public static class BaseJCClass extends JavaCompletion.AbstractClass { Class c; int classLevel; int fieldLevel; int methodLevel; /** Do reflection of given class */ public BaseJCClass(Class c, int classLevel, int fieldLevel, int methodLevel) { this.c = c; this.classLevel = classLevel; this.fieldLevel = fieldLevel; this.methodLevel = methodLevel; JCClass sc = createSimpleClass(c); name = sc.getName(); packageName = sc.getPackageName(); modifiers = c.getModifiers(); if (c.isInterface()) { modifiers |= Modifier.INTERFACE; } } protected void init() { body = new Body(); ArrayList lst = new ArrayList(); body.superClass = createSimpleClass(c.getSuperclass()); // create interface classes Class[] dI = c.getInterfaces(); for (int i = 0; i < dI.length; i++) { if (JavaCompletion.getLevel(dI[i].getModifiers()) >= classLevel) { lst.add(createSimpleClass(dI[i])); } } body.interfaces = new JCClass[lst.size()]; lst.toArray(body.interfaces); lst.clear(); // create fields try { Field[] dF = c.getDeclaredFields(); for (int i = 0; i < dF.length; i++) { if (JavaCompletion.getLevel(dF[i].getModifiers()) >= fieldLevel) { lst.add(new JavaCompletion.BaseField(this, dF[i].getName(), createType(dF[i].getType()), dF[i].getModifiers())); } } body.fields = new JCField[lst.size()]; lst.toArray(body.fields); lst.clear(); } catch (SecurityException e) { // can't access declared fields e.printStackTrace(); } // create constructors try { Constructor[] dC = c.getDeclaredConstructors(); for (int i = 0; i < dC.length; i++) { if (JavaCompletion.getLevel(dC[i].getModifiers()) >= methodLevel) { // get constructor parameters JCParameter[] parameters = JavaCompletion.EMPTY_PARAMETERS; try { Class[] dP = dC[i].getParameterTypes(); parameters = new JCParameter[dP.length]; for (int j = 0; j < dP.length; j++) { parameters[j] = new JavaCompletion.BaseParameter( "", // name not known from reflection // NOI18N createType(dP[j])); } } catch (SecurityException e) { // can't get parameter types e.printStackTrace(); } // get thrown exceptions - don't restrict to classes level JCClass[] exceptions = JavaCompletion.EMPTY_CLASSES; try { Class[] dE = dC[i].getExceptionTypes(); exceptions = new JCClass[dE.length]; for (int j = 0; j < dE.length; j++) { exceptions[j] = createSimpleClass(dE[j]); } } catch (SecurityException e) { // can't get exception types e.printStackTrace(); } lst.add(new JavaCompletion.BaseConstructor(this, dC[i].getModifiers(), parameters, exceptions)); } } body.constructors = new JCConstructor[lst.size()]; lst.toArray(body.constructors); lst.clear(); } catch (SecurityException e) { // can't access declared constructors e.printStackTrace(); } // create methods try { Method[] dM = c.getDeclaredMethods(); for (int i = 0; i < dM.length; i++) { if (JavaCompletion.getLevel(dM[i].getModifiers()) >= methodLevel) { // get method parameters JCParameter[] parameters = JavaCompletion.EMPTY_PARAMETERS; try { Class[] dP = dM[i].getParameterTypes(); parameters = new JCParameter[dP.length]; for (int j = 0; j < dP.length; j++) { parameters[j] = new JavaCompletion.BaseParameter( "", // name not known from reflection // NOI18N createType(dP[j])); } } catch (SecurityException e) { // can't get parameter types e.printStackTrace(); } // get thrown exceptions - don't restrict to classes level JCClass[] exceptions = JavaCompletion.EMPTY_CLASSES; try { Class[] dE = dM[i].getExceptionTypes(); exceptions = new JCClass[dE.length]; for (int j = 0; j < dE.length; j++) { exceptions[j] = createSimpleClass(dE[j]); } } catch (SecurityException e) { // can't get exception types e.printStackTrace(); } lst.add(new JavaCompletion.BaseMethod(this, dM[i].getName(), dM[i].getModifiers(), createType(dM[i].getReturnType()), parameters, exceptions)); } } body.methods = new JCMethod[lst.size()]; lst.toArray(body.methods); lst.clear(); } catch (SecurityException e) { // can't access declared methods e.printStackTrace(); } c = null; // can free this reference now } } public static boolean getPrimitivesAssignable(int i, int j){ return primitivesAssignable[i][j]; } public static boolean isPrimitiveClass(JCClass c) { return (c.getPackageName().length() == 0) && JavaTokenContext.isTypeOrVoid(c.getName()); } public static JCClass getPrimitivesCommonClass(int i, int j){ return primitivesCommonClass[i][j]; } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
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.