/* * classFileReader.java * * Created on August 20, 2001, 3:36 PM */ package classfilereader; import org.netbeans.modules.classfile.*; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.*; /** * * @author ottati */ public class classFileReader { /** * @param args the command line arguments */ public String[][][][][][][] multiDimensionalArray = {}; public static void main(String args[]) { ClassFile cf; try { cf = new ClassFile(new FileInputStream(new File("f:/ffj/primary/classfilereader/classFileReader.class"))); } catch (IOException e) { System.out.println("Got IO EXCEPTION = " + e); return; } Set classNames = cf.getConstantPool().getAllClassNames(); System.out.println("Orignial Code in Classfile package number of classes = " + classNames.size()); for (Iterator i = classNames.iterator(); i.hasNext();) { System.out.println(i.next()); } // My fixes String[] classNames2 = getAllClassNames(cf.getConstantPool()); System.out.println("\nMy fixes, number of classes = " + classNames2.length); for (int i = 0; i < classNames2.length; i++) { System.out.println(classNames2[i]); } } public static final String[] getAllClassNames(ConstantPool constPool) { /* Collect all class references. The safest way to do this * is to combine the ClassInfo constants with any UTF8Info * constants which match the pattern "L*;". */ Collection c = constPool.getAllConstants(CPClassInfo.class); HashSet v = new HashSet(c.size()); for (Iterator i = c.iterator(); i.hasNext();) { CPClassInfo ci = (CPClassInfo)i.next(); v.add(normalizeClassName(ci.getInternalName())); } c = constPool.getAllConstants(CPUTF8Info.class); for (Iterator i = c.iterator(); i.hasNext();) { CPUTF8Info utf = (CPUTF8Info)i.next(); String name = utf.getName(); if (name.length() > 0 && name.charAt(0) == 'L' && name.charAt(name.length() - 1) == ';') { String clsName = name.substring(1, name.length() - 1); if (!v.contains(clsName)) { v.add(normalizeClassName(clsName )); } } } return (String[])v.toArray(new String[v.size()]); } static String normalizeClassName(String typeString) { boolean simpleClassName = true; int off = 0; int len = typeString.length(); // // The typeString passed to this method can be either a simple // name of a class, or complicated type string. For example, a // simple one looks like: // java/io/PrintStream // // More complicated ones are method strings or array string: // [[I // (Ljava/lang/String;)V // If the first character is a '(' or a '[', then any class names // will start with an L character and end with a ';'. // while (off < len) { switch (typeString.charAt(off)) { case '(': case '[': simpleClassName = false; off++; break; case 'L': // // We have the name of a class followed by a ';' : // Lcom/sun/forte4j/j2ee/ejb/dd/EnvEntry; // find the ';' and extract the class name. // // the "L" case we are looking for here is only if // we know that we are NOT a simple className. In other words // the "L" is part of the signature. If we are a simple class name, // we will fall through here and take the default. if (!simpleClassName) { off++; int semi = typeString.indexOf(';', off); if (semi == -1) { throw new RuntimeException( "Badly formed type string " + typeString); } return typeString.substring(off, semi); } // FALL THROUGH TO DEFAULT default: if (!simpleClassName) { // // If this is the type string for a method, then all // classes start with 'L', so just ignore this and move // on. // off++; } else { // // Since this is not a method type string, then this // is just the name of a simple class. // return typeString; } break; } } throw new RuntimeException("Badly formed type string"); } class theFooClass { public int fooMethod() { return 3;} } }