Source Code Cross Referenced for ClassFileReader.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » compiler » classfmt » 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 » IDE Eclipse » jdt » org.eclipse.jdt.internal.compiler.classfmt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.jdt.internal.compiler.classfmt;
0011:
0012:        import java.io.File;
0013:        import java.io.IOException;
0014:        import java.io.InputStream;
0015:        import java.util.Arrays;
0016:
0017:        import org.eclipse.jdt.core.compiler.CharOperation;
0018:        import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
0019:        import org.eclipse.jdt.internal.compiler.env.*;
0020:        import org.eclipse.jdt.internal.compiler.impl.Constant;
0021:        import org.eclipse.jdt.internal.compiler.lookup.TagBits;
0022:        import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
0023:        import org.eclipse.jdt.internal.compiler.util.Util;
0024:
0025:        public class ClassFileReader extends ClassFileStruct implements 
0026:                IBinaryType {
0027:            private static String printTypeModifiers(int modifiers) {
0028:                java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
0029:                java.io.PrintWriter print = new java.io.PrintWriter(out);
0030:
0031:                if ((modifiers & ClassFileConstants.AccPublic) != 0)
0032:                    print.print("public "); //$NON-NLS-1$
0033:                if ((modifiers & ClassFileConstants.AccPrivate) != 0)
0034:                    print.print("private "); //$NON-NLS-1$
0035:                if ((modifiers & ClassFileConstants.AccFinal) != 0)
0036:                    print.print("final "); //$NON-NLS-1$
0037:                if ((modifiers & ClassFileConstants.AccSuper) != 0)
0038:                    print.print("super "); //$NON-NLS-1$
0039:                if ((modifiers & ClassFileConstants.AccInterface) != 0)
0040:                    print.print("interface "); //$NON-NLS-1$
0041:                if ((modifiers & ClassFileConstants.AccAbstract) != 0)
0042:                    print.print("abstract "); //$NON-NLS-1$
0043:                print.flush();
0044:                return out.toString();
0045:            }
0046:
0047:            public static ClassFileReader read(InputStream stream,
0048:                    String fileName) throws ClassFormatException, IOException {
0049:                return read(stream, fileName, false);
0050:            }
0051:
0052:            public static ClassFileReader read(File file)
0053:                    throws ClassFormatException, IOException {
0054:                return read(file, false);
0055:            }
0056:
0057:            public static ClassFileReader read(InputStream stream,
0058:                    String fileName, boolean fullyInitialize)
0059:                    throws ClassFormatException, IOException {
0060:                byte classFileBytes[] = Util.getInputStreamAsByteArray(stream,
0061:                        -1);
0062:                ClassFileReader classFileReader = new ClassFileReader(
0063:                        classFileBytes, fileName.toCharArray());
0064:                if (fullyInitialize) {
0065:                    classFileReader.initialize();
0066:                }
0067:                return classFileReader;
0068:            }
0069:
0070:            public static ClassFileReader read(File file,
0071:                    boolean fullyInitialize) throws ClassFormatException,
0072:                    IOException {
0073:                byte classFileBytes[] = Util.getFileByteContent(file);
0074:                ClassFileReader classFileReader = new ClassFileReader(
0075:                        classFileBytes, file.getAbsolutePath().toCharArray());
0076:                if (fullyInitialize) {
0077:                    classFileReader.initialize();
0078:                }
0079:                return classFileReader;
0080:            }
0081:
0082:            public static ClassFileReader read(java.util.zip.ZipFile zip,
0083:                    String filename) throws ClassFormatException,
0084:                    java.io.IOException {
0085:                return read(zip, filename, false);
0086:            }
0087:
0088:            public static ClassFileReader read(java.util.zip.ZipFile zip,
0089:                    String filename, boolean fullyInitialize)
0090:                    throws ClassFormatException, java.io.IOException {
0091:                java.util.zip.ZipEntry ze = zip.getEntry(filename);
0092:                if (ze == null)
0093:                    return null;
0094:                byte classFileBytes[] = Util.getZipEntryByteContent(ze, zip);
0095:                ClassFileReader classFileReader = new ClassFileReader(
0096:                        classFileBytes, filename.toCharArray());
0097:                if (fullyInitialize) {
0098:                    classFileReader.initialize();
0099:                }
0100:                return classFileReader;
0101:            }
0102:
0103:            public static ClassFileReader read(String fileName)
0104:                    throws ClassFormatException, java.io.IOException {
0105:                return read(fileName, false);
0106:            }
0107:
0108:            public static ClassFileReader read(String fileName,
0109:                    boolean fullyInitialize) throws ClassFormatException,
0110:                    java.io.IOException {
0111:                return read(new File(fileName), fullyInitialize);
0112:            }
0113:
0114:            private int accessFlags;
0115:            private char[] classFileName;
0116:            private char[] className;
0117:            private int classNameIndex;
0118:            private int constantPoolCount;
0119:            private AnnotationInfo[] annotations;
0120:            private FieldInfo[] fields;
0121:            private int fieldsCount;
0122:            // initialized in case the .class file is a nested type
0123:            private InnerClassInfo innerInfo;
0124:            private int innerInfoIndex;
0125:            private InnerClassInfo[] innerInfos;
0126:            private char[][] interfaceNames;
0127:            private int interfacesCount;
0128:            private MethodInfo[] methods;
0129:            private int methodsCount;
0130:            private char[] signature;
0131:            private char[] sourceName;
0132:            private char[] sourceFileName;
0133:            private char[] super className;
0134:            private long tagBits;
0135:            private long version;
0136:
0137:            private char[] enclosingTypeName;
0138:
0139:            /**
0140:             * @param classFileBytes Actual bytes of a .class file
0141:             * @param fileName	Actual name of the file that contains the bytes, can be null
0142:             * 
0143:             * @exception ClassFormatException
0144:             */
0145:            public ClassFileReader(byte classFileBytes[], char[] fileName)
0146:                    throws ClassFormatException {
0147:                this (classFileBytes, fileName, false);
0148:            }
0149:
0150:            /**
0151:             * @param classFileBytes byte[]
0152:             * 		Actual bytes of a .class file
0153:             * 
0154:             * @param fileName char[]
0155:             * 		Actual name of the file that contains the bytes, can be null
0156:             * 
0157:             * @param fullyInitialize boolean
0158:             * 		Flag to fully initialize the new object
0159:             * @exception ClassFormatException
0160:             */
0161:            public ClassFileReader(byte[] classFileBytes, char[] fileName,
0162:                    boolean fullyInitialize) throws ClassFormatException {
0163:                // This method looks ugly but is actually quite simple, the constantPool is constructed
0164:                // in 3 passes.  All non-primitive constant pool members that usually refer to other members
0165:                // by index are tweaked to have their value in inst vars, this minor cost at read-time makes
0166:                // all subsequent uses of the constant pool element faster.
0167:                super (classFileBytes, null, 0);
0168:                this .classFileName = fileName;
0169:                int readOffset = 10;
0170:                try {
0171:                    this .version = ((long) this .u2At(6) << 16) + this .u2At(4); // major<<16 + minor
0172:                    constantPoolCount = this .u2At(8);
0173:                    // Pass #1 - Fill in all primitive constants
0174:                    this .constantPoolOffsets = new int[constantPoolCount];
0175:                    for (int i = 1; i < constantPoolCount; i++) {
0176:                        int tag = this .u1At(readOffset);
0177:                        switch (tag) {
0178:                        case ClassFileConstants.Utf8Tag:
0179:                            this .constantPoolOffsets[i] = readOffset;
0180:                            readOffset += u2At(readOffset + 1);
0181:                            readOffset += ClassFileConstants.ConstantUtf8FixedSize;
0182:                            break;
0183:                        case ClassFileConstants.IntegerTag:
0184:                            this .constantPoolOffsets[i] = readOffset;
0185:                            readOffset += ClassFileConstants.ConstantIntegerFixedSize;
0186:                            break;
0187:                        case ClassFileConstants.FloatTag:
0188:                            this .constantPoolOffsets[i] = readOffset;
0189:                            readOffset += ClassFileConstants.ConstantFloatFixedSize;
0190:                            break;
0191:                        case ClassFileConstants.LongTag:
0192:                            this .constantPoolOffsets[i] = readOffset;
0193:                            readOffset += ClassFileConstants.ConstantLongFixedSize;
0194:                            i++;
0195:                            break;
0196:                        case ClassFileConstants.DoubleTag:
0197:                            this .constantPoolOffsets[i] = readOffset;
0198:                            readOffset += ClassFileConstants.ConstantDoubleFixedSize;
0199:                            i++;
0200:                            break;
0201:                        case ClassFileConstants.ClassTag:
0202:                            this .constantPoolOffsets[i] = readOffset;
0203:                            readOffset += ClassFileConstants.ConstantClassFixedSize;
0204:                            break;
0205:                        case ClassFileConstants.StringTag:
0206:                            this .constantPoolOffsets[i] = readOffset;
0207:                            readOffset += ClassFileConstants.ConstantStringFixedSize;
0208:                            break;
0209:                        case ClassFileConstants.FieldRefTag:
0210:                            this .constantPoolOffsets[i] = readOffset;
0211:                            readOffset += ClassFileConstants.ConstantFieldRefFixedSize;
0212:                            break;
0213:                        case ClassFileConstants.MethodRefTag:
0214:                            this .constantPoolOffsets[i] = readOffset;
0215:                            readOffset += ClassFileConstants.ConstantMethodRefFixedSize;
0216:                            break;
0217:                        case ClassFileConstants.InterfaceMethodRefTag:
0218:                            this .constantPoolOffsets[i] = readOffset;
0219:                            readOffset += ClassFileConstants.ConstantInterfaceMethodRefFixedSize;
0220:                            break;
0221:                        case ClassFileConstants.NameAndTypeTag:
0222:                            this .constantPoolOffsets[i] = readOffset;
0223:                            readOffset += ClassFileConstants.ConstantNameAndTypeFixedSize;
0224:                        }
0225:                    }
0226:                    // Read and validate access flags
0227:                    this .accessFlags = u2At(readOffset);
0228:                    readOffset += 2;
0229:
0230:                    // Read the classname, use exception handlers to catch bad format
0231:                    this .classNameIndex = u2At(readOffset);
0232:                    this .className = getConstantClassNameAt(this .classNameIndex);
0233:                    readOffset += 2;
0234:
0235:                    // Read the superclass name, can be null for java.lang.Object
0236:                    int super classNameIndex = u2At(readOffset);
0237:                    readOffset += 2;
0238:                    // if superclassNameIndex is equals to 0 there is no need to set a value for the 
0239:                    // field this.superclassName. null is fine.
0240:                    if (super classNameIndex != 0) {
0241:                        this .super className = getConstantClassNameAt(super classNameIndex);
0242:                    }
0243:
0244:                    // Read the interfaces, use exception handlers to catch bad format
0245:                    this .interfacesCount = u2At(readOffset);
0246:                    readOffset += 2;
0247:                    if (this .interfacesCount != 0) {
0248:                        this .interfaceNames = new char[this .interfacesCount][];
0249:                        for (int i = 0; i < this .interfacesCount; i++) {
0250:                            this .interfaceNames[i] = getConstantClassNameAt(u2At(readOffset));
0251:                            readOffset += 2;
0252:                        }
0253:                    }
0254:                    // Read the fields, use exception handlers to catch bad format
0255:                    this .fieldsCount = u2At(readOffset);
0256:                    readOffset += 2;
0257:                    if (this .fieldsCount != 0) {
0258:                        FieldInfo field;
0259:                        this .fields = new FieldInfo[this .fieldsCount];
0260:                        for (int i = 0; i < this .fieldsCount; i++) {
0261:                            field = FieldInfo.createField(reference,
0262:                                    this .constantPoolOffsets, readOffset);
0263:                            this .fields[i] = field;
0264:                            readOffset += field.sizeInBytes();
0265:                        }
0266:                    }
0267:                    // Read the methods
0268:                    this .methodsCount = u2At(readOffset);
0269:                    readOffset += 2;
0270:                    if (this .methodsCount != 0) {
0271:                        this .methods = new MethodInfo[this .methodsCount];
0272:                        boolean isAnnotationType = (this .accessFlags & ClassFileConstants.AccAnnotation) != 0;
0273:                        for (int i = 0; i < this .methodsCount; i++) {
0274:                            this .methods[i] = isAnnotationType ? AnnotationMethodInfo
0275:                                    .createAnnotationMethod(reference,
0276:                                            this .constantPoolOffsets,
0277:                                            readOffset)
0278:                                    : MethodInfo.createMethod(reference,
0279:                                            this .constantPoolOffsets,
0280:                                            readOffset);
0281:                            readOffset += this .methods[i].sizeInBytes();
0282:                        }
0283:                    }
0284:
0285:                    // Read the attributes
0286:                    int attributesCount = u2At(readOffset);
0287:                    readOffset += 2;
0288:
0289:                    for (int i = 0; i < attributesCount; i++) {
0290:                        int utf8Offset = this .constantPoolOffsets[u2At(readOffset)];
0291:                        char[] attributeName = utf8At(utf8Offset + 3,
0292:                                u2At(utf8Offset + 1));
0293:                        if (attributeName.length == 0) {
0294:                            readOffset += (6 + u4At(readOffset + 2));
0295:                            continue;
0296:                        }
0297:                        switch (attributeName[0]) {
0298:                        case 'E':
0299:                            if (CharOperation
0300:                                    .equals(
0301:                                            attributeName,
0302:                                            AttributeNamesConstants.EnclosingMethodName)) {
0303:                                utf8Offset = constantPoolOffsets[u2At(constantPoolOffsets[u2At(readOffset + 6)]
0304:                                        - structOffset + 1)]
0305:                                        - structOffset;
0306:                                this .enclosingTypeName = utf8At(utf8Offset + 3,
0307:                                        u2At(utf8Offset + 1));
0308:                            }
0309:                            break;
0310:                        case 'D':
0311:                            if (CharOperation.equals(attributeName,
0312:                                    AttributeNamesConstants.DeprecatedName)) {
0313:                                this .accessFlags |= ClassFileConstants.AccDeprecated;
0314:                            }
0315:                            break;
0316:                        case 'I':
0317:                            if (CharOperation.equals(attributeName,
0318:                                    AttributeNamesConstants.InnerClassName)) {
0319:                                int innerOffset = readOffset + 6;
0320:                                int number_of_classes = u2At(innerOffset);
0321:                                if (number_of_classes != 0) {
0322:                                    innerOffset += 2;
0323:                                    this .innerInfos = new InnerClassInfo[number_of_classes];
0324:                                    for (int j = 0; j < number_of_classes; j++) {
0325:                                        this .innerInfos[j] = new InnerClassInfo(
0326:                                                reference,
0327:                                                this .constantPoolOffsets,
0328:                                                innerOffset);
0329:                                        if (this .classNameIndex == this .innerInfos[j].innerClassNameIndex) {
0330:                                            this .innerInfo = this .innerInfos[j];
0331:                                            this .innerInfoIndex = j;
0332:                                        }
0333:                                        innerOffset += 8;
0334:                                    }
0335:                                    if (this .innerInfo != null) {
0336:                                        char[] enclosingType = this .innerInfo
0337:                                                .getEnclosingTypeName();
0338:                                        if (enclosingType != null) {
0339:                                            this .enclosingTypeName = enclosingType;
0340:                                        }
0341:                                    }
0342:                                }
0343:                            } else if (CharOperation
0344:                                    .equals(
0345:                                            attributeName,
0346:                                            AttributeNamesConstants.InconsistentHierarchy)) {
0347:                                this .tagBits |= TagBits.HasInconsistentHierarchy;
0348:                            }
0349:                            break;
0350:                        case 'S':
0351:                            if (attributeName.length > 2) {
0352:                                switch (attributeName[1]) {
0353:                                case 'o':
0354:                                    if (CharOperation.equals(attributeName,
0355:                                            AttributeNamesConstants.SourceName)) {
0356:                                        utf8Offset = this .constantPoolOffsets[u2At(readOffset + 6)];
0357:                                        this .sourceFileName = utf8At(
0358:                                                utf8Offset + 3,
0359:                                                u2At(utf8Offset + 1));
0360:                                    }
0361:                                    break;
0362:                                case 'y':
0363:                                    if (CharOperation
0364:                                            .equals(
0365:                                                    attributeName,
0366:                                                    AttributeNamesConstants.SyntheticName)) {
0367:                                        this .accessFlags |= ClassFileConstants.AccSynthetic;
0368:                                    }
0369:                                    break;
0370:                                case 'i':
0371:                                    if (CharOperation
0372:                                            .equals(
0373:                                                    attributeName,
0374:                                                    AttributeNamesConstants.SignatureName)) {
0375:                                        utf8Offset = this .constantPoolOffsets[u2At(readOffset + 6)];
0376:                                        this .signature = utf8At(utf8Offset + 3,
0377:                                                u2At(utf8Offset + 1));
0378:                                    }
0379:                                }
0380:                            }
0381:                            break;
0382:                        case 'R':
0383:                            if (CharOperation
0384:                                    .equals(
0385:                                            attributeName,
0386:                                            AttributeNamesConstants.RuntimeVisibleAnnotationsName)) {
0387:                                decodeAnnotations(readOffset, true);
0388:                            } else if (CharOperation
0389:                                    .equals(
0390:                                            attributeName,
0391:                                            AttributeNamesConstants.RuntimeInvisibleAnnotationsName)) {
0392:                                decodeAnnotations(readOffset, false);
0393:                            }
0394:                            break;
0395:                        }
0396:                        readOffset += (6 + u4At(readOffset + 2));
0397:                    }
0398:                    if (fullyInitialize) {
0399:                        this .initialize();
0400:                    }
0401:                } catch (ClassFormatException e) {
0402:                    throw e;
0403:                } catch (Exception e) {
0404:                    throw new ClassFormatException(
0405:                            ClassFormatException.ErrTruncatedInput, readOffset);
0406:                }
0407:            }
0408:
0409:            /**
0410:             * 	Answer the receiver's access flags.  The value of the access_flags
0411:             *	item is a mask of modifiers used with class and interface declarations.
0412:             *  @return int 
0413:             */
0414:            public int accessFlags() {
0415:                return this .accessFlags;
0416:            }
0417:
0418:            private void decodeAnnotations(int offset, boolean runtimeVisible) {
0419:                int numberOfAnnotations = u2At(offset + 6);
0420:                if (numberOfAnnotations > 0) {
0421:                    int readOffset = offset + 8;
0422:                    AnnotationInfo[] newInfos = null;
0423:                    int newInfoCount = 0;
0424:                    for (int i = 0; i < numberOfAnnotations; i++) {
0425:                        // With the last parameter being 'false', the data structure will not be flushed out
0426:                        AnnotationInfo newInfo = new AnnotationInfo(
0427:                                this .reference, this .constantPoolOffsets,
0428:                                readOffset, runtimeVisible, false);
0429:                        readOffset += newInfo.readOffset;
0430:                        long standardTagBits = newInfo.standardAnnotationTagBits;
0431:                        if (standardTagBits != 0) {
0432:                            this .tagBits |= standardTagBits;
0433:                        } else {
0434:                            if (newInfos == null)
0435:                                newInfos = new AnnotationInfo[numberOfAnnotations
0436:                                        - i];
0437:                            newInfos[newInfoCount++] = newInfo;
0438:                        }
0439:                    }
0440:                    if (newInfos == null)
0441:                        return; // nothing to record in this.annotations
0442:
0443:                    if (this .annotations == null) {
0444:                        if (newInfoCount != newInfos.length)
0445:                            System
0446:                                    .arraycopy(
0447:                                            newInfos,
0448:                                            0,
0449:                                            newInfos = new AnnotationInfo[newInfoCount],
0450:                                            0, newInfoCount);
0451:                        this .annotations = newInfos;
0452:                    } else {
0453:                        int length = this .annotations.length;
0454:                        AnnotationInfo[] temp = new AnnotationInfo[length
0455:                                + newInfoCount];
0456:                        System.arraycopy(this .annotations, 0, temp, 0, length);
0457:                        System.arraycopy(newInfos, 0, temp, length,
0458:                                newInfoCount);
0459:                        this .annotations = temp;
0460:                    }
0461:                }
0462:            }
0463:
0464:            /**
0465:             * Answer the char array that corresponds to the class name of the constant class.
0466:             * constantPoolIndex is the index in the constant pool that is a constant class entry.
0467:             *
0468:             * @param constantPoolIndex int
0469:             * @return char[]
0470:             */
0471:            private char[] getConstantClassNameAt(int constantPoolIndex) {
0472:                int utf8Offset = this .constantPoolOffsets[u2At(this .constantPoolOffsets[constantPoolIndex] + 1)];
0473:                return utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
0474:            }
0475:
0476:            /**
0477:             * Answer the int array that corresponds to all the offsets of each entry in the constant pool
0478:             *
0479:             * @return int[]
0480:             */
0481:            public int[] getConstantPoolOffsets() {
0482:                return this .constantPoolOffsets;
0483:            }
0484:
0485:            /*
0486:             * Answer the resolved compoundName of the enclosing type
0487:             * or null if the receiver is a top level type.
0488:             */
0489:            public char[] getEnclosingTypeName() {
0490:                return this .enclosingTypeName;
0491:            }
0492:
0493:            /**
0494:             * Answer the receiver's this.fields or null if the array is empty.
0495:             * @return org.eclipse.jdt.internal.compiler.api.IBinaryField[]
0496:             */
0497:            public IBinaryField[] getFields() {
0498:                return this .fields;
0499:            }
0500:
0501:            /**
0502:             * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
0503:             */
0504:            public char[] getFileName() {
0505:                return this .classFileName;
0506:            }
0507:
0508:            public char[] getGenericSignature() {
0509:                return this .signature;
0510:            }
0511:
0512:            /**
0513:             * Answer the source name if the receiver is a inner type. Return null if it is an anonymous class or if the receiver is a top-level class.
0514:             * e.g.
0515:             * public class A {
0516:             *	public class B {
0517:             *	}
0518:             *	public void foo() {
0519:             *		class C {}
0520:             *	}
0521:             *	public Runnable bar() {
0522:             *		return new Runnable() {
0523:             *			public void run() {}
0524:             *		};
0525:             *	}
0526:             * }
0527:             * It returns {'B'} for the member A$B
0528:             * It returns null for A
0529:             * It returns {'C'} for the local class A$1$C
0530:             * It returns null for the anonymous A$1
0531:             * @return char[]
0532:             */
0533:            public char[] getInnerSourceName() {
0534:                if (this .innerInfo != null)
0535:                    return this .innerInfo.getSourceName();
0536:                return null;
0537:            }
0538:
0539:            /**
0540:             * Answer the resolved names of the receiver's interfaces in the
0541:             * class file format as specified in section 4.2 of the Java 2 VM spec
0542:             * or null if the array is empty.
0543:             *
0544:             * For example, java.lang.String is java/lang/String.
0545:             * @return char[][]
0546:             */
0547:            public char[][] getInterfaceNames() {
0548:                return this .interfaceNames;
0549:            }
0550:
0551:            /**
0552:             * Answer the receiver's nested types or null if the array is empty.
0553:             * 
0554:             * This nested type info is extracted from the inner class attributes. Ask the
0555:             * name environment to find a member type using its compound name
0556:             * 
0557:             * @return org.eclipse.jdt.internal.compiler.api.IBinaryNestedType[]
0558:             */
0559:            public IBinaryNestedType[] getMemberTypes() {
0560:                // we might have some member types of the current type
0561:                if (this .innerInfos == null)
0562:                    return null;
0563:
0564:                int length = this .innerInfos.length;
0565:                int startingIndex = this .innerInfo != null ? this .innerInfoIndex + 1
0566:                        : 0;
0567:                if (length != startingIndex) {
0568:                    IBinaryNestedType[] memberTypes = new IBinaryNestedType[length
0569:                            - this .innerInfoIndex];
0570:                    int memberTypeIndex = 0;
0571:                    for (int i = startingIndex; i < length; i++) {
0572:                        InnerClassInfo currentInnerInfo = this .innerInfos[i];
0573:                        int outerClassNameIdx = currentInnerInfo.outerClassNameIndex;
0574:                        int innerNameIndex = currentInnerInfo.innerNameIndex;
0575:                        /*
0576:                         * Checking that outerClassNameIDx is different from 0 should be enough to determine if an inner class
0577:                         * attribute entry is a member class, but due to the bug:
0578:                         * http://dev.eclipse.org/bugs/show_bug.cgi?id=14592
0579:                         * we needed to add an extra check. So we check that innerNameIndex is different from 0 as well.
0580:                         * 
0581:                         * https://bugs.eclipse.org/bugs/show_bug.cgi?id=49879
0582:                         * From JavaMail 1.2, the class javax.mail.Folder contains an anonymous class in the
0583:                         * terminateQueue() method for which the inner attribute is boggus.
0584:                         * outerClassNameIdx is not 0, innerNameIndex is not 0, but the sourceName length is 0.
0585:                         * So I added this extra check to filter out this anonymous class from the 
0586:                         * member types.
0587:                         */
0588:                        if (outerClassNameIdx != 0 && innerNameIndex != 0
0589:                                && outerClassNameIdx == this .classNameIndex
0590:                                && currentInnerInfo.getSourceName().length != 0) {
0591:                            memberTypes[memberTypeIndex++] = currentInnerInfo;
0592:                        }
0593:                    }
0594:                    if (memberTypeIndex == 0)
0595:                        return null;
0596:                    if (memberTypeIndex != memberTypes.length) {
0597:                        // we need to resize the memberTypes array. Some local or anonymous classes
0598:                        // are present in the current class.
0599:                        System
0600:                                .arraycopy(
0601:                                        memberTypes,
0602:                                        0,
0603:                                        (memberTypes = new IBinaryNestedType[memberTypeIndex]),
0604:                                        0, memberTypeIndex);
0605:                    }
0606:                    return memberTypes;
0607:                }
0608:                return null;
0609:            }
0610:
0611:            /**
0612:             * Answer the receiver's this.methods or null if the array is empty.
0613:             * @return org.eclipse.jdt.internal.compiler.api.env.IBinaryMethod[]
0614:             */
0615:            public IBinaryMethod[] getMethods() {
0616:                return this .methods;
0617:            }
0618:
0619:            /**
0620:             * @return the annotations or null if there is none.
0621:             */
0622:            public IBinaryAnnotation[] getAnnotations() {
0623:                return this .annotations;
0624:            }
0625:
0626:            /**
0627:             * Answer an int whose bits are set according the access constants
0628:             * defined by the VM spec.
0629:             * Set the AccDeprecated and AccSynthetic bits if necessary
0630:             * @return int
0631:             */
0632:            public int getModifiers() {
0633:                if (this .innerInfo != null) {
0634:                    return this .innerInfo.getModifiers()
0635:                            | (this .accessFlags & ClassFileConstants.AccDeprecated);
0636:                }
0637:                return this .accessFlags;
0638:            }
0639:
0640:            /**
0641:             * Answer the resolved name of the type in the
0642:             * class file format as specified in section 4.2 of the Java 2 VM spec.
0643:             *
0644:             * For example, java.lang.String is java/lang/String.
0645:             * @return char[]
0646:             */
0647:            public char[] getName() {
0648:                return this .className;
0649:            }
0650:
0651:            public char[] getSourceName() {
0652:                if (this .sourceName != null)
0653:                    return this .sourceName;
0654:
0655:                char[] name = getInnerSourceName(); // member or local scenario
0656:                if (name == null) {
0657:                    name = getName(); // extract from full name
0658:                    int start;
0659:                    if (isAnonymous()) {
0660:                        start = CharOperation.indexOf('$', name, CharOperation
0661:                                .lastIndexOf('/', name) + 1) + 1;
0662:                    } else {
0663:                        start = CharOperation.lastIndexOf('/', name) + 1;
0664:                    }
0665:                    if (start > 0) {
0666:                        char[] newName = new char[name.length - start];
0667:                        System.arraycopy(name, start, newName, 0,
0668:                                newName.length);
0669:                        name = newName;
0670:                    }
0671:                }
0672:                return this .sourceName = name;
0673:            }
0674:
0675:            /**
0676:             * Answer the resolved name of the receiver's superclass in the
0677:             * class file format as specified in section 4.2 of the Java 2 VM spec
0678:             * or null if it does not have one.
0679:             *
0680:             * For example, java.lang.String is java/lang/String.
0681:             * @return char[]
0682:             */
0683:            public char[] getSuperclassName() {
0684:                return this .super className;
0685:            }
0686:
0687:            public long getTagBits() {
0688:                return this .tagBits;
0689:            }
0690:
0691:            /**
0692:             * Answer the major/minor version defined in this class file according to the VM spec.
0693:             * as a long: (major<<16)+minor
0694:             * @return the major/minor version found
0695:             */
0696:            public long getVersion() {
0697:                return this .version;
0698:            }
0699:
0700:            private boolean hasNonSyntheticFieldChanges(
0701:                    FieldInfo[] currentFieldInfos, FieldInfo[] otherFieldInfos) {
0702:                int length1 = currentFieldInfos == null ? 0
0703:                        : currentFieldInfos.length;
0704:                int length2 = otherFieldInfos == null ? 0
0705:                        : otherFieldInfos.length;
0706:                int index1 = 0;
0707:                int index2 = 0;
0708:
0709:                end: while (index1 < length1 && index2 < length2) {
0710:                    while (currentFieldInfos[index1].isSynthetic()) {
0711:                        if (++index1 >= length1)
0712:                            break end;
0713:                    }
0714:                    while (otherFieldInfos[index2].isSynthetic()) {
0715:                        if (++index2 >= length2)
0716:                            break end;
0717:                    }
0718:                    if (hasStructuralFieldChanges(currentFieldInfos[index1++],
0719:                            otherFieldInfos[index2++]))
0720:                        return true;
0721:                }
0722:
0723:                while (index1 < length1) {
0724:                    if (!currentFieldInfos[index1++].isSynthetic())
0725:                        return true;
0726:                }
0727:                while (index2 < length2) {
0728:                    if (!otherFieldInfos[index2++].isSynthetic())
0729:                        return true;
0730:                }
0731:                return false;
0732:            }
0733:
0734:            private boolean hasNonSyntheticMethodChanges(
0735:                    MethodInfo[] currentMethodInfos,
0736:                    MethodInfo[] otherMethodInfos) {
0737:                int length1 = currentMethodInfos == null ? 0
0738:                        : currentMethodInfos.length;
0739:                int length2 = otherMethodInfos == null ? 0
0740:                        : otherMethodInfos.length;
0741:                int index1 = 0;
0742:                int index2 = 0;
0743:
0744:                MethodInfo m;
0745:                end: while (index1 < length1 && index2 < length2) {
0746:                    while ((m = currentMethodInfos[index1]).isSynthetic()
0747:                            || m.isClinit()) {
0748:                        if (++index1 >= length1)
0749:                            break end;
0750:                    }
0751:                    while ((m = otherMethodInfos[index2]).isSynthetic()
0752:                            || m.isClinit()) {
0753:                        if (++index2 >= length2)
0754:                            break end;
0755:                    }
0756:                    if (hasStructuralMethodChanges(
0757:                            currentMethodInfos[index1++],
0758:                            otherMethodInfos[index2++]))
0759:                        return true;
0760:                }
0761:
0762:                while (index1 < length1) {
0763:                    if (!((m = currentMethodInfos[index1++]).isSynthetic() || m
0764:                            .isClinit()))
0765:                        return true;
0766:                }
0767:                while (index2 < length2) {
0768:                    if (!((m = otherMethodInfos[index2++]).isSynthetic() || m
0769:                            .isClinit()))
0770:                        return true;
0771:                }
0772:                return false;
0773:            }
0774:
0775:            /**
0776:             * Check if the receiver has structural changes compare to the byte array in argument.
0777:             * Structural changes are:
0778:             * - modifiers changes for the class, the this.fields or the this.methods
0779:             * - signature changes for this.fields or this.methods.
0780:             * - changes in the number of this.fields or this.methods
0781:             * - changes for field constants
0782:             * - changes for thrown exceptions
0783:             * - change for the super class or any super interfaces.
0784:             * - changes for member types name or modifiers
0785:             * If any of these changes occurs, the method returns true. false otherwise. 
0786:             * The synthetic fields are included and the members are not required to be sorted.
0787:             * @param newBytes the bytes of the .class file we want to compare the receiver to
0788:             * @return boolean Returns true is there is a structural change between the two .class files, false otherwise
0789:             */
0790:            public boolean hasStructuralChanges(byte[] newBytes) {
0791:                return hasStructuralChanges(newBytes, true, true);
0792:            }
0793:
0794:            /**
0795:             * Check if the receiver has structural changes compare to the byte array in argument.
0796:             * Structural changes are:
0797:             * - modifiers changes for the class, the this.fields or the this.methods
0798:             * - signature changes for this.fields or this.methods.
0799:             * - changes in the number of this.fields or this.methods
0800:             * - changes for field constants
0801:             * - changes for thrown exceptions
0802:             * - change for the super class or any super interfaces.
0803:             * - changes for member types name or modifiers
0804:             * If any of these changes occurs, the method returns true. false otherwise.
0805:             * @param newBytes the bytes of the .class file we want to compare the receiver to
0806:             * @param orderRequired a boolean indicating whether the members should be sorted or not
0807:             * @param excludesSynthetic a boolean indicating whether the synthetic members should be used in the comparison
0808:             * @return boolean Returns true is there is a structural change between the two .class files, false otherwise
0809:             */
0810:            public boolean hasStructuralChanges(byte[] newBytes,
0811:                    boolean orderRequired, boolean excludesSynthetic) {
0812:                try {
0813:                    ClassFileReader newClassFile = new ClassFileReader(
0814:                            newBytes, this .classFileName);
0815:                    // type level comparison
0816:                    // modifiers
0817:                    if (this .getModifiers() != newClassFile.getModifiers())
0818:                        return true;
0819:
0820:                    // only consider a portion of the tagbits which indicate a structural change for dependents
0821:                    // e.g. @Override change has no influence outside
0822:                    long OnlyStructuralTagBits = TagBits.AnnotationTargetMASK // different @Target status ?
0823:                            | TagBits.AnnotationDeprecated // different @Deprecated status ?
0824:                            | TagBits.AnnotationRetentionMASK // different @Retention status ?
0825:                            | TagBits.HasInconsistentHierarchy; // different hierarchy status ?
0826:
0827:                    // meta-annotations
0828:                    if ((this .getTagBits() & OnlyStructuralTagBits) != (newClassFile
0829:                            .getTagBits() & OnlyStructuralTagBits))
0830:                        return true;
0831:
0832:                    // generic signature
0833:                    if (!CharOperation.equals(this .getGenericSignature(),
0834:                            newClassFile.getGenericSignature()))
0835:                        return true;
0836:                    // superclass
0837:                    if (!CharOperation.equals(this .getSuperclassName(),
0838:                            newClassFile.getSuperclassName()))
0839:                        return true;
0840:                    // interfaces
0841:                    char[][] newInterfacesNames = newClassFile
0842:                            .getInterfaceNames();
0843:                    if (this .interfaceNames != newInterfacesNames) { // TypeConstants.NoSuperInterfaces
0844:                        int newInterfacesLength = newInterfacesNames == null ? 0
0845:                                : newInterfacesNames.length;
0846:                        if (newInterfacesLength != this .interfacesCount)
0847:                            return true;
0848:                        for (int i = 0, max = this .interfacesCount; i < max; i++)
0849:                            if (!CharOperation.equals(this .interfaceNames[i],
0850:                                    newInterfacesNames[i]))
0851:                                return true;
0852:                    }
0853:
0854:                    // member types
0855:                    IBinaryNestedType[] currentMemberTypes = this 
0856:                            .getMemberTypes();
0857:                    IBinaryNestedType[] otherMemberTypes = newClassFile
0858:                            .getMemberTypes();
0859:                    if (currentMemberTypes != otherMemberTypes) { // TypeConstants.NoMemberTypes
0860:                        int currentMemberTypeLength = currentMemberTypes == null ? 0
0861:                                : currentMemberTypes.length;
0862:                        int otherMemberTypeLength = otherMemberTypes == null ? 0
0863:                                : otherMemberTypes.length;
0864:                        if (currentMemberTypeLength != otherMemberTypeLength)
0865:                            return true;
0866:                        for (int i = 0; i < currentMemberTypeLength; i++)
0867:                            if (!CharOperation.equals(currentMemberTypes[i]
0868:                                    .getName(), otherMemberTypes[i].getName())
0869:                                    || currentMemberTypes[i].getModifiers() != otherMemberTypes[i]
0870:                                            .getModifiers())
0871:                                return true;
0872:                    }
0873:
0874:                    // fields
0875:                    FieldInfo[] otherFieldInfos = (FieldInfo[]) newClassFile
0876:                            .getFields();
0877:                    int otherFieldInfosLength = otherFieldInfos == null ? 0
0878:                            : otherFieldInfos.length;
0879:                    boolean compareFields = true;
0880:                    if (this .fieldsCount == otherFieldInfosLength) {
0881:                        int i = 0;
0882:                        for (; i < this .fieldsCount; i++)
0883:                            if (hasStructuralFieldChanges(this .fields[i],
0884:                                    otherFieldInfos[i]))
0885:                                break;
0886:                        if ((compareFields = i != this .fieldsCount)
0887:                                && !orderRequired && !excludesSynthetic)
0888:                            return true;
0889:                    }
0890:                    if (compareFields) {
0891:                        if (this .fieldsCount != otherFieldInfosLength
0892:                                && !excludesSynthetic)
0893:                            return true;
0894:                        if (orderRequired) {
0895:                            if (this .fieldsCount != 0)
0896:                                Arrays.sort(this .fields);
0897:                            if (otherFieldInfosLength != 0)
0898:                                Arrays.sort(otherFieldInfos);
0899:                        }
0900:                        if (excludesSynthetic) {
0901:                            if (hasNonSyntheticFieldChanges(this .fields,
0902:                                    otherFieldInfos))
0903:                                return true;
0904:                        } else {
0905:                            for (int i = 0; i < this .fieldsCount; i++)
0906:                                if (hasStructuralFieldChanges(this .fields[i],
0907:                                        otherFieldInfos[i]))
0908:                                    return true;
0909:                        }
0910:                    }
0911:
0912:                    // methods
0913:                    MethodInfo[] otherMethodInfos = (MethodInfo[]) newClassFile
0914:                            .getMethods();
0915:                    int otherMethodInfosLength = otherMethodInfos == null ? 0
0916:                            : otherMethodInfos.length;
0917:                    boolean compareMethods = true;
0918:                    if (this .methodsCount == otherMethodInfosLength) {
0919:                        int i = 0;
0920:                        for (; i < this .methodsCount; i++)
0921:                            if (hasStructuralMethodChanges(this .methods[i],
0922:                                    otherMethodInfos[i]))
0923:                                break;
0924:                        if ((compareMethods = i != this .methodsCount)
0925:                                && !orderRequired && !excludesSynthetic)
0926:                            return true;
0927:                    }
0928:                    if (compareMethods) {
0929:                        if (this .methodsCount != otherMethodInfosLength
0930:                                && !excludesSynthetic)
0931:                            return true;
0932:                        if (orderRequired) {
0933:                            if (this .methodsCount != 0)
0934:                                Arrays.sort(this .methods);
0935:                            if (otherMethodInfosLength != 0)
0936:                                Arrays.sort(otherMethodInfos);
0937:                        }
0938:                        if (excludesSynthetic) {
0939:                            if (hasNonSyntheticMethodChanges(this .methods,
0940:                                    otherMethodInfos))
0941:                                return true;
0942:                        } else {
0943:                            for (int i = 0; i < this .methodsCount; i++)
0944:                                if (hasStructuralMethodChanges(this .methods[i],
0945:                                        otherMethodInfos[i]))
0946:                                    return true;
0947:                        }
0948:                    }
0949:
0950:                    return false;
0951:                } catch (ClassFormatException e) {
0952:                    return true;
0953:                }
0954:            }
0955:
0956:            private boolean hasStructuralFieldChanges(
0957:                    FieldInfo currentFieldInfo, FieldInfo otherFieldInfo) {
0958:                // generic signature
0959:                if (!CharOperation.equals(currentFieldInfo
0960:                        .getGenericSignature(), otherFieldInfo
0961:                        .getGenericSignature()))
0962:                    return true;
0963:                if (currentFieldInfo.getModifiers() != otherFieldInfo
0964:                        .getModifiers())
0965:                    return true;
0966:                if ((currentFieldInfo.getTagBits() & TagBits.AnnotationDeprecated) != (otherFieldInfo
0967:                        .getTagBits() & TagBits.AnnotationDeprecated))
0968:                    return true;
0969:                if (!CharOperation.equals(currentFieldInfo.getName(),
0970:                        otherFieldInfo.getName()))
0971:                    return true;
0972:                if (!CharOperation.equals(currentFieldInfo.getTypeName(),
0973:                        otherFieldInfo.getTypeName()))
0974:                    return true;
0975:                if (currentFieldInfo.hasConstant() != otherFieldInfo
0976:                        .hasConstant())
0977:                    return true;
0978:                if (currentFieldInfo.hasConstant()) {
0979:                    Constant currentConstant = currentFieldInfo.getConstant();
0980:                    Constant otherConstant = otherFieldInfo.getConstant();
0981:                    if (currentConstant.typeID() != otherConstant.typeID())
0982:                        return true;
0983:                    if (!currentConstant.getClass().equals(
0984:                            otherConstant.getClass()))
0985:                        return true;
0986:                    switch (currentConstant.typeID()) {
0987:                    case TypeIds.T_int:
0988:                        return currentConstant.intValue() != otherConstant
0989:                                .intValue();
0990:                    case TypeIds.T_byte:
0991:                        return currentConstant.byteValue() != otherConstant
0992:                                .byteValue();
0993:                    case TypeIds.T_short:
0994:                        return currentConstant.shortValue() != otherConstant
0995:                                .shortValue();
0996:                    case TypeIds.T_char:
0997:                        return currentConstant.charValue() != otherConstant
0998:                                .charValue();
0999:                    case TypeIds.T_long:
1000:                        return currentConstant.longValue() != otherConstant
1001:                                .longValue();
1002:                    case TypeIds.T_float:
1003:                        return currentConstant.floatValue() != otherConstant
1004:                                .floatValue();
1005:                    case TypeIds.T_double:
1006:                        return currentConstant.doubleValue() != otherConstant
1007:                                .doubleValue();
1008:                    case TypeIds.T_boolean:
1009:                        return currentConstant.booleanValue() != otherConstant
1010:                                .booleanValue();
1011:                    case TypeIds.T_JavaLangString:
1012:                        return !currentConstant.stringValue().equals(
1013:                                otherConstant.stringValue());
1014:                    }
1015:                }
1016:                return false;
1017:            }
1018:
1019:            private boolean hasStructuralMethodChanges(
1020:                    MethodInfo currentMethodInfo, MethodInfo otherMethodInfo) {
1021:                // generic signature
1022:                if (!CharOperation.equals(currentMethodInfo
1023:                        .getGenericSignature(), otherMethodInfo
1024:                        .getGenericSignature()))
1025:                    return true;
1026:                if (currentMethodInfo.getModifiers() != otherMethodInfo
1027:                        .getModifiers())
1028:                    return true;
1029:                if ((currentMethodInfo.getTagBits() & TagBits.AnnotationDeprecated) != (otherMethodInfo
1030:                        .getTagBits() & TagBits.AnnotationDeprecated))
1031:                    return true;
1032:                if (!CharOperation.equals(currentMethodInfo.getSelector(),
1033:                        otherMethodInfo.getSelector()))
1034:                    return true;
1035:                if (!CharOperation.equals(currentMethodInfo
1036:                        .getMethodDescriptor(), otherMethodInfo
1037:                        .getMethodDescriptor()))
1038:                    return true;
1039:                if (!CharOperation.equals(currentMethodInfo
1040:                        .getGenericSignature(), otherMethodInfo
1041:                        .getGenericSignature()))
1042:                    return true;
1043:
1044:                char[][] currentThrownExceptions = currentMethodInfo
1045:                        .getExceptionTypeNames();
1046:                char[][] otherThrownExceptions = otherMethodInfo
1047:                        .getExceptionTypeNames();
1048:                if (currentThrownExceptions != otherThrownExceptions) { // TypeConstants.NoExceptions
1049:                    int currentThrownExceptionsLength = currentThrownExceptions == null ? 0
1050:                            : currentThrownExceptions.length;
1051:                    int otherThrownExceptionsLength = otherThrownExceptions == null ? 0
1052:                            : otherThrownExceptions.length;
1053:                    if (currentThrownExceptionsLength != otherThrownExceptionsLength)
1054:                        return true;
1055:                    for (int k = 0; k < currentThrownExceptionsLength; k++)
1056:                        if (!CharOperation.equals(currentThrownExceptions[k],
1057:                                otherThrownExceptions[k]))
1058:                            return true;
1059:                }
1060:                return false;
1061:            }
1062:
1063:            /**
1064:             * This method is used to fully initialize the contents of the receiver. All methodinfos, fields infos
1065:             * will be therefore fully initialized and we can get rid of the bytes.
1066:             */
1067:            private void initialize() throws ClassFormatException {
1068:                try {
1069:                    for (int i = 0, max = fieldsCount; i < max; i++) {
1070:                        fields[i].initialize();
1071:                    }
1072:                    for (int i = 0, max = methodsCount; i < max; i++) {
1073:                        methods[i].initialize();
1074:                    }
1075:                    if (innerInfos != null) {
1076:                        for (int i = 0, max = innerInfos.length; i < max; i++) {
1077:                            innerInfos[i].initialize();
1078:                        }
1079:                    }
1080:                    if (annotations != null) {
1081:                        for (int i = 0, max = annotations.length; i < max; i++) {
1082:                            annotations[i].initialize();
1083:                        }
1084:                    }
1085:                    this .reset();
1086:                } catch (RuntimeException e) {
1087:                    ClassFormatException exception = new ClassFormatException(
1088:                            e, this .classFileName);
1089:                    throw exception;
1090:                }
1091:            }
1092:
1093:            /**
1094:             * Answer true if the receiver is an anonymous type, false otherwise
1095:             *
1096:             * @return <CODE>boolean</CODE>
1097:             */
1098:            public boolean isAnonymous() {
1099:                if (this .innerInfo == null)
1100:                    return false;
1101:                char[] innerSourceName = this .innerInfo.getSourceName();
1102:                return (innerSourceName == null || innerSourceName.length == 0);
1103:            }
1104:
1105:            /**
1106:             * Answer whether the receiver contains the resolved binary form
1107:             * or the unresolved source form of the type.
1108:             * @return boolean
1109:             */
1110:            public boolean isBinaryType() {
1111:                return true;
1112:            }
1113:
1114:            /**
1115:             * Answer true if the receiver is a local type, false otherwise
1116:             *
1117:             * @return <CODE>boolean</CODE>
1118:             */
1119:            public boolean isLocal() {
1120:                if (this .innerInfo == null)
1121:                    return false;
1122:                if (this .innerInfo.getEnclosingTypeName() != null)
1123:                    return false;
1124:                char[] innerSourceName = this .innerInfo.getSourceName();
1125:                return (innerSourceName != null && innerSourceName.length > 0);
1126:            }
1127:
1128:            /**
1129:             * Answer true if the receiver is a member type, false otherwise
1130:             *
1131:             * @return <CODE>boolean</CODE>
1132:             */
1133:            public boolean isMember() {
1134:                if (this .innerInfo == null)
1135:                    return false;
1136:                if (this .innerInfo.getEnclosingTypeName() == null)
1137:                    return false;
1138:                char[] innerSourceName = this .innerInfo.getSourceName();
1139:                return (innerSourceName != null && innerSourceName.length > 0); // protection against ill-formed attributes (67600)
1140:            }
1141:
1142:            /**
1143:             * Answer true if the receiver is a nested type, false otherwise
1144:             *
1145:             * @return <CODE>boolean</CODE>
1146:             */
1147:            public boolean isNestedType() {
1148:                return this .innerInfo != null;
1149:            }
1150:
1151:            /**
1152:             * Answer the source file name attribute. Return null if there is no source file attribute for the receiver.
1153:             * 
1154:             * @return char[]
1155:             */
1156:            public char[] sourceFileName() {
1157:                return this .sourceFileName;
1158:            }
1159:
1160:            public String toString() {
1161:                java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
1162:                java.io.PrintWriter print = new java.io.PrintWriter(out);
1163:                print.println(this .getClass().getName() + "{"); //$NON-NLS-1$
1164:                print.println(" this.className: " + new String(getName())); //$NON-NLS-1$
1165:                print
1166:                        .println(" this.superclassName: " + (getSuperclassName() == null ? "null" : new String(getSuperclassName()))); //$NON-NLS-2$ //$NON-NLS-1$
1167:                print
1168:                        .println(" access_flags: " + printTypeModifiers(this .accessFlags()) + "(" + this .accessFlags() + ")"); //$NON-NLS-1$ //$NON-NLS-3$ //$NON-NLS-2$
1169:                print.flush();
1170:                return out.toString();
1171:            }
1172:
1173:            /*
1174:             public static void main(String[] args) throws ClassFormatException, IOException {
1175:             if (args == null || args.length != 1) {
1176:             System.err.println("ClassFileReader <filename>"); //$NON-NLS-1$
1177:             System.exit(1);
1178:             }
1179:             File file = new File(args[0]);
1180:             ClassFileReader reader = read(file, true);
1181:             if (reader.annotations != null) {
1182:             System.err.println();
1183:             for (int i = 0; i < reader.annotations.length; i++)
1184:             System.err.println(reader.annotations[i]);
1185:             }
1186:             System.err.print("class "); //$NON-NLS-1$
1187:             System.err.print(reader.getName());
1188:             char[] superclass = reader.getSuperclassName();
1189:             if (superclass != null) {
1190:             System.err.print(" extends "); //$NON-NLS-1$
1191:             System.err.print(superclass);
1192:             }
1193:             System.err.println();
1194:             char[][] interfaces = reader.getInterfaceNames();
1195:             if (interfaces != null && interfaces.length > 0) {
1196:             System.err.print(" implements "); //$NON-NLS-1$
1197:             for (int i = 0; i < interfaces.length; i++) {
1198:             if (i != 0) System.err.print(", "); //$NON-NLS-1$		
1199:             System.err.println(interfaces[i]);
1200:             }
1201:             }
1202:             System.err.println();
1203:             System.err.println('{');
1204:             if (reader.fields != null) {
1205:             for (int i = 0; i < reader.fields.length; i++) {
1206:             System.err.println(reader.fields[i]);
1207:             System.err.println();
1208:             }
1209:             }
1210:             if (reader.methods != null) {
1211:             for (int i = 0; i < reader.methods.length; i++) {
1212:             System.err.println(reader.methods[i]);
1213:             System.err.println();
1214:             }
1215:             }
1216:             System.err.println();
1217:             System.err.println('}');
1218:             }
1219:             */
1220:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.