1 18 package org.apache.batik.util; 19 20 import java.io.DataInputStream ; 21 import java.io.File ; 22 import java.io.FileInputStream ; 23 import java.io.IOException ; 24 import java.io.InputStream ; 25 import java.util.HashSet ; 26 import java.util.Iterator ; 27 import java.util.Set ; 28 29 35 public class ClassFileUtilities { 36 37 public final static byte CONSTANT_UTF8_INFO = 1; 39 public final static byte CONSTANT_INTEGER_INFO = 3; 40 public final static byte CONSTANT_FLOAT_INFO = 4; 41 public final static byte CONSTANT_LONG_INFO = 5; 42 public final static byte CONSTANT_DOUBLE_INFO = 6; 43 public final static byte CONSTANT_CLASS_INFO = 7; 44 public final static byte CONSTANT_STRING_INFO = 8; 45 public final static byte CONSTANT_FIELDREF_INFO = 9; 46 public final static byte CONSTANT_METHODREF_INFO = 10; 47 public final static byte CONSTANT_INTERFACEMETHODREF_INFO = 11; 48 public final static byte CONSTANT_NAMEANDTYPE_INFO = 12; 49 50 53 protected ClassFileUtilities() { 54 } 55 56 62 public static Set getClassDependencies(String path, Set classpath) 63 throws IOException { 64 InputStream is = new FileInputStream (path); 65 66 Set result = new HashSet (); 67 Set done = new HashSet (); 68 69 computeClassDependencies(is, classpath, done, result); 70 71 return result; 72 } 73 74 private static void computeClassDependencies(InputStream is, 75 Set classpath, 76 Set done, 77 Set result) throws IOException { 78 Iterator it = getClassDependencies(is).iterator(); 79 while (it.hasNext()) { 80 String s = (String )it.next(); 81 if (!done.contains(s)) { 82 done.add(s); 83 84 Iterator cpit = classpath.iterator(); 85 while (cpit.hasNext()) { 86 String root = (String )cpit.next(); 87 StringBuffer sb = new StringBuffer (root); 88 sb.append('/').append(s).append(".class"); 89 String path = sb.toString(); 90 91 File f = new File (path); 92 if (f.isFile()) { 93 result.add(path); 94 95 computeClassDependencies(new FileInputStream (f), 96 classpath, 97 done, 98 result); 99 } 100 } 101 } 102 } 103 } 104 105 109 public static Set getClassDependencies(InputStream is) throws IOException { 110 DataInputStream dis = new DataInputStream (is); 111 112 if (dis.readInt() != 0xcafebabe) { 113 throw new IOException ("Invalid classfile"); 114 } 115 116 dis.readInt(); 117 118 int len = dis.readShort(); 119 String [] strs = new String [len]; 120 Set classes = new HashSet (); 121 Set desc = new HashSet (); 122 123 for (int i = 1; i < len; i++) { 124 switch (dis.readByte() & 0xff) { 125 case CONSTANT_LONG_INFO: 126 case CONSTANT_DOUBLE_INFO: 127 dis.readLong(); 128 i++; 129 break; 130 131 case CONSTANT_FIELDREF_INFO: 132 case CONSTANT_METHODREF_INFO: 133 case CONSTANT_INTERFACEMETHODREF_INFO: 134 case CONSTANT_INTEGER_INFO: 135 case CONSTANT_FLOAT_INFO: 136 dis.readInt(); 137 break; 138 139 case CONSTANT_CLASS_INFO: 140 classes.add(new Integer (dis.readShort() & 0xffff)); 141 break; 142 143 case CONSTANT_STRING_INFO: 144 dis.readShort(); 145 break; 146 147 case CONSTANT_NAMEANDTYPE_INFO: 148 dis.readShort(); 149 desc.add(new Integer (dis.readShort() & 0xffff)); 150 break; 151 152 case CONSTANT_UTF8_INFO: 153 strs[i] = dis.readUTF(); 154 break; 155 156 default: 157 throw new RuntimeException (); 158 } 159 } 160 161 Set result = new HashSet (); 162 163 Iterator it = classes.iterator(); 164 while (it.hasNext()) { 165 result.add(strs[((Integer )it.next()).intValue()]); 166 } 167 168 it = desc.iterator(); 169 while (it.hasNext()) { 170 result.addAll(getDescriptorClasses(strs[((Integer )it.next()).intValue()])); 171 } 172 173 return result; 174 } 175 176 179 protected static Set getDescriptorClasses(String desc) { 180 Set result = new HashSet (); 181 int i = 0; 182 char c = desc.charAt(i); 183 switch (c) { 184 case '(': 185 loop: for (;;) { 186 c = desc.charAt(++i); 187 switch (c) { 188 case '[': 189 do { 190 c = desc.charAt(++i); 191 } while (c == '['); 192 if (c != 'L') { 193 break; 194 } 195 196 case 'L': 197 c = desc.charAt(++i); 198 StringBuffer sb = new StringBuffer (); 199 while (c != ';') { 200 sb.append(c); 201 c = desc.charAt(++i); 202 } 203 result.add(sb.toString()); 204 break; 205 206 default: 207 break; 208 209 case ')': 210 break loop; 211 } 212 } 213 c = desc.charAt(++i); 214 switch (c) { 215 case '[': 216 do { 217 c = desc.charAt(++i); 218 } while (c == '['); 219 if (c != 'L') { 220 break; 221 } 222 223 case 'L': 224 c = desc.charAt(++i); 225 StringBuffer sb = new StringBuffer (); 226 while (c != ';') { 227 sb.append(c); 228 c = desc.charAt(++i); 229 } 230 result.add(sb.toString()); 231 break; 232 233 default: 234 case 'V': 235 } 236 break; 237 238 case '[': 239 do { 240 c = desc.charAt(++i); 241 } while (c == '['); 242 if (c != 'L') { 243 break; 244 } 245 246 case 'L': 247 c = desc.charAt(++i); 248 StringBuffer sb = new StringBuffer (); 249 while (c != ';') { 250 sb.append(c); 251 c = desc.charAt(++i); 252 } 253 result.add(sb.toString()); 254 break; 255 256 default: 257 } 258 259 return result; 260 } 261 } 262 | Popular Tags |