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 org.codehaus.aspectwerkz.definition.SystemDefinitionContainer;
11 import org.codehaus.aspectwerkz.transform.AspectWerkzPreProcessor;
12 import org.codehaus.aspectwerkz.transform.Context;
13
14 import java.util.HashMap;
15 import java.util.List;
16 import java.util.Map;
17
18 /***
19 * Implementation of the transformation context interface for the delegation weaving.
20 *
21 * @author <a href="mailto:jboner@codehaus.org">Jonas Bonér </a>
22 * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
23 */
24 public class ContextImpl implements Context {
25 /***
26 * The name of the class.
27 */
28 private final String m_className;
29
30 /***
31 * The initial bytecode of the class
32 */
33 private byte[] m_initialBytecode;
34
35 /***
36 * The class loader for the class being transformed.
37 */
38 private final ClassLoader m_loader;
39
40 /***
41 * Marks the class being transformed as advised.
42 */
43 private boolean m_advised = false;
44
45 /***
46 * Marks the class being transformed as advised.
47 */
48 private boolean m_prepared = false;
49
50 /***
51 * Marks the context as read-only.
52 */
53 private boolean m_readOnly = false;
54
55 /***
56 * Meta-data for the transformation.
57 */
58 private Map m_metaData = new HashMap();
59
60 /***
61 * The contextual list of SystemDefinitions
62 */
63 private final List m_definitions;
64
65 /***
66 * The class abstraction.
67 */
68 private Klass m_classAbstraction;
69
70 /***
71 * Creates a new context.
72 *
73 * @param loader the class loader
74 */
75 public ContextImpl(final String className, final byte[] bytecode, final ClassLoader loader) {
76 m_className = className.replace('/', '.');
77 m_loader = loader;
78 m_initialBytecode = bytecode;
79
80 m_classAbstraction = new Klass(className, bytecode, loader);
81
82
83 m_definitions = SystemDefinitionContainer.getHierarchicalDefs(m_loader);
84 }
85
86 public String getClassName() {
87 return m_className;
88 }
89
90 /***
91 * @return bytecode
92 */
93 public byte[] getInitialBytecode() {
94 return m_initialBytecode;
95 }
96
97 /***
98 * @return bytecode
99 */
100 public byte[] getCurrentBytecode() {
101 return m_classAbstraction.getBytecode();
102 }
103
104 /***
105 * Sets the current bytecode.
106 *
107 * @param bytecode
108 */
109 public void setCurrentBytecode(final byte[] bytecode) {
110
111 }
112
113 /***
114 * Returns the class abstraction.
115 *
116 * @return clazz
117 */
118 public Object getClassAbstraction() {
119 return m_classAbstraction;
120 }
121
122 /***
123 * Returns the class loader.
124 *
125 * @return the class loader
126 */
127 public ClassLoader getLoader() {
128 return m_loader;
129 }
130
131 /***
132 * The definitions context (with hierarchical structure)
133 *
134 * @return
135 */
136 public List getDefinitions() {
137 return m_definitions;
138 }
139
140 /***
141 * Marks the class being transformed as advised. The marker can at most be set once per class per transformer
142 */
143 public void markAsAdvised() {
144 m_advised = true;
145 }
146
147 /***
148 * Marks the class as prepared.
149 */
150 public void markAsPrepared() {
151 m_prepared = true;
152 }
153
154 /***
155 * Resets the isAdviced flag.
156 */
157 public void resetAdvised() {
158 m_advised = false;
159 }
160
161 /***
162 * Checks if the class being transformed has beed advised.
163 *
164 * @return boolean
165 */
166 public boolean isAdvised() {
167 return m_advised;
168 }
169
170 /***
171 * Checks if the class is prepared.
172 *
173 * @return
174 */
175 public boolean isPrepared() {
176 return m_prepared;
177 }
178
179 /***
180 * Marks the context as read-only.
181 */
182 public void markAsReadOnly() {
183 m_readOnly = true;
184 }
185
186 /***
187 * Checks if the context is read-only.
188 *
189 * @return boolean
190 */
191 public boolean isReadOnly() {
192 return m_readOnly;
193 }
194
195 /***
196 * Returns meta-data for the transformation.
197 *
198 * @param key the key
199 * @return the value
200 */
201 public Object getMetaData(final Object key) {
202 return m_metaData.get(key);
203 }
204
205 /***
206 * Adds new meta-data for the transformation.
207 *
208 * @param key the key
209 * @param value the value
210 */
211 public void addMetaData(final Object key, final Object value) {
212 if (m_readOnly) {
213 throw new IllegalStateException("context is read only");
214 }
215 m_metaData.put(key, value);
216 }
217
218 /***
219 * Dump the class to specific directory.
220 *
221 * @param dir
222 */
223 public void dump(final String dir) {
224 try {
225 m_classAbstraction.getCtClass().writeFile(dir);
226 m_classAbstraction.getCtClass().defrost();
227 } catch (Exception e) {
228 AspectWerkzPreProcessor.log("failed to dump " + m_classAbstraction.getName());
229 e.printStackTrace();
230 }
231 }
232 }