1 /***************************************************************************************
2 * Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved. *
3 * http://aspectwerkz.codehaus.org *
4 * ---------------------------------------------------------------------------------- *
5 * The software in this package is published under the terms of the LGPL license *
6 * a copy of which has been included with this distribution in the license.txt file. *
7 **************************************************************************************/
8 package org.codehaus.aspectwerkz.aspect;
9
10 import org.codehaus.aspectwerkz.AspectSystem;
11 import org.codehaus.aspectwerkz.CrossCuttingInfo;
12 import org.codehaus.aspectwerkz.definition.SystemDefinition;
13 import org.codehaus.aspectwerkz.expression.PointcutType;
14 import org.codehaus.aspectwerkz.joinpoint.JoinPoint;
15 import org.codehaus.aspectwerkz.joinpoint.MethodRtti;
16 import org.codehaus.aspectwerkz.reflect.ClassInfo;
17 import org.codehaus.aspectwerkz.reflect.MethodInfo;
18 import org.codehaus.aspectwerkz.reflect.impl.java.JavaClassInfo;
19 import org.codehaus.aspectwerkz.reflect.impl.java.JavaMethodInfo;
20 import org.codehaus.aspectwerkz.transform.ReflectHelper;
21
22 import java.lang.reflect.Method;
23 import java.util.Iterator;
24 import java.util.List;
25
26 /***
27 * Manages the cflow pointcuts.
28 *
29 * @author <a href="mailto:jboner@codehaus.org">Jonas Bonér </a>
30 * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
31 */
32 public class CFlowSystemAspect {
33 /***
34 * The class name for the aspect.
35 */
36 public static final String CLASS_NAME = CFlowSystemAspect.class.getName();
37
38 /***
39 * A unique name for the aspect.
40 */
41 public static final String NAME = CLASS_NAME.replace('.', '$');
42
43 /***
44 * The deployment model for the aspect.
45 */
46 public static final String DEPLOYMENT_MODEL = SystemDefinition.PER_THREAD;
47
48 /***
49 * The name of the pre advice method.
50 */
51 public static final String PRE_ADVICE = "enterControlFlow";
52
53 /***
54 * The name of the post advice method.
55 */
56 public static final String POST_ADVICE = "exitControlFlow";
57
58 /***
59 * Index of the pre advice method.
60 */
61 public static final int PRE_ADVICE_INDEX;
62
63 /***
64 * Index of the post advice method.
65 */
66 public static final int POST_ADVICE_INDEX;
67
68 static {
69
70
71
72 List methods = ReflectHelper.createCompleteSortedMethodList(CFlowSystemAspect.class);
73 int index = 0;
74 int preIndex = 0;
75 int postIndex = 0;
76 for (Iterator i = methods.iterator(); i.hasNext(); index++) {
77 Method m = (Method) i.next();
78 if (PRE_ADVICE.equals(m.getName())) {
79 preIndex = index;
80 } else if (POST_ADVICE.equals(m.getName())) {
81 postIndex = index;
82 }
83 }
84 PRE_ADVICE_INDEX = preIndex;
85 POST_ADVICE_INDEX = postIndex;
86 }
87
88 /***
89 * Reference to the system.
90 */
91 private AspectSystem m_system = null;
92
93 /***
94 * Creates a new cflow system aspect instance.
95 *
96 * @param info the cross-cutting info
97 */
98 public CFlowSystemAspect(final CrossCuttingInfo info) {
99 m_system = info.getSystem();
100 }
101
102 /***
103 * Registers the join point as the start of a control flow (cflow) in the system.
104 *
105 * @param joinPoint the join point
106 * @throws Throwable the exception from the invocation
107 */
108 public void enterControlFlow(final JoinPoint joinPoint) throws Throwable {
109 m_system.enteringControlFlow(
110 getPointcutType(joinPoint),
111 createMethodInfo(joinPoint),
112 createWithinInfo(joinPoint));
113 }
114
115 /***
116 * Registers the join point as the end of a control flow (cflow) in the system.
117 *
118 * @param joinPoint the join point
119 * @throws Throwable the exception from the invocation
120 */
121 public void exitControlFlow(final JoinPoint joinPoint) throws Throwable {
122 m_system.exitingControlFlow(
123 getPointcutType(joinPoint),
124 createMethodInfo(joinPoint),
125 createWithinInfo(joinPoint));
126 }
127
128 /***
129 * Returns the pointcut type for the join point.
130 *
131 * @param joinPoint the join point
132 * @return the pointcut type
133 */
134 private PointcutType getPointcutType(final JoinPoint joinPoint) {
135 String type = joinPoint.getType();
136 if (type.equals(JoinPoint.METHOD_EXECUTION) || type.equals(JoinPoint.CONSTRUCTOR_EXECUTION)) {
137 return PointcutType.EXECUTION;
138 } else if (type.equals(JoinPoint.METHOD_CALL) || type.equals(JoinPoint.CONSTRUCTOR_CALL)) {
139 return PointcutType.CALL;
140 } else if (type.endsWith(JoinPoint.FIELD_SET)) {
141 return PointcutType.SET;
142 } else if (type.endsWith(JoinPoint.FIELD_GET)) {
143 return PointcutType.GET;
144 } else if (type.equals(JoinPoint.HANDLER)) {
145 return PointcutType.HANDLER;
146 } else if (type.endsWith(JoinPoint.STATIC_INITIALIZATION)) {
147 return PointcutType.STATIC_INITIALIZATION;
148 } else {
149 throw new IllegalStateException("join point [" + type + "] is unknown");
150 }
151 }
152
153 /***
154 * Creates info for the method.
155 *
156 * @return the created method info
157 */
158 private static MethodInfo createMethodInfo(final JoinPoint joinPoint) {
159 MethodRtti rtti = (MethodRtti) joinPoint.getRtti();
160 Method method = rtti.getMethod();
161 return JavaMethodInfo.getMethodInfo(method);
162 }
163
164 /***
165 * Creates info for the within class.
166 *
167 * @return the created within info
168 */
169 private static ClassInfo createWithinInfo(final JoinPoint joinPoint) {
170 Class targetClass = joinPoint.getTargetClass();
171 return JavaClassInfo.getClassInfo(targetClass);
172 }
173 }