Source Code Cross Referenced for ClassFile.java in  » Development » javaguard » net » sf » javaguard » classfile » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Development » javaguard » net.sf.javaguard.classfile 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         * JavaGuard -- an obfuscation package for Java classfiles.
0003:         *
0004:         * Copyright (c) 1999 Mark Welsh (markw@retrologic.com)
0005:         * Copyright (c) 2002 Thorsten Heit (theit@gmx.de)
0006:         *
0007:         * This library is free software; you can redistribute it and/or
0008:         * modify it under the terms of the GNU Lesser General Public
0009:         * License as published by the Free Software Foundation; either
0010:         * version 2 of the License, or (at your option) any later version.
0011:         *
0012:         * This library is distributed in the hope that it will be useful,
0013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015:         * Lesser General Public License for more details.
0016:         *
0017:         * You should have received a copy of the GNU Lesser General Public
0018:         * License along with this library; if not, write to the Free Software
0019:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0020:         *
0021:         * The author may be contacted at theit@gmx.de.
0022:         *
0023:         *
0024:         * $Id: ClassFile.java,v 1.9 2002/06/04 09:56:47 glurk Exp $
0025:         */package net.sf.javaguard.classfile;
0026:
0027:        import java.io.*;
0028:        import java.util.*;
0029:        import net.sf.javaguard.Cl;
0030:        import net.sf.javaguard.KeyValue;
0031:        import net.sf.javaguard.ClassTree;
0032:        import net.sf.javaguard.log.FileLogger;
0033:        import net.sf.javaguard.Tools;
0034:
0035:        /** This is a representation of the data in a Java class file (*.class).
0036:         * A ClassFile instance representing a *.class file can be generated
0037:         * using the static create(DataInput) method, manipulated using various
0038:         * operators, and persisted back using the write(DataOutput) method.
0039:         *
0040:         * @author <a href="mailto:theit@gmx.de">Thorsten Heit</a>
0041:         * @author <a href="mailto:markw@retrologic.com">Mark Welsh</a>
0042:         */
0043:        public class ClassFile implements  ClassConstants {
0044:            // Constants -------------------------------------------------------------
0045:            private static final String[] DANGEROUS_CLASS_SIMPLENAME_DESCRIPTOR_ARRAY = {
0046:                    "forName(Ljava/lang/String;)Ljava/lang/Class;",
0047:                    "getDeclaredField(Ljava/lang/String;)Ljava/lang/reflect/Field;",
0048:                    "getField(Ljava/lang/String;)Ljava/lang/reflect/Field;",
0049:                    "getDeclaredMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;",
0050:                    "getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;" };
0051:            private static final String LOG_DANGER_CLASS_PRE = "     Your class ";
0052:            private static final String LOG_DANGER_CLASS_MID = " calls the java/lang/Class method ";
0053:            private static final String[] DANGEROUS_CLASSLOADER_SIMPLENAME_DESCRIPTOR_ARRAY = {
0054:                    "defineClass(Ljava/lang/String;[BII)Ljava/lang/Class;",
0055:                    "findLoadedClass(Ljava/lang/String;)Ljava/lang/Class;",
0056:                    "findSystemClass(Ljava/lang/String;)Ljava/lang/Class;",
0057:                    "loadClass(Ljava/lang/String;)Ljava/lang/Class;",
0058:                    "loadClass(Ljava/lang/String;Z)Ljava/lang/Class;" };
0059:            private static final String LOG_DANGER_CLASSLOADER_PRE = "     Your class ";
0060:            private static final String LOG_DANGER_CLASSLOADER_MID = " calls the java/lang/ClassLoader method ";
0061:
0062:            /** Holds the class tree the class file is assigned to. */
0063:            private ClassTree classTree;
0064:            /** Holds the magic number stored in the class file (must be 0xcafebabe). */
0065:            private int magic;
0066:            /** Holds the minor version number. */
0067:            private int minorVersion;
0068:            /** Holds the major version number. */
0069:            private int majorVersion;
0070:            /** Holds the constant pool of the class file. */
0071:            private ConstantPool constantPool;
0072:            /** Holds the access flags for the class. */
0073:            private int accessFlags;
0074:            /** Index into the constant pool. The referenced element holds an index that
0075:             * references the class name. */
0076:            private int this ClassIndex;
0077:            /** Index into the constant pool. The referenced element holds an index that
0078:             * references the name of the super class. */
0079:            private int super ClassIndex;
0080:
0081:            /** Holds the number of direct implemented interfaces. */
0082:            private int interfacesCount;
0083:            /** Index array of interface names in the constant pool. */
0084:            private int interfaces[];
0085:            /** Holds the number of direct declared fields. */
0086:            private int fieldsCount;
0087:            /** Holds information about the declared fields. */
0088:            private FieldInfo fieldInfo[];
0089:            /** Holds the number of declared methods. */
0090:            private int methodsCount;
0091:            /** Holds information about the declared methods. */
0092:            private MethodInfo methodInfo[];
0093:            /** Holds the number of attributes for the class file. */
0094:            private int attributesCount;
0095:            /** Holds information about the attributes for the class file. */
0096:            private AttrInfo attributesInfo[];
0097:
0098:            /** Create a new ClassFile from the class file format data in the DataInput
0099:             * stream.
0100:             * @param classTree the class tree the class file is assigned to
0101:             * @param din the input stream
0102:             * @return the class file created from the input stream
0103:             * @throws IOException if class file is corrupt or incomplete
0104:             */
0105:            public static ClassFile create(ClassTree classTree, DataInput din)
0106:                    throws IOException {
0107:                if (null == din)
0108:                    throw new IOException("No input stream was provided.");
0109:                ClassFile cf = new ClassFile(classTree);
0110:                cf.read(din);
0111:                return cf;
0112:            }
0113:
0114:            /** Private constructor.
0115:             * @param classTree the class tree the class file is assigned to
0116:             */
0117:            private ClassFile(ClassTree classTree) {
0118:                this .classTree = classTree;
0119:            }
0120:
0121:            /** Returns the class tree the class file is assigned to.
0122:             * @return the class tree
0123:             */
0124:            private ClassTree getClassTree() {
0125:                return classTree;
0126:            }
0127:
0128:            /** Import the class data to internal representation.
0129:             * @param din the input stream
0130:             * @throws IOException if an I/O error occurs
0131:             */
0132:            private void read(DataInput din) throws IOException {
0133:                // Read the class file
0134:                setMagic(din.readInt());
0135:                setMinorVersion(din.readUnsignedShort());
0136:                setMajorVersion(din.readUnsignedShort());
0137:
0138:                // Check this is a valid classfile that we can handle
0139:                if (getMagic() != MAGIC) {
0140:                    throw new IOException("Invalid magic number in class file.");
0141:                }
0142:                if (getMajorVersion() > MAJOR_VERSION
0143:                        || (MAJOR_VERSION == getMajorVersion() && getMinorVersion() > MINOR_VERSION_MAX)) {
0144:                    throw new IOException(
0145:                            "Incompatible version number for class file format: "
0146:                                    + getMajorVersion() + " / "
0147:                                    + getMinorVersion());
0148:                }
0149:
0150:                int u2constantPoolCount = din.readUnsignedShort();
0151:                CpInfo[] cpInfo = new CpInfo[u2constantPoolCount];
0152:                // Fill the constant pool, recalling the zero entry
0153:                // is not persisted, nor are the entries following a Long or Double
0154:                for (int i = 1; i < u2constantPoolCount; i++) {
0155:                    cpInfo[i] = CpInfo.create(din);
0156:                    if ((cpInfo[i] instanceof  LongCpInfo)
0157:                            || (cpInfo[i] instanceof  DoubleCpInfo)) {
0158:                        i++;
0159:                    }
0160:                }
0161:                constantPool = new ConstantPool(this , cpInfo);
0162:
0163:                setAccessFlags(din.readUnsignedShort());
0164:                setClassIndex(din.readUnsignedShort());
0165:                setSuperClassIndex(din.readUnsignedShort());
0166:                // read the information about the implemented interfaces
0167:                setInterfacesCount(din.readUnsignedShort());
0168:                int[] u2interfaces = new int[getInterfacesCount()];
0169:                for (int i = 0; i < getInterfacesCount(); i++) {
0170:                    u2interfaces[i] = din.readUnsignedShort();
0171:                }
0172:                setInterfaces(u2interfaces);
0173:                // read the direct declared fields
0174:                setFieldsCount(din.readUnsignedShort());
0175:                FieldInfo[] fields = new FieldInfo[getFieldsCount()];
0176:                for (int i = 0; i < getFieldsCount(); i++) {
0177:                    fields[i] = FieldInfo.create(din, this );
0178:                }
0179:                setFieldInfo(fields);
0180:                // read the direct declared methods
0181:                setMethodsCount(din.readUnsignedShort());
0182:                MethodInfo[] methods = new MethodInfo[getMethodsCount()];
0183:                for (int i = 0; i < getMethodsCount(); i++) {
0184:                    methods[i] = MethodInfo.create(din, this );
0185:                }
0186:                setMethodInfo(methods);
0187:                // read the attributes for the class
0188:                setAttributesCount(din.readUnsignedShort());
0189:                AttrInfo[] attrs = new AttrInfo[getAttributesCount()];
0190:                for (int i = 0; i < getAttributesCount(); i++) {
0191:                    attrs[i] = AttrInfo.create(din, this );
0192:                }
0193:                setAttributeInfo(attrs);
0194:            }
0195:
0196:            /** Sets the magic number of the class file (normally 0xcafebabe).
0197:             * @param num the magic number
0198:             * @see #getMagic
0199:             */
0200:            private void setMagic(int num) {
0201:                this .magic = num;
0202:            }
0203:
0204:            /** Returns the magic number of the class file (normally 0xcafebabe).
0205:             * @return magic number
0206:             * @see #setMagic
0207:             */
0208:            private int getMagic() {
0209:                return magic;
0210:            }
0211:
0212:            /** Sets the major version of the class file.
0213:             * @param ver major class file version
0214:             * @see #getMajorVersion
0215:             */
0216:            private void setMajorVersion(int ver) {
0217:                majorVersion = ver;
0218:            }
0219:
0220:            /** Returns the major version of the class file.
0221:             * @return major class file version
0222:             * @see #setMajorVersion
0223:             */
0224:            private int getMajorVersion() {
0225:                return majorVersion;
0226:            }
0227:
0228:            /** Sets the minor version of the class file.
0229:             * @param ver minor class file version
0230:             * @see #setMinorVersion
0231:             */
0232:            private void setMinorVersion(int ver) {
0233:                minorVersion = ver;
0234:            }
0235:
0236:            /** Returns the minor version of the class file.
0237:             * @return minor class file version
0238:             * @see #setMinorVersion
0239:             */
0240:            private int getMinorVersion() {
0241:                return minorVersion;
0242:            }
0243:
0244:            /** Sets the access flags for the class.
0245:             * @param flags the access flags for the class
0246:             * @see #getAccessFlags
0247:             */
0248:            private void setAccessFlags(int flags) {
0249:                accessFlags = flags;
0250:            }
0251:
0252:            /** Returns the access flags for the class.
0253:             * @return access flags for the class
0254:             * @see #setAccessFlags
0255:             */
0256:            private int getAccessFlags() {
0257:                return accessFlags;
0258:            }
0259:
0260:            /** Sets the index for the element in the constant pool that knows the class
0261:             * name.
0262:             * @param index index into the constant pool
0263:             * @see #getClassIndex
0264:             */
0265:            private void setClassIndex(int index) {
0266:                this ClassIndex = index;
0267:            }
0268:
0269:            /** Returns the index for the element in the constant pool that knows the
0270:             * class name.
0271:             * @return index into the constant pool
0272:             * @see #setClassIndex
0273:             */
0274:            private int getClassIndex() {
0275:                return this ClassIndex;
0276:            }
0277:
0278:            /** Sets the index for the element in the constant pool that knows the name
0279:             * of the super class.
0280:             * @param index index into the constant pool
0281:             * @see #getSuperClassIndex
0282:             */
0283:            private void setSuperClassIndex(int index) {
0284:                super ClassIndex = index;
0285:            }
0286:
0287:            /** Returns the index for the element in the constant pool that knows the
0288:             * name of the super class.
0289:             * @return index into the constant pool
0290:             */
0291:            private int getSuperClassIndex() {
0292:                return super ClassIndex;
0293:            }
0294:
0295:            /** Sets the number of direct implemented interfaces.
0296:             * @param num the number of direct implemented interfaces
0297:             * @see #getInterfacesCount
0298:             */
0299:            private void setInterfacesCount(int num) {
0300:                interfacesCount = num;
0301:            }
0302:
0303:            /** Returns the number of direct implemented interfaces.
0304:             * @return number of direct implemented interfaces
0305:             * @see #setInterfacesCount
0306:             */
0307:            private int getInterfacesCount() {
0308:                return interfacesCount;
0309:            }
0310:
0311:            /** Sets the index array of interface names in the constant pool.
0312:             * @param interfaces index array of interface names in the constant pool
0313:             * @see #getInterfaces
0314:             */
0315:            private void setInterfaces(int[] interfaces) {
0316:                this .interfaces = interfaces;
0317:            }
0318:
0319:            /** Returns the index array of interface names in the constant pool.
0320:             * @return index array of interface names in the constant pool
0321:             * @see #setInterfaces
0322:             * @see #getInterface
0323:             */
0324:            private int[] getInterfaces() {
0325:                return interfaces;
0326:            }
0327:
0328:            /** Return the index of the specified interface from the index array.
0329:             * @param pos the position of the interface in the interface name index array
0330:             * @return index into the constant pool
0331:             * @see #getInterfaces
0332:             */
0333:            private int getInterface(int pos) {
0334:                return interfaces[pos];
0335:            }
0336:
0337:            /** Returns an array with the names of the direct implemented interfaces.
0338:             * @return array with interface names
0339:             */
0340:            public String[] getInterfaceNames() {
0341:                String[] names = new String[getInterfacesCount()];
0342:                for (int i = 0; i < getInterfacesCount(); i++) {
0343:                    names[i] = toName(getInterface(i));
0344:                }
0345:                return names;
0346:            }
0347:
0348:            /** Sets the number of declared fields.
0349:             * @param num number of declared fields
0350:             * @see #getFieldsCount
0351:             */
0352:            private void setFieldsCount(int num) {
0353:                fieldsCount = num;
0354:            }
0355:
0356:            /** Returns the number of declared fields.
0357:             * @return number of declared fields
0358:             */
0359:            public int getFieldsCount() {
0360:                return fieldsCount;
0361:            }
0362:
0363:            /** Sets the information about the declared fields.
0364:             * @param fields array with information about the declared fields
0365:             * @see #getFieldInfo
0366:             */
0367:            private void setFieldInfo(FieldInfo[] fields) {
0368:                this .fieldInfo = fields;
0369:            }
0370:
0371:            /** Returns an array with information about the declared fields.
0372:             * @return array with information about the declared fields
0373:             * @see #setFieldInfo
0374:             */
0375:            private FieldInfo[] getFieldInfo() {
0376:                return fieldInfo;
0377:            }
0378:
0379:            /** Return the information about a declared field.
0380:             * @param pos the position in the array of declared fields
0381:             * @return information about the declared fieldd
0382:             * @see #getFieldInfo
0383:             */
0384:            public FieldInfo getFieldInfo(int pos) {
0385:                return fieldInfo[pos];
0386:            }
0387:
0388:            /** Sets the number of declared methods.
0389:             * @param num the number of declared methods
0390:             * @see #getMethodsCount
0391:             */
0392:            private void setMethodsCount(int num) {
0393:                methodsCount = num;
0394:            }
0395:
0396:            /** Returns the number of declared methods.
0397:             * @return the number of declared methods
0398:             */
0399:            public int getMethodsCount() {
0400:                return methodsCount;
0401:            }
0402:
0403:            /** Sets the information about the declared methods.
0404:             * @param methods array with information about the declared methods
0405:             * @see #getMethodInfo
0406:             */
0407:            private void setMethodInfo(MethodInfo[] methods) {
0408:                this .methodInfo = methods;
0409:            }
0410:
0411:            /** Returns an array with information about the declared methods.
0412:             * @return array with information about the declared methods
0413:             * @see #setMethodInfo
0414:             */
0415:            private MethodInfo[] getMethodInfo() {
0416:                return methodInfo;
0417:            }
0418:
0419:            /** Return the information about a declared method.
0420:             * @param pos the position in the array of declared methods
0421:             * @return information about the declared method
0422:             * @see #getMethodInfo
0423:             */
0424:            public MethodInfo getMethodInfo(int pos) {
0425:                return methodInfo[pos];
0426:            }
0427:
0428:            /** Sets the number of attributes for the class file.
0429:             * @param num the number of attributes for the class file
0430:             * @see #getAttributesCount
0431:             */
0432:            private void setAttributesCount(int num) {
0433:                attributesCount = num;
0434:            }
0435:
0436:            /** Returns the number of attributes for the class file.
0437:             * @return the number of attributes for the class file
0438:             * @see #setAttributesCount
0439:             */
0440:            private int getAttributesCount() {
0441:                return attributesCount;
0442:            }
0443:
0444:            /** Sets the information about the attributes for the class file.
0445:             * @param attrs array with information about the attributes for the class file
0446:             * @see #getAttributeInfo
0447:             */
0448:            private void setAttributeInfo(AttrInfo[] attrs) {
0449:                this .attributesInfo = attrs;
0450:            }
0451:
0452:            /** Returns an array with information about the attributes for the class file.
0453:             * @return array with information about the attributes for the class file
0454:             * @see #setAttributeInfo
0455:             */
0456:            private AttrInfo[] getAttributeInfo() {
0457:                return attributesInfo;
0458:            }
0459:
0460:            /** Return the information about an attribute for the class file.
0461:             * @param pos the position in the array of attributes
0462:             * @return information about the attribute
0463:             * @see #getAttributeInfo
0464:             * @see #setAttributeInfo(int, AttrInfo)
0465:             */
0466:            private AttrInfo getAttributeInfo(int pos) {
0467:                return attributesInfo[pos];
0468:            }
0469:
0470:            /** Sets the information about a certain attribute.
0471:             * @param pos the position in the array of attributes
0472:             * @param attrInfo the new attribute information
0473:             * @see #getAttributeInfo(int)
0474:             * @see #setAttributeInfo
0475:             */
0476:            private void setAttributeInfo(int pos, AttrInfo attrInfo) {
0477:                attributesInfo[pos] = attrInfo;
0478:            }
0479:
0480:            /** Return the name of the class file.
0481:             * @return the name of the class file
0482:             */
0483:            public String getName() {
0484:                return toName(getClassIndex());
0485:            }
0486:
0487:            /** Return the name of this class's super class.
0488:             * @return the name of the super class
0489:             */
0490:            public String getSuper() {
0491:                // This may be java/lang/Object, in which case there is no super
0492:                return (0 == getSuperClassIndex()) ? null
0493:                        : toName(getSuperClassIndex());
0494:            }
0495:
0496:            /** Convert a constant pool index to a class name.
0497:             * @param index the index into the constant pool
0498:             * @return the name of the specified class
0499:             * @throws IllegalStateException if an error occurs
0500:             */
0501:            protected String toName(int index) throws IllegalStateException {
0502:                CpInfo classEntry = getCpEntry(index);
0503:                if (classEntry instanceof  ClassCpInfo) {
0504:                    CpInfo nameEntry = getCpEntry(((ClassCpInfo) classEntry)
0505:                            .getClassNameIndex());
0506:                    if (nameEntry instanceof  Utf8CpInfo) {
0507:                        return ((Utf8CpInfo) nameEntry).getString();
0508:                    }
0509:                }
0510:                throw new IllegalStateException(
0511:                        "Inconsistent Constant Pool in class file.");
0512:            }
0513:
0514:            /** Lookup the entry in the constant pool and return the object.
0515:             * @param index the index into the constant pool
0516:             * @return the entry at the specified index in the constant pool
0517:             */
0518:            protected CpInfo getCpEntry(int index) {
0519:                return constantPool.getCpEntry(index);
0520:            }
0521:
0522:            /** Check for methods which can break the obfuscated code, and log them to
0523:             * a string array.
0524:             * @return string array with methods which can break the obfuscated code
0525:             */
0526:            public String[] dangerousMethods() {
0527:                Vector warningVec = new Vector();
0528:
0529:                // Need only check CONSTANT_Methodref entries of constant pool since
0530:                // dangerous methods belong to classes 'Class' and 'ClassLoader', not to interfaces.
0531:                for (Iterator iter = constantPool.iterator(); iter.hasNext();) {
0532:                    Object obj = iter.next();
0533:                    if (obj instanceof  MethodrefCpInfo) {
0534:                        // Get the method class name, simple name and descriptor
0535:                        MethodrefCpInfo entry = (MethodrefCpInfo) obj;
0536:                        ClassCpInfo classEntry = (ClassCpInfo) getCpEntry(entry
0537:                                .getClassIndex());
0538:                        String className = ((Utf8CpInfo) getCpEntry(classEntry
0539:                                .getClassNameIndex())).getString();
0540:                        NameAndTypeCpInfo ntEntry = (NameAndTypeCpInfo) getCpEntry(entry
0541:                                .getNameAndTypeIndex());
0542:                        String name = ((Utf8CpInfo) getCpEntry(ntEntry
0543:                                .getNameIndex())).getString();
0544:                        String descriptor = ((Utf8CpInfo) getCpEntry(ntEntry
0545:                                .getDescriptorIndex())).getString();
0546:
0547:                        // Check if this is on the proscribed list
0548:                        if (className.equals("java/lang/Class")
0549:                                && Tools
0550:                                        .isInArray(name + descriptor,
0551:                                                DANGEROUS_CLASS_SIMPLENAME_DESCRIPTOR_ARRAY)) {
0552:                            warningVec.addElement(LOG_DANGER_CLASS_PRE
0553:                                    + getName() + LOG_DANGER_CLASS_MID + name
0554:                                    + descriptor);
0555:                        } else if (Tools
0556:                                .isInArray(name + descriptor,
0557:                                        DANGEROUS_CLASSLOADER_SIMPLENAME_DESCRIPTOR_ARRAY)) {
0558:                            warningVec.addElement(LOG_DANGER_CLASSLOADER_PRE
0559:                                    + getName() + LOG_DANGER_CLASSLOADER_MID
0560:                                    + name + descriptor);
0561:                        }
0562:                    }
0563:                }
0564:
0565:                // Copy any warnings to a String[]
0566:                String[] warnings = new String[warningVec.size()];
0567:                for (int i = 0; i < warnings.length; i++) {
0568:                    warnings[i] = (String) warningVec.elementAt(i);
0569:                }
0570:                return warnings;
0571:            }
0572:
0573:            /** Check for methods which can break the obfuscated code, and log them. */
0574:            private static boolean hasHeader = false;
0575:
0576:            public static void resetDangerHeader() {
0577:                hasHeader = false;
0578:            }
0579:
0580:            public void logDangerousMethods() {
0581:                // Get any warnings and print them to the logfile
0582:                String[] warnings = dangerousMethods();
0583:                if (warnings != null && warnings.length > 0) {
0584:                    FileLogger logfile = FileLogger.getInstance();
0585:                    if (!hasHeader) {
0586:                        logfile.addMethodWarning("#");
0587:                        logfile
0588:                                .addMethodWarning("# WARNING - Methods are called which may unavoidably break in obfuscated version at runtime.");
0589:                        logfile
0590:                                .addMethodWarning("#          Please review your source code to ensure that the dangerous methods are not intended");
0591:                        logfile
0592:                                .addMethodWarning("#          to act on classes which are within the obfuscated Jar file.");
0593:                        logfile.addMethodWarning("#");
0594:                        hasHeader = true;
0595:                    }
0596:                    for (int i = 0; i < warnings.length; i++) {
0597:                        logfile.addMethodWarning("# " + warnings[i]);
0598:                    }
0599:                }
0600:            }
0601:
0602:            /** Check for direct references to Utf8 constant pool entries.
0603:             * @param pool the constant pool
0604:             * @throws IllegalStateException if a reference is invalid
0605:             */
0606:            public void markUtf8Refs(ConstantPool pool)
0607:                    throws IllegalStateException {
0608:                try {
0609:                    // Check for references to Utf8 from outside the constant pool
0610:                    for (int i = 0; i < getFieldsCount(); i++) {
0611:                        getFieldInfo(i).markUtf8Refs(pool);
0612:                    }
0613:                    for (int i = 0; i < getMethodsCount(); i++) {
0614:                        getMethodInfo(i).markUtf8Refs(pool); // also checks Code/LVT attrs here
0615:                    }
0616:                    for (int i = 0; i < getAttributesCount(); i++) {
0617:                        getAttributeInfo(i).markUtf8Refs(pool); // checks InnerClasses, SourceFile and all attr names
0618:                    }
0619:
0620:                    // Now check for references from other CP entries
0621:                    for (Iterator iter = pool.iterator(); iter.hasNext();) {
0622:                        Object obj = iter.next();
0623:                        if (obj instanceof  NameAndTypeCpInfo
0624:                                || obj instanceof  ClassCpInfo
0625:                                || obj instanceof  StringCpInfo) {
0626:                            ((CpInfo) obj).markUtf8Refs(pool);
0627:                        }
0628:                    }
0629:                } catch (ArrayIndexOutOfBoundsException e) {
0630:                    throw new IllegalStateException(
0631:                            "Inconsistent reference to constant pool.");
0632:                }
0633:            }
0634:
0635:            /** Check for direct references to NameAndType constant pool entries.
0636:             * @param pool the constant pool
0637:             * @throws IllegalStateException if a reference is invalid
0638:             */
0639:            public void markNTRefs(ConstantPool pool)
0640:                    throws IllegalStateException {
0641:                try {
0642:                    // Now check the method and field CP entries
0643:                    for (Iterator iter = pool.iterator(); iter.hasNext();) {
0644:                        Object obj = iter.next();
0645:                        if (obj instanceof  RefCpInfo) {
0646:                            ((CpInfo) obj).markNTRefs(pool);
0647:                        }
0648:                    }
0649:                } catch (ArrayIndexOutOfBoundsException e) {
0650:                    throw new IllegalStateException(
0651:                            "Inconsistent reference to constant pool.");
0652:                }
0653:            }
0654:
0655:            /** Trim attributes from the classfile ('Code', 'Exceptions', 'ConstantValue'
0656:             * are preserved, all others except the list in the String[] are killed).
0657:             * @param extraAttrs array with additional attributes to keep
0658:             */
0659:            public void trimAttrsExcept(String[] extraAttrs) {
0660:                // Merge additional attributes with required list
0661:                String[] keepAttrs = REQUIRED_ATTRS;
0662:                if (extraAttrs != null && extraAttrs.length > 0) {
0663:                    String[] tmp = new String[keepAttrs.length
0664:                            + extraAttrs.length];
0665:                    System.arraycopy(keepAttrs, 0, tmp, 0, keepAttrs.length);
0666:                    System.arraycopy(extraAttrs, 0, tmp, keepAttrs.length,
0667:                            extraAttrs.length);
0668:                    keepAttrs = tmp;
0669:                }
0670:
0671:                // Traverse all attributes, removing all except those on 'keep' list
0672:                for (int i = 0; i < getFieldsCount(); i++) {
0673:                    getFieldInfo(i).trimAttrsExcept(keepAttrs);
0674:                }
0675:                for (int i = 0; i < getMethodsCount(); i++) {
0676:                    getMethodInfo(i).trimAttrsExcept(keepAttrs);
0677:                }
0678:                for (int i = 0; i < getAttributesCount(); i++) {
0679:                    if (Tools.isInArray(getAttributeInfo(i).getAttrName(),
0680:                            keepAttrs)) {
0681:                        getAttributeInfo(i).trimAttrsExcept(keepAttrs);
0682:                    } else {
0683:                        setAttributeInfo(i, null);
0684:                    }
0685:                }
0686:
0687:                // Delete the marked attributes
0688:                AttrInfo[] left = new AttrInfo[getAttributesCount()];
0689:                int j = 0;
0690:                for (int i = 0; i < getAttributesCount(); i++) {
0691:                    if (null != getAttributeInfo(i)) {
0692:                        left[j++] = getAttributeInfo(i);
0693:                    }
0694:                }
0695:                AttrInfo[] attributes = new AttrInfo[j];
0696:                System.arraycopy(left, 0, attributes, 0, j);
0697:                setAttributesCount(j);
0698:                setAttributeInfo(attributes);
0699:
0700:                // Update the constant pool reference counts
0701:                constantPool.updateRefCount();
0702:            }
0703:
0704:            /** Trim attributes from the classfile ('Code', 'Exceptions', 'ConstantValue'
0705:             * are preserved, all others are killed).
0706:             */
0707:            public void trimAttrs() {
0708:                trimAttrsExcept(null);
0709:            }
0710:
0711:            /** Remap the entities in the current class file.
0712:             * @param nm the name mapper for the class file
0713:             */
0714:            public void remap(NameMapper nm) {
0715:                // Remove unnecessary attributes from the class
0716:                String[] attrs = nm.getAttrsToKeep();
0717:                if (attrs.length > 0) {
0718:                    trimAttrsExcept(attrs);
0719:                } else {
0720:                    trimAttrs();
0721:                }
0722:
0723:                // Remap all the package/interface/class/method/field names
0724:                //
0725:                String this ClassName = ((Utf8CpInfo) getCpEntry(((ClassCpInfo) getCpEntry(getClassIndex()))
0726:                        .getClassNameIndex())).getString();
0727:
0728:                // Remap the 'inner name' reference of the 'InnerClasses' attribute
0729:                for (int i = 0; i < getAttributesCount(); i++) {
0730:                    AttrInfo attrInfo = getAttributeInfo(i);
0731:                    if (attrInfo instanceof  InnerClassesAttrInfo) {
0732:                        // For each inner class referemce,
0733:                        InnerClassesInfo[] info = ((InnerClassesAttrInfo) attrInfo)
0734:                                .getInnerClasses();
0735:                        for (int j = 0; j < info.length; j++) {
0736:                            // Get the 'inner name' (it is a CONSTANT_Utf8)
0737:                            CpInfo cpInfo = getCpEntry(info[j]
0738:                                    .getInnerNameIndex());
0739:                            if (cpInfo instanceof  Utf8CpInfo) {
0740:                                // Get the remapped class name
0741:                                Utf8CpInfo utf = (Utf8CpInfo) cpInfo;
0742:                                String origClass = utf.getString();
0743:
0744:                                // Only remap non-anonymous classes (anon are "")
0745:                                if (!origClass.equals("")) {
0746:                                    // Get the full inner class name
0747:                                    ClassCpInfo innerClassInfo = (ClassCpInfo) getCpEntry(info[j]
0748:                                            .getInnerClassInfoIndex());
0749:                                    String innerClassName = ((Utf8CpInfo) getCpEntry(innerClassInfo
0750:                                            .getClassNameIndex())).getString();
0751:
0752:                                    // It is the remapped simple name that must be stored, so truncate it
0753:                                    String remapClass = nm
0754:                                            .mapClass(innerClassName);
0755:                                    remapClass = remapClass
0756:                                            .substring(remapClass
0757:                                                    .lastIndexOf('$') + 1);
0758:                                    int remapIndex = constantPool.remapUtf8To(
0759:                                            remapClass, info[j]
0760:                                                    .getInnerNameIndex());
0761:                                    info[j].setInnerNameIndex(remapIndex);
0762:                                }
0763:                            }
0764:                        }
0765:                    }
0766:                }
0767:
0768:                // Remap the 'name' and 'descriptor' references of the 'LocalVariableTable'
0769:                // attribute, in the 'Code' attribute of method structures.
0770:                for (int i = 0; i < getMethodsCount(); i++) {
0771:                    for (int j = 0; j < getMethodInfo(i).getAttributesLength(); j++) {
0772:                        AttrInfo attrInfo = getMethodInfo(i).getAttribute(j);
0773:                        if (attrInfo instanceof  CodeAttrInfo) {
0774:                            CodeAttrInfo codeAttrInfo = (CodeAttrInfo) attrInfo;
0775:                            for (int k = 0; k < codeAttrInfo
0776:                                    .getAttributesLength(); k++) {
0777:                                AttrInfo innerAttrInfo = codeAttrInfo
0778:                                        .getAttributes()[k];
0779:                                if (innerAttrInfo instanceof  LocalVariableTableAttrInfo) {
0780:                                    LocalVariableTableAttrInfo lvtAttrInfo = (LocalVariableTableAttrInfo) innerAttrInfo;
0781:                                    LocalVariableInfo[] lvts = lvtAttrInfo
0782:                                            .getLocalVariableTable();
0783:                                    for (int m = 0; m < lvts.length; m++) {
0784:                                        // Remap name
0785:                                        Utf8CpInfo nameUtf = (Utf8CpInfo) getCpEntry(lvts[m]
0786:                                                .getNameIndex());
0787:                                        String remapName = nm.mapField(
0788:                                                this ClassName, nameUtf
0789:                                                        .getString());
0790:                                        // if no mapping is found use the original name
0791:                                        if (null == remapName) {
0792:                                            remapName = nameUtf.getString();
0793:                                        }
0794:                                        lvts[m].setNameIndex(constantPool
0795:                                                .remapUtf8To(remapName, lvts[m]
0796:                                                        .getNameIndex()));
0797:
0798:                                        // Remap descriptor
0799:                                        Utf8CpInfo descUtf = (Utf8CpInfo) getCpEntry(lvts[m]
0800:                                                .getDescriptorIndex());
0801:                                        String remapDesc = nm
0802:                                                .mapDescriptor(descUtf
0803:                                                        .getString());
0804:                                        lvts[m].setDescriptorIndex(constantPool
0805:                                                .remapUtf8To(remapDesc, lvts[m]
0806:                                                        .getDescriptorIndex()));
0807:                                    }
0808:                                }
0809:                            }
0810:                        }
0811:                    }
0812:                }
0813:
0814:                // Go through all of class's fields and methods mapping 'name' and 'descriptor' references
0815:                for (int i = 0; i < getFieldsCount(); i++) {
0816:                    // Remap field 'name', unless it is 'Synthetic'
0817:                    FieldInfo field = getFieldInfo(i);
0818:                    if (!field.isSynthetic()) {
0819:                        Utf8CpInfo nameUtf = (Utf8CpInfo) getCpEntry(field
0820:                                .getNameIndex());
0821:                        String remapName = nm.mapField(this ClassName, nameUtf
0822:                                .getString());
0823:                        // if no mapping is found use the original name
0824:                        if (null == remapName) {
0825:                            remapName = nameUtf.getString();
0826:                        }
0827:                        field.setNameIndex(constantPool.remapUtf8To(remapName,
0828:                                field.getNameIndex()));
0829:                    }
0830:
0831:                    // Remap field 'descriptor'
0832:                    Utf8CpInfo descUtf = (Utf8CpInfo) getCpEntry(field
0833:                            .getDescriptorIndex());
0834:                    String remapDesc = nm.mapDescriptor(descUtf.getString());
0835:                    field.setDescriptorIndex(constantPool.remapUtf8To(
0836:                            remapDesc, field.getDescriptorIndex()));
0837:                }
0838:                for (int i = 0; i < getMethodsCount(); i++) {
0839:                    // Remap method 'name', unless it is 'Synthetic'
0840:                    MethodInfo method = getMethodInfo(i);
0841:                    Utf8CpInfo descUtf = (Utf8CpInfo) getCpEntry(method
0842:                            .getDescriptorIndex());
0843:                    if (!method.isSynthetic()) {
0844:                        Utf8CpInfo nameUtf = (Utf8CpInfo) getCpEntry(method
0845:                                .getNameIndex());
0846:                        String remapName = nm.mapMethod(this ClassName, nameUtf
0847:                                .getString(), descUtf.getString());
0848:                        // if no mapping is found use the original name
0849:                        if (null == remapName) {
0850:                            remapName = nameUtf.getString();
0851:                        }
0852:                        method.setNameIndex(constantPool.remapUtf8To(remapName,
0853:                                method.getNameIndex()));
0854:                    }
0855:
0856:                    // Remap method 'descriptor'
0857:                    String remapDesc = nm.mapDescriptor(descUtf.getString());
0858:                    method.setDescriptorIndex(constantPool.remapUtf8To(
0859:                            remapDesc, method.getDescriptorIndex()));
0860:                }
0861:
0862:                // Remap all field/method names and descriptors in the constant pool (depends on class names)
0863:                int currentCpLength = constantPool.length(); // constant pool can be extended (never contracted) during loop
0864:                for (int i = 0; i < currentCpLength; i++) {
0865:                    CpInfo cpInfo = getCpEntry(i);
0866:                    if (null != cpInfo) {
0867:                        // If this is a CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref
0868:                        // get the CONSTANT_NameAndType and remap the name and the components of the
0869:                        // descriptor string.
0870:                        if (cpInfo instanceof  RefCpInfo) {
0871:                            // Get the unmodified class name
0872:                            ClassCpInfo classInfo = (ClassCpInfo) getCpEntry(((RefCpInfo) cpInfo)
0873:                                    .getClassIndex());
0874:                            Utf8CpInfo classUtf = (Utf8CpInfo) getCpEntry(classInfo
0875:                                    .getClassNameIndex());
0876:                            String className = classUtf.getString();
0877:
0878:                            // Get the current N&T reference and its 'name' and 'descriptor' utf's
0879:                            int ntIndex = ((RefCpInfo) cpInfo)
0880:                                    .getNameAndTypeIndex();
0881:                            NameAndTypeCpInfo nameTypeInfo = (NameAndTypeCpInfo) getCpEntry(ntIndex);
0882:                            Utf8CpInfo refUtf = (Utf8CpInfo) getCpEntry(nameTypeInfo
0883:                                    .getNameIndex());
0884:                            Utf8CpInfo descUtf = (Utf8CpInfo) getCpEntry(nameTypeInfo
0885:                                    .getDescriptorIndex());
0886:
0887:                            // Get the remapped versions of 'name' and 'descriptor'
0888:                            String remapRef;
0889:                            if (cpInfo instanceof  FieldrefCpInfo) {
0890:                                remapRef = nm.mapField(className, refUtf
0891:                                        .getString());
0892:                                // if no mapping is found use the original name
0893:                                if (null == remapRef) {
0894:                                    remapRef = refUtf.getString();
0895:                                }
0896:
0897:                                // cloder - check if this is a compiler generated field
0898:                                // supporting the JDK1.2-or-later '.class' construct
0899:                                if (refUtf.getString().startsWith("class$")) {
0900:                                    String realClassName = refUtf.getString()
0901:                                            .substring(6).replace('$', '.');
0902:                                    // check whether the hardcoded class name is not a class from the
0903:                                    // Java SDK, i.e. doesn't start with "java." or "javax."
0904:                                    if (!realClassName.startsWith("java.")
0905:                                            && !realClassName
0906:                                                    .startsWith("javax.")
0907:                                            && !realClassName
0908:                                                    .startsWith("sun.")
0909:                                            && !realClassName
0910:                                                    .startsWith("com.sun.")) {
0911:                                        // check whether the hardcoded class name exists in the main tree
0912:                                        // whether it is be obfuscated
0913:                                        Cl cl = getClassTree().findClass(
0914:                                                realClassName);
0915:                                        if (null != cl) {
0916:                                            if (cl.isBeingObfuscated()) {
0917:                                                FileLogger
0918:                                                        .getInstance()
0919:                                                        .addWarning(
0920:                                                                "# WARNING: "
0921:                                                                        + realClassName
0922:                                                                        + " shouldn't be obfuscated: it is referenced as "
0923:                                                                        + realClassName
0924:                                                                        + ".class from "
0925:                                                                        + this ClassName);
0926:                                            }
0927:                                        }
0928:                                    }
0929:                                }
0930:                                // end cloder
0931:                            } else {
0932:                                // instance of method mapping
0933:                                remapRef = nm.mapMethod(className, refUtf
0934:                                        .getString(), descUtf.getString());
0935:                                // if no mapping is found use the original name
0936:                                if (null == remapRef) {
0937:                                    remapRef = refUtf.getString();
0938:                                }
0939:                            }
0940:                            String remapDesc = nm.mapDescriptor(descUtf
0941:                                    .getString());
0942:
0943:                            // If a remap is required, make a new N&T (increment ref count on 'name' and
0944:                            // 'descriptor', decrement original N&T's ref count, set new N&T ref count to 1),
0945:                            // remap new N&T's utf's
0946:                            if (!remapRef.equals(refUtf.getString())
0947:                                    || !remapDesc.equals(descUtf.getString())) {
0948:                                // Get the new N&T guy
0949:                                NameAndTypeCpInfo newNameTypeInfo;
0950:                                if (nameTypeInfo.getRefCount() == 1) {
0951:                                    newNameTypeInfo = nameTypeInfo;
0952:                                } else {
0953:                                    // Create the new N&T info
0954:                                    newNameTypeInfo = (NameAndTypeCpInfo) nameTypeInfo
0955:                                            .clone();
0956:
0957:                                    // Adjust its reference counts of its utf's
0958:                                    ((CpInfo) getCpEntry(newNameTypeInfo
0959:                                            .getNameIndex())).incRefCount();
0960:                                    ((CpInfo) getCpEntry(newNameTypeInfo
0961:                                            .getDescriptorIndex()))
0962:                                            .incRefCount();
0963:
0964:                                    // Append it to the Constant Pool, and
0965:                                    // point the RefCpInfo entry to the new N&T data
0966:                                    ((RefCpInfo) cpInfo)
0967:                                            .setNameAndTypeIndex(constantPool
0968:                                                    .addEntry(newNameTypeInfo));
0969:
0970:                                    // Adjust reference counts from RefCpInfo
0971:                                    newNameTypeInfo.incRefCount();
0972:                                    nameTypeInfo.decRefCount();
0973:                                }
0974:
0975:                                // Remap the 'name' and 'descriptor' utf's in N&T
0976:                                newNameTypeInfo.setNameIndex(constantPool
0977:                                        .remapUtf8To(remapRef, newNameTypeInfo
0978:                                                .getNameIndex()));
0979:                                newNameTypeInfo.setDescriptorIndex(constantPool
0980:                                        .remapUtf8To(remapDesc, newNameTypeInfo
0981:                                                .getDescriptorIndex()));
0982:                            }
0983:                        }
0984:                    }
0985:                }
0986:
0987:                // Finally, remap all class references to Utf
0988:                for (int i = 0; i < constantPool.length(); i++) {
0989:                    CpInfo cpInfo = getCpEntry(i);
0990:                    if (cpInfo != null) {
0991:                        // If this is CONSTANT_Class, remap the class-name Utf8 entry
0992:                        if (cpInfo instanceof  ClassCpInfo) {
0993:                            ClassCpInfo classInfo = (ClassCpInfo) cpInfo;
0994:                            Utf8CpInfo utf = (Utf8CpInfo) getCpEntry(classInfo
0995:                                    .getClassNameIndex());
0996:                            String remapClass = nm.mapClass(utf.getString());
0997:                            int remapIndex = constantPool.remapUtf8To(
0998:                                    remapClass, classInfo.getClassNameIndex());
0999:                            classInfo.setClassNameIndex(remapIndex);
1000:                        }
1001:                    }
1002:                }
1003:            }
1004:
1005:            /** Export the representation of the class file to a DataOutput stream.
1006:             * @param dout the output stream
1007:             * @throws IOException if an I/O error occurs
1008:             */
1009:            public void write(DataOutput dout) throws IOException {
1010:                if (dout == null)
1011:                    throw new IOException("No output stream was provided.");
1012:                dout.writeInt(getMagic());
1013:                dout.writeShort(getMinorVersion());
1014:                dout.writeShort(getMajorVersion());
1015:                dout.writeShort(constantPool.length());
1016:                for (Iterator iter = constantPool.iterator(); iter.hasNext();) {
1017:                    CpInfo cpInfo = (CpInfo) iter.next();
1018:                    if (cpInfo != null) {
1019:                        cpInfo.write(dout);
1020:                    }
1021:                }
1022:                dout.writeShort(getAccessFlags());
1023:                dout.writeShort(getClassIndex());
1024:                dout.writeShort(getSuperClassIndex());
1025:                dout.writeShort(getInterfacesCount());
1026:                for (int i = 0; i < getInterfacesCount(); i++) {
1027:                    dout.writeShort(getInterface(i));
1028:                }
1029:                dout.writeShort(getFieldsCount());
1030:                for (int i = 0; i < getFieldsCount(); i++) {
1031:                    getFieldInfo(i).write(dout);
1032:                }
1033:                dout.writeShort(getMethodsCount());
1034:                for (int i = 0; i < getMethodsCount(); i++) {
1035:                    getMethodInfo(i).write(dout);
1036:                }
1037:                dout.writeShort(getAttributesCount());
1038:                for (int i = 0; i < getAttributesCount(); i++) {
1039:                    getAttributeInfo(i).write(dout);
1040:                }
1041:            }
1042:
1043:            /** Dump the content of the class file to the specified file (used for
1044:             * debugging).
1045:             * @param pw the print writer
1046:             */
1047:            public void dump(PrintWriter pw) {
1048:                pw
1049:                        .println("_____________________________________________________________________");
1050:                pw.println("CLASS: " + getName());
1051:                pw.println("Magic: " + Integer.toHexString(getMagic()) + " ("
1052:                        + getMagic() + ")");
1053:                pw.println("Minor version: "
1054:                        + Integer.toHexString(getMinorVersion()) + " ("
1055:                        + getMinorVersion() + ")");
1056:                pw.println("Major version: "
1057:                        + Integer.toHexString(getMajorVersion()) + " ("
1058:                        + getMajorVersion() + ")");
1059:                pw.println();
1060:                pw.println("Access: " + getAccessFlags());
1061:                pw
1062:                        .println("This class: " + getClassIndex() + " / "
1063:                                + getName());
1064:                pw.println("Superclass: " + getSuperClassIndex() + " / "
1065:                        + getSuper());
1066:                pw.println();
1067:                pw.println("CP length: " + constantPool.length());
1068:                for (int i = 0; i < constantPool.length(); i++) {
1069:                    CpInfo cpInfo = (CpInfo) constantPool.getCpEntry(i);
1070:                    if (cpInfo != null) {
1071:                        cpInfo.dump(pw, this , i);
1072:                    }
1073:                }
1074:                pw.println("Attributes: " + getAttributesCount());
1075:                for (int i = 0; i < getAttributesCount(); i++) {
1076:                    pw.println();
1077:                    pw.print("attribute[" + i + "]: ");
1078:                    getAttributeInfo(i).dump(pw, this );
1079:                }
1080:                pw.println();
1081:                pw.println("Direct implemented interfaces: "
1082:                        + getInterfacesCount());
1083:                for (int i = 0; i < getInterfacesCount(); i++) {
1084:                    CpInfo info = getCpEntry(getInterface(i));
1085:                    pw.print("  interface[" + i + "]: ");
1086:                    if (null == info) {
1087:                        pw.println("(null)");
1088:                    } else {
1089:                        pw
1090:                                .println(((Utf8CpInfo) getCpEntry(((ClassCpInfo) info)
1091:                                        .getClassNameIndex())).getString());
1092:                    }
1093:                }
1094:                pw.println();
1095:                pw.println("Declared fields: " + getFieldsCount());
1096:                for (int i = 0; i < getFieldsCount(); i++) {
1097:                    ClassItemInfo info = getFieldInfo(i);
1098:                    pw.print("  field[" + i + "]: ");
1099:                    if (null == info) {
1100:                        pw.println("(null)");
1101:                    } else {
1102:                        pw
1103:                                .println("    name:       "
1104:                                        + ((Utf8CpInfo) getCpEntry(info
1105:                                                .getNameIndex())).getString());
1106:                        pw.println("    descriptor: "
1107:                                + ((Utf8CpInfo) getCpEntry(info
1108:                                        .getDescriptorIndex())).getString());
1109:                    }
1110:                    pw.println("    attributes: " + info.getAttributesLength());
1111:                    for (int j = 0; j < info.getAttributesLength(); j++) {
1112:                        pw.print("    attribute[" + j + "]: ");
1113:                        info.getAttribute(j).dump(pw, this );
1114:                        pw.println();
1115:                    }
1116:                }
1117:                pw.println();
1118:                pw.println("Declared methods: " + getMethodsCount());
1119:                for (int i = 0; i < getMethodsCount(); i++) {
1120:                    ClassItemInfo info = getMethodInfo(i);
1121:                    pw.print("  method[" + i + "]: ");
1122:                    if (info == null) {
1123:                        pw.println("(null)");
1124:                    } else {
1125:                        pw.println();
1126:                        pw
1127:                                .println("    name:         "
1128:                                        + ((Utf8CpInfo) getCpEntry(info
1129:                                                .getNameIndex())).getString());
1130:                        pw.println("    descriptor:   "
1131:                                + ((Utf8CpInfo) getCpEntry(info
1132:                                        .getDescriptorIndex())).getString());
1133:                        pw
1134:                                .println("    access flags: "
1135:                                        + info.getAccessFlags());
1136:                    }
1137:                    pw.println("    attributes:   "
1138:                            + info.getAttributesLength());
1139:                    for (int j = 0; j < info.getAttributesLength(); j++) {
1140:                        pw.print("    attribute[" + j + "]: ");
1141:                        info.getAttribute(j).dump(pw, this );
1142:                        pw.println();
1143:                    }
1144:                }
1145:            }
1146:
1147:            /** Retrieve a list of classes that are used in hardcoded references.
1148:             * @return a vector containing strings with class names
1149:             * @see #remap
1150:             */
1151:            public Set getHardcodedClassNames() {
1152:                HashSet result = new HashSet();
1153:
1154:                int currentCpLength = constantPool.length();
1155:                for (int i = 0; i < currentCpLength; i++) {
1156:                    CpInfo cpInfo = getCpEntry(i);
1157:                    if (cpInfo != null && cpInfo instanceof  RefCpInfo) {
1158:                        // Get the current name and type reference and its 'name' utf's
1159:                        int ntIndex = ((RefCpInfo) cpInfo)
1160:                                .getNameAndTypeIndex();
1161:                        NameAndTypeCpInfo nameTypeInfo = (NameAndTypeCpInfo) getCpEntry(ntIndex);
1162:                        Utf8CpInfo refUtf = (Utf8CpInfo) getCpEntry(nameTypeInfo
1163:                                .getNameIndex());
1164:
1165:                        if (cpInfo instanceof  FieldrefCpInfo) {
1166:                            // cloder - check if this is a compiler generated field
1167:                            // supporting the JDK1.2-or-later '.class' construct
1168:                            if (refUtf.getString().startsWith("class$")) {
1169:                                String realClassName = refUtf.getString()
1170:                                        .substring(6).replace('$', '.');
1171:                                if (!realClassName.startsWith("java.")
1172:                                        && !realClassName.startsWith("javax.")
1173:                                        && !realClassName.startsWith("sun.")
1174:                                        && !realClassName
1175:                                                .startsWith("com.sun.")) {
1176:                                    result.add(realClassName);
1177:                                }
1178:                            }
1179:                            // end cloder
1180:                        }
1181:                    }
1182:                }
1183:                return result;
1184:            }
1185:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.