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.transform.delegation;
9
10 import java.util.ArrayList;
11 import java.util.Hashtable;
12 import java.util.Iterator;
13 import java.util.List;
14
15 import org.codehaus.aspectwerkz.transform.AspectWerkzPreProcessor;
16 import org.codehaus.aspectwerkz.transform.Context;
17 import org.codehaus.aspectwerkz.transform.Transformer;
18 import org.codehaus.aspectwerkz.transform.WeavingStrategy;
19
20 /***
21 * A weaving strategy implementing a weaving scheme based on delegation.
22 *
23 * @author <a href="mailto:jboner@codehaus.org">Jonas Bonér </a>
24 * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
25 */
26 public class DelegationWeavingStrategy implements WeavingStrategy {
27 /***
28 * The transformation m_stack
29 */
30 private List m_stack;
31
32 /***
33 * The transformer to add serial ver uid Out of the transformation stack to be applied only if class is weaved
34 */
35 private Transformer m_addSerialVerUidTransformer;
36
37 /***
38 * Initializes the transformer stack.
39 *
40 * @param params not used
41 */
42 public void initialize(final Hashtable params) {
43 m_addSerialVerUidTransformer = new AddSerialVersionUidTransformer();
44
45
46 m_stack = new ArrayList();
47 m_stack.add(new PrepareAdvisedClassTransformer());
48 m_stack.add(new AddInterfaceTransformer());
49 m_stack.add(new AddImplementationTransformer());
50
51
52 m_stack.add(new PrepareAdvisedClassTransformer());
53 m_stack.add(new FieldSetGetTransformer());
54 m_stack.add(new MethodCallTransformer());
55 m_stack.add(new ConstructorCallTransformer());
56 m_stack.add(new MethodExecutionTransformer());
57 m_stack.add(new ConstructorExecutionTransformer());
58 m_stack.add(new HandlerTransformer());
59 }
60
61 /***
62 * Transforms the class.
63 *
64 * @param className
65 * @param context
66 */
67 public void transform(final String className, final Context context) {
68 boolean advisedAtLeastOnce = false;
69 Klass klass = (Klass) context.getClassAbstraction();
70 for (Iterator it = m_stack.iterator(); it.hasNext();) {
71 Object transformer = it.next();
72 if (transformer instanceof Transformer) {
73 Transformer tf = (Transformer) transformer;
74 context.resetAdvised();
75 try {
76 tf.transform(context, klass);
77 } catch (Exception e) {
78 e.printStackTrace();
79 }
80 if (context.isAdvised()) {
81 advisedAtLeastOnce = true;
82 }
83 if (context.isAdvised()) {
84 AspectWerkzPreProcessor.log(" " + className + " <- " + transformer.getClass().getName());
85 }
86 }
87 }
88
89 if (advisedAtLeastOnce) {
90 try {
91 m_addSerialVerUidTransformer.transform(context, klass);
92 } catch (Exception e) {
93 System.err.println(
94 "WARNING: could not add new serial version UID to class [" + klass.getName() +
95 "] and this might cause problems with serialization"
96 );
97 e.printStackTrace();
98 }
99 }
100 }
101
102 /***
103 * Creates a new transformation context.
104 *
105 * @param name
106 * @param bytecode
107 * @param loader
108 * @return
109 */
110 public Context newContext(final String name, final byte[] bytecode, final ClassLoader loader) {
111 return new ContextImpl(name, bytecode, loader);
112 }
113 }