Source Code Cross Referenced for ClassGeneratorUtil.java in  » Swing-Library » jEdit » org » gjt » sp » jedit » bsh » 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 » Swing Library » jEdit » org.gjt.sp.jedit.bsh 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*****************************************************************************
0002:         *                                                                           *
0003:         *  This file is part of the BeanShell Java Scripting distribution.          *
0004:         *  Documentation and updates may be found at http://www.beanshell.org/      *
0005:         *                                                                           *
0006:         *  Sun Public License Notice:                                               *
0007:         *                                                                           *
0008:         *  The contents of this file are subject to the Sun Public License Version  *
0009:         *  1.0 (the "License"); you may not use this file except in compliance with *
0010:         *  the License. A copy of the License is available at http://www.sun.com    * 
0011:         *                                                                           *
0012:         *  The Original Code is BeanShell. The Initial Developer of the Original    *
0013:         *  Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright     *
0014:         *  (C) 2000.  All Rights Reserved.                                          *
0015:         *                                                                           *
0016:         *  GNU Public License Notice:                                               *
0017:         *                                                                           *
0018:         *  Alternatively, the contents of this file may be used under the terms of  *
0019:         *  the GNU Lesser General Public License (the "LGPL"), in which case the    *
0020:         *  provisions of LGPL are applicable instead of those above. If you wish to *
0021:         *  allow use of your version of this file only under the  terms of the LGPL *
0022:         *  and not to allow others to use your version of this file under the SPL,  *
0023:         *  indicate your decision by deleting the provisions above and replace      *
0024:         *  them with the notice and other provisions required by the LGPL.  If you  *
0025:         *  do not delete the provisions above, a recipient may use your version of  *
0026:         *  this file under either the SPL or the LGPL.                              *
0027:         *                                                                           *
0028:         *  Patrick Niemeyer (pat@pat.net)                                           *
0029:         *  Author of Learning Java, O'Reilly & Associates                           *
0030:         *  http://www.pat.net/~pat/                                                 *
0031:         *                                                                           *
0032:         *****************************************************************************/package org.gjt.sp.jedit.bsh;
0033:
0034:        import org.gjt.sp.jedit.bsh.org.objectweb.asm.*;
0035:        import org.gjt.sp.jedit.bsh.org.objectweb.asm.Type;
0036:
0037:        import java.lang.reflect.*;
0038:        import java.util.ArrayList;
0039:        import java.util.List;
0040:
0041:        /**
0042:         ClassGeneratorUtil utilizes the ASM (www.objectweb.org) bytecode generator 
0043:         by Eric Bruneton in order to generate class "stubs" for BeanShell at
0044:         runtime.  
0045:         <p>
0046:
0047:         Stub classes contain all of the fields of a BeanShell scripted class
0048:         as well as two "callback" references to BeanShell namespaces: one for
0049:         static methods and one for instance methods.  Methods of the class are
0050:         delegators which invoke corresponding methods on either the static or
0051:         instance bsh object and then unpack and return the results.  The static
0052:         namespace utilizes a static import to delegate variable access to the
0053:         class' static fields.  The instance namespace utilizes a dynamic import
0054:         (i.e. mixin) to delegate variable access to the class' instance variables.
0055:         <p>
0056:
0057:         Constructors for the class delegate to the static initInstance() method of 
0058:         ClassGeneratorUtil to initialize new instances of the object.  initInstance()
0059:         invokes the instance intializer code (init vars and instance blocks) and
0060:         then delegates to the corresponding scripted constructor method in the
0061:         instance namespace.  Constructors contain special switch logic which allows
0062:         the BeanShell to control the calling of alternate constructors (this() or
0063:         super() references) at runtime.
0064:         <p>
0065:
0066:         Specially named superclass delegator methods are also generated in order to
0067:         allow BeanShell to access overridden methods of the superclass (which
0068:         reflection does not normally allow).
0069:         <p>
0070:
0071:         @author Pat Niemeyer
0072:         */
0073:        /*
0074:         Notes:
0075:         It would not be hard to eliminate the use of org.objectweb.asm.Type from
0076:         this class, making the distribution a tiny bit smaller.
0077:         */
0078:        public class ClassGeneratorUtil implements  Constants {
0079:            /** The name of the static field holding the reference to the bsh
0080:             	 static This (the callback namespace for static methods) */
0081:            static final String BSHSTATIC = "_bshStatic";
0082:
0083:            /** The name of the instance field holding the reference to the bsh
0084:             	 instance This (the callback namespace for instance methods) */
0085:            static final String BSHTHIS = "_bshThis";
0086:
0087:            /** The prefix for the name of the super delegate methods. e.g.
0088:             	_bshSuperfoo() is equivalent to super.foo() */
0089:            static final String BSHSUPER = "_bshSuper";
0090:
0091:            /** The bsh static namespace variable name of the instance initializer */
0092:            static final String BSHINIT = "_bshInstanceInitializer";
0093:
0094:            /** The bsh static namespace variable that holds the constructor methods */
0095:            static final String BSHCONSTRUCTORS = "_bshConstructors";
0096:
0097:            /** The switch branch number for the default constructor. 
0098:            	The value -1 will cause the default branch to be taken. */
0099:            static final int DEFAULTCONSTRUCTOR = -1;
0100:
0101:            static final String OBJECT = "Ljava/lang/Object;";
0102:
0103:            String className;
0104:            /** fully qualified class name (with package) e.g. foo/bar/Blah */
0105:            String fqClassName;
0106:            Class super Class;
0107:            String super ClassName;
0108:            Class[] interfaces;
0109:            Variable[] vars;
0110:            Constructor[] super Constructors;
0111:            DelayedEvalBshMethod[] constructors;
0112:            DelayedEvalBshMethod[] methods;
0113:            NameSpace classStaticNameSpace;
0114:            Modifiers classModifiers;
0115:            boolean isInterface;
0116:
0117:            /**
0118:            	@param packageName e.g. "com.foo.bar"
0119:             */
0120:            public ClassGeneratorUtil(Modifiers classModifiers,
0121:                    String className, String packageName, Class super Class,
0122:                    Class[] interfaces, Variable[] vars,
0123:                    DelayedEvalBshMethod[] bshmethods,
0124:                    NameSpace classStaticNameSpace, boolean isInterface) {
0125:                this .classModifiers = classModifiers;
0126:                this .className = className;
0127:                if (packageName != null)
0128:                    this .fqClassName = packageName.replace('.', '/') + "/"
0129:                            + className;
0130:                else
0131:                    this .fqClassName = className;
0132:                if (super Class == null)
0133:                    super Class = Object.class;
0134:                this .super Class = super Class;
0135:                this .super ClassName = Type.getInternalName(super Class);
0136:                if (interfaces == null)
0137:                    interfaces = new Class[0];
0138:                this .interfaces = interfaces;
0139:                this .vars = vars;
0140:                this .classStaticNameSpace = classStaticNameSpace;
0141:                this .super Constructors = super Class.getDeclaredConstructors();
0142:
0143:                // Split the methods into constructors and regular method lists
0144:                List consl = new ArrayList();
0145:                List methodsl = new ArrayList();
0146:                String classBaseName = getBaseName(className); // for inner classes
0147:                for (int i = 0; i < bshmethods.length; i++)
0148:                    if (bshmethods[i].getName().equals(classBaseName))
0149:                        consl.add(bshmethods[i]);
0150:                    else
0151:                        methodsl.add(bshmethods[i]);
0152:
0153:                this .constructors = (DelayedEvalBshMethod[]) consl
0154:                        .toArray(new DelayedEvalBshMethod[0]);
0155:                this .methods = (DelayedEvalBshMethod[]) methodsl
0156:                        .toArray(new DelayedEvalBshMethod[0]);
0157:
0158:                try {
0159:                    classStaticNameSpace.setLocalVariable(BSHCONSTRUCTORS,
0160:                            constructors, false/*strict*/);
0161:                } catch (UtilEvalError e) {
0162:                    throw new InterpreterError("can't set cons var");
0163:                }
0164:
0165:                this .isInterface = isInterface;
0166:            }
0167:
0168:            /**
0169:            	Generate the class bytecode for this class.
0170:             */
0171:            public byte[] generateClass() {
0172:                // Force the class public for now...
0173:                int classMods = getASMModifiers(classModifiers) | ACC_PUBLIC;
0174:                if (isInterface)
0175:                    classMods |= ACC_INTERFACE;
0176:
0177:                String[] interfaceNames = new String[interfaces.length];
0178:                for (int i = 0; i < interfaces.length; i++)
0179:                    interfaceNames[i] = Type.getInternalName(interfaces[i]);
0180:
0181:                String sourceFile = "BeanShell Generated via ASM (www.objectweb.org)";
0182:                ClassWriter cw = new ClassWriter(false);
0183:                cw.visit(classMods, fqClassName, super ClassName,
0184:                        interfaceNames, sourceFile);
0185:
0186:                if (!isInterface) {
0187:                    // Generate the bsh instance 'This' reference holder field
0188:                    generateField(BSHTHIS + className,
0189:                            "Lorg/gjt/sp/jedit/bsh/This;", ACC_PUBLIC, cw);
0190:
0191:                    // Generate the static bsh static reference holder field
0192:                    generateField(BSHSTATIC + className,
0193:                            "Lorg/gjt/sp/jedit/bsh/This;", ACC_PUBLIC
0194:                                    + ACC_STATIC, cw);
0195:                }
0196:
0197:                // Generate the fields
0198:                for (int i = 0; i < vars.length; i++) {
0199:                    String type = vars[i].getTypeDescriptor();
0200:
0201:                    // Don't generate private or loosely typed fields
0202:                    // Note: loose types aren't currently parsed anyway...
0203:                    if (vars[i].hasModifier("private") || type == null)
0204:                        continue;
0205:
0206:                    int modifiers;
0207:                    if (isInterface)
0208:                        modifiers = ACC_PUBLIC | ACC_STATIC | ACC_FINAL;
0209:                    else
0210:                        modifiers = getASMModifiers(vars[i].getModifiers());
0211:
0212:                    generateField(vars[i].getName(), type, modifiers, cw);
0213:                }
0214:
0215:                // Generate the constructors
0216:                boolean hasConstructor = false;
0217:                for (int i = 0; i < constructors.length; i++) {
0218:                    // Don't generate private constructors
0219:                    if (constructors[i].hasModifier("private"))
0220:                        continue;
0221:
0222:                    int modifiers = getASMModifiers(constructors[i]
0223:                            .getModifiers());
0224:                    generateConstructor(i, constructors[i]
0225:                            .getParamTypeDescriptors(), modifiers, cw);
0226:                    hasConstructor = true;
0227:                }
0228:
0229:                // If no other constructors, generate a default constructor
0230:                if (!isInterface && !hasConstructor)
0231:                    generateConstructor(DEFAULTCONSTRUCTOR/*index*/,
0232:                            new String[0], ACC_PUBLIC, cw);
0233:
0234:                // Generate the delegate methods
0235:                for (int i = 0; i < methods.length; i++) {
0236:                    String returnType = methods[i].getReturnTypeDescriptor();
0237:
0238:                    // Don't generate private /*or loosely return typed */ methods
0239:                    if (methods[i].hasModifier("private") /*|| returnType == null*/)
0240:                        continue;
0241:
0242:                    int modifiers = getASMModifiers(methods[i].getModifiers());
0243:                    if (isInterface)
0244:                        modifiers |= (ACC_PUBLIC | ACC_ABSTRACT);
0245:
0246:                    generateMethod(className, fqClassName,
0247:                            methods[i].getName(), returnType, methods[i]
0248:                                    .getParamTypeDescriptors(), modifiers, cw);
0249:
0250:                    boolean isStatic = (modifiers & ACC_STATIC) > 0;
0251:                    boolean overridden = classContainsMethod(super Class,
0252:                            methods[i].getName(), methods[i]
0253:                                    .getParamTypeDescriptors());
0254:                    if (!isStatic && overridden)
0255:                        generateSuperDelegateMethod(super ClassName, methods[i]
0256:                                .getName(), returnType, methods[i]
0257:                                .getParamTypeDescriptors(), modifiers, cw);
0258:                }
0259:
0260:                return cw.toByteArray();
0261:            }
0262:
0263:            /**
0264:            	Translate bsh.Modifiers into ASM modifier bitflags.
0265:             */
0266:            static int getASMModifiers(Modifiers modifiers) {
0267:                int mods = 0;
0268:                if (modifiers == null)
0269:                    return mods;
0270:
0271:                if (modifiers.hasModifier("public"))
0272:                    mods += ACC_PUBLIC;
0273:                if (modifiers.hasModifier("protected"))
0274:                    mods += ACC_PROTECTED;
0275:                if (modifiers.hasModifier("static"))
0276:                    mods += ACC_STATIC;
0277:                if (modifiers.hasModifier("synchronized"))
0278:                    mods += ACC_SYNCHRONIZED;
0279:                if (modifiers.hasModifier("abstract"))
0280:                    mods += ACC_ABSTRACT;
0281:
0282:                return mods;
0283:            }
0284:
0285:            /**
0286:            	Generate a field - static or instance.
0287:             */
0288:            static void generateField(String fieldName, String type,
0289:                    int modifiers, ClassWriter cw) {
0290:                cw.visitField(modifiers, fieldName, type, null/*value*/);
0291:            }
0292:
0293:            /**
0294:            	Generate a delegate method - static or instance.
0295:            	The generated code packs the method arguments into an object array
0296:            	(wrapping primitive types in bsh.Primitive), invokes the static or
0297:            	instance namespace invokeMethod() method, and then unwraps / returns
0298:            	the result.
0299:             */
0300:            static void generateMethod(String className, String fqClassName,
0301:                    String methodName, String returnType, String[] paramTypes,
0302:                    int modifiers, ClassWriter cw) {
0303:                String[] exceptions = null;
0304:                boolean isStatic = (modifiers & ACC_STATIC) != 0;
0305:
0306:                if (returnType == null) // map loose return type to Object
0307:                    returnType = OBJECT;
0308:
0309:                String methodDescriptor = getMethodDescriptor(returnType,
0310:                        paramTypes);
0311:
0312:                // Generate method body
0313:                CodeVisitor cv = cw.visitMethod(modifiers, methodName,
0314:                        methodDescriptor, exceptions);
0315:
0316:                if ((modifiers & ACC_ABSTRACT) != 0)
0317:                    return;
0318:
0319:                // Generate code to push the BSHTHIS or BSHSTATIC field 
0320:                if (isStatic) {
0321:                    cv.visitFieldInsn(GETSTATIC, fqClassName, BSHSTATIC
0322:                            + className, "Lorg/gjt/sp/jedit/bsh/This;");
0323:                } else {
0324:                    // Push 'this'
0325:                    cv.visitVarInsn(ALOAD, 0);
0326:
0327:                    // Get the instance field
0328:                    cv.visitFieldInsn(GETFIELD, fqClassName, BSHTHIS
0329:                            + className, "Lorg/gjt/sp/jedit/bsh/This;");
0330:                }
0331:
0332:                // Push the name of the method as a constant
0333:                cv.visitLdcInsn(methodName);
0334:
0335:                // Generate code to push arguments as an object array
0336:                generateParameterReifierCode(paramTypes, isStatic, cv);
0337:
0338:                // Push nulls for various args of invokeMethod
0339:                cv.visitInsn(ACONST_NULL); // interpreter
0340:                cv.visitInsn(ACONST_NULL); // callstack
0341:                cv.visitInsn(ACONST_NULL); // callerinfo
0342:
0343:                // Push the boolean constant 'true' (for declaredOnly)
0344:                cv.visitInsn(ICONST_1);
0345:
0346:                // Invoke the method This.invokeMethod( name, Class [] sig, boolean )
0347:                cv.visitMethodInsn(INVOKEVIRTUAL, "org/gjt/sp/jedit/bsh/This",
0348:                        "invokeMethod", Type.getMethodDescriptor(Type
0349:                                .getType(Object.class), new Type[] {
0350:                                Type.getType(String.class),
0351:                                Type.getType(Object[].class),
0352:                                Type.getType(Interpreter.class),
0353:                                Type.getType(CallStack.class),
0354:                                Type.getType(SimpleNode.class),
0355:                                Type.getType(Boolean.TYPE) }));
0356:
0357:                // Generate code to unwrap bsh Primitive types
0358:                cv.visitMethodInsn(INVOKESTATIC,
0359:                        "org/gjt/sp/jedit/bsh/Primitive", "unwrap",
0360:                        "(Ljava/lang/Object;)Ljava/lang/Object;");
0361:
0362:                // Generate code to return the value
0363:                generateReturnCode(returnType, cv);
0364:
0365:                // Need to calculate this... just fudging here for now.
0366:                cv.visitMaxs(20, 20);
0367:            }
0368:
0369:            /**
0370:            	Generate a constructor.
0371:             */
0372:            void generateConstructor(int index, String[] paramTypes,
0373:                    int modifiers, ClassWriter cw) {
0374:                /** offset after params of the args object [] var */
0375:                final int argsVar = paramTypes.length + 1;
0376:                /** offset after params of the ConstructorArgs var */
0377:                final int consArgsVar = paramTypes.length + 2;
0378:
0379:                String[] exceptions = null;
0380:                String methodDescriptor = getMethodDescriptor("V", paramTypes);
0381:
0382:                // Create this constructor method
0383:                CodeVisitor cv = cw.visitMethod(modifiers, "<init>",
0384:                        methodDescriptor, exceptions);
0385:
0386:                // Generate code to push arguments as an object array
0387:                generateParameterReifierCode(paramTypes, false/*isStatic*/, cv);
0388:                cv.visitVarInsn(ASTORE, argsVar);
0389:
0390:                // Generate the code implementing the alternate constructor switch
0391:                generateConstructorSwitch(index, argsVar, consArgsVar, cv);
0392:
0393:                // Generate code to invoke the ClassGeneratorUtil initInstance() method
0394:
0395:                // push 'this' 
0396:                cv.visitVarInsn(ALOAD, 0);
0397:
0398:                // Push the class/constructor name as a constant
0399:                cv.visitLdcInsn(className);
0400:
0401:                // Push arguments as an object array
0402:                cv.visitVarInsn(ALOAD, argsVar);
0403:
0404:                // invoke the initInstance() method
0405:                cv
0406:                        .visitMethodInsn(INVOKESTATIC,
0407:                                "org/gjt/sp/jedit/bsh/ClassGeneratorUtil",
0408:                                "initInstance",
0409:                                "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V");
0410:
0411:                cv.visitInsn(RETURN);
0412:
0413:                // Need to calculate this... just fudging here for now.
0414:                cv.visitMaxs(20, 20);
0415:            }
0416:
0417:            /**
0418:            	Generate a switch with a branch for each possible alternate
0419:            	constructor.  This includes all superclass constructors and all 
0420:            	constructors of this class.  The default branch of this switch is the
0421:            	default superclass constructor.
0422:            	<p>
0423:            	This method also generates the code to call the static
0424:            	ClassGeneratorUtil
0425:            	getConstructorArgs() method which inspects the scripted constructor to
0426:            	find the alternate constructor signature (if any) and evalute the
0427:            	arguments at runtime.  The getConstructorArgs() method returns the
0428:            	actual arguments as well as the index of the constructor to call. 
0429:             */
0430:            void generateConstructorSwitch(int consIndex, int argsVar,
0431:                    int consArgsVar, CodeVisitor cv) {
0432:                Label defaultLabel = new Label();
0433:                Label endLabel = new Label();
0434:                int cases = super Constructors.length + constructors.length;
0435:
0436:                Label[] labels = new Label[cases];
0437:                for (int i = 0; i < cases; i++)
0438:                    labels[i] = new Label();
0439:
0440:                // Generate code to call ClassGeneratorUtil to get our switch index 
0441:                // and give us args...
0442:
0443:                // push super class name
0444:                cv.visitLdcInsn(super Class.getName()); // use superClassName var?
0445:
0446:                // push class static This object
0447:                cv.visitFieldInsn(GETSTATIC, fqClassName,
0448:                        BSHSTATIC + className, "Lorg/gjt/sp/jedit/bsh/This;");
0449:
0450:                // push args
0451:                cv.visitVarInsn(ALOAD, argsVar);
0452:
0453:                // push this constructor index number onto stack
0454:                cv.visitIntInsn(BIPUSH, consIndex);
0455:
0456:                // invoke the ClassGeneratorUtil getConstructorsArgs() method
0457:                cv
0458:                        .visitMethodInsn(
0459:                                INVOKESTATIC,
0460:                                "org/gjt/sp/jedit/bsh/ClassGeneratorUtil",
0461:                                "getConstructorArgs",
0462:                                "(Ljava/lang/String;Lorg/gjt/sp/jedit/bsh/This;[Ljava/lang/Object;I)"
0463:                                        + "Lorg/gjt/sp/jedit/bsh/ClassGeneratorUtil$ConstructorArgs;");
0464:
0465:                // store ConstructorArgs in consArgsVar
0466:                cv.visitVarInsn(ASTORE, consArgsVar);
0467:
0468:                // Get the ConstructorArgs selector field from ConstructorArgs
0469:
0470:                // push ConstructorArgs 
0471:                cv.visitVarInsn(ALOAD, consArgsVar);
0472:                cv
0473:                        .visitFieldInsn(
0474:                                GETFIELD,
0475:                                "org/gjt/sp/jedit/bsh/ClassGeneratorUtil$ConstructorArgs",
0476:                                "selector", "I");
0477:
0478:                // start switch
0479:                cv.visitTableSwitchInsn(0/*min*/, cases - 1/*max*/,
0480:                        defaultLabel, labels);
0481:
0482:                // generate switch body
0483:                int index = 0;
0484:                for (int i = 0; i < super Constructors.length; i++, index++)
0485:                    doSwitchBranch(index, super ClassName,
0486:                            getTypeDescriptors(super Constructors[i]
0487:                                    .getParameterTypes()), endLabel, labels,
0488:                            consArgsVar, cv);
0489:                for (int i = 0; i < constructors.length; i++, index++)
0490:                    doSwitchBranch(index, fqClassName, constructors[i]
0491:                            .getParamTypeDescriptors(), endLabel, labels,
0492:                            consArgsVar, cv);
0493:
0494:                // generate the default branch of switch
0495:                cv.visitLabel(defaultLabel);
0496:                // default branch always invokes no args super
0497:                cv.visitVarInsn(ALOAD, 0); // push 'this' 
0498:                cv.visitMethodInsn(INVOKESPECIAL, super ClassName, "<init>",
0499:                        "()V");
0500:
0501:                // done with switch
0502:                cv.visitLabel(endLabel);
0503:            }
0504:
0505:            /*
0506:            	Generate a branch of the constructor switch.  This method is called by
0507:            	generateConstructorSwitch.
0508:            	The code generated by this method assumes that the argument array is 
0509:            	on the stack.
0510:             */
0511:            static void doSwitchBranch(int index, String targetClassName,
0512:                    String[] paramTypes, Label endLabel, Label[] labels,
0513:                    int consArgsVar, CodeVisitor cv) {
0514:                cv.visitLabel(labels[index]);
0515:                //cv.visitLineNumber( index, labels[index] );
0516:                cv.visitVarInsn(ALOAD, 0); // push this before args
0517:
0518:                // Unload the arguments from the ConstructorArgs object
0519:                for (int i = 0; i < paramTypes.length; i++) {
0520:                    String type = paramTypes[i];
0521:                    String method = null;
0522:                    if (type.equals("Z"))
0523:                        method = "getBoolean";
0524:                    else if (type.equals("B"))
0525:                        method = "getByte";
0526:                    else if (type.equals("C"))
0527:                        method = "getChar";
0528:                    else if (type.equals("S"))
0529:                        method = "getShort";
0530:                    else if (type.equals("I"))
0531:                        method = "getInt";
0532:                    else if (type.equals("J"))
0533:                        method = "getLong";
0534:                    else if (type.equals("D"))
0535:                        method = "getDouble";
0536:                    else if (type.equals("F"))
0537:                        method = "getFloat";
0538:                    else
0539:                        method = "getObject";
0540:
0541:                    // invoke the iterator method on the ConstructorArgs
0542:                    cv.visitVarInsn(ALOAD, consArgsVar); // push the ConstructorArgs
0543:                    String className = "org/gjt/sp/jedit/bsh/ClassGeneratorUtil$ConstructorArgs";
0544:                    String retType;
0545:                    if (method.equals("getObject"))
0546:                        retType = OBJECT;
0547:                    else
0548:                        retType = type;
0549:                    cv.visitMethodInsn(INVOKEVIRTUAL, className, method, "()"
0550:                            + retType);
0551:                    // if it's an object type we must do a check cast
0552:                    if (method.equals("getObject"))
0553:                        cv
0554:                                .visitTypeInsn(CHECKCAST,
0555:                                        descriptorToClassName(type));
0556:                }
0557:
0558:                // invoke the constructor for this branch
0559:                String descriptor = getMethodDescriptor("V", paramTypes);
0560:                cv.visitMethodInsn(INVOKESPECIAL, targetClassName, "<init>",
0561:                        descriptor);
0562:                cv.visitJumpInsn(GOTO, endLabel);
0563:            }
0564:
0565:            static String getMethodDescriptor(String returnType,
0566:                    String[] paramTypes) {
0567:                StringBuffer sb = new StringBuffer("(");
0568:                for (int i = 0; i < paramTypes.length; i++)
0569:                    sb.append(paramTypes[i]);
0570:                sb.append(")" + returnType);
0571:                return sb.toString();
0572:            }
0573:
0574:            /**
0575:            	Generate a superclass method delegate accessor method.
0576:            	These methods are specially named methods which allow access to
0577:            	overridden methods of the superclass (which the Java reflection API
0578:            	normally does not allow).
0579:             */
0580:            // Maybe combine this with generateMethod()
0581:            static void generateSuperDelegateMethod(String super ClassName,
0582:                    String methodName, String returnType, String[] paramTypes,
0583:                    int modifiers, ClassWriter cw) {
0584:                String[] exceptions = null;
0585:
0586:                if (returnType == null) // map loose return to Object
0587:                    returnType = OBJECT;
0588:
0589:                String methodDescriptor = getMethodDescriptor(returnType,
0590:                        paramTypes);
0591:
0592:                // Add method body
0593:                CodeVisitor cv = cw.visitMethod(modifiers, "_bshSuper"
0594:                        + methodName, methodDescriptor, exceptions);
0595:
0596:                cv.visitVarInsn(ALOAD, 0);
0597:                // Push vars
0598:                int localVarIndex = 1;
0599:                for (int i = 0; i < paramTypes.length; ++i) {
0600:                    if (isPrimitive(paramTypes[i]))
0601:                        cv.visitVarInsn(ILOAD, localVarIndex);
0602:                    else
0603:                        cv.visitVarInsn(ALOAD, localVarIndex);
0604:                    localVarIndex += ((paramTypes[i].equals("D") || paramTypes[i]
0605:                            .equals("J")) ? 2 : 1);
0606:                }
0607:
0608:                cv.visitMethodInsn(INVOKESPECIAL, super ClassName, methodName,
0609:                        methodDescriptor);
0610:
0611:                generatePlainReturnCode(returnType, cv);
0612:
0613:                // Need to calculate this... just fudging here for now.
0614:                cv.visitMaxs(20, 20);
0615:            }
0616:
0617:            boolean classContainsMethod(Class clas, String methodName,
0618:                    String[] paramTypes) {
0619:                while (clas != null) {
0620:                    Method[] methods = clas.getDeclaredMethods();
0621:                    for (int i = 0; i < methods.length; i++) {
0622:                        if (methods[i].getName().equals(methodName)) {
0623:                            String[] methodParamTypes = getTypeDescriptors(methods[i]
0624:                                    .getParameterTypes());
0625:                            boolean found = true;
0626:                            for (int j = 0; j < methodParamTypes.length; j++) {
0627:                                if (!paramTypes[j].equals(methodParamTypes[j])) {
0628:                                    found = false;
0629:                                    break;
0630:                                }
0631:                            }
0632:                            if (found)
0633:                                return true;
0634:                        }
0635:                    }
0636:
0637:                    clas = clas.getSuperclass();
0638:                }
0639:
0640:                return false;
0641:            }
0642:
0643:            /**
0644:            	Generate return code for a normal bytecode
0645:             */
0646:            static void generatePlainReturnCode(String returnType,
0647:                    CodeVisitor cv) {
0648:                if (returnType.equals("V"))
0649:                    cv.visitInsn(RETURN);
0650:                else if (isPrimitive(returnType)) {
0651:                    int opcode = IRETURN;
0652:                    if (returnType.equals("D"))
0653:                        opcode = DRETURN;
0654:                    else if (returnType.equals("F"))
0655:                        opcode = FRETURN;
0656:                    else if (returnType.equals("J")) //long
0657:                        opcode = LRETURN;
0658:
0659:                    cv.visitInsn(opcode);
0660:                } else {
0661:                    cv.visitTypeInsn(CHECKCAST,
0662:                            descriptorToClassName(returnType));
0663:                    cv.visitInsn(ARETURN);
0664:                }
0665:            }
0666:
0667:            /**
0668:            	Generates the code to reify the arguments of the given method.
0669:            	For a method "int m (int i, String s)", this code is the bytecode
0670:            	corresponding to the "new Object[] { new bsh.Primitive(i), s }" 
0671:            	expression.
0672:
0673:             	@author Eric Bruneton
0674:             	@author Pat Niemeyer
0675:            	@param cv the code visitor to be used to generate the bytecode.
0676:            	@param isStatic the enclosing methods is static
0677:             */
0678:            public static void generateParameterReifierCode(
0679:                    String[] paramTypes, boolean isStatic, final CodeVisitor cv) {
0680:                cv.visitIntInsn(SIPUSH, paramTypes.length);
0681:                cv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
0682:                int localVarIndex = isStatic ? 0 : 1;
0683:                for (int i = 0; i < paramTypes.length; ++i) {
0684:                    String param = paramTypes[i];
0685:                    cv.visitInsn(DUP);
0686:                    cv.visitIntInsn(SIPUSH, i);
0687:                    if (isPrimitive(param)) {
0688:                        int opcode;
0689:                        if (param.equals("F")) {
0690:                            opcode = FLOAD;
0691:                        } else if (param.equals("D")) {
0692:                            opcode = DLOAD;
0693:                        } else if (param.equals("J")) {
0694:                            opcode = LLOAD;
0695:                        } else {
0696:                            opcode = ILOAD;
0697:                        }
0698:
0699:                        String type = "org/gjt/sp/jedit/bsh/Primitive";
0700:                        cv.visitTypeInsn(NEW, type);
0701:                        cv.visitInsn(DUP);
0702:                        cv.visitVarInsn(opcode, localVarIndex);
0703:                        String desc = param; // ok?
0704:                        cv.visitMethodInsn(INVOKESPECIAL, type, "<init>", "("
0705:                                + desc + ")V");
0706:                    } else {
0707:                        // Technically incorrect here - we need to wrap null values
0708:                        // as bsh.Primitive.NULL.  However the This.invokeMethod()
0709:                        // will do that much for us.
0710:                        // We need to generate a conditional here to test for null
0711:                        // and return Primitive.NULL
0712:                        cv.visitVarInsn(ALOAD, localVarIndex);
0713:                    }
0714:                    cv.visitInsn(AASTORE);
0715:                    localVarIndex += ((param.equals("D") || param.equals("J")) ? 2
0716:                            : 1);
0717:                }
0718:            }
0719:
0720:            /**
0721:            	Generates the code to unreify the result of the given method.  For a
0722:            	method "int m (int i, String s)", this code is the bytecode
0723:            	corresponding to the "((Integer)...).intValue()" expression.
0724:               
0725:            	@param cv the code visitor to be used to generate the bytecode.
0726:            	@author Eric Bruneton
0727:            	@author Pat Niemeyer
0728:             */
0729:            public static void generateReturnCode(String returnType,
0730:                    CodeVisitor cv) {
0731:                if (returnType.equals("V")) {
0732:                    cv.visitInsn(POP);
0733:                    cv.visitInsn(RETURN);
0734:                } else if (isPrimitive(returnType)) {
0735:                    int opcode = IRETURN;
0736:                    String type;
0737:                    String meth;
0738:                    if (returnType.equals("B")) {
0739:                        type = "java/lang/Byte";
0740:                        meth = "byteValue";
0741:                    } else if (returnType.equals("I")) {
0742:                        type = "java/lang/Integer";
0743:                        meth = "intValue";
0744:                    } else if (returnType.equals("Z")) {
0745:                        type = "java/lang/Boolean";
0746:                        meth = "booleanValue";
0747:                    } else if (returnType.equals("D")) {
0748:                        opcode = DRETURN;
0749:                        type = "java/lang/Double";
0750:                        meth = "doubleValue";
0751:                    } else if (returnType.equals("F")) {
0752:                        opcode = FRETURN;
0753:                        type = "java/lang/Float";
0754:                        meth = "floatValue";
0755:                    } else if (returnType.equals("J")) {
0756:                        opcode = LRETURN;
0757:                        type = "java/lang/Long";
0758:                        meth = "longValue";
0759:                    } else if (returnType.equals("C")) {
0760:                        type = "java/lang/Character";
0761:                        meth = "charValue";
0762:                    } else /*if (returnType.equals("S") )*/{
0763:                        type = "java/lang/Short";
0764:                        meth = "shortValue";
0765:                    }
0766:
0767:                    String desc = returnType;
0768:                    cv.visitTypeInsn(CHECKCAST, type); // type is correct here
0769:                    cv.visitMethodInsn(INVOKEVIRTUAL, type, meth, "()" + desc);
0770:                    cv.visitInsn(opcode);
0771:                } else {
0772:                    cv.visitTypeInsn(CHECKCAST,
0773:                            descriptorToClassName(returnType));
0774:                    cv.visitInsn(ARETURN);
0775:                }
0776:            }
0777:
0778:            /**
0779:            	Evaluate the arguments (if any) for the constructor specified by
0780:            	the constructor index.  Return the ConstructorArgs object which
0781:            	contains the actual arguments to the alternate constructor and also the
0782:            	index of that constructor for the constructor switch.
0783:
0784:            	@param consArgs the arguments to the constructor.  These are necessary in
0785:            	the evaluation of the alt constructor args.  e.g. Foo(a) { super(a); }
0786:            	@return the ConstructorArgs object containing a constructor selector
0787:            		and evaluated arguments for the alternate constructor
0788:             */
0789:            public static ConstructorArgs getConstructorArgs(
0790:                    String super ClassName, This classStaticThis,
0791:                    Object[] consArgs, int index) {
0792:                DelayedEvalBshMethod[] constructors;
0793:                try {
0794:                    constructors = (DelayedEvalBshMethod[]) classStaticThis
0795:                            .getNameSpace().getVariable(BSHCONSTRUCTORS);
0796:                } catch (Exception e) {
0797:                    throw new InterpreterError(
0798:                            "unable to get instance initializer: " + e);
0799:                }
0800:
0801:                if (index == DEFAULTCONSTRUCTOR) // auto-gen default constructor
0802:                    return ConstructorArgs.DEFAULT; // use default super constructor
0803:
0804:                DelayedEvalBshMethod constructor = constructors[index];
0805:
0806:                if (constructor.methodBody.jjtGetNumChildren() == 0)
0807:                    return ConstructorArgs.DEFAULT; // use default super constructor
0808:
0809:                // Determine if the constructor calls this() or super()
0810:                String altConstructor = null;
0811:                BSHArguments argsNode = null;
0812:                SimpleNode firstStatement = (SimpleNode) constructor.methodBody
0813:                        .jjtGetChild(0);
0814:                if (firstStatement instanceof  BSHPrimaryExpression)
0815:                    firstStatement = (SimpleNode) firstStatement.jjtGetChild(0);
0816:                if (firstStatement instanceof  BSHMethodInvocation) {
0817:                    BSHMethodInvocation methodNode = (BSHMethodInvocation) firstStatement;
0818:                    BSHAmbiguousName methodName = methodNode.getNameNode();
0819:                    if (methodName.text.equals("super")
0820:                            || methodName.text.equals("this")) {
0821:                        altConstructor = methodName.text;
0822:                        argsNode = methodNode.getArgsNode();
0823:                    }
0824:                }
0825:
0826:                if (altConstructor == null)
0827:                    return ConstructorArgs.DEFAULT; // use default super constructor
0828:
0829:                // Make a tmp namespace to hold the original constructor args for
0830:                // use in eval of the parameters node
0831:                NameSpace consArgsNameSpace = new NameSpace(classStaticThis
0832:                        .getNameSpace(), "consArgs");
0833:                String[] consArgNames = constructor.getParameterNames();
0834:                Class[] consArgTypes = constructor.getParameterTypes();
0835:                for (int i = 0; i < consArgs.length; i++) {
0836:                    try {
0837:                        consArgsNameSpace
0838:                                .setTypedVariable(consArgNames[i],
0839:                                        consArgTypes[i], consArgs[i], null/*modifiers*/);
0840:                    } catch (UtilEvalError e) {
0841:                        throw new InterpreterError(
0842:                                "err setting local cons arg:" + e);
0843:                    }
0844:                }
0845:
0846:                // evaluate the args
0847:
0848:                CallStack callstack = new CallStack();
0849:                callstack.push(consArgsNameSpace);
0850:                Object[] args = null;
0851:                Interpreter interpreter = classStaticThis.declaringInterpreter;
0852:
0853:                try {
0854:                    args = argsNode.getArguments(callstack, interpreter);
0855:                } catch (EvalError e) {
0856:                    throw new InterpreterError(
0857:                            "Error evaluating constructor args: " + e);
0858:                }
0859:
0860:                Class[] argTypes = Types.getTypes(args);
0861:                args = Primitive.unwrap(args);
0862:                Class super Class = interpreter.getClassManager().classForName(
0863:                        super ClassName);
0864:                if (super Class == null)
0865:                    throw new InterpreterError("can't find superclass: "
0866:                            + super ClassName);
0867:                Constructor[] super Cons = super Class.getDeclaredConstructors();
0868:
0869:                // find the matching super() constructor for the args
0870:                if (altConstructor.equals("super")) {
0871:                    int i = Reflect.findMostSpecificConstructorIndex(argTypes,
0872:                            super Cons);
0873:                    if (i == -1)
0874:                        throw new InterpreterError(
0875:                                "can't find constructor for args!");
0876:                    return new ConstructorArgs(i, args);
0877:                }
0878:
0879:                // find the matching this() constructor for the args
0880:                Class[][] candidates = new Class[constructors.length][];
0881:                for (int i = 0; i < candidates.length; i++)
0882:                    candidates[i] = constructors[i].getParameterTypes();
0883:                int i = Reflect.findMostSpecificSignature(argTypes, candidates);
0884:                if (i == -1)
0885:                    throw new InterpreterError(
0886:                            "can't find constructor for args 2!");
0887:                // this() constructors come after super constructors in the table
0888:
0889:                int selector = i + super Cons.length;
0890:                int ourSelector = index + super Cons.length;
0891:
0892:                // Are we choosing ourselves recursively through a this() reference?
0893:                if (selector == ourSelector)
0894:                    throw new InterpreterError("Recusive constructor call.");
0895:
0896:                return new ConstructorArgs(selector, args);
0897:            }
0898:
0899:            /**
0900:            	Initialize an instance of the class.
0901:            	This method is called from the generated class constructor to evaluate
0902:            	the instance initializer and scripted constructor in the instance
0903:            	namespace.
0904:             */
0905:            public static void initInstance(Object instance, String className,
0906:                    Object[] args) {
0907:                Class[] sig = Types.getTypes(args);
0908:                CallStack callstack = new CallStack();
0909:                Interpreter interpreter;
0910:                NameSpace instanceNameSpace;
0911:
0912:                // check to see if the instance has already been initialized
0913:                // (the case if using a this() alternate constuctor)
0914:                This instanceThis = getClassInstanceThis(instance, className);
0915:
0916:                // XXX clean up this conditional
0917:                if (instanceThis == null) {
0918:                    // Create the instance 'This' namespace, set it on the object
0919:                    // instance and invoke the instance initializer
0920:
0921:                    // Get the static This reference from the proto-instance
0922:                    This classStaticThis = getClassStaticThis(instance
0923:                            .getClass(), className);
0924:                    interpreter = classStaticThis.declaringInterpreter;
0925:
0926:                    // Get the instance initializer block from the static This 
0927:                    BSHBlock instanceInitBlock;
0928:                    try {
0929:                        instanceInitBlock = (BSHBlock) classStaticThis
0930:                                .getNameSpace().getVariable(BSHINIT);
0931:                    } catch (Exception e) {
0932:                        throw new InterpreterError(
0933:                                "unable to get instance initializer: " + e);
0934:                    }
0935:
0936:                    // Create the instance namespace
0937:                    instanceNameSpace = new NameSpace(classStaticThis
0938:                            .getNameSpace(), className);
0939:                    instanceNameSpace.isClass = true;
0940:
0941:                    // Set the instance This reference on the instance
0942:                    instanceThis = instanceNameSpace.getThis(interpreter);
0943:                    try {
0944:                        LHS lhs = Reflect.getLHSObjectField(instance, BSHTHIS
0945:                                + className);
0946:                        lhs.assign(instanceThis, false/*strict*/);
0947:                    } catch (Exception e) {
0948:                        throw new InterpreterError("Error in class gen setup: "
0949:                                + e);
0950:                    }
0951:
0952:                    // Give the instance space its object import
0953:                    instanceNameSpace.setClassInstance(instance);
0954:
0955:                    // should use try/finally here to pop ns
0956:                    callstack.push(instanceNameSpace);
0957:
0958:                    // evaluate the instance portion of the block in it
0959:                    try { // Evaluate the initializer block
0960:                        instanceInitBlock
0961:                                .evalBlock(
0962:                                        callstack,
0963:                                        interpreter,
0964:                                        true/*override*/,
0965:                                        ClassGeneratorImpl.ClassNodeFilter.CLASSINSTANCE);
0966:                    } catch (Exception e) {
0967:                        throw new InterpreterError(
0968:                                "Error in class initialization: " + e);
0969:                    }
0970:
0971:                    callstack.pop();
0972:
0973:                } else {
0974:                    // The object instance has already been initialzed by another
0975:                    // constructor.  Fall through to invoke the constructor body below.
0976:                    interpreter = instanceThis.declaringInterpreter;
0977:                    instanceNameSpace = instanceThis.getNameSpace();
0978:                }
0979:
0980:                // invoke the constructor method from the instanceThis 
0981:
0982:                String constructorName = getBaseName(className);
0983:                try {
0984:                    // Find the constructor (now in the instance namespace)
0985:                    BshMethod constructor = instanceNameSpace.getMethod(
0986:                            constructorName, sig, true/*declaredOnly*/);
0987:
0988:                    // if args, we must have constructor
0989:                    if (args.length > 0 && constructor == null)
0990:                        throw new InterpreterError("Can't find constructor: "
0991:                                + className);
0992:
0993:                    // Evaluate the constructor
0994:                    if (constructor != null)
0995:                        constructor
0996:                                .invoke(args, interpreter, callstack,
0997:                                        null/*callerInfo*/, false/*overrideNameSpace*/);
0998:                } catch (Exception e) {
0999:                    if (e instanceof  TargetError)
1000:                        e = (Exception) ((TargetError) e).getTarget();
1001:                    if (e instanceof  InvocationTargetException)
1002:                        e = (Exception) ((InvocationTargetException) e)
1003:                                .getTargetException();
1004:                    e.printStackTrace(System.err);
1005:                    throw new InterpreterError(
1006:                            "Error in class initialization: " + e);
1007:                }
1008:            }
1009:
1010:            /**
1011:            	Get the static bsh namespace field from the class.
1012:            	@param className may be the name of clas itself or a superclass of clas.
1013:             */
1014:            static This getClassStaticThis(Class clas, String className) {
1015:                try {
1016:                    return (This) Reflect.getStaticFieldValue(clas, BSHSTATIC
1017:                            + className);
1018:                } catch (Exception e) {
1019:                    throw new InterpreterError(
1020:                            "Unable to get class static space: " + e);
1021:                }
1022:            }
1023:
1024:            /**
1025:            	Get the instance bsh namespace field from the object instance.
1026:            	@return the class instance This object or null if the object has not
1027:            	been initialized.
1028:             */
1029:            static This getClassInstanceThis(Object instance, String className) {
1030:                try {
1031:                    Object o = Reflect.getObjectFieldValue(instance, BSHTHIS
1032:                            + className);
1033:                    return (This) Primitive.unwrap(o); // unwrap Primitive.Null to null
1034:                } catch (Exception e) {
1035:                    throw new InterpreterError(
1036:                            "Generated class: Error getting This" + e);
1037:                }
1038:            }
1039:
1040:            /**
1041:            	Does the type descriptor string describe a primitive type?
1042:             */
1043:            private static boolean isPrimitive(String typeDescriptor) {
1044:                return typeDescriptor.length() == 1; // right?
1045:            }
1046:
1047:            static String[] getTypeDescriptors(Class[] cparams) {
1048:                String[] sa = new String[cparams.length];
1049:                for (int i = 0; i < sa.length; i++)
1050:                    sa[i] = BSHType.getTypeDescriptor(cparams[i]);
1051:                return sa;
1052:            }
1053:
1054:            /**
1055:            	If a non-array object type, remove the prefix "L" and suffix ";".
1056:             */
1057:            // Can this be factored out...?  
1058:            // Should be be adding the L...; here instead?
1059:            private static String descriptorToClassName(String s) {
1060:                if (s.startsWith("[") || !s.startsWith("L"))
1061:                    return s;
1062:                return s.substring(1, s.length() - 1);
1063:            }
1064:
1065:            private static String getBaseName(String className) {
1066:                int i = className.indexOf("$");
1067:                if (i == -1)
1068:                    return className;
1069:
1070:                return className.substring(i + 1);
1071:            }
1072:
1073:            /**
1074:            	A ConstructorArgs object holds evaluated arguments for a constructor
1075:            	call as well as the index of a possible alternate selector to invoke.
1076:            	This object is used by the constructor switch.
1077:             	@see #generateConstructor( int , String [] , int , ClassWriter )
1078:             */
1079:            public static class ConstructorArgs {
1080:                /** A ConstructorArgs which calls the default constructor */
1081:                public static ConstructorArgs DEFAULT = new ConstructorArgs();
1082:
1083:                public int selector = DEFAULTCONSTRUCTOR;
1084:                Object[] args;
1085:                int arg = 0;
1086:
1087:                /**
1088:                	The index of the constructor to call.
1089:                 */
1090:
1091:                ConstructorArgs() {
1092:                }
1093:
1094:                ConstructorArgs(int selector, Object[] args) {
1095:                    this .selector = selector;
1096:                    this .args = args;
1097:                }
1098:
1099:                Object next() {
1100:                    return args[arg++];
1101:                }
1102:
1103:                public boolean getBoolean() {
1104:                    return ((Boolean) next()).booleanValue();
1105:                }
1106:
1107:                public byte getByte() {
1108:                    return ((Byte) next()).byteValue();
1109:                }
1110:
1111:                public char getChar() {
1112:                    return ((Character) next()).charValue();
1113:                }
1114:
1115:                public short getShort() {
1116:                    return ((Short) next()).shortValue();
1117:                }
1118:
1119:                public int getInt() {
1120:                    return ((Integer) next()).intValue();
1121:                }
1122:
1123:                public long getLong() {
1124:                    return ((Long) next()).longValue();
1125:                }
1126:
1127:                public double getDouble() {
1128:                    return ((Double) next()).doubleValue();
1129:                }
1130:
1131:                public float getFloat() {
1132:                    return ((Float) next()).floatValue();
1133:                }
1134:
1135:                public Object getObject() {
1136:                    return next();
1137:                }
1138:            }
1139:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.