Showing the changes to java/tools/javal/javal.java (1 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,244 @@ | |||
| 1 | package javal; | ||
| 2 | // Copyright (c) Lucent Technologies 1997 | ||
| 3 | // Revisions copyright (c) Vita Nuova Holdings Limited 2004 | ||
| 4 | |||
| 5 | import java.lang.reflect.*; | ||
| 6 | import java.io.FileInputStream; | ||
| 7 | import java.io.File; | ||
| 8 | import java.io.IOException; | ||
| 9 | |||
| 10 | |||
| 11 | public | ||
| 12 | class javal | ||
| 13 | { | ||
| 14 | |||
| 15 | private static java.io.PrintStream out = System.out; | ||
| 16 | |||
| 17 | private static boolean opt_verbose = false; | ||
| 18 | private static boolean opt_classinfo = false; //dump class info | ||
| 19 | private static boolean opt_module = false; //create Limbo mod (.m) | ||
| 20 | private static boolean opt_impl = false; //create Limbo impl skeleton (.b) | ||
| 21 | |||
| 22 | |||
| 23 | public static void main( String[] args ) | ||
| 24 | { | ||
| 25 | int args_len = args.length; | ||
| 26 | |||
| 27 | if ( (args_len < 1) || (args_len > 2) ) | ||
| 28 | error( "wrong args", true ); | ||
| 29 | |||
| 30 | if ( args_len == 2 ) | ||
| 31 | SetArgs( args[0] ); | ||
| 32 | |||
| 33 | // class to create limbo module for | ||
| 34 | String targ_name = args[args_len-1]; | ||
| 35 | Class targ_class = null; | ||
| 36 | |||
| 37 | try | ||
| 38 | { | ||
| 39 | TargetLoader tl = new TargetLoader( opt_verbose ); | ||
| 40 | targ_class = tl.loadClass( targ_name, false ); | ||
| 41 | } | ||
| 42 | catch ( NoClassDefFoundError ee ) | ||
| 43 | { | ||
| 44 | ee.printStackTrace(); | ||
| 45 | error( "ERROR: Class "+ targ_name +" not found.", false ); | ||
| 46 | } | ||
| 47 | catch ( ClassNotFoundException ee ) | ||
| 48 | { | ||
| 49 | error( "Error: Class "+ targ_name +" not found: "+ ee.getMessage(), false ); | ||
| 50 | } | ||
| 51 | catch ( Exception ee ) | ||
| 52 | { | ||
| 53 | error( "Error: Could not load class "+ targ_name +".", false ); | ||
| 54 | } | ||
| 55 | |||
| 56 | out.println( "Class Name: "+ targ_class ); | ||
| 57 | |||
| 58 | Field[] fields = GetFields( targ_class ); | ||
| 59 | Method[] methods = GetMethods( targ_class); | ||
| 60 | |||
| 61 | if ( opt_classinfo ) | ||
| 62 | { | ||
| 63 | Dump( "Fields", fields ); | ||
| 64 | Dump( "Methods", methods ); | ||
| 65 | } | ||
| 66 | |||
| 67 | if ( opt_module || opt_impl ) | ||
| 68 | { | ||
| 69 | try | ||
| 70 | { | ||
| 71 | LimboGen limbogen = new LimboGen( targ_class, fields, methods, opt_verbose ); | ||
| 72 | |||
| 73 | if ( opt_module ) | ||
| 74 | limbogen.DotM(); | ||
| 75 | |||
| 76 | if ( opt_impl ) | ||
| 77 | limbogen.DotB(); | ||
| 78 | } | ||
| 79 | catch ( RuntimeException ee ) | ||
| 80 | { | ||
| 81 | System.err.println( "Error: internal error: "+ ee ); | ||
| 82 | ee.printStackTrace(); | ||
| 83 | error( "...too bad.", false ); | ||
| 84 | } | ||
| 85 | catch ( Exception ee ) | ||
| 86 | { | ||
| 87 | error( "Error: could not generate limbo file: "+ ee, false ); | ||
| 88 | } | ||
| 89 | |||
| 90 | } | ||
| 91 | |||
| 92 | } | ||
| 93 | |||
| 94 | |||
| 95 | /** | ||
| 96 | * Get all data fields for the class and | ||
| 97 | * all of his ancestors. | ||
| 98 | */ | ||
| 99 | private static Field[] GetFields( Class c ) | ||
| 100 | { | ||
| 101 | if ( c == null ) return( new Field[0] ); | ||
| 102 | |||
| 103 | Class sup = c.getSuperclass(); | ||
| 104 | Field[] sup_f = GetFields( sup ); | ||
| 105 | |||
| 106 | Field[] f = c.getDeclaredFields(); | ||
| 107 | |||
| 108 | return( (Field[])ConcatArray( sup_f, f ) ); | ||
| 109 | } | ||
| 110 | |||
| 111 | |||
| 112 | /** | ||
| 113 | * Get methods for the specified class | ||
| 114 | * only (i.e. don't care about ancestor's) | ||
| 115 | */ | ||
| 116 | private static Method[] GetMethods( Class c ) | ||
| 117 | { | ||
| 118 | return( c.getDeclaredMethods() ); | ||
| 119 | } | ||
| 120 | |||
| 121 | |||
| 122 | private static Object ConcatArray( Object[] a1, Object[] a2 ) | ||
| 123 | { | ||
| 124 | if ( (a2 == null) || (a2.length==0) ) return( a1 ); | ||
| 125 | if ( (a1 == null) || (a1.length==0) ) return( a2 ); | ||
| 126 | |||
| 127 | int[] dim = {a1.length+a2.length}; | ||
| 128 | Object a = Array.newInstance( a1[0].getClass(), dim ); | ||
| 129 | |||
| 130 | System.arraycopy( a1, 0, a, 0, a1.length ); | ||
| 131 | System.arraycopy( a2, 0, a, a1.length, a2.length ); | ||
| 132 | |||
| 133 | return( a ); | ||
| 134 | } | ||
| 135 | |||
| 136 | |||
| 137 | private static void Dump( String title, Object[] ary ) | ||
| 138 | { | ||
| 139 | System.out.println( title ); | ||
| 140 | for(int x=0; x<ary.length; x++ ) | ||
| 141 | { | ||
| 142 | System.out.println( "\t"+ ary[x] ); | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | private static void SetArgs( String opts ) | ||
| 147 | { | ||
| 148 | |||
| 149 | if ( (opts.length() > 5) || | ||
| 150 | (opts.length() < 2) || | ||
| 151 | (! opts.startsWith("-")) ) | ||
| 152 | error( "Error: bad options", true ); | ||
| 153 | |||
| 154 | opt_verbose = opts.indexOf( "v" ) != -1; | ||
| 155 | opt_classinfo = opts.indexOf( "c" ) != -1; | ||
| 156 | opt_module = opts.indexOf( "m" ) != -1; | ||
| 157 | opt_impl = opts.indexOf( "b" ) != -1; | ||
| 158 | |||
| 159 | if ( opt_verbose ) | ||
| 160 | Runtime.getRuntime().traceMethodCalls(true); | ||
| 161 | } | ||
| 162 | |||
| 163 | |||
| 164 | private static void error( String msg, boolean usage ) | ||
| 165 | { | ||
| 166 | out.println( msg ); | ||
| 167 | if ( usage ) | ||
| 168 | { | ||
| 169 | out.println( " javal [-vcmb] <class name>" ); | ||
| 170 | } | ||
| 171 | System.exit(1); | ||
| 172 | } | ||
| 173 | } | ||
| 174 | |||
| 175 | /** | ||
| 176 | * This loader simply reads from a disk based | ||
| 177 | * .class file in the "current" directory. It | ||
| 178 | * only accepts the base name of the class, | ||
| 179 | * appends ".class" and reads the file. The | ||
| 180 | * purpose is to allow classes like "String.java" | ||
| 181 | * to be read and queried, where the class | ||
| 182 | * is different then the one used by this | ||
| 183 | * program. This tool is used to develop a | ||
| 184 | * new java class library and this class loader | ||
| 185 | * avoids the conflics of using a java based | ||
| 186 | * tool to develop java classes, etc. | ||
| 187 | */ | ||
| 188 | class TargetLoader extends ClassLoader | ||
| 189 | { | ||
| 190 | private boolean verbose; | ||
| 191 | private String class_name = null; | ||
| 192 | |||
| 193 | TargetLoader( boolean verbose ) | ||
| 194 | { | ||
| 195 | this.verbose = verbose; | ||
| 196 | } | ||
| 197 | |||
| 198 | public Class loadClass( String name, boolean resolve ) throws ClassNotFoundException | ||
| 199 | { | ||
| 200 | |||
| 201 | // if we have already been here once | ||
| 202 | // then load all other classes from the system | ||
| 203 | if ( class_name != null ) | ||
| 204 | { | ||
| 205 | return( findSystemClass( name ) ); | ||
| 206 | } | ||
| 207 | |||
| 208 | // otherwise do our one time load from a disk file | ||
| 209 | |||
| 210 | // read from the current directory the file "name".java | ||
| 211 | class_name = name +".class"; | ||
| 212 | |||
| 213 | try | ||
| 214 | { | ||
| 215 | FileInputStream fin = new FileInputStream( class_name ); | ||
| 216 | |||
| 217 | int len = fin.available(); // how big is the file | ||
| 218 | |||
| 219 | if ( len == 0 ) | ||
| 220 | throw new ClassNotFoundException( class_name ); | ||
| 221 | |||
| 222 | byte[] buf = new byte[len]; | ||
| 223 | |||
| 224 | fin.read( buf ); //read the .class file | ||
| 225 | |||
| 226 | if ( verbose ) | ||
| 227 | { | ||
| 228 | System.out.println( "loading class ["+ class_name +"]("+ len +")" ); | ||
| 229 | } | ||
| 230 | |||
| 231 | // create class object and return it | ||
| 232 | return( defineClass( buf, 0, buf.length ) ); | ||
| 233 | } | ||
| 234 | catch ( IOException ee ) | ||
| 235 | { | ||
| 236 | File f = new File( class_name ); | ||
| 237 | throw new ClassNotFoundException( "(path:"+f.getAbsolutePath() +")" ); | ||
| 238 | } | ||
| 239 | catch ( Exception ee ) | ||
| 240 | { | ||
| 241 | throw new ClassNotFoundException( ee.getMessage() ); | ||
| 242 | } | ||
| 243 | } | ||
| 244 | } | ||