001    /*
002     * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
003     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004     *
005     * This code is free software; you can redistribute it and/or modify it
006     * under the terms of the GNU General Public License version 2 only, as
007     * published by the Free Software Foundation.  Sun designates this
008     * particular file as subject to the "Classpath" exception as provided
009     * by Sun in the LICENSE file that accompanied this code.
010     *
011     * This code is distributed in the hope that it will be useful, but WITHOUT
012     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013     * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014     * version 2 for more details (a copy is included in the LICENSE file that
015     * accompanied this code).
016     *
017     * You should have received a copy of the GNU General Public License version
018     * 2 along with this work; if not, write to the Free Software Foundation,
019     * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020     *
021     * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022     * CA 95054 USA or visit www.sun.com if you need additional information or
023     * have any questions.
024     */
025    
026    package com.sun.tools.classfile;
027    
028    import java.io.File;
029    import java.io.FileInputStream;
030    import java.io.IOException;
031    import java.io.InputStream;
032    
033    import static com.sun.tools.classfile.AccessFlags.*;
034    
035    /**
036     * See JVMS3, section 4.2.
037     *
038     *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
039     *  you write code that depends on this, you do so at your own risk.
040     *  This code and its internal interfaces are subject to change or
041     *  deletion without notice.</b>
042     */
043    public class ClassFile {
044        public static ClassFile read(File file)
045                throws IOException, ConstantPoolException {
046            return read(file, new Attribute.Factory());
047        }
048    
049        public static ClassFile read(File file, Attribute.Factory attributeFactory)
050                throws IOException, ConstantPoolException {
051            FileInputStream in = new FileInputStream(file);
052            try {
053                return new ClassFile(in, attributeFactory);
054            } finally {
055                try {
056                    in.close();
057                } catch (IOException e) {
058                    // ignore
059                }
060            }
061        }
062    
063        public static ClassFile read(InputStream in)
064                throws IOException, ConstantPoolException {
065            return new ClassFile(in, new Attribute.Factory());
066        }
067    
068        public static ClassFile read(InputStream in, Attribute.Factory attributeFactory)
069                throws IOException, ConstantPoolException {
070            return new ClassFile(in, attributeFactory);
071        }
072    
073        ClassFile(InputStream in, Attribute.Factory attributeFactory) throws IOException, ConstantPoolException {
074            ClassReader cr = new ClassReader(this, in, attributeFactory);
075            magic = cr.readInt();
076            minor_version = cr.readUnsignedShort();
077            major_version = cr.readUnsignedShort();
078            constant_pool = new ConstantPool(cr);
079            access_flags = new AccessFlags(cr);
080            this_class = cr.readUnsignedShort();
081            super_class = cr.readUnsignedShort();
082    
083            int interfaces_count = cr.readUnsignedShort();
084            interfaces = new int[interfaces_count];
085            for (int i = 0; i < interfaces_count; i++)
086                interfaces[i] = cr.readUnsignedShort();
087    
088            int fields_count = cr.readUnsignedShort();
089            fields = new Field[fields_count];
090            for (int i = 0; i < fields_count; i++)
091                fields[i] = new Field(cr);
092    
093            int methods_count = cr.readUnsignedShort();
094            methods = new Method[methods_count];
095            for (int i = 0; i < methods_count; i++)
096                methods[i] = new Method(cr);
097    
098            attributes = new Attributes(cr);
099        }
100    
101        public ClassFile(int magic, int minor_version, int major_version,
102                ConstantPool constant_pool, AccessFlags access_flags,
103                int this_class, int super_class, int[] interfaces,
104                Field[] fields, Method[] methods, Attributes attributes) {
105            this.magic = magic;
106            this.minor_version = minor_version;
107            this.major_version = major_version;
108            this.constant_pool = constant_pool;
109            this.access_flags = access_flags;
110            this.this_class = this_class;
111            this.super_class = super_class;
112            this.interfaces = interfaces;
113            this.fields = fields;
114            this.methods = methods;
115            this.attributes = attributes;
116        }
117    
118        public String getName() throws ConstantPoolException {
119            return constant_pool.getClassInfo(this_class).getName();
120        }
121    
122        public String getSuperclassName() throws ConstantPoolException {
123            return constant_pool.getClassInfo(super_class).getName();
124        }
125    
126        public String getInterfaceName(int i) throws ConstantPoolException {
127            return constant_pool.getClassInfo(interfaces[i]).getName();
128        }
129    
130        public Attribute getAttribute(String name) {
131            return attributes.get(name);
132        }
133    
134        public boolean isClass() {
135            return !isInterface();
136        }
137    
138        public boolean isInterface() {
139            return access_flags.is(ACC_INTERFACE);
140        }
141    
142        public final int magic;
143        public final int minor_version;
144        public final int major_version;
145        public final ConstantPool constant_pool;
146        public final AccessFlags access_flags;
147        public final int this_class;
148        public final int super_class;
149        public final int[] interfaces;
150        public final Field[] fields;
151        public final Method[] methods;
152        public final Attributes attributes;
153    }