Source Code Cross Referenced for AspectWerkzAspectModel.java in  » Net » Terracotta » com » tc » aspectwerkz » transform » inlining » model » 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 » Net » Terracotta » com.tc.aspectwerkz.transform.inlining.model 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice.  All rights reserved.
003:         */
004:        package com.tc.aspectwerkz.transform.inlining.model;
005:
006:        import com.tc.asm.ClassVisitor;
007:        import com.tc.asm.ClassWriter;
008:        import com.tc.asm.MethodVisitor;
009:        import com.tc.asm.Opcodes;
010:        import com.tc.asm.Label;
011:        import com.tc.asm.Type;
012:
013:        import com.tc.aspectwerkz.DeploymentModel;
014:        import com.tc.aspectwerkz.aspect.AdviceInfo;
015:        import com.tc.aspectwerkz.aspect.AdviceType;
016:        import com.tc.aspectwerkz.cflow.CflowCompiler;
017:        import com.tc.aspectwerkz.definition.AspectDefinition;
018:        import com.tc.aspectwerkz.exception.DefinitionException;
019:        import com.tc.aspectwerkz.joinpoint.management.AdviceInfoContainer;
020:        import com.tc.aspectwerkz.reflect.impl.asm.AsmClassInfo;
021:        import com.tc.aspectwerkz.reflect.ClassInfo;
022:        import com.tc.aspectwerkz.reflect.MethodInfo;
023:        import com.tc.aspectwerkz.reflect.ClassInfoHelper;
024:        import com.tc.aspectwerkz.transform.JoinPointCompiler;
025:        import com.tc.aspectwerkz.transform.TransformationConstants;
026:        import com.tc.aspectwerkz.transform.inlining.AdviceMethodInfo;
027:        import com.tc.aspectwerkz.transform.inlining.AsmHelper;
028:        import com.tc.aspectwerkz.transform.inlining.AspectInfo;
029:        import com.tc.aspectwerkz.transform.inlining.compiler.AbstractJoinPointCompiler;
030:        import com.tc.aspectwerkz.transform.inlining.compiler.CompilationInfo;
031:        import com.tc.aspectwerkz.transform.inlining.compiler.CompilerInput;
032:        import com.tc.aspectwerkz.transform.inlining.spi.AspectModel;
033:
034:        import java.util.ArrayList;
035:        import java.util.HashSet;
036:        import java.util.Iterator;
037:        import java.util.List;
038:        import java.util.Set;
039:
040:        /**
041:         * TODO doc
042:         *
043:         * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
044:         * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
045:         */
046:        public class AspectWerkzAspectModel implements  AspectModel, Opcodes,
047:                TransformationConstants {
048:
049:            protected final List m_customProceedMethodStructs;
050:
051:            public AspectWerkzAspectModel() {
052:                m_customProceedMethodStructs = null;
053:                //prototype
054:            }
055:
056:            private AspectWerkzAspectModel(
057:                    CompilationInfo.Model compilationModel) {
058:                m_customProceedMethodStructs = new ArrayList(0);
059:                collectCustomProceedMethods(compilationModel, compilationModel
060:                        .getAdviceInfoContainer());
061:            }
062:
063:            public static final String TYPE = AspectWerkzAspectModel.class
064:                    .getName();
065:
066:            public AspectModel getInstance(
067:                    CompilationInfo.Model compilationModel) {
068:                // return a new instance to handle custom proceed
069:                return new AspectWerkzAspectModel(compilationModel);
070:            }
071:
072:            public String getAspectModelType() {
073:                return TYPE;
074:            }
075:
076:            public void defineAspect(ClassInfo aspectClassInfo,
077:                    AspectDefinition aspectDef, ClassLoader loader) {
078:            }
079:
080:            public AroundClosureClassInfo getAroundClosureClassInfo() {
081:                if (m_customProceedMethodStructs.isEmpty()) {
082:                    //let the compiler deal with JP / SJP interface
083:                    return new AroundClosureClassInfo(OBJECT_CLASS_NAME,
084:                            new String[0]);
085:                } else {
086:                    // getDefault the custom join point interfaces
087:                    Set interfaces = new HashSet();
088:                    for (Iterator it = m_customProceedMethodStructs.iterator(); it
089:                            .hasNext();) {
090:                        MethodInfo methodInfo = ((CustomProceedMethodStruct) it
091:                                .next()).customProceed;
092:                        interfaces.add(methodInfo.getDeclaringType().getName()
093:                                .replace('.', '/'));
094:                    }
095:                    return new AroundClosureClassInfo(OBJECT_CLASS_NAME,
096:                            (String[]) interfaces.toArray(new String[] {}));
097:                }
098:            }
099:
100:            public void createMandatoryMethods(ClassWriter cw,
101:                    JoinPointCompiler compiler) {
102:                createCustomProceedMethods(cw,
103:                        (AbstractJoinPointCompiler) compiler);
104:            }
105:
106:            public void createInvocationOfAroundClosureSuperClass(
107:                    MethodVisitor cv) {
108:                ;// AW model has no super class apart Object, which is handled by the compiler
109:            }
110:
111:            /**
112:             * Create and initialize the aspect field for a specific aspect (qualified since it depends
113:             * on the param, deployment model, container etc).
114:             * And creates instantiation of aspects using the Aspects.aspectOf() methods which uses the AspectContainer impls.
115:             * We are using the THIS_CLASS classloader since the aspect can be visible from that one only f.e. for getDefault/set/call
116:             * <p/>
117:             * TODO for perJVM and perClass aspect this means we eagerly load the aspect. Different from AJ
118:             *
119:             * @param cw
120:             * @param cv
121:             * @param aspectInfo
122:             * @param joinPointClassName
123:             */
124:            public void createAndStoreStaticAspectInstantiation(
125:                    ClassVisitor cw, MethodVisitor cv, AspectInfo aspectInfo,
126:                    String joinPointClassName) {
127:                String aspectClassSignature = aspectInfo
128:                        .getAspectClassSignature();
129:                String aspectClassName = aspectInfo.getAspectClassName();
130:                // retrieve the aspect set it to the field
131:                DeploymentModel deploymentModel = aspectInfo
132:                        .getDeploymentModel();
133:                if (CflowCompiler.isCflowClass(aspectClassName)) {
134:                    cw.visitField(ACC_PRIVATE + ACC_STATIC, aspectInfo
135:                            .getAspectFieldName(), aspectClassSignature, null,
136:                            null);
137:                    // handle Cflow native aspectOf
138:                    //TODO: would be better done with a custom aspectModel for cflow, or with default factory handling
139:                    //FIXME AVF what does factory do there ?
140:                    cv.visitMethodInsn(INVOKESTATIC, aspectClassName,
141:                            CflowCompiler.CFLOW_ASPECTOF_METHOD_NAME, "()"
142:                                    + aspectClassSignature);
143:                    cv.visitFieldInsn(PUTSTATIC, joinPointClassName, aspectInfo
144:                            .getAspectFieldName(), aspectClassSignature);
145:                } else if (deploymentModel.equals(DeploymentModel.PER_JVM)) {
146:                    cw.visitField(ACC_PRIVATE + ACC_STATIC, aspectInfo
147:                            .getAspectFieldName(), aspectClassSignature, null,
148:                            null);
149:                    cv.visitMethodInsn(INVOKESTATIC, aspectInfo
150:                            .getAspectFactoryClassName(), "aspectOf", "()"
151:                            + aspectClassSignature);
152:                    cv.visitFieldInsn(PUTSTATIC, joinPointClassName, aspectInfo
153:                            .getAspectFieldName(), aspectClassSignature);
154:                } else if (deploymentModel.equals(DeploymentModel.PER_CLASS)) {
155:                    cw.visitField(ACC_PRIVATE + ACC_STATIC, aspectInfo
156:                            .getAspectFieldName(), aspectClassSignature, null,
157:                            null);
158:                    cv.visitFieldInsn(GETSTATIC, joinPointClassName,
159:                            THIS_CLASS_FIELD_NAME_IN_JP, CLASS_CLASS_SIGNATURE);
160:                    cv.visitMethodInsn(INVOKESTATIC, aspectInfo
161:                            .getAspectFactoryClassName(), "aspectOf",
162:                            "(Ljava/lang/Class;)" + aspectClassSignature);
163:                    cv.visitFieldInsn(PUTSTATIC, joinPointClassName, aspectInfo
164:                            .getAspectFieldName(), aspectClassSignature);
165:                } else if (AbstractJoinPointCompiler
166:                        .requiresCallerOrCallee(deploymentModel)) {
167:                    cw.visitField(ACC_PRIVATE, aspectInfo.getAspectFieldName(),
168:                            aspectClassSignature, null, null);
169:                } else {
170:                    throw new UnsupportedOperationException(
171:                            "unsupported deployment model - "
172:                                    + aspectInfo.getAspectClassName() + " "
173:                                    + deploymentModel);
174:                }
175:            }
176:
177:            /**
178:             * Initializes instance level aspects, retrieves them from the target instance through the
179:             * <code>HasInstanceLevelAspect</code> interfaces.
180:             * <p/>
181:             * Use by 'perInstance', 'perThis' and 'perTarget' deployment models.
182:             *
183:             * @param cv
184:             * @param aspectInfo
185:             * @param input
186:             */
187:            public void createAndStoreRuntimeAspectInstantiation(
188:                    final MethodVisitor cv, final CompilerInput input,
189:                    final AspectInfo aspectInfo) {
190:                // gen code: if (Aspects.hasAspect(...) { aspectField = (<TYPE>)((HasInstanceLocalAspect)CALLER).aw$getAspect(className, qualifiedName, containerClassName) }
191:                if (DeploymentModel.PER_INSTANCE.equals(aspectInfo
192:                        .getDeploymentModel())) {//TODO && callerIndex >= 0
193:                    //storeAspectInstance(cv, input, aspectInfo, input.callerIndex);
194:                } else if (DeploymentModel.PER_THIS.equals(aspectInfo
195:                        .getDeploymentModel())
196:                        && input.callerIndex >= 0) {
197:                    Label hasAspectCheck = pushPerXCondition(cv,
198:                            input.callerIndex, aspectInfo);
199:                    storeAspectInstance(cv, input, aspectInfo,
200:                            input.callerIndex);
201:                    cv.visitLabel(hasAspectCheck);
202:                } else if (DeploymentModel.PER_TARGET.equals(aspectInfo
203:                        .getDeploymentModel())
204:                        && input.calleeIndex >= 0) {
205:                    Label hasAspectCheck = pushPerXCondition(cv,
206:                            input.calleeIndex, aspectInfo);
207:                    storeAspectInstance(cv, input, aspectInfo,
208:                            input.calleeIndex);
209:                    cv.visitLabel(hasAspectCheck);
210:                }
211:
212:                if (aspectInfo.getDeploymentModel() == DeploymentModel.PER_INSTANCE) {//TODO refactor with previous if block
213:                    // gen code: aspectField = (<TYPE>)((HasInstanceLocalAspect)CALLER).aw$getAspect(className, qualifiedName, containerClassName)
214:                    AbstractJoinPointCompiler.loadJoinPointInstance(cv, input);
215:                    if (input.callerIndex >= 0) {
216:                        cv.visitVarInsn(ALOAD, input.callerIndex);
217:                    } else {
218:                        // caller instance not available - skipping
219:                        //TODO clean up should not occur
220:                    }
221:                    cv.visitMethodInsn(INVOKESTATIC, aspectInfo
222:                            .getAspectFactoryClassName(), "aspectOf",
223:                            "(Ljava/lang/Object;)"
224:                                    + aspectInfo.getAspectClassSignature());
225:                    //            cv.visitLdcInsn(aspectInfo.getAspectClassName().replace('/', '.'));
226:                    //            cv.visitLdcInsn(aspectInfo.getAspectQualifiedName());
227:                    //            AsmHelper.loadStringConstant(cv, aspectInfo.getAspectDefinition().getContainerClassName());
228:                    //            cv.visitMethodInsn(
229:                    //                    INVOKEINTERFACE,
230:                    //                    HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME,
231:                    //                    INSTANCE_LEVEL_GETASPECT_METHOD_NAME,
232:                    //                    INSTANCE_LEVEL_GETASPECT_METHOD_SIGNATURE
233:                    //            );
234:                    //            cv.visitTypeInsn(CHECKCAST, aspectInfo.getAspectClassName());
235:                    cv.visitFieldInsn(PUTFIELD, input.joinPointClassName,
236:                            aspectInfo.getAspectFieldName(), aspectInfo
237:                                    .getAspectClassSignature());
238:                }
239:            }
240:
241:            /**
242:             * Load aspect instance on stack
243:             *
244:             * @param cv
245:             * @param input
246:             * @param aspectInfo
247:             */
248:            public void loadAspect(final MethodVisitor cv,
249:                    final CompilerInput input, final AspectInfo aspectInfo) {
250:                DeploymentModel deploymentModel = aspectInfo
251:                        .getDeploymentModel();
252:                if (DeploymentModel.PER_JVM.equals(deploymentModel)
253:                        || DeploymentModel.PER_CLASS.equals(deploymentModel)) {
254:                    cv.visitFieldInsn(GETSTATIC, input.joinPointClassName,
255:                            aspectInfo.getAspectFieldName(), aspectInfo
256:                                    .getAspectClassSignature());
257:                } else if (DeploymentModel.PER_INSTANCE.equals(deploymentModel)) {
258:                    AbstractJoinPointCompiler.loadJoinPointInstance(cv, input);
259:                    cv.visitFieldInsn(GETFIELD, input.joinPointClassName,
260:                            aspectInfo.getAspectFieldName(), aspectInfo
261:                                    .getAspectClassSignature());
262:                } else if (DeploymentModel.PER_THIS.equals(deploymentModel)) {
263:                    AbstractJoinPointCompiler.loadJoinPointInstance(cv, input);
264:                    cv.visitFieldInsn(GETFIELD, input.joinPointClassName,
265:                            aspectInfo.getAspectFieldName(), aspectInfo
266:                                    .getAspectClassSignature());
267:
268:                    //FIXME see FIXME on aspect instantion
269:                    Label nullCheck = new Label();
270:                    cv.visitJumpInsn(IFNONNULL, nullCheck);
271:                    storeAspectInstance(cv, input, aspectInfo,
272:                            input.callerIndex);
273:                    cv.visitLabel(nullCheck);
274:
275:                    AbstractJoinPointCompiler.loadJoinPointInstance(cv, input);
276:                    cv.visitFieldInsn(GETFIELD, input.joinPointClassName,
277:                            aspectInfo.getAspectFieldName(), aspectInfo
278:                                    .getAspectClassSignature());
279:                } else if (DeploymentModel.PER_TARGET.equals(deploymentModel)) {
280:                    AbstractJoinPointCompiler.loadJoinPointInstance(cv, input);
281:                    cv.visitFieldInsn(GETFIELD, input.joinPointClassName,
282:                            aspectInfo.getAspectFieldName(), aspectInfo
283:                                    .getAspectClassSignature());
284:                    //FIXME see FIXME on aspect instantion
285:
286:                    Label nullCheck = new Label();
287:                    cv.visitJumpInsn(IFNONNULL, nullCheck);
288:                    storeAspectInstance(cv, input, aspectInfo,
289:                            input.calleeIndex);
290:                    cv.visitLabel(nullCheck);
291:
292:                    AbstractJoinPointCompiler.loadJoinPointInstance(cv, input);
293:                    cv.visitFieldInsn(GETFIELD, input.joinPointClassName,
294:                            aspectInfo.getAspectFieldName(), aspectInfo
295:                                    .getAspectClassSignature());
296:                } else {
297:                    throw new DefinitionException("deployment model ["
298:                            + deploymentModel + "] is not supported");
299:                }
300:            }
301:
302:            public void createAroundAdviceArgumentHandling(MethodVisitor cv,
303:                    CompilerInput input, Type[] joinPointArgumentTypes,
304:                    AdviceMethodInfo adviceMethodInfo) {
305:                defaultCreateAroundAdviceArgumentHandling(cv, input,
306:                        joinPointArgumentTypes, adviceMethodInfo);
307:            }
308:
309:            public void createBeforeOrAfterAdviceArgumentHandling(
310:                    MethodVisitor cv, CompilerInput input,
311:                    Type[] joinPointArgumentTypes,
312:                    AdviceMethodInfo adviceMethodInfo, int specialArgIndex) {
313:                defaultCreateBeforeOrAfterAdviceArgumentHandling(cv, input,
314:                        joinPointArgumentTypes, adviceMethodInfo,
315:                        specialArgIndex);
316:            }
317:
318:            public boolean requiresReflectiveInfo() {
319:                // custom proceed() JoinPoint will not be recognize by the default logic
320:                return m_customProceedMethodStructs.size() > 0;
321:            }
322:
323:            ///////---------- Helpers
324:
325:            /**
326:             * Generate a "if Aspects.hasAspect(qName, instance)"
327:             *
328:             * @param cv
329:             * @param perInstanceIndex
330:             * @param aspectInfo
331:             * @return
332:             */
333:            private Label pushPerXCondition(final MethodVisitor cv,
334:                    final int perInstanceIndex, final AspectInfo aspectInfo) {
335:                Label hasAspectCheck = new Label();
336:
337:                cv.visitVarInsn(ALOAD, perInstanceIndex);
338:                cv.visitMethodInsn(INVOKESTATIC, aspectInfo
339:                        .getAspectFactoryClassName(),
340:                        FACTORY_HASASPECT_METHOD_NAME,
341:                        FACTORY_HASASPECT_PEROBJECT_METHOD_SIGNATURE);
342:                cv.visitJumpInsn(IFEQ, hasAspectCheck);
343:
344:                return hasAspectCheck;
345:            }
346:
347:            /**
348:             * Creates the instance of an aspect by invoking
349:             * "HasInstanceLevelAspect.aw$getAspect(String, String)" on perInstanceIndex variable
350:             * and stores the aspect instance in the joinpoint instance field
351:             */
352:            private void storeAspectInstance(final MethodVisitor cv,
353:                    final CompilerInput input, final AspectInfo aspectInfo,
354:                    final int perInstanceIndex) {
355:                AbstractJoinPointCompiler.loadJoinPointInstance(cv, input);
356:
357:                if (perInstanceIndex >= 0) {
358:                    cv.visitVarInsn(ALOAD, perInstanceIndex);
359:                }
360:
361:                cv.visitMethodInsn(INVOKESTATIC, aspectInfo
362:                        .getAspectFactoryClassName(),
363:                        FACTORY_ASPECTOF_METHOD_NAME, "(Ljava/lang/Object;)"
364:                                + aspectInfo.getAspectClassSignature());
365:                //
366:                //        cv.visitLdcInsn(aspectInfo.getAspectClassName().replace('/', '.'));
367:                //        cv.visitLdcInsn(aspectInfo.getAspectQualifiedName());
368:                //        AsmHelper.loadStringConstant(cv, aspectInfo.getAspectDefinition().getContainerClassName());
369:                //        cv.visitMethodInsn(
370:                //                INVOKEINTERFACE,
371:                //                HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME,
372:                //                INSTANCE_LEVEL_GETASPECT_METHOD_NAME,
373:                //                INSTANCE_LEVEL_GETASPECT_METHOD_SIGNATURE
374:                //        );
375:                //
376:                //        cv.visitTypeInsn(CHECKCAST, aspectInfo.getAspectClassName());
377:
378:                cv.visitFieldInsn(PUTFIELD, input.joinPointClassName,
379:                        aspectInfo.getAspectFieldName(), aspectInfo
380:                                .getAspectClassSignature());
381:            }
382:
383:            /**
384:             * Creates the custom proceed methods.
385:             */
386:            private void createCustomProceedMethods(ClassWriter cw,
387:                    AbstractJoinPointCompiler compiler) {
388:                Set addedMethodSignatures = new HashSet();
389:                for (Iterator it = m_customProceedMethodStructs.iterator(); it
390:                        .hasNext();) {
391:                    CustomProceedMethodStruct customProceedStruct = (CustomProceedMethodStruct) it
392:                            .next();
393:                    MethodInfo methodInfo = customProceedStruct.customProceed;
394:                    final String desc = methodInfo.getSignature();
395:
396:                    if (addedMethodSignatures.contains(desc)) {
397:                        continue;
398:                    }
399:                    addedMethodSignatures.add(desc);
400:
401:                    MethodVisitor cv = cw.visitMethod(ACC_PUBLIC | ACC_FINAL,
402:                            PROCEED_METHOD_NAME, desc, null,
403:                            new String[] { THROWABLE_CLASS_NAME });
404:
405:                    // update the joinpoint instance with the given values
406:                    // starts at 1 since first arg is the custom join point by convention
407:                    //TODO see JoinPointManage for this custom jp is first convention
408:                    int argStackIndex = 1;
409:                    for (int i = 1; i < customProceedStruct.adviceToTargetArgs.length; i++) {
410:                        int targetArg = customProceedStruct.adviceToTargetArgs[i];
411:                        if (targetArg >= 0) {
412:                            // regular arg
413:                            String fieldName = compiler.m_fieldNames[targetArg];
414:                            cv.visitVarInsn(ALOAD, 0);
415:                            Type type = compiler.m_argumentTypes[targetArg];
416:                            argStackIndex = AsmHelper.loadType(cv,
417:                                    argStackIndex, type);
418:                            cv.visitFieldInsn(PUTFIELD,
419:                                    compiler.m_joinPointClassName, fieldName,
420:                                    type.getDescriptor());
421:                        } else if (targetArg == AdviceInfo.TARGET_ARG) {
422:                            cv.visitVarInsn(ALOAD, 0);
423:                            argStackIndex = AsmHelper
424:                                    .loadType(
425:                                            cv,
426:                                            argStackIndex,
427:                                            Type
428:                                                    .getType(compiler.m_calleeClassSignature));
429:                            cv.visitFieldInsn(PUTFIELD,
430:                                    compiler.m_joinPointClassName,
431:                                    CALLEE_INSTANCE_FIELD_NAME,
432:                                    compiler.m_calleeClassSignature);
433:                        } else if (targetArg == AdviceInfo.THIS_ARG) {
434:                            cv.visitVarInsn(ALOAD, 0);
435:                            argStackIndex = AsmHelper
436:                                    .loadType(
437:                                            cv,
438:                                            argStackIndex,
439:                                            Type
440:                                                    .getType(compiler.m_callerClassSignature));
441:                            cv.visitFieldInsn(PUTFIELD,
442:                                    compiler.m_joinPointClassName,
443:                                    CALLER_INSTANCE_FIELD_NAME,
444:                                    compiler.m_callerClassSignature);
445:                        } else {
446:                            ;//skip it
447:                        }
448:                    }
449:
450:                    // call proceed()
451:                    // and handles unwrapping for returning primitive
452:                    Type returnType = Type
453:                            .getType(customProceedStruct.customProceed
454:                                    .getReturnType().getSignature());
455:                    if (AsmHelper.isPrimitive(returnType)) {
456:                        cv.visitVarInsn(ALOAD, 0);
457:                        cv.visitMethodInsn(INVOKESPECIAL,
458:                                compiler.m_joinPointClassName,
459:                                PROCEED_METHOD_NAME, PROCEED_METHOD_SIGNATURE);
460:                        AsmHelper.unwrapType(cv, returnType);
461:                    } else {
462:                        cv.visitVarInsn(ALOAD, 0);
463:                        cv.visitMethodInsn(INVOKESPECIAL,
464:                                compiler.m_joinPointClassName,
465:                                PROCEED_METHOD_NAME, PROCEED_METHOD_SIGNATURE);
466:                        if (!returnType.getClassName().equals(
467:                                OBJECT_CLASS_SIGNATURE)) {
468:                            cv.visitTypeInsn(CHECKCAST, returnType
469:                                    .getInternalName());
470:                        }
471:                    }
472:                    AsmHelper.addReturnStatement(cv, returnType);
473:                    cv.visitMaxs(0, 0);
474:                }
475:            }
476:
477:            //---------- Model specific methods
478:
479:            /**
480:             * Collects the custom proceed methods used in the advice specified.
481:             *
482:             * @param model
483:             * @param advices
484:             */
485:            private void collectCustomProceedMethods(
486:                    final CompilationInfo.Model model,
487:                    final AdviceInfoContainer advices) {
488:                ClassLoader loader = model.getThisClassInfo().getClassLoader();
489:                final AdviceInfo[] beforeAdviceInfos = advices
490:                        .getBeforeAdviceInfos();
491:                for (int i = 0; i < beforeAdviceInfos.length; i++) {
492:                    collectCustomProceedMethods(beforeAdviceInfos[i], loader);
493:                }
494:                final AdviceInfo[] aroundAdviceInfos = advices
495:                        .getAroundAdviceInfos();
496:                for (int i = 0; i < aroundAdviceInfos.length; i++) {
497:                    collectCustomProceedMethods(aroundAdviceInfos[i], loader);
498:                }
499:                final AdviceInfo[] afterFinallyAdviceInfos = advices
500:                        .getAfterFinallyAdviceInfos();
501:                for (int i = 0; i < afterFinallyAdviceInfos.length; i++) {
502:                    collectCustomProceedMethods(afterFinallyAdviceInfos[i],
503:                            loader);
504:                }
505:                final AdviceInfo[] afterReturningAdviceInfos = advices
506:                        .getAfterReturningAdviceInfos();
507:                for (int i = 0; i < afterReturningAdviceInfos.length; i++) {
508:                    collectCustomProceedMethods(afterReturningAdviceInfos[i],
509:                            loader);
510:                }
511:                final AdviceInfo[] afterThrowingAdviceInfos = advices
512:                        .getAfterThrowingAdviceInfos();
513:                for (int i = 0; i < afterThrowingAdviceInfos.length; i++) {
514:                    collectCustomProceedMethods(afterThrowingAdviceInfos[i],
515:                            loader);
516:                }
517:            }
518:
519:            /**
520:             * Collects the custom proceed methods used in the advice specified.
521:             *
522:             * @param adviceInfo
523:             * @param loader
524:             */
525:            private void collectCustomProceedMethods(
526:                    final AdviceInfo adviceInfo, final ClassLoader loader) {
527:                final Type[] paramTypes = adviceInfo.getMethodParameterTypes();
528:                if (paramTypes.length != 0) {
529:                    Type firstParam = paramTypes[0];
530:                    //TODO should we support JP at other positions or lock the other advice models then so that JP..
531:                    // ..is not there or first only ?
532:                    // check if first param is an object but not a JP or SJP
533:                    if (firstParam.getSort() == Type.OBJECT
534:                            && !firstParam.getClassName().equals(
535:                                    JOIN_POINT_JAVA_CLASS_NAME)
536:                            && !firstParam.getClassName().equals(
537:                                    STATIC_JOIN_POINT_JAVA_CLASS_NAME)) {
538:                        ClassInfo classInfo = AsmClassInfo.getClassInfo(
539:                                firstParam.getClassName(), loader);
540:                        if (ClassInfoHelper.implements Interface(classInfo,
541:                                JOIN_POINT_JAVA_CLASS_NAME)
542:                                || ClassInfoHelper.implements Interface(
543:                                        classInfo,
544:                                        STATIC_JOIN_POINT_JAVA_CLASS_NAME)) {
545:                            // we have ourselves a custom joinpoint
546:                            MethodInfo[] methods = classInfo.getMethods();
547:                            for (int j = 0; j < methods.length; j++) {
548:                                MethodInfo method = methods[j];
549:                                if (method.getName()
550:                                        .equals(PROCEED_METHOD_NAME)) {
551:                                    // we inherit the binding from the advice that actually use us
552:                                    // for now the first advice sets the rule
553:                                    // it is up to the user to ensure consistency if the custom proceed
554:                                    // is used more than once in different advices.
555:                                    m_customProceedMethodStructs
556:                                            .add(new CustomProceedMethodStruct(
557:                                                    method,
558:                                                    adviceInfo
559:                                                            .getMethodToArgIndexes()));
560:                                }
561:                            }
562:                        }
563:                    }
564:                }
565:            }
566:
567:            private static class CustomProceedMethodStruct {
568:                MethodInfo customProceed;
569:                int[] adviceToTargetArgs;
570:
571:                public CustomProceedMethodStruct(MethodInfo customProceed,
572:                        int[] adviceToTargetArgs) {
573:                    this .customProceed = customProceed;
574:                    this .adviceToTargetArgs = adviceToTargetArgs;
575:                }
576:            }
577:
578:            public static void defaultCreateBeforeOrAfterAdviceArgumentHandling(
579:                    MethodVisitor cv, CompilerInput input,
580:                    Type[] joinPointArgumentTypes,
581:                    AdviceMethodInfo adviceMethodInfo, int specialArgIndex) {
582:                int[] argIndexes = adviceMethodInfo.getAdviceMethodArgIndexes();
583:                // if empty, we consider for now that we have to push JoinPoint for old advice with JoinPoint as sole arg
584:                for (int j = 0; j < argIndexes.length; j++) {
585:                    int argIndex = argIndexes[j];
586:                    if (argIndex >= 0) {
587:                        Type argumentType = joinPointArgumentTypes[argIndex];
588:                        int argStackIndex = AsmHelper.getRegisterIndexOf(
589:                                joinPointArgumentTypes, argIndex)
590:                                + input.argStartIndex;
591:                        AsmHelper.loadType(cv, argStackIndex, argumentType);
592:                    } else if (argIndex == AdviceInfo.JOINPOINT_ARG
593:                            || argIndex == AdviceInfo.STATIC_JOINPOINT_ARG) {
594:                        AbstractJoinPointCompiler.loadJoinPointInstance(cv,
595:                                input);
596:                    } else if (argIndex == AdviceInfo.TARGET_ARG) {
597:                        AbstractJoinPointCompiler.loadCallee(cv, input);
598:                        // add a cast if runtime check was used
599:                        if (adviceMethodInfo.getAdviceInfo()
600:                                .hasTargetWithRuntimeCheck()) {
601:                            cv.visitTypeInsn(CHECKCAST,
602:                                    adviceMethodInfo.getAdviceInfo()
603:                                            .getMethodParameterTypes()[j]
604:                                            .getInternalName());
605:                        }
606:                    } else if (argIndex == AdviceInfo.THIS_ARG) {
607:                        AbstractJoinPointCompiler.loadCaller(cv, input);
608:                    } else if (argIndex == AdviceInfo.SPECIAL_ARGUMENT
609:                            && specialArgIndex != INDEX_NOTAVAILABLE) {
610:                        Type argumentType = adviceMethodInfo.getAdviceInfo()
611:                                .getMethodParameterTypes()[j];
612:                        AsmHelper.loadType(cv, specialArgIndex, argumentType);
613:                        if (AdviceType.AFTER_THROWING.equals(adviceMethodInfo
614:                                .getAdviceInfo().getAdviceDefinition()
615:                                .getType())
616:                                || AdviceType.AFTER_RETURNING
617:                                        .equals(adviceMethodInfo
618:                                                .getAdviceInfo()
619:                                                .getAdviceDefinition()
620:                                                .getType())) {
621:                            cv.visitTypeInsn(CHECKCAST, argumentType
622:                                    .getInternalName());
623:                        }
624:                    } else {
625:                        throw new Error("magic index is not supported: "
626:                                + argIndex);
627:                    }
628:                }
629:            }
630:
631:            public static void defaultCreateAroundAdviceArgumentHandling(
632:                    MethodVisitor cv, CompilerInput input,
633:                    Type[] joinPointArgumentTypes,
634:                    AdviceMethodInfo adviceMethodInfo) {
635:                int[] argIndexes = adviceMethodInfo.getAdviceMethodArgIndexes();
636:                for (int j = 0; j < argIndexes.length; j++) {
637:                    int argIndex = argIndexes[j];
638:                    if (argIndex >= 0) {
639:                        Type argumentType = joinPointArgumentTypes[argIndex];
640:                        cv.visitVarInsn(ALOAD, 0);
641:                        cv.visitFieldInsn(GETFIELD, input.joinPointClassName,
642:                                ARGUMENT_FIELD + argIndex, argumentType
643:                                        .getDescriptor());
644:                    } else if (argIndex == AdviceInfo.JOINPOINT_ARG
645:                            || argIndex == AdviceInfo.STATIC_JOINPOINT_ARG
646:                            || argIndex == AdviceInfo.VALID_NON_AW_AROUND_CLOSURE_TYPE
647:                            || argIndex == AdviceInfo.CUSTOM_JOIN_POINT_ARG) {
648:                        cv.visitVarInsn(ALOAD, 0);
649:                    } else if (argIndex == AdviceInfo.TARGET_ARG) {
650:                        AbstractJoinPointCompiler.loadCallee(cv, input);
651:                        // add a cast if runtime check was used
652:                        if (adviceMethodInfo.getAdviceInfo()
653:                                .hasTargetWithRuntimeCheck()) {
654:                            cv.visitTypeInsn(CHECKCAST,
655:                                    adviceMethodInfo.getAdviceInfo()
656:                                            .getMethodParameterTypes()[j]
657:                                            .getInternalName());
658:                        }
659:                    } else if (argIndex == AdviceInfo.THIS_ARG) {
660:                        AbstractJoinPointCompiler.loadCaller(cv, input);
661:                    } else {
662:                        throw new Error(
663:                                "advice method argument index type is not supported: "
664:                                        + argIndex);
665:                    }
666:                }
667:            }
668:
669:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.