KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > aspectwerkz > cflow > CflowBinding


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

32 public class CflowBinding {
33
34     /**
35      * the base implementation that hosts the cflow advices
36      */

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

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

67     private ExpressionInfo m_cflowSubExpression;
68
69     /**
70      * pointcut that represents the containing expression
71      */

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

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

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

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

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

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

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