KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > perx > PerObjectAspect


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.aspectwerkz.perx;
5
6 import com.tc.aspectwerkz.AspectContext;
7 import com.tc.aspectwerkz.DeploymentModel;
8 import com.tc.aspectwerkz.expression.ExpressionInfo;
9 import com.tc.aspectwerkz.aspect.AdviceType;
10 import com.tc.aspectwerkz.aspect.management.HasInstanceLevelAspect;
11 import com.tc.aspectwerkz.definition.AdviceDefinition;
12 import com.tc.aspectwerkz.definition.AspectDefinition;
13 import com.tc.aspectwerkz.definition.SystemDefinition;
14 import com.tc.aspectwerkz.reflect.impl.java.JavaClassInfo;
15 import com.tc.aspectwerkz.reflect.MethodInfo;
16 import com.tc.aspectwerkz.reflect.ClassInfo;
17 import com.tc.aspectwerkz.transform.TransformationConstants;
18
19 /**
20  * Generic aspect used by perX deployment modes to initialize the aspect instance.
21  * It gets registered programatically when finding perX aspects.
22  * fake
23  *
24  * @author <a HREF='mailto:the_mindstorm@evolva.ro'>Alexandru Popescu</a>
25  */

26 public class PerObjectAspect {
27
28   /**
29    * PerObjectAspect class name
30    */

31   public static final String JavaDoc PEROBJECT_ASPECT_NAME = PerObjectAspect.class.getName().replace('/', '.');
32
33   /**
34    * Name of system advice that will bind the aspect to the perX X instance.
35    * This advice is bound to the "X && target(aw_instance)" pointcut for pertarget(X)
36    * and "X && this(aw_instance)" pointcut for perthis(X) and thus its signature
37    * is a beforePerObjecr(HasInstanceLevelAspect aw_instance).
38    */

39   private static final String JavaDoc BEFORE_ADVICE_NAME = "beforePerObject";
40
41   /**
42    * Name of the advice argument where we bound the perX X instance.
43    */

44   public static final String JavaDoc ADVICE_ARGUMENT_NAME = "aw_Instance";
45
46   /**
47    * ClassInfo and method Info for the PerObjectAspect
48    */

49   private static final ClassInfo PEROBJECT_CLASSINFO = JavaClassInfo.getClassInfo(PerObjectAspect.class);
50   private static MethodInfo BEFORE_ADVICE_METHOD_INFO;
51
52   static {
53     MethodInfo[] methods = PEROBJECT_CLASSINFO.getMethods();
54     for (int i = 0; i < methods.length; i++) {
55       if (PerObjectAspect.BEFORE_ADVICE_NAME.equals(methods[i].getName())) {
56         BEFORE_ADVICE_METHOD_INFO = methods[i];
57         break;
58       }
59     }
60     if (BEFORE_ADVICE_METHOD_INFO == null) {
61       throw new Error JavaDoc("Could not find PerObjectAspect." + BEFORE_ADVICE_NAME);
62     }
63   }
64
65   /**
66    * One PerObjectAspect instance gets created for each X of perthis(X) / pertarget(X) and
67    * is passed as aspect context parameters the Qname of the perX aspect for which it acts
68    * and the container class name of that one.
69    */

70   private static final String JavaDoc ASPECT_QNAME_PARAM = "perobject.aspect.qname";
71   private static final String JavaDoc CONTAINER_CLASSNAME_PARAM = "perobject.container.classname";
72
73   private static final String JavaDoc ADVICE_ARGUMENT_TYPE = TransformationConstants.HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME.replace('/', '.');
74
75   private static final String JavaDoc ADVICE_SIGNATURE = BEFORE_ADVICE_NAME
76           + "("
77           + ADVICE_ARGUMENT_TYPE
78           + " "
79           + ADVICE_ARGUMENT_NAME
80           + ")";
81
82   private final String JavaDoc m_aspectQName;
83
84   private final String JavaDoc m_containerClassName;
85
86   /**
87    * PerObjectAspect constructor.
88    * We keep track of the aspectQname and container class name to further call Aspects.aspectOf
89    *
90    * @param ctx
91    */

92   public PerObjectAspect(AspectContext ctx) {
93     m_aspectQName = ctx.getParameter(ASPECT_QNAME_PARAM);
94     m_containerClassName = ctx.getParameter(CONTAINER_CLASSNAME_PARAM);
95   }
96
97   /**
98    * Before perPointcut && this/target(targetInstance) bound that will associate the aspect and the instance.
99    * Note: do not refactor the names here without refactoring the constants.
100    */

101   public void beforePerObject(HasInstanceLevelAspect aw_instance) {
102     if (aw_instance == null) {
103       return;
104     }
105     aw_instance.aw$getAspect(getClass());
106   }
107
108   /**
109    * Creates the generic AspectDefinition for the PerObjectAspect
110    *
111    * @param systemDefinition
112    * @param aspectDefinition
113    * @return definition for the perObjectAspect for the given perX aspect
114    */

115   public static AspectDefinition getAspectDefinition(SystemDefinition systemDefinition,
116                                                      AspectDefinition aspectDefinition) {
117     DeploymentModel.PointcutControlledDeploymentModel deploymentModel =
118             (DeploymentModel.PointcutControlledDeploymentModel) aspectDefinition.getDeploymentModel();
119
120     AspectDefinition perXSystemAspectDef = new AspectDefinition(
121             getAspectName(aspectDefinition.getQualifiedName(), deploymentModel),
122             PEROBJECT_CLASSINFO,
123             systemDefinition);
124
125     perXSystemAspectDef.setDeploymentModel(DeploymentModel.PER_JVM);
126     perXSystemAspectDef.addParameter(PerObjectAspect.ASPECT_QNAME_PARAM, aspectDefinition.getQualifiedName());
127     perXSystemAspectDef.addParameter(PerObjectAspect.CONTAINER_CLASSNAME_PARAM, aspectDefinition.getContainerClassName());
128
129     ExpressionInfo expressionInfo = createExpressionInfo(deploymentModel,
130             aspectDefinition.getQualifiedName(),
131             PEROBJECT_CLASSINFO.getClassLoader()
132     );
133
134     perXSystemAspectDef.addBeforeAdviceDefinition(
135             new AdviceDefinition(
136                     PerObjectAspect.ADVICE_SIGNATURE,
137                     AdviceType.BEFORE,
138                     null,
139                     perXSystemAspectDef.getName(),
140                     PEROBJECT_ASPECT_NAME,
141                     expressionInfo,
142                     BEFORE_ADVICE_METHOD_INFO,
143                     perXSystemAspectDef
144             )
145     );
146
147     return perXSystemAspectDef;
148   }
149
150   /**
151    * Naming strategy depends on the perX(X) X pointcut.
152    * One definition is created per perX X pointcut hashcode, thus perthis(X) and pertarget(X)
153    * are sharing the same system aspect perObjectAspect definition.
154    * Note: depends on perX aspect Qname to support pointcut references of the same name in 2 different aspect.
155    *
156    * @param perXAspectQName Qname of the perX deployed aspect
157    * @param deploymentModel
158    * @return
159    */

160   private static String JavaDoc getAspectName(String JavaDoc perXAspectQName,
161                                       DeploymentModel.PointcutControlledDeploymentModel deploymentModel) {
162     return PEROBJECT_ASPECT_NAME + '_' + perXAspectQName.hashCode() + '_' + deploymentModel.hashCode();
163   }
164
165   /**
166    * Create the expression info where to bind the perObjectAspect for the given perX model
167    *
168    * @param deployModel
169    * @param qualifiedName of the perX Aspect
170    * @param cl
171    * @return
172    */

173   public static ExpressionInfo createExpressionInfo(final DeploymentModel.PointcutControlledDeploymentModel deployModel,
174                                                     final String JavaDoc qualifiedName,
175                                                     final ClassLoader JavaDoc cl) {
176     ExpressionInfo expressionInfo = new ExpressionInfo(deployModel.getDeploymentExpression(), qualifiedName);
177     expressionInfo.addArgument(PerObjectAspect.ADVICE_ARGUMENT_NAME,
178             PerObjectAspect.ADVICE_ARGUMENT_TYPE,
179             cl);
180
181     return expressionInfo;
182   }
183
184 }
185
Popular Tags