1 17 package org.apache.bcel.classfile; 18 19 import java.io.BufferedInputStream ; 20 import java.io.DataInputStream ; 21 import java.io.FileInputStream ; 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.util.zip.ZipEntry ; 25 import java.util.zip.ZipFile ; 26 import org.apache.bcel.Constants; 27 28 43 public final class ClassParser { 44 45 private DataInputStream file; 46 private boolean fileOwned; 47 private String file_name; 48 private String zip_file; 49 private int class_name_index, superclass_name_index; 50 private int major, minor; private int access_flags; private int[] interfaces; private ConstantPool constant_pool; private Field[] fields; private Method[] methods; private Attribute[] attributes; private boolean is_zip; private static final int BUFSIZE = 8192; 59 60 61 67 public ClassParser(InputStream file, String file_name) { 68 this.file_name = file_name; 69 fileOwned = false; 70 String clazz = file.getClass().getName(); is_zip = clazz.startsWith("java.util.zip.") || clazz.startsWith("java.util.jar."); 72 if (file instanceof DataInputStream ) { 73 this.file = (DataInputStream ) file; 74 } else { 75 this.file = new DataInputStream (new BufferedInputStream (file, BUFSIZE)); 76 } 77 } 78 79 80 84 public ClassParser(String file_name) throws IOException { 85 is_zip = false; 86 this.file_name = file_name; 87 fileOwned = true; 88 } 89 90 91 96 public ClassParser(String zip_file, String file_name) { 97 is_zip = true; 98 fileOwned = true; 99 this.zip_file = zip_file; 100 this.file_name = file_name; 101 } 102 103 104 115 public JavaClass parse() throws IOException , ClassFormatException { 116 ZipFile zip = null; 117 try { 118 if (fileOwned) { 119 if (is_zip) { 120 zip = new ZipFile (zip_file); 121 ZipEntry entry = zip.getEntry(file_name); 122 file = new DataInputStream (new BufferedInputStream (zip.getInputStream(entry), 123 BUFSIZE)); 124 } else { 125 file = new DataInputStream (new BufferedInputStream (new FileInputStream ( 126 file_name), BUFSIZE)); 127 } 128 } 129 130 readID(); 132 readVersion(); 134 135 readConstantPool(); 137 readClassInfo(); 139 readInterfaces(); 141 142 readFields(); 144 readMethods(); 146 readAttributes(); 148 } finally { 163 if (fileOwned) { 165 file.close(); 166 if (zip != null) { 167 zip.close(); 168 } 169 } 170 } 171 return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor, 173 access_flags, constant_pool, interfaces, fields, methods, attributes, is_zip 174 ? JavaClass.ZIP 175 : JavaClass.FILE); 176 } 177 178 179 184 private final void readAttributes() throws IOException , ClassFormatException { 185 int attributes_count; 186 attributes_count = file.readUnsignedShort(); 187 attributes = new Attribute[attributes_count]; 188 for (int i = 0; i < attributes_count; i++) { 189 attributes[i] = Attribute.readAttribute(file, constant_pool); 190 } 191 } 192 193 194 199 private final void readClassInfo() throws IOException , ClassFormatException { 200 access_flags = file.readUnsignedShort(); 201 204 if ((access_flags & Constants.ACC_INTERFACE) != 0) { 205 access_flags |= Constants.ACC_ABSTRACT; 206 } 207 if (((access_flags & Constants.ACC_ABSTRACT) != 0) 208 && ((access_flags & Constants.ACC_FINAL) != 0)) { 209 throw new ClassFormatException("Class can't be both final and abstract"); 210 } 211 class_name_index = file.readUnsignedShort(); 212 superclass_name_index = file.readUnsignedShort(); 213 } 214 215 216 221 private final void readConstantPool() throws IOException , ClassFormatException { 222 constant_pool = new ConstantPool(file); 223 } 224 225 226 231 private final void readFields() throws IOException , ClassFormatException { 232 int fields_count; 233 fields_count = file.readUnsignedShort(); 234 fields = new Field[fields_count]; 235 for (int i = 0; i < fields_count; i++) { 236 fields[i] = new Field(file, constant_pool); 237 } 238 } 239 240 241 242 248 private final void readID() throws IOException , ClassFormatException { 249 int magic = 0xCAFEBABE; 250 if (file.readInt() != magic) { 251 throw new ClassFormatException(file_name + " is not a Java .class file"); 252 } 253 } 254 255 256 261 private final void readInterfaces() throws IOException , ClassFormatException { 262 int interfaces_count; 263 interfaces_count = file.readUnsignedShort(); 264 interfaces = new int[interfaces_count]; 265 for (int i = 0; i < interfaces_count; i++) { 266 interfaces[i] = file.readUnsignedShort(); 267 } 268 } 269 270 271 276 private final void readMethods() throws IOException , ClassFormatException { 277 int methods_count; 278 methods_count = file.readUnsignedShort(); 279 methods = new Method[methods_count]; 280 for (int i = 0; i < methods_count; i++) { 281 methods[i] = new Method(file, constant_pool); 282 } 283 } 284 285 286 291 private final void readVersion() throws IOException , ClassFormatException { 292 minor = file.readUnsignedShort(); 293 major = file.readUnsignedShort(); 294 } 295 } 296 | Popular Tags |