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.definition;
9
10 import org.codehaus.aspectwerkz.AspectSystem;
11 import org.codehaus.aspectwerkz.ContextClassLoader;
12 import org.codehaus.aspectwerkz.CrossCuttingInfo;
13 import org.codehaus.aspectwerkz.DeploymentModel;
14 import org.codehaus.aspectwerkz.SystemLoader;
15 import org.codehaus.aspectwerkz.aspect.AspectContainer;
16 import org.codehaus.aspectwerkz.aspect.CFlowSystemAspect;
17 import org.codehaus.aspectwerkz.aspect.AdviceType;
18 import org.codehaus.aspectwerkz.aspect.management.AspectManager;
19 import org.codehaus.aspectwerkz.aspect.management.Pointcut;
20 import org.codehaus.aspectwerkz.aspect.management.PointcutManager;
21 import org.codehaus.aspectwerkz.exception.DefinitionException;
22 import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;
23 import org.codehaus.aspectwerkz.expression.ExpressionInfo;
24 import org.codehaus.aspectwerkz.joinpoint.JoinPoint;
25
26 import java.lang.reflect.Constructor;
27 import java.lang.reflect.InvocationTargetException;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32
33 /***
34 * Manages the startup procedure, walks through the definition and instantiates the
35 * aspects/advices/introduction/pointcuts. <p/>Reads the definition, either as a class of as an XML file. <p/>To use
36 * your XML definition file pass <code>-Daspectwerkz.definition.file=PathToFile</code> as parameter to the JVM. <p/>If
37 * the above given parameter is not specified, the <code>StartupManager</code> tries locate a file called
38 * <code>aspectwerkz.xml</code> in the classpath and if this fails the last attempt is to use the
39 * <code>ASPECTWERKZ_HOME/config/aspectwerkz.xml</code> file (if there is one).
40 *
41 * @author <a href="mailto:jboner@codehaus.org">Jonas Bonér </a>
42 * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
43 */
44 public class StartupManager {
45 /***
46 * The default aspect container class.
47 */
48 public static final String DEFAULT_ASPECT_CONTAINER = "org.codehaus.aspectwerkz.aspect.DefaultAspectContainerStrategy";
49
50 /***
51 * Private constructor to prevent instantiability.
52 */
53 private StartupManager() {
54 }
55
56 /***
57 * Loads the system definition.
58 *
59 * @param aspectManager the aspectManager for the system
60 * @param definition the definition for the system
61 */
62 public static void initializeSystem(final AspectManager aspectManager, final SystemDefinition definition) {
63
64 registerAspects(aspectManager, definition);
65 registerPointcuts(aspectManager, definition);
66 registerCflowPointcuts(aspectManager, definition);
67 }
68
69 /***
70 * ReLoads the system definition.
71 *
72 * @param loader the class loader
73 * @param definition the definition for the system
74 */
75 public static void reinitializeSystem(final ClassLoader loader, final SystemDefinition definition) {
76 AspectSystem aspectSystem = SystemLoader.getSystem(loader);
77 AspectManager aspectManager = aspectSystem.getAspectManager(definition.getUuid());
78
79
80
81 registerPointcuts(aspectManager, definition);
82 registerCflowPointcuts(aspectManager, definition);
83 return;
84 }
85
86 /***
87 * Creates a new aspect container.
88 *
89 * @param crossCuttingInfo the cross-cutting info for the aspect
90 */
91 public static AspectContainer createAspectContainer(final CrossCuttingInfo crossCuttingInfo) {
92 String containerClassName = "";
93 try {
94 Class klass;
95 containerClassName = crossCuttingInfo.getAspectDefinition().getContainerClassName();
96 if ((containerClassName == null)
97 || crossCuttingInfo.getAspectClass().getName().equals(CFlowSystemAspect.CLASS_NAME)) {
98 klass = ContextClassLoader.loadClass(DEFAULT_ASPECT_CONTAINER);
99 } else {
100 klass = ContextClassLoader.loadClass(containerClassName);
101 }
102 Constructor constructor = klass.getConstructor(new Class[] {
103 CrossCuttingInfo.class
104 });
105 return (AspectContainer) constructor.newInstance(new Object[] {
106 crossCuttingInfo
107 });
108 } catch (InvocationTargetException e) {
109 throw new DefinitionException(e.getTargetException().toString());
110 } catch (NoSuchMethodException e) {
111 throw new DefinitionException("aspect container does not have a valid constructor ["
112 + containerClassName
113 + "] (one that takes a CrossCuttingInfo instance as its only parameter): "
114 + e.toString());
115 } catch (Throwable e) {
116 StringBuffer cause = new StringBuffer();
117 cause.append("could not create aspect container using the implementation specified [");
118 cause.append(containerClassName);
119 cause.append("] due to: ");
120 cause.append(e.toString());
121 e.printStackTrace();
122 throw new DefinitionException(cause.toString());
123 }
124 }
125
126 /***
127 * Creates and registers the aspects defined.
128 *
129 * @param aspectManager the aspectManager for the system
130 * @param definition the definition
131 */
132 private static void registerAspects(final AspectManager aspectManager, final SystemDefinition definition) {
133 try {
134 for (Iterator it = definition.getAspectDefinitions().iterator(); it.hasNext();) {
135 AspectDefinition aspectDef = (AspectDefinition) it.next();
136 registerAspect(aspectManager, aspectDef, definition.getParameters(aspectDef.getName()));
137 }
138 } catch (NullPointerException e) {
139 throw new DefinitionException("aspects not properly defined");
140 } catch (Exception e) {
141 throw new WrappedRuntimeException(e);
142 }
143 }
144
145 /***
146 * Registers and creates a new aspect container for the aspect.
147 *
148 * @param aspectManager the aspectManager for the system
149 * @param aspectDef the aspect definition
150 */
151 private static void registerAspect(
152 final AspectManager aspectManager,
153 final AspectDefinition aspectDef,
154 final Map parameters) {
155 try {
156 String aspectClassName = aspectDef.getClassName();
157
158
159 final Class aspectClass;
160 try {
161 aspectClass = aspectManager.m_system.getDefiningClassLoader().loadClass(aspectClassName);
162 } catch (ClassNotFoundException e) {
163 throw new RuntimeException(aspectClassName + " could not be found on classpath: " + e.toString());
164 }
165 int deploymentModel;
166 if ((aspectDef.getDeploymentModel() == null) || aspectDef.getDeploymentModel().equals("")) {
167 deploymentModel = DeploymentModel.PER_JVM;
168 } else {
169 deploymentModel = DeploymentModel.getDeploymentModelAsInt(aspectDef.getDeploymentModel());
170 }
171
172
173 final CrossCuttingInfo crossCuttingInfoPrototype = new CrossCuttingInfo(
174 aspectManager.getUuid(),
175 aspectClass,
176 aspectDef.getName(),
177 deploymentModel,
178 aspectDef,
179 parameters);
180 final AspectContainer container = createAspectContainer(crossCuttingInfoPrototype);
181 crossCuttingInfoPrototype.setContainer(container);
182 PointcutManager pointcutManager = new PointcutManager(aspectDef.getName(), deploymentModel);
183 aspectManager.register(container, pointcutManager);
184 } catch (Exception e) {
185 throw new WrappedRuntimeException(e);
186 }
187 }
188
189 /***
190 * Creates and registers the aspects defined.
191 *
192 * @param aspectManager the aspectManager for the system
193 * @param definition the AspectWerkz definition
194 */
195 private static void registerPointcuts(final AspectManager aspectManager, final SystemDefinition definition) {
196 for (Iterator it = definition.getAspectDefinitions().iterator(); it.hasNext();) {
197 AspectDefinition aspectDef = (AspectDefinition) it.next();
198 if (aspectDef.getName().equals(CFlowSystemAspect.CLASS_NAME)) {
199 continue;
200 }
201 PointcutManager pointcutManager = aspectManager.getPointcutManager(aspectDef.getName());
202 for (Iterator it2 = aspectDef.getAroundAdvices().iterator(); it2.hasNext();) {
203 AdviceDefinition adviceDef = (AdviceDefinition) it2.next();
204 Pointcut pointcut = pointcutManager.getPointcut(adviceDef.getExpressionInfo().getExpressionAsString());
205 if (pointcut == null) {
206 pointcut = new Pointcut(aspectManager, adviceDef.getExpressionInfo());
207 pointcutManager.addPointcut(pointcut);
208 }
209 pointcut.addAroundAdvice(aspectDef.getName() + '/' + adviceDef.getName());
210 }
211 for (Iterator it2 = aspectDef.getBeforeAdvices().iterator(); it2.hasNext();) {
212 AdviceDefinition adviceDef = (AdviceDefinition) it2.next();
213 Pointcut pointcut = pointcutManager.getPointcut(adviceDef.getExpressionInfo().getExpressionAsString());
214 if (pointcut == null) {
215 pointcut = new Pointcut(aspectManager, adviceDef.getExpressionInfo());
216 pointcutManager.addPointcut(pointcut);
217 }
218 pointcut.addBeforeAdvice(aspectDef.getName() + '/' + adviceDef.getName());
219 }
220 for (Iterator it2 = aspectDef.getAfterAdvices().iterator(); it2.hasNext();) {
221 AdviceDefinition adviceDef = (AdviceDefinition) it2.next();
222 Pointcut pointcut = pointcutManager.getPointcut(adviceDef.getExpressionInfo().getExpressionAsString());
223 if (pointcut == null) {
224 pointcut = new Pointcut(aspectManager, adviceDef.getExpressionInfo());
225 pointcutManager.addPointcut(pointcut);
226 }
227 if (adviceDef.getType().equals(AdviceType.AFTER) ||
228 adviceDef.getType().equals(AdviceType.AFTER_FINALLY)) {
229 pointcut.addAfterFinallyAdvices(aspectDef.getName() + '/' + adviceDef.getName());
230 }
231 if (adviceDef.getType().equals(AdviceType.AFTER_RETURNING)) {
232 pointcut.addAfterReturningAdvices(aspectDef.getName() + '/' + adviceDef.getName());
233 }
234 if (adviceDef.getType().equals(AdviceType.AFTER_THROWING)) {
235 pointcut.addAfterThrowingAdvices(aspectDef.getName() + '/' + adviceDef.getName());
236 }
237 }
238 }
239 }
240
241 /***
242 * Registers the cflow pointcuts.
243 *
244 * @param aspectManager the aspectManager for the system
245 * @param definition the AspectWerkz definition
246 */
247 private static void registerCflowPointcuts(final AspectManager aspectManager, final SystemDefinition definition) {
248
249 for (Iterator it1 = definition.getAspectDefinitions().iterator(); it1.hasNext();) {
250 AspectDefinition aspectDef = (AspectDefinition) it1.next();
251 PointcutManager pointcutManager = aspectManager.getPointcutManager(aspectDef.getName());
252 List cflowPointcuts = pointcutManager.getCflowPointcuts();
253 for (Iterator it2 = cflowPointcuts.iterator(); it2.hasNext();) {
254 Pointcut cflowPointcut = (Pointcut) it2.next();
255 ExpressionInfo expressionInfo = cflowPointcut.getExpressionInfo();
256
257
258
259
260 if (!aspectManager.hasAspect(CFlowSystemAspect.NAME)) {
261 AspectDefinition cflowAspectDef = new AspectDefinition(
262 CFlowSystemAspect.NAME,
263 CFlowSystemAspect.CLASS_NAME,
264 aspectManager.getUuid());
265 PointcutDefinition pointcutDef = new PointcutDefinition(expressionInfo.getExpressionAsString());
266 cflowAspectDef.setDeploymentModel(CFlowSystemAspect.DEPLOYMENT_MODEL);
267 cflowAspectDef.addPointcut(pointcutDef);
268 try {
269 AdviceDefinition beforeAdviceDefinition = new AdviceDefinition(
270 CFlowSystemAspect.PRE_ADVICE,
271 AdviceType.BEFORE,
272 null,
273 cflowAspectDef.getName(),
274 cflowAspectDef.getClassName(),
275 expressionInfo,
276 CFlowSystemAspect.class.getDeclaredMethod(CFlowSystemAspect.PRE_ADVICE, new Class[] {
277 JoinPoint.class
278 }),
279 CFlowSystemAspect.PRE_ADVICE_INDEX,
280 cflowAspectDef);
281 cflowAspectDef.addBeforeAdvice(beforeAdviceDefinition);
282 AdviceDefinition afterAdviceDefinition = new AdviceDefinition(
283 CFlowSystemAspect.POST_ADVICE,
284 AdviceType.AFTER_FINALLY,
285 null,
286 cflowAspectDef.getName(),
287 cflowAspectDef.getClassName(),
288 expressionInfo,
289 CFlowSystemAspect.class.getDeclaredMethod(CFlowSystemAspect.POST_ADVICE, new Class[] {
290 JoinPoint.class
291 }),
292 CFlowSystemAspect.POST_ADVICE_INDEX,
293 cflowAspectDef);
294 cflowAspectDef.addAfterAdvice(afterAdviceDefinition);
295 } catch (NoSuchMethodException e) {
296 ;
297 }
298 definition.addAspect(cflowAspectDef);
299 registerAspect(aspectManager, cflowAspectDef, new HashMap());
300 }
301 cflowPointcut.addBeforeAdvice(CFlowSystemAspect.NAME + '/' + CFlowSystemAspect.PRE_ADVICE);
302 cflowPointcut.addAfterFinallyAdvices(CFlowSystemAspect.NAME + '/' + CFlowSystemAspect.POST_ADVICE);
303 }
304 }
305 }
306 }