Source Code Cross Referenced for EasyBeansInvocationContextGenerator.java in  » J2EE » ow2-easybeans » org » ow2 » easybeans » enhancer » interceptors » 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 » J2EE » ow2 easybeans » org.ow2.easybeans.enhancer.interceptors 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         * EasyBeans
0003:         * Copyright (C) 2006 Bull S.A.S.
0004:         * Contact: easybeans@ow2.org
0005:         *
0006:         * This library is free software; you can redistribute it and/or
0007:         * modify it under the terms of the GNU Lesser General Public
0008:         * License as published by the Free Software Foundation; either
0009:         * version 2.1 of the License, or any later version.
0010:         *
0011:         * This library is distributed in the hope that it will be useful,
0012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014:         * Lesser General Public License for more details.
0015:         *
0016:         * You should have received a copy of the GNU Lesser General Public
0017:         * License along with this library; if not, write to the Free Software
0018:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
0019:         * USA
0020:         *
0021:         * --------------------------------------------------------------------------
0022:         * $Id: EasyBeansInvocationContextGenerator.java 2057 2007-11-21 15:35:32Z benoitf $
0023:         * --------------------------------------------------------------------------
0024:         */package org.ow2.easybeans.enhancer.interceptors;
0025:
0026:        import static org.ow2.easybeans.deployment.annotations.InterceptorType.AROUND_INVOKE;
0027:
0028:        import java.io.File;
0029:        import java.io.FileOutputStream;
0030:        import java.util.ArrayList;
0031:        import java.util.List;
0032:
0033:        import org.ow2.easybeans.asm.ClassWriter;
0034:        import org.ow2.easybeans.asm.Label;
0035:        import org.ow2.easybeans.asm.MethodVisitor;
0036:        import org.ow2.easybeans.asm.Type;
0037:        import org.ow2.easybeans.api.EasyBeansInvocationContext;
0038:        import org.ow2.easybeans.deployment.annotations.InterceptorType;
0039:        import org.ow2.easybeans.deployment.annotations.JClassInterceptor;
0040:        import org.ow2.easybeans.deployment.annotations.JMethod;
0041:        import org.ow2.easybeans.deployment.annotations.metadata.ClassAnnotationMetadata;
0042:        import org.ow2.easybeans.deployment.annotations.metadata.EjbJarAnnotationMetadata;
0043:        import org.ow2.easybeans.deployment.annotations.metadata.MethodAnnotationMetadata;
0044:        import org.ow2.easybeans.enhancer.CommonClassGenerator;
0045:        import org.ow2.easybeans.enhancer.lib.MethodRenamer;
0046:        import org.ow2.util.log.Log;
0047:        import org.ow2.util.log.LogFactory;
0048:
0049:        /**
0050:         * Generates the implementation of
0051:         * {@link org.ow2.easybeans.api.EasyBeansInvocationContext} interface for a
0052:         * given business method.
0053:         * @author Florent Benoit
0054:         */
0055:        public class EasyBeansInvocationContextGenerator extends
0056:                CommonClassGenerator {
0057:
0058:            /**
0059:             * Prefix used as package name for generated classes
0060:             * (EasyBeansInvocationContext* impl).
0061:             */
0062:            public static final String PACKAGE_NAME_PREFIX = "org.ow2.easybeans.gen.invocationcontext.";
0063:
0064:            /**
0065:             * Name of the attributes will start with this name with an index as suffix,
0066:             * ie : arg0, arg1, arg2,...
0067:             */
0068:            public static final String ARG = "arg";
0069:
0070:            /**
0071:             * Name of the interceptor attributes will start with this name with an index as suffix,
0072:             * ie : interceptor0, interceptor1, interceptor2,...
0073:             */
0074:            public static final String INTERCEPTOR = "interceptor";
0075:
0076:            /**
0077:             * Suffix for generated classes EasyBeansInvocationContextImpl.
0078:             */
0079:            public static final String SUFFIX_CLASS = "EasyBeansInvocationContextImpl";
0080:
0081:            /**
0082:             * Interface of this invocation context.
0083:             */
0084:            public static final String[] INTERFACES = new String[] { "org/ow2/easybeans/api/EasyBeansInvocationContext" };
0085:
0086:            /**
0087:             * Exceptions of the proceed method.
0088:             */
0089:            public static final String[] PROCEED_EXCEPTIONS = new String[] { Type
0090:                    .getInternalName(Exception.class) };
0091:
0092:            /**
0093:             * EasyBeansInvocationContext interface.
0094:             */
0095:            public static final String EASYBEANS_INVOCATION_CONTEXT = Type
0096:                    .getDescriptor(EasyBeansInvocationContext.class);
0097:
0098:            /**
0099:             * Logger.
0100:             */
0101:            private static Log logger = LogFactory
0102:                    .getLog(EasyBeansInvocationContextGenerator.class);
0103:
0104:            /**
0105:             * Metadata available for a class (extracted from method metadat object.
0106:             * (parent))
0107:             */
0108:            private ClassAnnotationMetadata classAnnotationMetadata = null;
0109:
0110:            /**
0111:             * Package name which is used for generating class.
0112:             */
0113:            private String packageName = null;
0114:
0115:            /**
0116:             * Full class name of the generated class (prefixed by packageName).
0117:             */
0118:            private String generatedClassName = null;
0119:
0120:            /**
0121:             * JMethod object which correspond to the current method metadata which is
0122:             * used.
0123:             */
0124:            private JMethod jMethod = null;
0125:
0126:            /**
0127:             * Metadata available for a method (given as constructor arg).
0128:             */
0129:            private MethodAnnotationMetadata methodAnnotationMetadata;
0130:
0131:            /**
0132:             * Bean class descriptor.
0133:             */
0134:            private String beanClassDesc = null;
0135:
0136:            /**
0137:             * Bean class name.
0138:             */
0139:            private String beanClassName = null;
0140:
0141:            /**
0142:             * Bean class Type (ASM).
0143:             */
0144:            private Type beanClassType = null;
0145:
0146:            /**
0147:             * ASM descriptor of the generated constructor.
0148:             */
0149:            private String constructorDesc = null;
0150:
0151:            /**
0152:             * ASM Type arguments of the method.
0153:             */
0154:            private Type[] methodArgsType = null;
0155:
0156:            /**
0157:             * List of interceptors.
0158:             */
0159:            private List<JClassInterceptor> allInterceptors = null;
0160:
0161:            /**
0162:             * Type of the interceptor (AroundInvoke, PostConstruct, etc).
0163:             */
0164:            private InterceptorType interceptorType = null;
0165:
0166:            /**
0167:             * Name of the interceptor manager class.
0168:             */
0169:            private String interceptorManagerClassName = null;
0170:
0171:            /**
0172:             * Suffix for InterceptorManager.
0173:             */
0174:            public static final String SUFFIX_INTERCEPTOR_MANAGER = "InterceptorManager";
0175:
0176:            /**
0177:             * Constructor It will generate a class for the given method metadata.
0178:             * @param methodAnnotationMetadata method meta data
0179:             * @param interceptorType the type of invocationContext to generate (AroundInvoke, PostConstruct, etc)
0180:             */
0181:            public EasyBeansInvocationContextGenerator(
0182:                    final MethodAnnotationMetadata methodAnnotationMetadata,
0183:                    final InterceptorType interceptorType) {
0184:                super (new ClassWriter(ClassWriter.COMPUTE_MAXS));
0185:                this .methodAnnotationMetadata = methodAnnotationMetadata;
0186:                this .classAnnotationMetadata = methodAnnotationMetadata
0187:                        .getClassAnnotationMetadata();
0188:                this .jMethod = methodAnnotationMetadata.getJMethod();
0189:
0190:                // package name is prefixed
0191:                packageName = PACKAGE_NAME_PREFIX
0192:                        + classAnnotationMetadata.getClassName();
0193:
0194:                // Type of the generated interceptor
0195:                this .interceptorType = interceptorType;
0196:
0197:                this .interceptorManagerClassName = classAnnotationMetadata
0198:                        .getClassName()
0199:                        + SUFFIX_INTERCEPTOR_MANAGER;
0200:
0201:                // Name of the class that is generated
0202:                generatedClassName = packageName.replace(".", "/") + "/"
0203:                        + SUFFIX_CLASS;
0204:                generatedClassName += methodAnnotationMetadata.getJMethod()
0205:                        .getName()
0206:                        + interceptorType.name().replace("_", "");
0207:                // Also, as two methods with the same name but different parameters will produce the same class name,
0208:                // add the hashcode of the ASM descriptor.
0209:                generatedClassName += methodAnnotationMetadata.getJMethod()
0210:                        .getDescriptor().hashCode();
0211:
0212:                // useful constants
0213:                beanClassDesc = encodeClassDesc(classAnnotationMetadata
0214:                        .getClassName());
0215:                beanClassName = classAnnotationMetadata.getClassName();
0216:                beanClassType = Type.getType(beanClassDesc);
0217:
0218:                // type arguments of the method
0219:                methodArgsType = Type.getArgumentTypes(jMethod.getDescriptor());
0220:
0221:                // build a list of all interceptors (first = global then method then users)
0222:                allInterceptors = new ArrayList<JClassInterceptor>();
0223:                if (classAnnotationMetadata.getGlobalEasyBeansInterceptors() != null) {
0224:                    for (JClassInterceptor interceptor : classAnnotationMetadata
0225:                            .getGlobalEasyBeansInterceptors()) {
0226:                        allInterceptors.add(interceptor);
0227:                    }
0228:                }
0229:
0230:                // global interceptor on the method (remove annotation for example)
0231:                if (methodAnnotationMetadata.getGlobalEasyBeansInterceptors() != null) {
0232:                    for (JClassInterceptor interceptor : methodAnnotationMetadata
0233:                            .getGlobalEasyBeansInterceptors()) {
0234:                        allInterceptors.add(interceptor);
0235:                    }
0236:                }
0237:
0238:                // Get interceptors on method metadata (tx, security, etc)
0239:                if (methodAnnotationMetadata.getInterceptors() != null) {
0240:                    for (JClassInterceptor interceptor : methodAnnotationMetadata
0241:                            .getInterceptors()) {
0242:                        allInterceptors.add(interceptor);
0243:                    }
0244:                }
0245:
0246:                // Default interceptors (if they are not excluded) and that the interceptors haven't been ordered
0247:                EjbJarAnnotationMetadata ejbJarAnnotationMetadata = classAnnotationMetadata
0248:                        .getEjbJarAnnotationMetadata();
0249:                if (!classAnnotationMetadata.isOrderedInterceptors()
0250:                        && ejbJarAnnotationMetadata.getDefaultInterceptors() != null
0251:                        && !classAnnotationMetadata
0252:                                .isExcludedDefaultInterceptors()) {
0253:                    // Not excluded at method level too
0254:                    if (!methodAnnotationMetadata
0255:                            .isExcludedDefaultInterceptors()) {
0256:                        List<JClassInterceptor> defaultInterceptorslist = ejbJarAnnotationMetadata
0257:                                .getDefaultInterceptors().get(interceptorType);
0258:                        if (defaultInterceptorslist != null) {
0259:                            for (JClassInterceptor interceptor : defaultInterceptorslist) {
0260:                                allInterceptors.add(interceptor);
0261:                            }
0262:                        }
0263:                    }
0264:                }
0265:
0266:                // interceptors in the interceptor classes (user) + not excluded
0267:                if (classAnnotationMetadata
0268:                        .getExternalUserEasyBeansInterceptors() != null
0269:                        && !methodAnnotationMetadata
0270:                                .isExcludedClassInterceptors()) {
0271:                    List<JClassInterceptor> userInterceptorslist = classAnnotationMetadata
0272:                            .getExternalUserEasyBeansInterceptors().get(
0273:                                    interceptorType);
0274:                    if (userInterceptorslist != null) {
0275:                        for (JClassInterceptor interceptor : userInterceptorslist) {
0276:                            allInterceptors.add(interceptor);
0277:                        }
0278:                    }
0279:                }
0280:
0281:                // interceptors on the method (user)
0282:                if (methodAnnotationMetadata.getUserEasyBeansInterceptors() != null) {
0283:                    List<JClassInterceptor> userInterceptorslist = methodAnnotationMetadata
0284:                            .getUserEasyBeansInterceptors()
0285:                            .get(interceptorType);
0286:                    if (userInterceptorslist != null) {
0287:                        for (JClassInterceptor interceptor : userInterceptorslist) {
0288:                            allInterceptors.add(interceptor);
0289:                        }
0290:                    }
0291:                }
0292:
0293:                // interceptors on the bean class (user) + not excluded  and that the interceptors haven't been ordered
0294:                if (!classAnnotationMetadata.isOrderedInterceptors()
0295:                        && classAnnotationMetadata
0296:                                .getInternalUserEasyBeansInterceptors() != null
0297:                        && !methodAnnotationMetadata
0298:                                .isExcludedClassInterceptors()) {
0299:                    List<JClassInterceptor> userInterceptorslist = classAnnotationMetadata
0300:                            .getInternalUserEasyBeansInterceptors().get(
0301:                                    interceptorType);
0302:                    if (userInterceptorslist != null) {
0303:                        for (JClassInterceptor interceptor : userInterceptorslist) {
0304:                            allInterceptors.add(interceptor);
0305:                        }
0306:                    }
0307:                }
0308:            }
0309:
0310:            /**
0311:             * Generates the class. It call sub methods for being more clear for read
0312:             * the code
0313:             */
0314:            public void generate() {
0315:                if (logger.isDebugEnabled()) {
0316:                    logger.debug("Generating InvocationContext for Method "
0317:                            + jMethod + " of class " + beanClassName);
0318:                }
0319:
0320:                addClassDeclaration();
0321:                addAttributes();
0322:                addConstructor();
0323:                addStaticClassInitialization();
0324:                addMethods();
0325:                endClass();
0326:
0327:                if (logger.isDebugEnabled()) {
0328:                    String fName = System.getProperty("java.io.tmpdir")
0329:                            + File.separator
0330:                            + generatedClassName.replace("/", ".") + ".class";
0331:                    logger.debug("Writing Invocation context of method "
0332:                            + methodAnnotationMetadata.getMethodName() + " to "
0333:                            + fName);
0334:                    try {
0335:                        FileOutputStream fos = new FileOutputStream(fName);
0336:                        fos.write(getCW().toByteArray());
0337:                        fos.close();
0338:                    } catch (Exception e) {
0339:                        throw new RuntimeException(e);
0340:                    }
0341:                }
0342:            }
0343:
0344:            /**
0345:             * @return the bytecode of the generated class.
0346:             */
0347:            public byte[] getBytes() {
0348:                return getCW().toByteArray();
0349:            }
0350:
0351:            /**
0352:             * Creates the declaration of the class with the given interfaces.
0353:             */
0354:            private void addClassDeclaration() {
0355:                // create class
0356:                getCW().visit(GENERATED_CLASS_VERSION, ACC_PUBLIC + ACC_SUPER,
0357:                        generatedClassName, null, "java/lang/Object",
0358:                        INTERFACES);
0359:            }
0360:
0361:            /**
0362:             * Create the constructor which should look like :
0363:             * <ul>
0364:             * <li> First arg = bean instance</li>
0365:             * <li> Last args are arguments of the method (if any)</li>
0366:             * </ul>
0367:             * <br>
0368:             *
0369:             * <pre>
0370:             *  public CtxImpl(Bean bean, int i, Long k, ...) {
0371:             *      this.bean = bean;
0372:             *      this.factory = bean.getEasyBeansFactory();
0373:             *      this.interceptorManager = bean.getEasyBeansInterceptorManager();
0374:             *      this.i = i;
0375:             *      this.k = k;
0376:             *      this... = ...
0377:             *      this.interceptor0 = interceptorManager.getXXXInterceptor();
0378:             *      this.interceptor1 = interceptorManager....();
0379:             *  }
0380:             * </pre>
0381:             */
0382:            private void addConstructor() {
0383:
0384:                // First, get the desc of the intercepted method
0385:                String argsMethodDesc = "";
0386:                for (Type t : methodArgsType) {
0387:                    argsMethodDesc += t.getDescriptor();
0388:                }
0389:
0390:                // Add the bean class type before arguments
0391:                // public CtxImpl(Bean bean, <args of the method>)
0392:                // it is a void type for return type
0393:                constructorDesc = "(" + beanClassDesc + argsMethodDesc + ")V";
0394:
0395:                // Generate constructor
0396:                MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "<init>",
0397:                        constructorDesc, null, null);
0398:                mv.visitCode();
0399:
0400:                // Call super constructor
0401:                int arg = 1;
0402:                mv.visitVarInsn(ALOAD, 0);
0403:                mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>",
0404:                        "()V");
0405:
0406:                // Now, set the attributes of the class
0407:                // this.bean = bean
0408:                int argBean = arg++;
0409:                mv.visitVarInsn(ALOAD, 0);
0410:                mv.visitVarInsn(ALOAD, argBean);
0411:                mv
0412:                        .visitFieldInsn(PUTFIELD, generatedClassName, "bean",
0413:                                encodeClassDesc(classAnnotationMetadata
0414:                                        .getClassName()));
0415:
0416:                // this.factory = bean.getEasyBeansFactory();
0417:                mv.visitVarInsn(ALOAD, 0);
0418:                mv.visitVarInsn(ALOAD, argBean);
0419:                mv.visitMethodInsn(INVOKEVIRTUAL, classAnnotationMetadata
0420:                        .getClassName(), "getEasyBeansFactory",
0421:                        "()Lorg/ow2/easybeans/api/Factory;");
0422:                mv.visitFieldInsn(PUTFIELD, generatedClassName, "factory",
0423:                        "Lorg/ow2/easybeans/api/Factory;");
0424:
0425:                // this.interceptorManager = bean.getEasyBeansInterceptorManager();
0426:                mv.visitVarInsn(ALOAD, 0);
0427:                mv.visitVarInsn(ALOAD, argBean);
0428:                mv.visitMethodInsn(INVOKEVIRTUAL, classAnnotationMetadata
0429:                        .getClassName(), "getEasyBeansInterceptorManager", "()"
0430:                        + encodeClassDesc(interceptorManagerClassName));
0431:                mv.visitFieldInsn(PUTFIELD, generatedClassName,
0432:                        "interceptorManager",
0433:                        encodeClassDesc(interceptorManagerClassName));
0434:
0435:                // And now, the attributes corresponding to the arguments of the method
0436:                // it will do : this.ARG0 = xxx;
0437:                int methodArg = 0;
0438:                for (Type type : methodArgsType) {
0439:                    mv.visitVarInsn(ALOAD, 0);
0440:                    int opCode = putFieldLoadOpCode(type.getSort());
0441:                    mv.visitVarInsn(opCode, arg++);
0442:                    mv.visitFieldInsn(PUTFIELD, generatedClassName, ARG
0443:                            + (methodArg++), type.getDescriptor());
0444:                    // Double and Long are special parameters
0445:                    if (opCode == LLOAD || opCode == DLOAD) {
0446:                        arg++;
0447:                    }
0448:                }
0449:
0450:                // this.interceptorXX = interceptorManager.getXXXInterceptor();
0451:                int index = 0;
0452:                for (JClassInterceptor interceptor : allInterceptors) {
0453:                    // Only if interceptor is not in the bean class
0454:                    if (!interceptor.getClassName().equals(beanClassName)) {
0455:                        mv.visitVarInsn(ALOAD, 0);
0456:                        mv.visitVarInsn(ALOAD, 0);
0457:                        mv.visitFieldInsn(GETFIELD, generatedClassName,
0458:                                "interceptorManager",
0459:                                encodeClassDesc(interceptorManagerClassName));
0460:                        String getterName = "get"
0461:                                + interceptor.getClassName().replace("/", "");
0462:                        mv.visitMethodInsn(INVOKEVIRTUAL,
0463:                                interceptorManagerClassName, getterName, "()"
0464:                                        + encodeClassDesc(interceptor
0465:                                                .getClassName()));
0466:                        mv.visitFieldInsn(PUTFIELD, generatedClassName,
0467:                                INTERCEPTOR + (index++),
0468:                                encodeClassDesc(interceptor.getClassName()));
0469:                    }
0470:                }
0471:
0472:                // need to add return instruction
0473:                mv.visitInsn(RETURN);
0474:
0475:                // visit max compute automatically
0476:                mv.visitMaxs(0, 0);
0477:                mv.visitEnd();
0478:
0479:            }
0480:
0481:            /**
0482:             * Called when the generated class is done.
0483:             */
0484:            private void endClass() {
0485:                getCW().visitEnd();
0486:            }
0487:
0488:            /**
0489:             * Add attributes of the class in two steps.
0490:             * <ul>
0491:             * <li>InvocationContext interface</li>
0492:             * <li>EasyBeansInvocationContext interface</li>
0493:             * </ul>
0494:             */
0495:            private void addAttributes() {
0496:                addInvocationContextAttributes();
0497:                addEasyBeansInvocationContextAttributes();
0498:
0499:            }
0500:
0501:            /**
0502:             * Add methods of the class in two steps.
0503:             * <ul>
0504:             * <li>InvocationContext interface</li>
0505:             * <li>EasyBeansInvocationContext interface</li>
0506:             * <li>toString() method</li>
0507:             * </ul>
0508:             */
0509:            private void addMethods() {
0510:                addInvocationContextMethods();
0511:                addEasyBeansInvocationContextMethods();
0512:                addToString();
0513:
0514:            }
0515:
0516:            /**
0517:             * Add methods for InvocationContext interface.
0518:             */
0519:            private void addInvocationContextMethods() {
0520:                addInvocationContextGetParameters();
0521:                addInvocationContextSetParameters();
0522:                addInvocationContextGetMethod();
0523:                addInvocationContextGetTarget();
0524:                addInvocationContextProceed();
0525:                addInvocationContextGetContextData();
0526:            }
0527:
0528:            /**
0529:             * Add methods for EasyBeansInvocationContext interface.
0530:             */
0531:            private void addEasyBeansInvocationContextMethods() {
0532:
0533:                addEasyBeansInvocationContextGetFactory();
0534:
0535:            }
0536:
0537:            /**
0538:             * Adds the getTarget method of InvocationContext interface.<br>
0539:             * It adds :
0540:             *
0541:             * <pre>
0542:             * public Object getTarget() {
0543:             *   return bean;
0544:             * }
0545:             * </pre>
0546:             */
0547:            private void addInvocationContextGetTarget() {
0548:                MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "getTarget",
0549:                        "()Ljava/lang/Object;", null, null);
0550:                mv.visitCode();
0551:                mv.visitVarInsn(ALOAD, 0);
0552:                mv.visitFieldInsn(GETFIELD, generatedClassName, "bean",
0553:                        beanClassDesc);
0554:                mv.visitInsn(ARETURN);
0555:                mv.visitMaxs(0, 0);
0556:                mv.visitEnd();
0557:            }
0558:
0559:            /**
0560:             * Adds the getFactory method of EasyBeansInvocationContext interface.<br>
0561:             * It adds :
0562:             *
0563:             * <pre>
0564:             * public Factory getFactory() {
0565:             *     return this.factory;
0566:             * }
0567:             * </pre>
0568:             */
0569:            private void addEasyBeansInvocationContextGetFactory() {
0570:                MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC,
0571:                        "getFactory", "()" + EASYBEANS_FACTORY, null, null);
0572:                mv.visitCode();
0573:                mv.visitVarInsn(ALOAD, 0);
0574:                mv.visitFieldInsn(GETFIELD, generatedClassName, "factory",
0575:                        EASYBEANS_FACTORY);
0576:                mv.visitInsn(ARETURN);
0577:                mv.visitMaxs(0, 0);
0578:                mv.visitEnd();
0579:
0580:            }
0581:
0582:            /**
0583:             * Adds the getMethod() method of InvocationContext interface.<br>
0584:             * It adds :
0585:             *
0586:             * <pre>
0587:             * public Method getMethod() {
0588:             *   if (method == null) {
0589:             *     try {
0590:             *       method = MyEjb.class.getMethod("methodName", new Class[] {xxx, yyy, ...});
0591:             *     } catch (SecurityException e) {
0592:             *       throw new RuntimeException("Cannot...", e);
0593:             *     } catch (NoSuchMethodException e) {
0594:             *       throw new RuntimeException("Cannot...", e);
0595:             *     }
0596:             *   }
0597:             *   return method;
0598:             * }
0599:             * </pre>
0600:             */
0601:            private void addInvocationContextGetMethod() {
0602:                MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "getMethod",
0603:                        "()" + JAVA_LANG_REFLECT_METHOD, null, null);
0604:                mv.visitCode();
0605:
0606:                // only for around invoke type, lifecycle interceptor should return null
0607:                if (interceptorType == AROUND_INVOKE) {
0608:
0609:                    // if (method == null) {
0610:                    mv.visitFieldInsn(GETSTATIC, generatedClassName, "method",
0611:                            JAVA_LANG_REFLECT_METHOD);
0612:                    // go to this label if not null
0613:                    Label notNullParametersLabel = new Label();
0614:                    mv.visitJumpInsn(IFNONNULL, notNullParametersLabel);
0615:
0616:                    // Start of the try block
0617:                    Label tryLabel = new Label();
0618:                    mv.visitLabel(tryLabel);
0619:
0620:                    // call a method on the bean class
0621:                    mv.visitLdcInsn(beanClassType);
0622:                    // name of the method which is searched
0623:                    mv.visitLdcInsn(jMethod.getName());
0624:
0625:                    // build an array of java.lang.Class with the size of args of the method
0626:                    mv.visitIntInsn(BIPUSH, methodArgsType.length);
0627:                    mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
0628:                    int argCount = 0;
0629:                    for (Type type : methodArgsType) {
0630:                        mv.visitInsn(DUP);
0631:                        mv.visitIntInsn(BIPUSH, argCount);
0632:                        visitClassType(type, mv);
0633:                        mv.visitInsn(AASTORE);
0634:                        argCount++;
0635:                    }
0636:
0637:                    // signature of the getMethod() method on java.lang.Class class
0638:                    mv
0639:                            .visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class",
0640:                                    "getMethod",
0641:                                    "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;");
0642:
0643:                    // set the result : method = ...
0644:                    mv.visitFieldInsn(PUTSTATIC, generatedClassName, "method",
0645:                            "Ljava/lang/reflect/Method;");
0646:
0647:                    // go to the return label
0648:                    mv.visitJumpInsn(GOTO, notNullParametersLabel);
0649:
0650:                    // start of the catch label which throw a runtime exception
0651:                    // } catch (SecurityException e) {
0652:                    //   throw new RuntimeException("Cannot...", e);
0653:                    // }
0654:                    Label firstCatchLabel = new Label();
0655:                    mv.visitLabel(firstCatchLabel);
0656:                    mv.visitVarInsn(ASTORE, 1);
0657:                    mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
0658:                    mv.visitInsn(DUP);
0659:                    mv
0660:                            .visitLdcInsn("Cannot find method due to a security exception");
0661:                    mv.visitVarInsn(ALOAD, 1);
0662:                    mv.visitMethodInsn(INVOKESPECIAL,
0663:                            "java/lang/RuntimeException", "<init>",
0664:                            "(Ljava/lang/String;Ljava/lang/Throwable;)V");
0665:                    mv.visitInsn(ATHROW);
0666:
0667:                    // } catch (NoSuchMethodException e) {
0668:                    //   throw new RuntimeException("Cannot...", e);
0669:                    // }
0670:                    Label secondCatchLabel = new Label();
0671:                    mv.visitLabel(secondCatchLabel);
0672:                    mv.visitVarInsn(ASTORE, 1);
0673:                    mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
0674:                    mv.visitInsn(DUP);
0675:                    mv.visitLdcInsn("Cannot find the method");
0676:                    mv.visitVarInsn(ALOAD, 1);
0677:                    mv.visitMethodInsn(INVOKESPECIAL,
0678:                            "java/lang/RuntimeException", "<init>",
0679:                            "(Ljava/lang/String;Ljava/lang/Throwable;)V");
0680:                    mv.visitInsn(ATHROW);
0681:
0682:                    // if method is not null, return it
0683:                    mv.visitLabel(notNullParametersLabel);
0684:                    mv.visitFieldInsn(GETSTATIC, generatedClassName, "method",
0685:                            JAVA_LANG_REFLECT_METHOD);
0686:                    mv.visitInsn(ARETURN);
0687:
0688:                    // add try/cacth
0689:                    mv.visitTryCatchBlock(tryLabel, firstCatchLabel,
0690:                            firstCatchLabel, "java/lang/SecurityException");
0691:                    mv
0692:                            .visitTryCatchBlock(tryLabel, firstCatchLabel,
0693:                                    secondCatchLabel,
0694:                                    "java/lang/NoSuchMethodException");
0695:                } else {
0696:                    // for lifecycle method
0697:                    mv.visitInsn(ACONST_NULL);
0698:                    mv.visitInsn(ARETURN);
0699:                }
0700:
0701:                // finish
0702:                mv.visitMaxs(0, 0);
0703:                mv.visitEnd();
0704:
0705:            }
0706:
0707:            /**
0708:             * Adds attributes of InvocationContext interface.
0709:             *
0710:             * <pre>
0711:             *      private StatelessBean bean;
0712:             *      private Object[] parameters;
0713:             *      private static Method method;
0714:             *      private int interceptor;
0715:             *      private Map contextData;
0716:             *
0717:             *      // args of the method
0718:             *      private TYPE_ARG_METHOD arg0 = xxx;
0719:             *      private TYPE_ARG_METHOD arg1 = xxx;
0720:             *      private TYPE_ARG_METHOD arg2 = xxx;
0721:             *      private TYPE_ARG_METHOD.......;
0722:             * </pre>
0723:             */
0724:            private void addInvocationContextAttributes() {
0725:
0726:                // Add bean attribute
0727:                // private StatelessBean bean;
0728:                addAttribute(ACC_PRIVATE, "bean", beanClassDesc);
0729:
0730:                // Add parameters attribute
0731:                // private Object[] parameters;
0732:                addAttribute(ACC_PRIVATE, "parameters", ARRAY_OBJECTS);
0733:
0734:                // Add java.lang.reflect.Method attribute
0735:                // private static Method method;
0736:                addAttribute(ACC_PRIVATE + ACC_STATIC, "method",
0737:                        JAVA_LANG_REFLECT_METHOD);
0738:
0739:                // Add the interceptor counter
0740:                // private int interceptor;
0741:                addAttribute(ACC_PRIVATE, "interceptor", "I", Integer
0742:                        .valueOf(0));
0743:
0744:                // Now, add argument of the method as attributes
0745:                int arg = 0;
0746:                for (Type t : methodArgsType) {
0747:                    addAttribute(ACC_PRIVATE, ARG + (arg++), t.getDescriptor());
0748:                }
0749:
0750:                // Now, add interceptors objects
0751:                int intercpt = 0;
0752:                for (JClassInterceptor interceptor : allInterceptors) {
0753:                    // Only if interceptor is not in the bean class
0754:                    if (!interceptor.getClassName().equals(beanClassName)) {
0755:                        addAttribute(ACC_PRIVATE, INTERCEPTOR + (intercpt++),
0756:                                encodeClassDesc(interceptor.getClassName()));
0757:                    }
0758:                }
0759:
0760:                // ContextData
0761:                addAttribute(ACC_PRIVATE, "contextData", "Ljava/util/Map;");
0762:
0763:            }
0764:
0765:            /**
0766:             * Adds the initialization of static attributes.
0767:             * ie : private static Method method = null
0768:             *      private static InterceptorClass interceptor0 = new MyInterceptor();
0769:             *      private static InterceptorClass2 interceptor1 = ....
0770:             */
0771:            private void addStaticClassInitialization() {
0772:                MethodVisitor mv = getCW().visitMethod(ACC_STATIC, "<clinit>",
0773:                        "()V", null, null);
0774:                mv.visitCode();
0775:
0776:                // private static Method method = null
0777:                mv.visitInsn(ACONST_NULL);
0778:                mv.visitFieldInsn(PUTSTATIC, generatedClassName, "method",
0779:                        JAVA_LANG_REFLECT_METHOD);
0780:
0781:                mv.visitInsn(RETURN);
0782:                mv.visitMaxs(0, 0);
0783:                mv.visitEnd();
0784:
0785:            }
0786:
0787:            /**
0788:             * Adds attributes of EasyBeansInvocationContext interface.
0789:             *
0790:             * <pre>
0791:             * private Factory factory;
0792:             * </pre>
0793:             */
0794:            private void addEasyBeansInvocationContextAttributes() {
0795:
0796:                // Add factory attribute
0797:                // private Factory factory;
0798:                addAttribute(ACC_PRIVATE, "factory", EASYBEANS_FACTORY);
0799:
0800:                // Add interceptor manager attribute
0801:                // private interceptorManagerClassName interceptorManager;
0802:                addAttribute(ACC_PRIVATE, "interceptorManager",
0803:                        encodeClassDesc(interceptorManagerClassName));
0804:
0805:            }
0806:
0807:            /**
0808:             * Adds the proceed method.<br>
0809:             * It adds :
0810:             *
0811:             * <pre>
0812:             *  public Object proceed() throws Exception {
0813:             *    interceptor++;
0814:             *    switch (interceptor) {
0815:             *      case 1 :
0816:             *        return myInterceptor.intercept(this);
0817:             *      case 2 :
0818:             *        return otherInterceptor.intercept(this);
0819:             *      case 3 :
0820:             *           return bean.originalmethod(...);
0821:             *       default:
0822:             *           throw new IllegalStateException("Problem in interceptors");
0823:             *    }
0824:             *  }
0825:             * </pre>
0826:             */
0827:            private void addInvocationContextProceed() {
0828:                MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "proceed",
0829:                        "()" + JAVA_LANG_OBJECT, null, PROCEED_EXCEPTIONS);
0830:                mv.visitCode();
0831:
0832:                // interceptor++ or in fact : interceptor = interceptor + 1;
0833:                mv.visitVarInsn(ALOAD, 0);
0834:                mv.visitInsn(DUP);
0835:                mv.visitFieldInsn(GETFIELD, generatedClassName, "interceptor",
0836:                        "I");
0837:                mv.visitInsn(ICONST_1);
0838:                mv.visitInsn(IADD); // + 1
0839:                mv.visitFieldInsn(PUTFIELD, generatedClassName, "interceptor",
0840:                        "I");
0841:
0842:                // load interceptor constant to do the switch
0843:                mv.visitVarInsn(ALOAD, 0);
0844:                mv.visitFieldInsn(GETFIELD, generatedClassName, "interceptor",
0845:                        "I");
0846:
0847:                // Size
0848:                int sizeInterceptors = allInterceptors.size();
0849:
0850:                // need to add call to the original method
0851:                int switchSize = sizeInterceptors + 1;
0852:
0853:                // Build array of labels corresponding to swtich entries
0854:                Label[] switchLabels = new Label[switchSize];
0855:                for (int s = 0; s < switchSize; s++) {
0856:                    switchLabels[s] = new Label();
0857:                }
0858:
0859:                // default label
0860:                Label defaultCaseLabel = new Label();
0861:
0862:                // switch
0863:                mv.visitTableSwitchInsn(1, switchSize, defaultCaseLabel,
0864:                        switchLabels);
0865:
0866:                // add each interceptor switch entry with a return block at the end
0867:                // ie : case 1 :
0868:                //        return myInterceptor.intercept(this); // interceptor class
0869:                // or case 1 :
0870:                //        return bean.intercept(this) // bean class
0871:                int index = 0;
0872:                int interceptorIndex = 0;
0873:                for (JClassInterceptor interceptor : allInterceptors) {
0874:                    mv.visitLabel(switchLabels[index]);
0875:
0876:                    Type returnType = Type.getReturnType(interceptor
0877:                            .getJMethod().getDescriptor());
0878:
0879:                    // interceptor on the bean
0880:                    if (interceptor.getClassName().equals(beanClassName)) {
0881:                        mv.visitVarInsn(ALOAD, 0);
0882:                        mv.visitFieldInsn(GETFIELD, generatedClassName, "bean",
0883:                                beanClassDesc);
0884:                        mv.visitVarInsn(ALOAD, 0);
0885:                        mv.visitMethodInsn(INVOKEVIRTUAL, beanClassName,
0886:                                interceptor.getJMethod().getName(), interceptor
0887:                                        .getJMethod().getDescriptor());
0888:
0889:                        // return object or null if the return type is void
0890:                        returnsObject(returnType, mv);
0891:                    } else { // interceptor in another class
0892:                        mv.visitVarInsn(ALOAD, 0);
0893:                        mv.visitFieldInsn(GETFIELD, generatedClassName,
0894:                                INTERCEPTOR + interceptorIndex,
0895:                                encodeClassDesc(interceptor.getClassName()));
0896:                        mv.visitVarInsn(ALOAD, 0);
0897:                        mv.visitMethodInsn(INVOKEVIRTUAL, interceptor
0898:                                .getClassName(), interceptor.getJMethod()
0899:                                .getName(), interceptor.getJMethod()
0900:                                .getDescriptor());
0901:                        // return object or null if the return type is void
0902:                        returnsObject(returnType, mv);
0903:                        interceptorIndex++;
0904:                    }
0905:                    index++;
0906:                }
0907:
0908:                // then, add call to original method, ie bean.businessMethod(i,j,...);
0909:                mv.visitLabel(switchLabels[index++]);
0910:                // get bean object
0911:                mv.visitVarInsn(ALOAD, 0);
0912:                mv.visitFieldInsn(GETFIELD, generatedClassName, "bean",
0913:                        beanClassDesc);
0914:
0915:                // arguments of the method
0916:                int indexArg = 0;
0917:                for (Type argType : methodArgsType) {
0918:                    mv.visitVarInsn(ALOAD, 0);
0919:                    mv.visitFieldInsn(GETFIELD, generatedClassName, ARG
0920:                            + (indexArg++), argType.getDescriptor());
0921:                }
0922:
0923:                // Call to the renamed method only for AroundInvoke
0924:                // LifeCycle interceptors call the original method
0925:                String interceptedMethod = null;
0926:                if (interceptorType.equals(AROUND_INVOKE)) {
0927:                    interceptedMethod = MethodRenamer.encode(jMethod.getName());
0928:                } else {
0929:                    interceptedMethod = jMethod.getName();
0930:                }
0931:
0932:                mv.visitMethodInsn(INVOKEVIRTUAL, beanClassName,
0933:                        interceptedMethod, jMethod.getDescriptor());
0934:                Type returnType = Type.getReturnType(jMethod.getDescriptor());
0935:                // return object or null if the return type is void
0936:                returnsObject(returnType, mv);
0937:
0938:                // default case
0939:                mv.visitLabel(defaultCaseLabel);
0940:                mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
0941:                mv.visitInsn(DUP);
0942:                mv
0943:                        .visitLdcInsn("Problem in interceptors. Shouldn't go in the default case.");
0944:                mv.visitMethodInsn(INVOKESPECIAL,
0945:                        "java/lang/IllegalStateException", "<init>",
0946:                        "(Ljava/lang/String;)V");
0947:                mv.visitInsn(ATHROW);
0948:
0949:                // end
0950:                mv.visitMaxs(0, 0);
0951:                mv.visitEnd();
0952:            }
0953:
0954:            /**
0955:             * Adds the getContextData() method.
0956:             * <pre>
0957:             * public Map getContextData() {
0958:             *    if (contextData == null) {
0959:             *       contextData = new HashMap();
0960:             *    }
0961:             *    return contextData;
0962:             * }
0963:             * </pre>
0964:             *
0965:             */
0966:            public void addInvocationContextGetContextData() {
0967:                MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC,
0968:                        "getContextData", "()Ljava/util/Map;", null, null);
0969:                mv.visitCode();
0970:                mv.visitVarInsn(ALOAD, 0);
0971:                mv.visitFieldInsn(GETFIELD, generatedClassName, "contextData",
0972:                        "Ljava/util/Map;");
0973:
0974:                Label elseLabel = new Label();
0975:                mv.visitJumpInsn(IFNONNULL, elseLabel);
0976:
0977:                // if
0978:                mv.visitVarInsn(ALOAD, 0);
0979:                mv.visitTypeInsn(NEW, "java/util/HashMap");
0980:                mv.visitInsn(DUP);
0981:                mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap",
0982:                        "<init>", "()V");
0983:                mv.visitFieldInsn(PUTFIELD, generatedClassName, "contextData",
0984:                        "Ljava/util/Map;");
0985:
0986:                // else
0987:                mv.visitLabel(elseLabel);
0988:                mv.visitVarInsn(ALOAD, 0);
0989:                mv.visitFieldInsn(GETFIELD, generatedClassName, "contextData",
0990:                        "Ljava/util/Map;");
0991:
0992:                // return
0993:                mv.visitInsn(ARETURN);
0994:
0995:                mv.visitMaxs(0, 0);
0996:                mv.visitEnd();
0997:
0998:            }
0999:
1000:            /**
1001:             * Adds the getParameters method of InvocationContext interface.<br>
1002:             * It adds :
1003:             *
1004:             * <pre>
1005:             * public Object[] getParameters() {
1006:             *     if (parameters == null) {
1007:             *         parameters = new Object[] {arg0, arg1, argxxx};
1008:             *     }
1009:             *     return parameters;
1010:             * }
1011:             * </pre>
1012:             */
1013:            private void addInvocationContextGetParameters() {
1014:                MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC,
1015:                        "getParameters", "()" + ARRAY_OBJECTS, null, null);
1016:                mv.visitCode();
1017:
1018:                // only for around invoke type
1019:                if (interceptorType == AROUND_INVOKE) {
1020:
1021:                    // if (parameters == null) {
1022:                    mv.visitVarInsn(ALOAD, 0);
1023:                    mv.visitFieldInsn(GETFIELD, generatedClassName,
1024:                            "parameters", ARRAY_OBJECTS);
1025:                    // go to this label if not null
1026:                    Label notNullParametersLabel = new Label();
1027:                    mv.visitJumpInsn(IFNONNULL, notNullParametersLabel);
1028:
1029:                    // parameters = new Object[] {arg0, arg1, arg...};
1030:                    // put size of the array
1031:                    mv.visitVarInsn(ALOAD, 0);
1032:                    mv.visitIntInsn(BIPUSH, methodArgsType.length);
1033:                    mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
1034:
1035:                    // for each argument of the methods :
1036:                    int argCount = 0;
1037:                    for (Type type : methodArgsType) {
1038:                        mv.visitInsn(DUP);
1039:                        mv.visitIntInsn(BIPUSH, argCount);
1040:                        mv.visitVarInsn(ALOAD, 0);
1041:                        mv.visitFieldInsn(GETFIELD, generatedClassName, ARG
1042:                                + argCount, type.getDescriptor());
1043:                        // if type is not object type, need to convert it
1044:                        // for example : Integer.valueOf(i);
1045:                        transformPrimitiveIntoObject(type, mv);
1046:                        mv.visitInsn(AASTORE);
1047:                        argCount++;
1048:                    }
1049:
1050:                    // store field
1051:                    mv.visitFieldInsn(PUTFIELD, generatedClassName,
1052:                            "parameters", ARRAY_OBJECTS);
1053:
1054:                    // not null label :
1055:                    // return parameters;
1056:                    mv.visitLabel(notNullParametersLabel);
1057:                    mv.visitVarInsn(ALOAD, 0);
1058:                    mv.visitFieldInsn(GETFIELD, generatedClassName,
1059:                            "parameters", ARRAY_OBJECTS);
1060:                } else {
1061:                    // throw Exception
1062:                    mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
1063:                    mv.visitInsn(DUP);
1064:                    mv
1065:                            .visitLdcInsn("Operation getParameters can only be applied on AroundInvoke interceptors");
1066:                    mv.visitMethodInsn(INVOKESPECIAL,
1067:                            "java/lang/IllegalStateException", "<init>",
1068:                            "(Ljava/lang/String;)V");
1069:                    mv.visitInsn(ATHROW);
1070:                }
1071:
1072:                // return
1073:                mv.visitInsn(ARETURN);
1074:                mv.visitMaxs(0, 0);
1075:                mv.visitEnd();
1076:
1077:            }
1078:
1079:            /**
1080:             * Adds the setParameters method of InvocationContext interface.<br>
1081:             * It adds :
1082:             *
1083:             * <pre>
1084:             * public void setParameters(Object aobj[]) {
1085:             *   if (aobj == null) {
1086:             *     throw new IllegalStateException("Cannot set a null array.");
1087:             *   }
1088:             *   if (aobj.length != ...) {
1089:             *     throw new IllegalStateException("Invalid size of the given array. The length should be '" + ... + "'.");
1090:             *   }
1091:             *   parameters = aobj;
1092:             *
1093:             *   arg0 = (Integer) aobj[0];
1094:             *   arg1 = ((Integer) aobj[1]).intValue();
1095:             *   arg2 = ((Double) aobj[2]).doubleValue();
1096:             *   arg3 = ((Float) aobj[3]).floatValue();
1097:             *   arg4 = (String) aobj[4];
1098:             *   ...
1099:             * }
1100:             *
1101:             * </pre>
1102:             */
1103:            private void addInvocationContextSetParameters() {
1104:                MethodVisitor mv = getCW()
1105:                        .visitMethod(ACC_PUBLIC, "setParameters",
1106:                                "(" + ARRAY_OBJECTS + ")V", null, null);
1107:                mv.visitCode();
1108:
1109:                // only for aroundInvoke
1110:                if (interceptorType == AROUND_INVOKE) {
1111:                    /**
1112:                     * if (aobj == null) { throw new IllegalStateException("Cannot set a
1113:                     * null array."); }
1114:                     */
1115:                    mv.visitVarInsn(ALOAD, 1);
1116:                    Label notNull = new Label();
1117:                    mv.visitJumpInsn(IFNONNULL, notNull);
1118:                    mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
1119:                    mv.visitInsn(DUP);
1120:                    mv.visitLdcInsn("Cannot set a null array.");
1121:                    mv.visitMethodInsn(INVOKESPECIAL,
1122:                            "java/lang/IllegalStateException", "<init>",
1123:                            "(Ljava/lang/String;)V");
1124:                    mv.visitInsn(ATHROW);
1125:                    mv.visitLabel(notNull);
1126:
1127:                    /**
1128:                     * if (aobj.length != ...) { throw new
1129:                     * IllegalStateException("Invalid size of the given array. The
1130:                     * length should be '" + ... + "'."); }
1131:                     */
1132:                    mv.visitVarInsn(ALOAD, 1);
1133:                    mv.visitInsn(ARRAYLENGTH);
1134:                    mv.visitIntInsn(BIPUSH, methodArgsType.length);
1135:                    Label sizeOk = new Label();
1136:                    mv.visitJumpInsn(IF_ICMPEQ, sizeOk);
1137:                    mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
1138:                    mv.visitInsn(DUP);
1139:                    mv
1140:                            .visitLdcInsn("Invalid size of the given array. The length should be '"
1141:                                    + methodArgsType.length + "'.");
1142:                    mv.visitMethodInsn(INVOKESPECIAL,
1143:                            "java/lang/IllegalStateException", "<init>",
1144:                            "(Ljava/lang/String;)V");
1145:                    mv.visitInsn(ATHROW);
1146:                    mv.visitLabel(sizeOk);
1147:
1148:                    // this.parameters = parameters
1149:                    mv.visitVarInsn(ALOAD, 0);
1150:                    mv.visitVarInsn(ALOAD, 1);
1151:                    mv.visitFieldInsn(PUTFIELD, generatedClassName,
1152:                            "parameters", ARRAY_OBJECTS);
1153:
1154:                    /**
1155:                     * arg0 = (Integer) aobj[0]; arg1 = ((Integer) aobj[1]).intValue();
1156:                     * arg2 = ((Double) aobj[2]).doubleValue(); arg3 = ((Float)
1157:                     * aobj[3]).floatValue(); arg4 = (String) aobj[4]; ...
1158:                     */
1159:                    int argCount = 0;
1160:                    for (Type type : methodArgsType) {
1161:                        mv.visitVarInsn(ALOAD, 0);
1162:                        mv.visitVarInsn(ALOAD, 1);
1163:                        mv.visitIntInsn(BIPUSH, argCount);
1164:                        mv.visitInsn(AALOAD);
1165:                        // Cast object Integer.valueOf(i);
1166:                        transformObjectIntoPrimitive(type, mv);
1167:                        // write result
1168:                        mv.visitFieldInsn(PUTFIELD, generatedClassName, ARG
1169:                                + argCount, type.getDescriptor());
1170:                        argCount++;
1171:                    }
1172:                } else {
1173:                    // throw Exception
1174:                    mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
1175:                    mv.visitInsn(DUP);
1176:                    mv
1177:                            .visitLdcInsn("Operation setParameters can only be applied on AroundInvoke interceptors");
1178:                    mv.visitMethodInsn(INVOKESPECIAL,
1179:                            "java/lang/IllegalStateException", "<init>",
1180:                            "(Ljava/lang/String;)V");
1181:                    mv.visitInsn(ATHROW);
1182:                }
1183:
1184:                mv.visitInsn(RETURN);
1185:                mv.visitMaxs(0, 0);
1186:                mv.visitEnd();
1187:            }
1188:
1189:            /**
1190:             * Generated toString() method.
1191:             * Generated code is in the comments of the method body.
1192:             */
1193:            private void addToString() {
1194:                MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "toString",
1195:                        "()Ljava/lang/String;", null, null);
1196:                mv.visitCode();
1197:
1198:                // local vars
1199:                // 1 = sb
1200:                // 2 = classNames
1201:                // 3 = className
1202:                // 4 = indent2
1203:                // 5 = indent4
1204:                // 6 = i
1205:                //
1206:                int localVar = 1;
1207:                final int varSB = localVar++;
1208:                int varCLASSNAMES = localVar++;
1209:                int varCLASSNAME = localVar++;
1210:                int varINDENT2 = localVar++;
1211:                int varINDENT4 = localVar++;
1212:                int varI = localVar++;
1213:
1214:                /*
1215:                 * StringBuilder sb = new StringBuilder();
1216:                 * String[] classNames = this.getClass().getName().split("\\.");
1217:                 * String className = classNames[classNames.length - 1];
1218:                 * // classname
1219:                 * sb.append(className);
1220:                 * sb.append("[\n");
1221:                 * String indent2 = "  ";
1222:                 * String indent4 = "    ";
1223:                 * sb.append(indent2);
1224:                 * sb.append("List of interceptors :\n");
1225:                 */
1226:
1227:                mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
1228:                mv.visitInsn(DUP);
1229:                mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder",
1230:                        "<init>", "()V");
1231:                mv.visitVarInsn(ASTORE, varSB);
1232:                mv.visitVarInsn(ALOAD, 0);
1233:                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object",
1234:                        "getClass", "()Ljava/lang/Class;");
1235:                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName",
1236:                        "()Ljava/lang/String;");
1237:                mv.visitLdcInsn("\\.");
1238:                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "split",
1239:                        "(Ljava/lang/String;)[Ljava/lang/String;");
1240:                mv.visitVarInsn(ASTORE, varCLASSNAMES);
1241:                mv.visitVarInsn(ALOAD, varCLASSNAMES);
1242:                mv.visitVarInsn(ALOAD, varCLASSNAMES);
1243:                mv.visitInsn(ARRAYLENGTH);
1244:                mv.visitInsn(ICONST_1);
1245:                mv.visitInsn(ISUB);
1246:                mv.visitInsn(AALOAD);
1247:                mv.visitVarInsn(ASTORE, varCLASSNAME);
1248:                mv.visitVarInsn(ALOAD, varSB);
1249:                mv.visitVarInsn(ALOAD, varCLASSNAME);
1250:                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder",
1251:                        "append",
1252:                        "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1253:                mv.visitInsn(POP);
1254:                mv.visitVarInsn(ALOAD, varSB);
1255:                mv.visitLdcInsn("[\n");
1256:                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder",
1257:                        "append",
1258:                        "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1259:                mv.visitInsn(POP);
1260:                mv.visitLdcInsn("  ");
1261:                mv.visitVarInsn(ASTORE, varINDENT2);
1262:                mv.visitLdcInsn("    ");
1263:                mv.visitVarInsn(ASTORE, varINDENT4);
1264:                mv.visitVarInsn(ALOAD, varSB);
1265:                mv.visitVarInsn(ALOAD, varINDENT2);
1266:                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder",
1267:                        "append",
1268:                        "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1269:                mv.visitInsn(POP);
1270:                mv.visitVarInsn(ALOAD, varSB);
1271:                mv.visitLdcInsn("List of interceptors :\n");
1272:                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder",
1273:                        "append",
1274:                        "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1275:                mv.visitInsn(POP);
1276:
1277:                /*
1278:                 * In the loop, print :
1279:                 * sb.append(indent4);
1280:                 * sb.append(i);
1281:                 * sb.append(") - ");
1282:                 * sb.append(interceptor.getClassName());
1283:                 * sb.append("[");
1284:                 * sb.append(interceptor.getJMethod().getName());
1285:                 * sb.append("]\n");
1286:                 */
1287:                int i = 1;
1288:
1289:                // int i = 1;
1290:                mv.visitInsn(ICONST_1);
1291:                mv.visitVarInsn(ISTORE, varI);
1292:
1293:                if (allInterceptors != null) {
1294:                    for (JClassInterceptor interceptor : allInterceptors) {
1295:                        mv.visitVarInsn(ALOAD, varSB);
1296:                        mv.visitVarInsn(ALOAD, varINDENT4);
1297:                        mv
1298:                                .visitMethodInsn(INVOKEVIRTUAL,
1299:                                        "java/lang/StringBuilder", "append",
1300:                                        "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1301:                        mv.visitInsn(POP);
1302:
1303:                        mv.visitVarInsn(ALOAD, varSB);
1304:                        mv.visitVarInsn(ILOAD, varI);
1305:                        mv.visitMethodInsn(INVOKEVIRTUAL,
1306:                                "java/lang/StringBuilder", "append",
1307:                                "(I)Ljava/lang/StringBuilder;");
1308:                        mv.visitInsn(POP);
1309:
1310:                        mv.visitVarInsn(ALOAD, varSB);
1311:                        mv.visitLdcInsn(") - ");
1312:                        mv
1313:                                .visitMethodInsn(INVOKEVIRTUAL,
1314:                                        "java/lang/StringBuilder", "append",
1315:                                        "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1316:                        mv.visitInsn(POP);
1317:
1318:                        // sb.append(interceptor.getClassName());
1319:                        mv.visitVarInsn(ALOAD, varSB);
1320:                        mv.visitLdcInsn(interceptor.getClassName());
1321:                        mv
1322:                                .visitMethodInsn(INVOKEVIRTUAL,
1323:                                        "java/lang/StringBuilder", "append",
1324:                                        "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1325:                        mv.visitInsn(POP);
1326:
1327:                        mv.visitVarInsn(ALOAD, varSB);
1328:                        mv.visitLdcInsn("[");
1329:                        mv
1330:                                .visitMethodInsn(INVOKEVIRTUAL,
1331:                                        "java/lang/StringBuilder", "append",
1332:                                        "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1333:                        mv.visitInsn(POP);
1334:
1335:                        // sb.append(interceptor.getJMethod().getName());
1336:                        mv.visitVarInsn(ALOAD, varSB);
1337:                        mv.visitLdcInsn(interceptor.getJMethod().getName());
1338:                        mv
1339:                                .visitMethodInsn(INVOKEVIRTUAL,
1340:                                        "java/lang/StringBuilder", "append",
1341:                                        "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1342:                        mv.visitInsn(POP);
1343:
1344:                        mv.visitVarInsn(ALOAD, varSB);
1345:                        mv.visitLdcInsn("]\n");
1346:                        mv
1347:                                .visitMethodInsn(INVOKEVIRTUAL,
1348:                                        "java/lang/StringBuilder", "append",
1349:                                        "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1350:                        mv.visitInsn(POP);
1351:
1352:                        i++;
1353:                        // i++
1354:                        mv.visitIincInsn(varI, 1);
1355:                    }
1356:                    /*
1357:                     * sb.append(indent2);
1358:                     * sb.append("Current interceptor : ");
1359:                     * sb.append(interceptor); sb.append("/");
1360:                     * sb.append(allInterceptors.size());
1361:                     */
1362:                    mv.visitVarInsn(ALOAD, varSB);
1363:                    mv.visitVarInsn(ALOAD, varINDENT2);
1364:                    mv.visitMethodInsn(INVOKEVIRTUAL,
1365:                            "java/lang/StringBuilder", "append",
1366:                            "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1367:                    mv.visitInsn(POP);
1368:
1369:                    mv.visitVarInsn(ALOAD, varSB);
1370:                    mv.visitLdcInsn("Current interceptor : ");
1371:                    mv.visitMethodInsn(INVOKEVIRTUAL,
1372:                            "java/lang/StringBuilder", "append",
1373:                            "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1374:                    mv.visitInsn(POP);
1375:
1376:                    mv.visitVarInsn(ALOAD, varSB);
1377:                    mv.visitVarInsn(ALOAD, 0);
1378:                    mv.visitFieldInsn(GETFIELD, generatedClassName,
1379:                            "interceptor", "I");
1380:                    mv.visitMethodInsn(INVOKEVIRTUAL,
1381:                            "java/lang/StringBuilder", "append",
1382:                            "(I)Ljava/lang/StringBuilder;");
1383:                    mv.visitInsn(POP);
1384:
1385:                    mv.visitVarInsn(ALOAD, varSB);
1386:                    mv.visitLdcInsn("/");
1387:                    mv.visitMethodInsn(INVOKEVIRTUAL,
1388:                            "java/lang/StringBuilder", "append",
1389:                            "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1390:                    mv.visitInsn(POP);
1391:
1392:                    mv.visitVarInsn(ALOAD, varSB);
1393:                    mv.visitLdcInsn(String.valueOf(allInterceptors.size()));
1394:                    mv.visitMethodInsn(INVOKEVIRTUAL,
1395:                            "java/lang/StringBuilder", "append",
1396:                            "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1397:                    mv.visitInsn(POP);
1398:
1399:                } else {
1400:                    /*
1401:                     * sb.append(indent2);
1402:                     * sb.append("No interceptors : ");
1403:                     */
1404:                    mv.visitVarInsn(ALOAD, varSB);
1405:                    mv.visitVarInsn(ALOAD, varINDENT2);
1406:                    mv.visitMethodInsn(INVOKEVIRTUAL,
1407:                            "java/lang/StringBuilder", "append",
1408:                            "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1409:                    mv.visitInsn(POP);
1410:
1411:                    mv.visitVarInsn(ALOAD, varSB);
1412:                    mv.visitLdcInsn("No interceptors : ");
1413:                    mv.visitMethodInsn(INVOKEVIRTUAL,
1414:                            "java/lang/StringBuilder", "append",
1415:                            "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1416:                    mv.visitInsn(POP);
1417:                }
1418:
1419:                /*
1420:                 * sb.append("\n");
1421:                 * sb.append("]");
1422:                 * return sb.toString();
1423:                 */
1424:                mv.visitVarInsn(ALOAD, varSB);
1425:                mv.visitLdcInsn("\n");
1426:                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder",
1427:                        "append",
1428:                        "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1429:                mv.visitInsn(POP);
1430:
1431:                mv.visitVarInsn(ALOAD, varSB);
1432:                mv.visitLdcInsn("]");
1433:                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder",
1434:                        "append",
1435:                        "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1436:                mv.visitInsn(POP);
1437:
1438:                mv.visitVarInsn(ALOAD, varSB);
1439:                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder",
1440:                        "toString", "()Ljava/lang/String;");
1441:                mv.visitInsn(ARETURN);
1442:
1443:                mv.visitMaxs(0, 0);
1444:                mv.visitEnd();
1445:
1446:            }
1447:
1448:            /**
1449:             * @return method metadata used by this generator
1450:             */
1451:            public MethodAnnotationMetadata getMethodAnnotationMetadata() {
1452:                return methodAnnotationMetadata;
1453:            }
1454:
1455:            /**
1456:             * @return the name of the generated class name (with package name)
1457:             */
1458:            public String getGeneratedClassName() {
1459:                return generatedClassName;
1460:            }
1461:
1462:            /**
1463:             * @return the ASM descriptor of the generated constructor.
1464:             */
1465:            public String getConstructorDesc() {
1466:                return constructorDesc;
1467:            }
1468:
1469:            /**
1470:             * @return the interceptors used by this InvocationContext implementation object.
1471:             */
1472:            public List<JClassInterceptor> getAllInterceptors() {
1473:                return allInterceptors;
1474:            }
1475:
1476:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.