Source Code Cross Referenced for CtClassType.java in  » Byte-Code » Javassist » javassist » 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 » Byte Code » Javassist » javassist 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Javassist, a Java-bytecode translator toolkit.
0003:         * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
0004:         *
0005:         * The contents of this file are subject to the Mozilla Public License Version
0006:         * 1.1 (the "License"); you may not use this file except in compliance with
0007:         * the License.  Alternatively, the contents of this file may be used under
0008:         * the terms of the GNU Lesser General Public License Version 2.1 or later.
0009:         *
0010:         * Software distributed under the License is distributed on an "AS IS" basis,
0011:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
0012:         * for the specific language governing rights and limitations under the
0013:         * License.
0014:         */
0015:
0016:        package javassist;
0017:
0018:        import java.io.BufferedInputStream;
0019:        import java.io.DataInputStream;
0020:        import java.io.DataOutputStream;
0021:        import java.io.IOException;
0022:        import java.io.InputStream;
0023:        import java.net.URL;
0024:        import java.util.ArrayList;
0025:        import java.util.Enumeration;
0026:        import java.util.HashMap;
0027:        import java.util.Hashtable;
0028:        import java.util.List;
0029:        import java.util.Set;
0030:
0031:        import javassist.bytecode.AccessFlag;
0032:        import javassist.bytecode.AttributeInfo;
0033:        import javassist.bytecode.AnnotationsAttribute;
0034:        import javassist.bytecode.BadBytecode;
0035:        import javassist.bytecode.Bytecode;
0036:        import javassist.bytecode.ClassFile;
0037:        import javassist.bytecode.CodeAttribute;
0038:        import javassist.bytecode.ConstantAttribute;
0039:        import javassist.bytecode.CodeIterator;
0040:        import javassist.bytecode.ConstPool;
0041:        import javassist.bytecode.Descriptor;
0042:        import javassist.bytecode.EnclosingMethodAttribute;
0043:        import javassist.bytecode.FieldInfo;
0044:        import javassist.bytecode.InnerClassesAttribute;
0045:        import javassist.bytecode.MethodInfo;
0046:        import javassist.bytecode.ParameterAnnotationsAttribute;
0047:        import javassist.bytecode.annotation.Annotation;
0048:        import javassist.compiler.AccessorMaker;
0049:        import javassist.compiler.CompileError;
0050:        import javassist.compiler.Javac;
0051:        import javassist.expr.ExprEditor;
0052:
0053:        /**
0054:         * Class types.
0055:         */
0056:        class CtClassType extends CtClass {
0057:            ClassPool classPool;
0058:            boolean wasChanged;
0059:            private boolean wasFrozen;
0060:            boolean wasPruned;
0061:            boolean memberRemoved;
0062:            ClassFile classfile;
0063:
0064:            private CtMember fieldsCache;
0065:            private CtMember methodsCache;
0066:            private CtMember constructorsCache;
0067:            private CtConstructor classInitializerCache;
0068:
0069:            private AccessorMaker accessors;
0070:
0071:            private FieldInitLink fieldInitializers;
0072:            private Hashtable hiddenMethods; // must be synchronous
0073:            private int uniqueNumberSeed;
0074:
0075:            private boolean doPruning = ClassPool.doPruning;
0076:            int getCounter;
0077:            private static int readCounter = 0;
0078:            private static final int READ_THRESHOLD = 100; // see getClassFile2()
0079:
0080:            CtClassType(String name, ClassPool cp) {
0081:                super (name);
0082:                classPool = cp;
0083:                wasChanged = wasFrozen = wasPruned = memberRemoved = false;
0084:                classfile = null;
0085:                accessors = null;
0086:                fieldInitializers = null;
0087:                hiddenMethods = null;
0088:                uniqueNumberSeed = 0;
0089:                eraseCache();
0090:                getCounter = 0;
0091:            }
0092:
0093:            CtClassType(InputStream ins, ClassPool cp) throws IOException {
0094:                this ((String) null, cp);
0095:                classfile = new ClassFile(new DataInputStream(ins));
0096:                qualifiedName = classfile.getName();
0097:            }
0098:
0099:            protected void extendToString(StringBuffer buffer) {
0100:                if (wasChanged)
0101:                    buffer.append("changed ");
0102:
0103:                if (wasFrozen)
0104:                    buffer.append("frozen ");
0105:
0106:                if (wasPruned)
0107:                    buffer.append("pruned ");
0108:
0109:                buffer.append(Modifier.toString(getModifiers()));
0110:                buffer.append(" class ");
0111:                buffer.append(getName());
0112:
0113:                try {
0114:                    CtClass ext = getSuperclass();
0115:                    if (ext != null) {
0116:                        String name = ext.getName();
0117:                        if (!name.equals("java.lang.Object"))
0118:                            buffer.append(" extends " + ext.getName());
0119:                    }
0120:                } catch (NotFoundException e) {
0121:                    buffer.append(" extends ??");
0122:                }
0123:
0124:                try {
0125:                    CtClass[] intf = getInterfaces();
0126:                    if (intf.length > 0)
0127:                        buffer.append(" implements ");
0128:
0129:                    for (int i = 0; i < intf.length; ++i) {
0130:                        buffer.append(intf[i].getName());
0131:                        buffer.append(", ");
0132:                    }
0133:                } catch (NotFoundException e) {
0134:                    buffer.append(" extends ??");
0135:                }
0136:
0137:                CtMember field = getFieldsCache();
0138:                buffer.append(" fields=");
0139:                while (field != null) {
0140:                    buffer.append(field);
0141:                    buffer.append(", ");
0142:                    field = field.next;
0143:                }
0144:
0145:                CtMember c = getConstructorsCache();
0146:                buffer.append(" constructors=");
0147:                while (c != null) {
0148:                    buffer.append(c);
0149:                    buffer.append(", ");
0150:                    c = c.next;
0151:                }
0152:
0153:                CtMember m = getMethodsCache();
0154:                buffer.append(" methods=");
0155:                while (m != null) {
0156:                    buffer.append(m);
0157:                    buffer.append(", ");
0158:                    m = m.next;
0159:                }
0160:            }
0161:
0162:            protected void eraseCache() {
0163:                fieldsCache = null;
0164:                constructorsCache = null;
0165:                classInitializerCache = null;
0166:                methodsCache = null;
0167:            }
0168:
0169:            public AccessorMaker getAccessorMaker() {
0170:                if (accessors == null)
0171:                    accessors = new AccessorMaker(this );
0172:
0173:                return accessors;
0174:            }
0175:
0176:            public ClassFile getClassFile2() {
0177:                if (classfile != null)
0178:                    return classfile;
0179:
0180:                if (readCounter++ > READ_THRESHOLD
0181:                        && ClassPool.releaseUnmodifiedClassFile) {
0182:                    releaseClassFiles();
0183:                    readCounter = 0;
0184:                }
0185:
0186:                InputStream fin = null;
0187:                try {
0188:                    fin = classPool.openClassfile(getName());
0189:                    if (fin == null)
0190:                        throw new NotFoundException(getName());
0191:
0192:                    fin = new BufferedInputStream(fin);
0193:                    classfile = new ClassFile(new DataInputStream(fin));
0194:                    if (!classfile.getName().equals(qualifiedName))
0195:                        throw new RuntimeException("cannot find "
0196:                                + qualifiedName + ": " + classfile.getName()
0197:                                + " found in "
0198:                                + qualifiedName.replace('.', '/') + ".class");
0199:
0200:                    return classfile;
0201:                } catch (NotFoundException e) {
0202:                    throw new RuntimeException(e.toString());
0203:                } catch (IOException e) {
0204:                    throw new RuntimeException(e.toString());
0205:                } finally {
0206:                    if (fin != null)
0207:                        try {
0208:                            fin.close();
0209:                        } catch (IOException e) {
0210:                        }
0211:                }
0212:            }
0213:
0214:            /* Inherited from CtClass.  Called by get() in ClassPool.
0215:             *
0216:             * @see javassist.CtClass#incGetCounter()
0217:             */
0218:            void incGetCounter() {
0219:                ++getCounter;
0220:            }
0221:
0222:            /**
0223:             * Releases the class files and cached CtBehaviors
0224:             * of the CtClasses that have not been recently used
0225:             * if they are unmodified. 
0226:             */
0227:            private void releaseClassFiles() {
0228:                Enumeration e = classPool.classes.elements();
0229:                while (e.hasMoreElements()) {
0230:                    Object obj = e.nextElement();
0231:                    if (obj instanceof  CtClassType) {
0232:                        CtClassType cct = (CtClassType) obj;
0233:                        if (cct.getCounter < 2 && !cct.isModified()) {
0234:                            cct.eraseCache();
0235:                            cct.classfile = null;
0236:                        }
0237:
0238:                        cct.getCounter = 0;
0239:                    }
0240:                }
0241:            }
0242:
0243:            public ClassPool getClassPool() {
0244:                return classPool;
0245:            }
0246:
0247:            void setClassPool(ClassPool cp) {
0248:                classPool = cp;
0249:            }
0250:
0251:            public URL getURL() throws NotFoundException {
0252:                URL url = classPool.find(getName());
0253:                if (url == null)
0254:                    throw new NotFoundException(getName());
0255:                else
0256:                    return url;
0257:            }
0258:
0259:            public boolean isModified() {
0260:                return wasChanged;
0261:            }
0262:
0263:            public boolean isFrozen() {
0264:                return wasFrozen;
0265:            }
0266:
0267:            void freeze() {
0268:                wasFrozen = true;
0269:            }
0270:
0271:            void checkModify() throws RuntimeException {
0272:                if (isFrozen()) {
0273:                    String msg = getName() + " class is frozen";
0274:                    if (wasPruned)
0275:                        msg += " and pruned";
0276:
0277:                    throw new RuntimeException(msg);
0278:                }
0279:
0280:                wasChanged = true;
0281:            }
0282:
0283:            public void defrost() {
0284:                checkPruned("defrost");
0285:                wasFrozen = false;
0286:            }
0287:
0288:            public boolean subtypeOf(CtClass clazz) throws NotFoundException {
0289:                int i;
0290:                String cname = clazz.getName();
0291:                if (this  == clazz || getName().equals(cname))
0292:                    return true;
0293:
0294:                ClassFile file = getClassFile2();
0295:                String super name = file.getSuperclass();
0296:                if (super name != null && super name.equals(cname))
0297:                    return true;
0298:
0299:                String[] ifs = file.getInterfaces();
0300:                int num = ifs.length;
0301:                for (i = 0; i < num; ++i)
0302:                    if (ifs[i].equals(cname))
0303:                        return true;
0304:
0305:                if (super name != null
0306:                        && classPool.get(super name).subtypeOf(clazz))
0307:                    return true;
0308:
0309:                for (i = 0; i < num; ++i)
0310:                    if (classPool.get(ifs[i]).subtypeOf(clazz))
0311:                        return true;
0312:
0313:                return false;
0314:            }
0315:
0316:            public void setName(String name) throws RuntimeException {
0317:                String oldname = getName();
0318:                if (name.equals(oldname))
0319:                    return;
0320:
0321:                // check this in advance although classNameChanged() below does.
0322:                classPool.checkNotFrozen(name);
0323:                ClassFile cf = getClassFile2();
0324:                super .setName(name);
0325:                cf.setName(name);
0326:                eraseCache();
0327:                classPool.classNameChanged(oldname, this );
0328:            }
0329:
0330:            public void replaceClassName(ClassMap classnames)
0331:                    throws RuntimeException {
0332:                String oldClassName = getName();
0333:                String newClassName = (String) classnames.get(Descriptor
0334:                        .toJvmName(oldClassName));
0335:                if (newClassName != null) {
0336:                    newClassName = Descriptor.toJavaName(newClassName);
0337:                    // check this in advance although classNameChanged() below does.
0338:                    classPool.checkNotFrozen(newClassName);
0339:                }
0340:
0341:                super .replaceClassName(classnames);
0342:                ClassFile cf = getClassFile2();
0343:                cf.renameClass(classnames);
0344:                eraseCache();
0345:
0346:                if (newClassName != null) {
0347:                    super .setName(newClassName);
0348:                    classPool.classNameChanged(oldClassName, this );
0349:                }
0350:            }
0351:
0352:            public void replaceClassName(String oldname, String newname)
0353:                    throws RuntimeException {
0354:                String this name = getName();
0355:                if (this name.equals(oldname))
0356:                    setName(newname);
0357:                else {
0358:                    super .replaceClassName(oldname, newname);
0359:                    getClassFile2().renameClass(oldname, newname);
0360:                    eraseCache();
0361:                }
0362:            }
0363:
0364:            public boolean isInterface() {
0365:                return Modifier.isInterface(getModifiers());
0366:            }
0367:
0368:            public boolean isAnnotation() {
0369:                return Modifier.isAnnotation(getModifiers());
0370:            }
0371:
0372:            public boolean isEnum() {
0373:                return Modifier.isEnum(getModifiers());
0374:            }
0375:
0376:            public int getModifiers() {
0377:                ClassFile cf = getClassFile2();
0378:                int acc = cf.getAccessFlags();
0379:                acc = AccessFlag.clear(acc, AccessFlag.SUPER);
0380:                int inner = cf.getInnerAccessFlags();
0381:                if (inner != -1 && (inner & AccessFlag.STATIC) != 0)
0382:                    acc |= AccessFlag.STATIC;
0383:
0384:                return AccessFlag.toModifier(acc);
0385:            }
0386:
0387:            public CtClass[] getNestedClasses() throws NotFoundException {
0388:                ClassFile cf = getClassFile2();
0389:                InnerClassesAttribute ica = (InnerClassesAttribute) cf
0390:                        .getAttribute(InnerClassesAttribute.tag);
0391:                if (ica == null)
0392:                    return new CtClass[0];
0393:
0394:                String this Name = cf.getName();
0395:                int n = ica.tableLength();
0396:                ArrayList list = new ArrayList(n);
0397:                for (int i = 0; i < n; i++) {
0398:                    String outer = ica.outerClass(i);
0399:                    /*
0400:                     * If a nested class is local or anonymous,
0401:                     * the outer_class_info_index is 0.
0402:                     */
0403:                    if (outer == null || outer.equals(this Name)) {
0404:                        String inner = ica.innerClass(i);
0405:                        if (inner != null)
0406:                            list.add(classPool.get(inner));
0407:                    }
0408:                }
0409:
0410:                return (CtClass[]) list.toArray(new CtClass[list.size()]);
0411:            }
0412:
0413:            public void setModifiers(int mod) {
0414:                ClassFile cf = getClassFile2();
0415:                if (Modifier.isStatic(mod)) {
0416:                    int flags = cf.getInnerAccessFlags();
0417:                    if (flags != -1 && (flags & AccessFlag.STATIC) != 0)
0418:                        mod = mod & ~Modifier.STATIC;
0419:                    else
0420:                        throw new RuntimeException("cannot change " + getName()
0421:                                + " into a static class");
0422:                }
0423:
0424:                checkModify();
0425:                int acc = AccessFlag.of(mod) | AccessFlag.SUPER;
0426:                cf.setAccessFlags(acc);
0427:            }
0428:
0429:            public Object[] getAnnotations() throws ClassNotFoundException {
0430:                return getAnnotations(false);
0431:            }
0432:
0433:            public Object[] getAvailableAnnotations() {
0434:                try {
0435:                    return getAnnotations(true);
0436:                } catch (ClassNotFoundException e) {
0437:                    throw new RuntimeException("Unexpected exception ", e);
0438:                }
0439:            }
0440:
0441:            private Object[] getAnnotations(boolean ignoreNotFound)
0442:                    throws ClassNotFoundException {
0443:                ClassFile cf = getClassFile2();
0444:                AnnotationsAttribute ainfo = (AnnotationsAttribute) cf
0445:                        .getAttribute(AnnotationsAttribute.invisibleTag);
0446:                AnnotationsAttribute ainfo2 = (AnnotationsAttribute) cf
0447:                        .getAttribute(AnnotationsAttribute.visibleTag);
0448:                return toAnnotationType(ignoreNotFound, getClassPool(), ainfo,
0449:                        ainfo2);
0450:            }
0451:
0452:            static Object[] toAnnotationType(boolean ignoreNotFound,
0453:                    ClassPool cp, AnnotationsAttribute a1,
0454:                    AnnotationsAttribute a2) throws ClassNotFoundException {
0455:                Annotation[] anno1, anno2;
0456:                int size1, size2;
0457:
0458:                if (a1 == null) {
0459:                    anno1 = null;
0460:                    size1 = 0;
0461:                } else {
0462:                    anno1 = a1.getAnnotations();
0463:                    size1 = anno1.length;
0464:                }
0465:
0466:                if (a2 == null) {
0467:                    anno2 = null;
0468:                    size2 = 0;
0469:                } else {
0470:                    anno2 = a2.getAnnotations();
0471:                    size2 = anno2.length;
0472:                }
0473:
0474:                if (!ignoreNotFound) {
0475:                    Object[] result = new Object[size1 + size2];
0476:                    for (int i = 0; i < size1; i++)
0477:                        result[i] = toAnnoType(anno1[i], cp);
0478:
0479:                    for (int j = 0; j < size2; j++)
0480:                        result[j + size1] = toAnnoType(anno2[j], cp);
0481:
0482:                    return result;
0483:                } else {
0484:                    ArrayList annotations = new ArrayList();
0485:                    for (int i = 0; i < size1; i++) {
0486:                        try {
0487:                            annotations.add(toAnnoType(anno1[i], cp));
0488:                        } catch (ClassNotFoundException e) {
0489:                        }
0490:                    }
0491:                    for (int j = 0; j < size2; j++) {
0492:                        try {
0493:                            annotations.add(toAnnoType(anno2[j], cp));
0494:                        } catch (ClassNotFoundException e) {
0495:                        }
0496:                    }
0497:
0498:                    return annotations.toArray();
0499:                }
0500:            }
0501:
0502:            static Object[][] toAnnotationType(boolean ignoreNotFound,
0503:                    ClassPool cp, ParameterAnnotationsAttribute a1,
0504:                    ParameterAnnotationsAttribute a2, MethodInfo minfo)
0505:                    throws ClassNotFoundException {
0506:                int numParameters = 0;
0507:                if (a1 != null)
0508:                    numParameters = a1.numParameters();
0509:                else if (a2 != null)
0510:                    numParameters = a2.numParameters();
0511:                else
0512:                    numParameters = Descriptor.numOfParameters(minfo
0513:                            .getDescriptor());
0514:
0515:                Object[][] result = new Object[numParameters][];
0516:                for (int i = 0; i < numParameters; i++) {
0517:                    Annotation[] anno1, anno2;
0518:                    int size1, size2;
0519:
0520:                    if (a1 == null) {
0521:                        anno1 = null;
0522:                        size1 = 0;
0523:                    } else {
0524:                        anno1 = a1.getAnnotations()[i];
0525:                        size1 = anno1.length;
0526:                    }
0527:
0528:                    if (a2 == null) {
0529:                        anno2 = null;
0530:                        size2 = 0;
0531:                    } else {
0532:                        anno2 = a2.getAnnotations()[i];
0533:                        size2 = anno2.length;
0534:                    }
0535:
0536:                    if (!ignoreNotFound) {
0537:                        result[i] = new Object[size1 + size2];
0538:                        for (int j = 0; j < size1; ++j)
0539:                            result[i][j] = toAnnoType(anno1[j], cp);
0540:
0541:                        for (int j = 0; j < size2; ++j)
0542:                            result[i][j + size1] = toAnnoType(anno2[j], cp);
0543:                    } else {
0544:                        ArrayList annotations = new ArrayList();
0545:                        for (int j = 0; j < size1; j++) {
0546:                            try {
0547:                                annotations.add(toAnnoType(anno1[j], cp));
0548:                            } catch (ClassNotFoundException e) {
0549:                            }
0550:                        }
0551:                        for (int j = 0; j < size2; j++) {
0552:                            try {
0553:                                annotations.add(toAnnoType(anno2[j], cp));
0554:                            } catch (ClassNotFoundException e) {
0555:                            }
0556:                        }
0557:
0558:                        result[i] = annotations.toArray();
0559:                    }
0560:                }
0561:
0562:                return result;
0563:            }
0564:
0565:            private static Object toAnnoType(Annotation anno, ClassPool cp)
0566:                    throws ClassNotFoundException {
0567:                try {
0568:                    ClassLoader cl = cp.getClassLoader();
0569:                    return anno.toAnnotationType(cl, cp);
0570:                } catch (ClassNotFoundException e) {
0571:                    ClassLoader cl2 = cp.getClass().getClassLoader();
0572:                    return anno.toAnnotationType(cl2, cp);
0573:                }
0574:            }
0575:
0576:            public boolean subclassOf(CtClass super class) {
0577:                if (super class == null)
0578:                    return false;
0579:
0580:                String super Name = super class.getName();
0581:                CtClass curr = this ;
0582:                try {
0583:                    while (curr != null) {
0584:                        if (curr.getName().equals(super Name))
0585:                            return true;
0586:
0587:                        curr = curr.getSuperclass();
0588:                    }
0589:                } catch (Exception ignored) {
0590:                }
0591:                return false;
0592:            }
0593:
0594:            public CtClass getSuperclass() throws NotFoundException {
0595:                String super name = getClassFile2().getSuperclass();
0596:                if (super name == null)
0597:                    return null;
0598:                else
0599:                    return classPool.get(super name);
0600:            }
0601:
0602:            public void setSuperclass(CtClass clazz)
0603:                    throws CannotCompileException {
0604:                checkModify();
0605:                if (isInterface())
0606:                    addInterface(clazz);
0607:                else
0608:                    getClassFile2().setSuperclass(clazz.getName());
0609:            }
0610:
0611:            public CtClass[] getInterfaces() throws NotFoundException {
0612:                String[] ifs = getClassFile2().getInterfaces();
0613:                int num = ifs.length;
0614:                CtClass[] ifc = new CtClass[num];
0615:                for (int i = 0; i < num; ++i)
0616:                    ifc[i] = classPool.get(ifs[i]);
0617:
0618:                return ifc;
0619:            }
0620:
0621:            public void setInterfaces(CtClass[] list) {
0622:                checkModify();
0623:                String[] ifs;
0624:                if (list == null)
0625:                    ifs = new String[0];
0626:                else {
0627:                    int num = list.length;
0628:                    ifs = new String[num];
0629:                    for (int i = 0; i < num; ++i)
0630:                        ifs[i] = list[i].getName();
0631:                }
0632:
0633:                getClassFile2().setInterfaces(ifs);
0634:            }
0635:
0636:            public void addInterface(CtClass anInterface) {
0637:                checkModify();
0638:                if (anInterface != null)
0639:                    getClassFile2().addInterface(anInterface.getName());
0640:            }
0641:
0642:            public CtClass getDeclaringClass() throws NotFoundException {
0643:                ClassFile cf = getClassFile2();
0644:                InnerClassesAttribute ica = (InnerClassesAttribute) cf
0645:                        .getAttribute(InnerClassesAttribute.tag);
0646:                if (ica == null)
0647:                    return null;
0648:
0649:                String name = getName();
0650:                int n = ica.tableLength();
0651:                for (int i = 0; i < n; ++i)
0652:                    if (name.equals(ica.innerClass(i))) {
0653:                        String outName = ica.outerClass(i);
0654:                        if (outName != null)
0655:                            return classPool.get(outName);
0656:                        else {
0657:                            // maybe anonymous or local class.
0658:                            EnclosingMethodAttribute ema = (EnclosingMethodAttribute) cf
0659:                                    .getAttribute(EnclosingMethodAttribute.tag);
0660:                            if (ema != null)
0661:                                return classPool.get(ema.className());
0662:                        }
0663:                    }
0664:
0665:                return null;
0666:            }
0667:
0668:            public CtMethod getEnclosingMethod() throws NotFoundException {
0669:                ClassFile cf = getClassFile2();
0670:                EnclosingMethodAttribute ema = (EnclosingMethodAttribute) cf
0671:                        .getAttribute(EnclosingMethodAttribute.tag);
0672:                if (ema != null) {
0673:                    CtClass enc = classPool.get(ema.className());
0674:                    return enc.getMethod(ema.methodName(), ema
0675:                            .methodDescriptor());
0676:                }
0677:
0678:                return null;
0679:            }
0680:
0681:            public CtClass makeNestedClass(String name, boolean isStatic) {
0682:                if (!isStatic)
0683:                    throw new RuntimeException(
0684:                            "sorry, only nested static class is supported");
0685:
0686:                checkModify();
0687:                CtClass c = classPool.makeNestedClass(getName() + "$" + name);
0688:                ClassFile cf = getClassFile2();
0689:                ClassFile cf2 = c.getClassFile2();
0690:                InnerClassesAttribute ica = (InnerClassesAttribute) cf
0691:                        .getAttribute(InnerClassesAttribute.tag);
0692:                if (ica == null) {
0693:                    ica = new InnerClassesAttribute(cf.getConstPool());
0694:                    cf.addAttribute(ica);
0695:                }
0696:
0697:                ica.append(c.getName(), this .getName(), name, (cf2
0698:                        .getAccessFlags() & ~AccessFlag.SUPER)
0699:                        | AccessFlag.STATIC);
0700:                cf2.addAttribute(ica.copy(cf2.getConstPool(), null));
0701:                return c;
0702:            }
0703:
0704:            public CtField[] getFields() {
0705:                ArrayList alist = new ArrayList();
0706:                getFields(alist, this );
0707:                return (CtField[]) alist.toArray(new CtField[alist.size()]);
0708:            }
0709:
0710:            private static void getFields(ArrayList alist, CtClass cc) {
0711:                int i, num;
0712:                if (cc == null)
0713:                    return;
0714:
0715:                try {
0716:                    getFields(alist, cc.getSuperclass());
0717:                } catch (NotFoundException e) {
0718:                }
0719:
0720:                try {
0721:                    CtClass[] ifs = cc.getInterfaces();
0722:                    num = ifs.length;
0723:                    for (i = 0; i < num; ++i)
0724:                        getFields(alist, ifs[i]);
0725:                } catch (NotFoundException e) {
0726:                }
0727:
0728:                CtMember cf = ((CtClassType) cc).getFieldsCache();
0729:                while (cf != null) {
0730:                    if (!Modifier.isPrivate(cf.getModifiers()))
0731:                        alist.add(cf);
0732:
0733:                    cf = cf.next;
0734:                }
0735:            }
0736:
0737:            public CtField getField(String name) throws NotFoundException {
0738:                CtField f = getField2(name);
0739:                if (f == null)
0740:                    throw new NotFoundException("field: " + name + " in "
0741:                            + getName());
0742:                else
0743:                    return f;
0744:            }
0745:
0746:            CtField getField2(String name) {
0747:                CtField df = getDeclaredField2(name);
0748:                if (df != null)
0749:                    return df;
0750:
0751:                try {
0752:                    CtClass[] ifs = getInterfaces();
0753:                    int num = ifs.length;
0754:                    for (int i = 0; i < num; ++i) {
0755:                        CtField f = ifs[i].getField2(name);
0756:                        if (f != null)
0757:                            return f;
0758:                    }
0759:
0760:                    CtClass s = getSuperclass();
0761:                    if (s != null)
0762:                        return s.getField2(name);
0763:                } catch (NotFoundException e) {
0764:                }
0765:                return null;
0766:            }
0767:
0768:            public CtField[] getDeclaredFields() {
0769:                CtMember cf = getFieldsCache();
0770:                int num = CtField.count(cf);
0771:                CtField[] cfs = new CtField[num];
0772:                int i = 0;
0773:                while (cf != null) {
0774:                    cfs[i++] = (CtField) cf;
0775:                    cf = cf.next;
0776:                }
0777:
0778:                return cfs;
0779:            }
0780:
0781:            protected CtMember getFieldsCache() {
0782:                if (fieldsCache == null) {
0783:                    List list = getClassFile2().getFields();
0784:                    int n = list.size();
0785:                    CtMember allFields = null;
0786:                    CtField tail = null;
0787:                    for (int i = 0; i < n; ++i) {
0788:                        FieldInfo finfo = (FieldInfo) list.get(i);
0789:                        CtField newTail = new CtField(finfo, this );
0790:                        allFields = CtMember.append(allFields, tail, newTail);
0791:                        tail = newTail;
0792:                    }
0793:
0794:                    fieldsCache = allFields;
0795:                }
0796:
0797:                return fieldsCache;
0798:            }
0799:
0800:            public CtField getDeclaredField(String name)
0801:                    throws NotFoundException {
0802:                CtField f = getDeclaredField2(name);
0803:                if (f == null)
0804:                    throw new NotFoundException("field: " + name + " in "
0805:                            + getName());
0806:                else
0807:                    return f;
0808:            }
0809:
0810:            private CtField getDeclaredField2(String name) {
0811:                CtMember cf = getFieldsCache();
0812:                while (cf != null) {
0813:                    if (cf.getName().equals(name))
0814:                        return (CtField) cf;
0815:
0816:                    cf = cf.next;
0817:                }
0818:
0819:                return null;
0820:            }
0821:
0822:            public CtBehavior[] getDeclaredBehaviors() {
0823:                CtMember cc = getConstructorsCache();
0824:                CtMember cm = getMethodsCache();
0825:                int num = CtMember.count(cm) + CtMember.count(cc);
0826:                CtBehavior[] cb = new CtBehavior[num];
0827:                int i = 0;
0828:                while (cc != null) {
0829:                    cb[i++] = (CtBehavior) cc;
0830:                    cc = cc.next;
0831:                }
0832:
0833:                while (cm != null) {
0834:                    cb[i++] = (CtBehavior) cm;
0835:                    cm = cm.next;
0836:                }
0837:
0838:                return cb;
0839:            }
0840:
0841:            public CtConstructor[] getConstructors() {
0842:                CtConstructor[] cons = getDeclaredConstructors();
0843:                if (cons.length == 0)
0844:                    return cons;
0845:
0846:                int n = 0;
0847:                int i = cons.length;
0848:                while (--i >= 0)
0849:                    if (!Modifier.isPrivate(cons[i].getModifiers()))
0850:                        ++n;
0851:
0852:                CtConstructor[] result = new CtConstructor[n];
0853:                n = 0;
0854:                i = cons.length;
0855:                while (--i >= 0) {
0856:                    CtConstructor c = cons[i];
0857:                    if (!Modifier.isPrivate(c.getModifiers()))
0858:                        result[n++] = c;
0859:                }
0860:
0861:                return result;
0862:            }
0863:
0864:            public CtConstructor getConstructor(String desc)
0865:                    throws NotFoundException {
0866:                CtConstructor cc = (CtConstructor) getConstructorsCache();
0867:                while (cc != null) {
0868:                    if (cc.getMethodInfo2().getDescriptor().equals(desc))
0869:                        return cc;
0870:
0871:                    cc = (CtConstructor) cc.next;
0872:                }
0873:
0874:                return super .getConstructor(desc);
0875:            }
0876:
0877:            public CtConstructor[] getDeclaredConstructors() {
0878:                CtMember cc = getConstructorsCache();
0879:                int num = CtMember.count(cc);
0880:                CtConstructor[] ccs = new CtConstructor[num];
0881:                int i = 0;
0882:                while (cc != null) {
0883:                    ccs[i++] = (CtConstructor) cc;
0884:                    cc = cc.next;
0885:                }
0886:
0887:                return ccs;
0888:            }
0889:
0890:            protected CtMember getConstructorsCache() {
0891:                if (constructorsCache == null) {
0892:                    List list = getClassFile2().getMethods();
0893:                    int n = list.size();
0894:                    CtMember allConstructors = null;
0895:                    CtConstructor tail = null;
0896:                    for (int i = 0; i < n; ++i) {
0897:                        MethodInfo minfo = (MethodInfo) list.get(i);
0898:                        if (minfo.isConstructor()) {
0899:                            CtConstructor newTail = new CtConstructor(minfo,
0900:                                    this );
0901:                            allConstructors = CtMember.append(allConstructors,
0902:                                    tail, newTail);
0903:                            tail = newTail;
0904:                        }
0905:                    }
0906:
0907:                    constructorsCache = allConstructors;
0908:                }
0909:
0910:                return constructorsCache;
0911:            }
0912:
0913:            public CtConstructor getClassInitializer() {
0914:                if (classInitializerCache == null) {
0915:                    MethodInfo minfo = getClassFile2().getStaticInitializer();
0916:                    if (minfo != null)
0917:                        classInitializerCache = new CtConstructor(minfo, this );
0918:                }
0919:
0920:                return classInitializerCache;
0921:            }
0922:
0923:            public CtMethod[] getMethods() {
0924:                HashMap h = new HashMap();
0925:                getMethods0(h, this );
0926:                return (CtMethod[]) h.values().toArray(new CtMethod[h.size()]);
0927:            }
0928:
0929:            private static void getMethods0(HashMap h, CtClass cc) {
0930:                try {
0931:                    CtClass[] ifs = cc.getInterfaces();
0932:                    int size = ifs.length;
0933:                    for (int i = 0; i < size; ++i)
0934:                        getMethods0(h, ifs[i]);
0935:                } catch (NotFoundException e) {
0936:                }
0937:
0938:                try {
0939:                    CtClass s = cc.getSuperclass();
0940:                    if (s != null)
0941:                        getMethods0(h, s);
0942:                } catch (NotFoundException e) {
0943:                }
0944:
0945:                if (cc instanceof  CtClassType) {
0946:                    CtMember cm = ((CtClassType) cc).getMethodsCache();
0947:                    while (cm != null) {
0948:                        if (!Modifier.isPrivate(cm.getModifiers()))
0949:                            h.put(((CtMethod) cm).getStringRep(), cm);
0950:
0951:                        cm = cm.next;
0952:                    }
0953:                }
0954:            }
0955:
0956:            public CtMethod getMethod(String name, String desc)
0957:                    throws NotFoundException {
0958:                CtMethod m = getMethod0(this , name, desc);
0959:                if (m != null)
0960:                    return m;
0961:                else
0962:                    throw new NotFoundException(name + "(..) is not found in "
0963:                            + getName());
0964:            }
0965:
0966:            private static CtMethod getMethod0(CtClass cc, String name,
0967:                    String desc) {
0968:                if (cc instanceof  CtClassType) {
0969:                    CtMethod cm = (CtMethod) ((CtClassType) cc)
0970:                            .getMethodsCache();
0971:                    while (cm != null) {
0972:                        if (cm.getName().equals(name)
0973:                                && cm.getMethodInfo2().getDescriptor().equals(
0974:                                        desc))
0975:                            return cm;
0976:
0977:                        cm = (CtMethod) cm.next;
0978:                    }
0979:                }
0980:
0981:                try {
0982:                    CtClass s = cc.getSuperclass();
0983:                    if (s != null) {
0984:                        CtMethod m = getMethod0(s, name, desc);
0985:                        if (m != null)
0986:                            return m;
0987:                    }
0988:                } catch (NotFoundException e) {
0989:                }
0990:
0991:                try {
0992:                    CtClass[] ifs = cc.getInterfaces();
0993:                    int size = ifs.length;
0994:                    for (int i = 0; i < size; ++i) {
0995:                        CtMethod m = getMethod0(ifs[i], name, desc);
0996:                        if (m != null)
0997:                            return m;
0998:                    }
0999:                } catch (NotFoundException e) {
1000:                }
1001:                return null;
1002:            }
1003:
1004:            public CtMethod[] getDeclaredMethods() {
1005:                CtMember cm = getMethodsCache();
1006:                int num = CtMember.count(cm);
1007:                CtMethod[] cms = new CtMethod[num];
1008:                int i = 0;
1009:                while (cm != null) {
1010:                    cms[i++] = (CtMethod) cm;
1011:                    cm = cm.next;
1012:                }
1013:
1014:                return cms;
1015:            }
1016:
1017:            public CtMethod getDeclaredMethod(String name)
1018:                    throws NotFoundException {
1019:                CtMember m = getMethodsCache();
1020:                while (m != null) {
1021:                    if (m.getName().equals(name))
1022:                        return (CtMethod) m;
1023:
1024:                    m = m.next;
1025:                }
1026:
1027:                throw new NotFoundException(name + "(..) is not found in "
1028:                        + getName());
1029:            }
1030:
1031:            public CtMethod getDeclaredMethod(String name, CtClass[] params)
1032:                    throws NotFoundException {
1033:                String desc = Descriptor.ofParameters(params);
1034:                CtMethod m = (CtMethod) getMethodsCache();
1035:                while (m != null) {
1036:                    if (m.getName().equals(name)
1037:                            && m.getMethodInfo2().getDescriptor().startsWith(
1038:                                    desc))
1039:                        return m;
1040:
1041:                    m = (CtMethod) m.next;
1042:                }
1043:
1044:                throw new NotFoundException(name + "(..) is not found in "
1045:                        + getName());
1046:            }
1047:
1048:            protected CtMember getMethodsCache() {
1049:                if (methodsCache == null) {
1050:                    List list = getClassFile2().getMethods();
1051:                    int n = list.size();
1052:                    CtMember allMethods = null;
1053:                    CtMethod tail = null;
1054:                    for (int i = 0; i < n; ++i) {
1055:                        MethodInfo minfo = (MethodInfo) list.get(i);
1056:                        if (minfo.isMethod()) {
1057:                            CtMethod newTail = new CtMethod(minfo, this );
1058:                            allMethods = CtMember.append(allMethods, tail,
1059:                                    newTail);
1060:                            tail = newTail;
1061:                        }
1062:                    }
1063:
1064:                    methodsCache = allMethods;
1065:                }
1066:
1067:                return methodsCache;
1068:            }
1069:
1070:            public void addField(CtField f, String init)
1071:                    throws CannotCompileException {
1072:                addField(f, CtField.Initializer.byExpr(init));
1073:            }
1074:
1075:            public void addField(CtField f, CtField.Initializer init)
1076:                    throws CannotCompileException {
1077:                checkModify();
1078:                if (f.getDeclaringClass() != this )
1079:                    throw new CannotCompileException("cannot add");
1080:
1081:                if (init == null)
1082:                    init = f.getInit();
1083:
1084:                if (init != null) {
1085:                    int mod = f.getModifiers();
1086:                    if (Modifier.isStatic(mod) && Modifier.isFinal(mod))
1087:                        try {
1088:                            ConstPool cp = getClassFile2().getConstPool();
1089:                            int index = init.getConstantValue(cp, f.getType());
1090:                            if (index != 0) {
1091:                                f.getFieldInfo2().addAttribute(
1092:                                        new ConstantAttribute(cp, index));
1093:                                init = null;
1094:                            }
1095:                        } catch (NotFoundException e) {
1096:                        }
1097:                }
1098:
1099:                getFieldsCache();
1100:                fieldsCache = CtField.append(fieldsCache, f);
1101:                getClassFile2().addField(f.getFieldInfo2());
1102:
1103:                if (init != null) {
1104:                    FieldInitLink fil = new FieldInitLink(f, init);
1105:                    FieldInitLink link = fieldInitializers;
1106:                    if (link == null)
1107:                        fieldInitializers = fil;
1108:                    else {
1109:                        while (link.next != null)
1110:                            link = link.next;
1111:
1112:                        link.next = fil;
1113:                    }
1114:                }
1115:            }
1116:
1117:            public void removeField(CtField f) throws NotFoundException {
1118:                checkModify();
1119:                FieldInfo fi = f.getFieldInfo2();
1120:                ClassFile cf = getClassFile2();
1121:                if (cf.getFields().remove(fi)) {
1122:                    fieldsCache = CtMember.remove(fieldsCache, f);
1123:                    memberRemoved = true;
1124:                } else
1125:                    throw new NotFoundException(f.toString());
1126:            }
1127:
1128:            public CtConstructor makeClassInitializer()
1129:                    throws CannotCompileException {
1130:                CtConstructor clinit = getClassInitializer();
1131:                if (clinit != null)
1132:                    return clinit;
1133:
1134:                checkModify();
1135:                ClassFile cf = getClassFile2();
1136:                Bytecode code = new Bytecode(cf.getConstPool(), 0, 0);
1137:                modifyClassConstructor(cf, code, 0, 0);
1138:                return getClassInitializer();
1139:            }
1140:
1141:            public void addConstructor(CtConstructor c)
1142:                    throws CannotCompileException {
1143:                checkModify();
1144:                if (c.getDeclaringClass() != this )
1145:                    throw new CannotCompileException("cannot add");
1146:
1147:                getConstructorsCache();
1148:                constructorsCache = (CtConstructor) CtMember.append(
1149:                        constructorsCache, c);
1150:                getClassFile2().addMethod(c.getMethodInfo2());
1151:            }
1152:
1153:            public void removeConstructor(CtConstructor m)
1154:                    throws NotFoundException {
1155:                checkModify();
1156:                MethodInfo mi = m.getMethodInfo2();
1157:                ClassFile cf = getClassFile2();
1158:                if (cf.getMethods().remove(mi)) {
1159:                    constructorsCache = CtMember.remove(constructorsCache, m);
1160:                    memberRemoved = true;
1161:                } else
1162:                    throw new NotFoundException(m.toString());
1163:            }
1164:
1165:            public void addMethod(CtMethod m) throws CannotCompileException {
1166:                checkModify();
1167:                if (m.getDeclaringClass() != this )
1168:                    throw new CannotCompileException("cannot add");
1169:
1170:                getMethodsCache();
1171:                methodsCache = CtMember.append(methodsCache, m);
1172:                getClassFile2().addMethod(m.getMethodInfo2());
1173:                if ((m.getModifiers() & Modifier.ABSTRACT) != 0)
1174:                    setModifiers(getModifiers() | Modifier.ABSTRACT);
1175:            }
1176:
1177:            public void removeMethod(CtMethod m) throws NotFoundException {
1178:                checkModify();
1179:                MethodInfo mi = m.getMethodInfo2();
1180:                ClassFile cf = getClassFile2();
1181:                if (cf.getMethods().remove(mi)) {
1182:                    methodsCache = CtMember.remove(methodsCache, m);
1183:                    memberRemoved = true;
1184:                } else
1185:                    throw new NotFoundException(m.toString());
1186:            }
1187:
1188:            public byte[] getAttribute(String name) {
1189:                AttributeInfo ai = getClassFile2().getAttribute(name);
1190:                if (ai == null)
1191:                    return null;
1192:                else
1193:                    return ai.get();
1194:            }
1195:
1196:            public void setAttribute(String name, byte[] data) {
1197:                checkModify();
1198:                ClassFile cf = getClassFile2();
1199:                cf
1200:                        .addAttribute(new AttributeInfo(cf.getConstPool(),
1201:                                name, data));
1202:            }
1203:
1204:            public void instrument(CodeConverter converter)
1205:                    throws CannotCompileException {
1206:                checkModify();
1207:                ClassFile cf = getClassFile2();
1208:                ConstPool cp = cf.getConstPool();
1209:                List list = cf.getMethods();
1210:                int n = list.size();
1211:                for (int i = 0; i < n; ++i) {
1212:                    MethodInfo minfo = (MethodInfo) list.get(i);
1213:                    converter.doit(this , minfo, cp);
1214:                }
1215:            }
1216:
1217:            public void instrument(ExprEditor editor)
1218:                    throws CannotCompileException {
1219:                checkModify();
1220:                ClassFile cf = getClassFile2();
1221:                List list = cf.getMethods();
1222:                int n = list.size();
1223:                for (int i = 0; i < n; ++i) {
1224:                    MethodInfo minfo = (MethodInfo) list.get(i);
1225:                    editor.doit(this , minfo);
1226:                }
1227:            }
1228:
1229:            /**
1230:             * @see javassist.CtClass#prune()
1231:             * @see javassist.CtClass#stopPruning(boolean)
1232:             */
1233:            public void prune() {
1234:                if (wasPruned)
1235:                    return;
1236:
1237:                wasPruned = wasFrozen = true;
1238:                getClassFile2().prune();
1239:            }
1240:
1241:            public void toBytecode(DataOutputStream out)
1242:                    throws CannotCompileException, IOException {
1243:                try {
1244:                    if (isModified()) {
1245:                        checkPruned("toBytecode");
1246:                        ClassFile cf = getClassFile2();
1247:                        if (memberRemoved) {
1248:                            cf.compact();
1249:                            memberRemoved = false;
1250:                        }
1251:
1252:                        modifyClassConstructor(cf);
1253:                        modifyConstructors(cf);
1254:                        cf.write(out);
1255:                        out.flush();
1256:                        fieldInitializers = null;
1257:                        if (doPruning) {
1258:                            // to save memory
1259:                            cf.prune();
1260:                            wasPruned = true;
1261:                        }
1262:                    } else {
1263:                        classPool.writeClassfile(getName(), out);
1264:                        // to save memory
1265:                        eraseCache();
1266:                        classfile = null;
1267:                    }
1268:
1269:                    wasFrozen = true;
1270:                } catch (NotFoundException e) {
1271:                    throw new CannotCompileException(e);
1272:                } catch (IOException e) {
1273:                    throw new CannotCompileException(e);
1274:                }
1275:            }
1276:
1277:            /* See also checkModified()
1278:             */
1279:            private void checkPruned(String method) {
1280:                if (wasPruned)
1281:                    throw new RuntimeException(method + "(): " + getName()
1282:                            + " was pruned.");
1283:            }
1284:
1285:            public boolean stopPruning(boolean stop) {
1286:                boolean prev = !doPruning;
1287:                doPruning = !stop;
1288:                return prev;
1289:            }
1290:
1291:            private void modifyClassConstructor(ClassFile cf)
1292:                    throws CannotCompileException, NotFoundException {
1293:                if (fieldInitializers == null)
1294:                    return;
1295:
1296:                Bytecode code = new Bytecode(cf.getConstPool(), 0, 0);
1297:                Javac jv = new Javac(code, this );
1298:                int stacksize = 0;
1299:                boolean doInit = false;
1300:                for (FieldInitLink fi = fieldInitializers; fi != null; fi = fi.next) {
1301:                    CtField f = fi.field;
1302:                    if (Modifier.isStatic(f.getModifiers())) {
1303:                        doInit = true;
1304:                        int s = fi.init.compileIfStatic(f.getType(), f
1305:                                .getName(), code, jv);
1306:                        if (stacksize < s)
1307:                            stacksize = s;
1308:                    }
1309:                }
1310:
1311:                if (doInit) // need an initializer for static fileds.
1312:                    modifyClassConstructor(cf, code, stacksize, 0);
1313:            }
1314:
1315:            private void modifyClassConstructor(ClassFile cf, Bytecode code,
1316:                    int stacksize, int localsize) throws CannotCompileException {
1317:                MethodInfo m = cf.getStaticInitializer();
1318:                if (m == null) {
1319:                    code.add(Bytecode.RETURN);
1320:                    code.setMaxStack(stacksize);
1321:                    code.setMaxLocals(localsize);
1322:                    m = new MethodInfo(cf.getConstPool(), "<clinit>", "()V");
1323:                    m.setAccessFlags(AccessFlag.STATIC);
1324:                    m.setCodeAttribute(code.toCodeAttribute());
1325:                    cf.addMethod(m);
1326:                } else {
1327:                    CodeAttribute codeAttr = m.getCodeAttribute();
1328:                    if (codeAttr == null)
1329:                        throw new CannotCompileException("empty <clinit>");
1330:
1331:                    try {
1332:                        CodeIterator it = codeAttr.iterator();
1333:                        int pos = it.insertEx(code.get());
1334:                        it.insert(code.getExceptionTable(), pos);
1335:                        int maxstack = codeAttr.getMaxStack();
1336:                        if (maxstack < stacksize)
1337:                            codeAttr.setMaxStack(stacksize);
1338:
1339:                        int maxlocals = codeAttr.getMaxLocals();
1340:                        if (maxlocals < localsize)
1341:                            codeAttr.setMaxLocals(localsize);
1342:                    } catch (BadBytecode e) {
1343:                        throw new CannotCompileException(e);
1344:                    }
1345:                }
1346:            }
1347:
1348:            private void modifyConstructors(ClassFile cf)
1349:                    throws CannotCompileException, NotFoundException {
1350:                if (fieldInitializers == null)
1351:                    return;
1352:
1353:                ConstPool cp = cf.getConstPool();
1354:                List list = cf.getMethods();
1355:                int n = list.size();
1356:                for (int i = 0; i < n; ++i) {
1357:                    MethodInfo minfo = (MethodInfo) list.get(i);
1358:                    if (minfo.isConstructor()) {
1359:                        CodeAttribute codeAttr = minfo.getCodeAttribute();
1360:                        if (codeAttr != null)
1361:                            try {
1362:                                Bytecode init = new Bytecode(cp, 0, codeAttr
1363:                                        .getMaxLocals());
1364:                                CtClass[] params = Descriptor
1365:                                        .getParameterTypes(minfo
1366:                                                .getDescriptor(), classPool);
1367:                                int stacksize = makeFieldInitializer(init,
1368:                                        params);
1369:                                insertAuxInitializer(codeAttr, init, stacksize);
1370:                            } catch (BadBytecode e) {
1371:                                throw new CannotCompileException(e);
1372:                            }
1373:                    }
1374:                }
1375:            }
1376:
1377:            private static void insertAuxInitializer(CodeAttribute codeAttr,
1378:                    Bytecode initializer, int stacksize) throws BadBytecode {
1379:                CodeIterator it = codeAttr.iterator();
1380:                int index = it.skipSuperConstructor();
1381:                if (index < 0) {
1382:                    index = it.skipThisConstructor();
1383:                    if (index >= 0)
1384:                        return; // this() is called.
1385:
1386:                    // Neither this() or super() is called.
1387:                }
1388:
1389:                int pos = it.insertEx(initializer.get());
1390:                it.insert(initializer.getExceptionTable(), pos);
1391:                int maxstack = codeAttr.getMaxStack();
1392:                if (maxstack < stacksize)
1393:                    codeAttr.setMaxStack(stacksize);
1394:            }
1395:
1396:            private int makeFieldInitializer(Bytecode code, CtClass[] parameters)
1397:                    throws CannotCompileException, NotFoundException {
1398:                int stacksize = 0;
1399:                Javac jv = new Javac(code, this );
1400:                try {
1401:                    jv.recordParams(parameters, false);
1402:                } catch (CompileError e) {
1403:                    throw new CannotCompileException(e);
1404:                }
1405:
1406:                for (FieldInitLink fi = fieldInitializers; fi != null; fi = fi.next) {
1407:                    CtField f = fi.field;
1408:                    if (!Modifier.isStatic(f.getModifiers())) {
1409:                        int s = fi.init.compile(f.getType(), f.getName(), code,
1410:                                parameters, jv);
1411:                        if (stacksize < s)
1412:                            stacksize = s;
1413:                    }
1414:                }
1415:
1416:                return stacksize;
1417:            }
1418:
1419:            // Methods used by CtNewWrappedMethod
1420:
1421:            Hashtable getHiddenMethods() {
1422:                if (hiddenMethods == null)
1423:                    hiddenMethods = new Hashtable();
1424:
1425:                return hiddenMethods;
1426:            }
1427:
1428:            int getUniqueNumber() {
1429:                return uniqueNumberSeed++;
1430:            }
1431:
1432:            public String makeUniqueName(String prefix) {
1433:                HashMap table = new HashMap();
1434:                makeMemberList(table);
1435:                Set keys = table.keySet();
1436:                String[] methods = new String[keys.size()];
1437:                keys.toArray(methods);
1438:
1439:                if (notFindInArray(prefix, methods))
1440:                    return prefix;
1441:
1442:                int i = 100;
1443:                String name;
1444:                do {
1445:                    if (i > 999)
1446:                        throw new RuntimeException("too many unique name");
1447:
1448:                    name = prefix + i++;
1449:                } while (!notFindInArray(name, methods));
1450:                return name;
1451:            }
1452:
1453:            private static boolean notFindInArray(String prefix, String[] values) {
1454:                int len = values.length;
1455:                for (int i = 0; i < len; i++)
1456:                    if (values[i].startsWith(prefix))
1457:                        return false;
1458:
1459:                return true;
1460:            }
1461:
1462:            private void makeMemberList(HashMap table) {
1463:                int mod = getModifiers();
1464:                if (Modifier.isAbstract(mod) || Modifier.isInterface(mod))
1465:                    try {
1466:                        CtClass[] ifs = getInterfaces();
1467:                        int size = ifs.length;
1468:                        for (int i = 0; i < size; i++) {
1469:                            CtClass ic = ifs[i];
1470:                            if (ic != null && ic instanceof  CtClassType)
1471:                                ((CtClassType) ic).makeMemberList(table);
1472:                        }
1473:                    } catch (NotFoundException e) {
1474:                    }
1475:
1476:                try {
1477:                    CtClass s = getSuperclass();
1478:                    if (s != null && s instanceof  CtClassType)
1479:                        ((CtClassType) s).makeMemberList(table);
1480:                } catch (NotFoundException e) {
1481:                }
1482:
1483:                List list = getClassFile2().getMethods();
1484:                int n = list.size();
1485:                for (int i = 0; i < n; i++) {
1486:                    MethodInfo minfo = (MethodInfo) list.get(i);
1487:                    table.put(minfo.getName(), this );
1488:                }
1489:
1490:                list = getClassFile2().getFields();
1491:                n = list.size();
1492:                for (int i = 0; i < n; i++) {
1493:                    FieldInfo finfo = (FieldInfo) list.get(i);
1494:                    table.put(finfo.getName(), this );
1495:                }
1496:            }
1497:        }
1498:
1499:        class FieldInitLink {
1500:            FieldInitLink next;
1501:            CtField field;
1502:            CtField.Initializer init;
1503:
1504:            FieldInitLink(CtField f, CtField.Initializer i) {
1505:                next = null;
1506:                field = f;
1507:                init = i;
1508:            }
1509:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.