KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > cflow > CflowBinding


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.cflow;
5
6
7 import com.tc.aspectwerkz.aspect.AdviceType;
8 import com.tc.aspectwerkz.definition.AdviceDefinition;
9 import com.tc.aspectwerkz.definition.AspectDefinition;
10 import com.tc.aspectwerkz.definition.SystemDefinition;
11 import com.tc.aspectwerkz.reflect.impl.java.JavaClassInfo;
12 import com.tc.aspectwerkz.reflect.MethodInfo;
13 import com.tc.aspectwerkz.reflect.ClassInfo;
14 import com.tc.aspectwerkz.expression.ExpressionInfo;
15
16 import java.util.List JavaDoc;
17 import java.util.ArrayList JavaDoc;
18
19 /**
20  * A Cflow binding represents an extracted cflow or cflowbelow subexpression
21  * <p/>
22  * For a given pointcut "pcA and cflowA or cflowbelowB", we will extract two bindings.
23  * The m_cflowID must be unique on a per cflow sub expresion basis ie JVM wide.
24  * <p/>
25  * Note: CflowBinding hashcode depends on Cflow_ID (sub expr) + isCflowBelow only.
26  *
27  * @author <a HREF="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
28  */

29 public class CflowBinding {
30
31   /**
32    * the base implementation that hosts the cflow advices
33    */

34   private final static ClassInfo ABSTRACT_CFLOWCLASS = JavaClassInfo.getClassInfo(AbstractCflowSystemAspect.class);
35   private final static MethodInfo CFLOW_ENTER_ADVICE;
36   private final static MethodInfo CFLOW_EXIT_ADVICE;
37
38   static {
39     MethodInfo enter = null;
40     MethodInfo exit = null;
41     for (int i = 0; i < ABSTRACT_CFLOWCLASS.getMethods().length; i++) {
42       MethodInfo methodInfo = ABSTRACT_CFLOWCLASS.getMethods()[i];
43       if (methodInfo.getName().equals("enter")) {
44         enter = methodInfo;
45       } else if (methodInfo.getName().equals("exit")) {
46         exit = methodInfo;
47       }
48     }
49     if (enter == null || exit == null) {
50       throw new Error JavaDoc("Could not gather cflow advices from " + AbstractCflowSystemAspect.class);
51     } else {
52       CFLOW_ENTER_ADVICE = enter;
53       CFLOW_EXIT_ADVICE = exit;
54     }
55   }
56
57   /**
58    * cflow unique id
59    */

60   private int m_cflowID;
61
62   /**
63    * pointcut that represents this cflow sub-expression
64    */

65   private ExpressionInfo m_cflowSubExpression;
66
67   /**
68    * pointcut that represents the containing expression
69    */

70   private ExpressionInfo m_outerExpression;
71
72   /**
73    * marker if this binding is a cflow below, not used at the moment
74    */

75   private boolean m_isCflowBelow;
76
77   /**
78    * Cosntructs a new cflow binding
79    *
80    * @param cflowID
81    * @param cflowSubExpression
82    * @param isCflowBelow
83    */

84   public CflowBinding(int cflowID, ExpressionInfo cflowSubExpression, ExpressionInfo outerExpression, boolean isCflowBelow) {
85     m_cflowID = cflowID;
86     m_cflowSubExpression = cflowSubExpression;
87     m_outerExpression = outerExpression;
88     m_isCflowBelow = isCflowBelow;
89   }
90
91   /**
92    * @return the sub expression
93    */

94   public ExpressionInfo getExpression() {
95     return m_cflowSubExpression;
96   }
97
98   /**
99    * Extract the cflow bindings from any pointcut
100    * This includes both cflow and cflowbelow
101    *
102    * @param expressionInfo the pointcut expression frow where to extract the cflow bindings
103    * @return a list of CflowBinding, can be empty
104    */

105   public static List JavaDoc getCflowBindingsForCflowOf(ExpressionInfo expressionInfo) {
106     List JavaDoc cflowBindings = new ArrayList JavaDoc();
107     if (expressionInfo != null) {
108       expressionInfo.getCflowAspectExpression().populateCflowAspectBindings(cflowBindings);
109     }
110     return cflowBindings;
111   }
112
113   /**
114    * Create an aspect definition for this cflow binding in the given system.
115    * The cflow jit aspects will gets compiled and loaded
116    *
117    * @param systemDefinition
118    * @param loader
119    * @return the cflow aspect definition
120    */

121   public AspectDefinition getAspectDefinition(SystemDefinition systemDefinition, ClassLoader JavaDoc loader) {
122     String JavaDoc aspectName = CflowCompiler.getCflowAspectClassName(m_cflowID);
123
124     // check if we have already register this aspect
125
// TODO: it may happen that the aspect gets register somewhere up in the hierarchy ??
126
// it is optim only
127

128     // TODO: how to do this class define lazyly and not pass in a classloader ?
129
// could be done in the JIT jp clinit when 1+ advice has a cflow binding
130
Class JavaDoc aspectClass = CflowCompiler.compileCflowAspectAndAttachToClassLoader(loader, m_cflowID);
131     ClassInfo cflowAspectInfo = JavaClassInfo.getClassInfo(aspectClass);
132
133     AspectDefinition aspectDef = new AspectDefinition(
134             aspectName.replace('/', '.'),
135             cflowAspectInfo,
136             systemDefinition
137     );
138     aspectDef.addBeforeAdviceDefinition(
139             new AdviceDefinition(
140                     CFLOW_ENTER_ADVICE.getName(),
141                     AdviceType.BEFORE,
142                     null,
143                     aspectName,
144                     aspectName,
145                     m_cflowSubExpression,
146                     CFLOW_ENTER_ADVICE,
147                     aspectDef
148             )
149     );
150     aspectDef.addAfterAdviceDefinition(
151             new AdviceDefinition(
152                     CFLOW_EXIT_ADVICE.getName(),
153                     AdviceType.AFTER_FINALLY,
154                     null,
155                     aspectName,
156                     aspectName,
157                     m_cflowSubExpression,
158                     CFLOW_EXIT_ADVICE,
159                     aspectDef
160             )
161     );
162
163     return aspectDef;
164   }
165
166   public boolean isCflowBelow() {
167     return m_isCflowBelow;
168   }
169
170   public int getCflowID() {
171     return m_cflowID;
172   }
173
174   public boolean equals(Object JavaDoc o) {
175     if (this == o) return true;
176     if (!(o instanceof CflowBinding)) return false;
177
178     final CflowBinding cflowBinding = (CflowBinding) o;
179
180     if (m_cflowID != cflowBinding.m_cflowID) return false;
181     if (m_isCflowBelow != cflowBinding.m_isCflowBelow) return false;
182
183     return true;
184   }
185
186   public int hashCode() {
187     int result;
188     result = m_cflowID;
189     result = 29 * result + (m_isCflowBelow ? 1 : 0);
190     return result;
191   }
192 }
193
Popular Tags