KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > transform > InstrumentationContext


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.transform;
5
6 import com.tc.asm.Label;
7
8 import com.tc.aspectwerkz.definition.SystemDefinitionContainer;
9 import com.tc.aspectwerkz.proxy.ProxyDelegationStrategy;
10 import com.tc.aspectwerkz.proxy.ProxySubclassingStrategy;
11 import com.tc.aspectwerkz.transform.inlining.EmittedJoinPoint;
12
13 import java.io.File JavaDoc;
14 import java.io.FileOutputStream JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.Set JavaDoc;
20
21
22 /**
23  * Implementation of the transformation context interface for the delegation weaving.
24  *
25  * @author <a HREF="mailto:jboner@codehaus.org">Jonas BonŽr </a>
26  * @author <a HREF="mailto:alex@gnilux.com">Alexandre Vasseur </a>
27  */

28 public class InstrumentationContext {
29   /**
30    * The name of the class.
31    */

32   private final String JavaDoc m_className;
33
34   /**
35    * The initial bytecode of the class
36    */

37   private final byte[] m_initialBytecode;
38
39   /**
40    * The current bytecode of the class
41    */

42   private byte[] m_currentBytecode;
43
44   /**
45    * The class loader for the class being transformed.
46    */

47   private final ClassLoader JavaDoc m_loader;
48
49   /**
50    * Marks the class being transformed as advised.
51    */

52   private boolean m_advised = false;
53
54   /**
55    * Marks the class being transformed as made advisable for interceptor support.
56    */

57   private boolean m_madeAdvisable = false;
58
59   /**
60    * Is the class being transformed a proxy or not?
61    */

62   private boolean m_isProxy = false;
63
64   /**
65    * Marks the context as read-only.
66    */

67   private boolean m_readOnly = false;
68
69   /**
70    * Meta-data for the transformation.
71    */

72   private Map JavaDoc m_metaData = new HashMap JavaDoc();
73
74   /**
75    * The contextual set of SystemDefinitions
76    */

77   private final Set JavaDoc m_definitions;
78
79   /**
80    * The emitted join points.
81    */

82   private final List JavaDoc m_emittedJoinPoints = new ArrayList JavaDoc();
83
84   /**
85    * A map of line number per label.
86    * Note: labels are valid in the scope of one single ASM accept() only (one phase)
87    */

88   private final HashMap JavaDoc m_labelTolineNumbers = new HashMap JavaDoc();
89
90   private long m_serialVerUid;
91
92   /**
93    * Creates a new context.
94    */

95   public InstrumentationContext(final String JavaDoc className, final byte[] bytecode, final ClassLoader JavaDoc loader, final Set JavaDoc definitions) {
96     m_className = className.replace('.', '/');
97     m_loader = loader;
98     m_initialBytecode = bytecode;
99     m_currentBytecode = bytecode;
100     m_definitions = definitions;
101     if (isAWProxy(className) || isCGLIBProxy(className) || isDynamicProxy(className)) {
102       markAsProxy();
103     }
104   }
105
106   /**
107    * Creates a new context.
108    */

109   public InstrumentationContext(final String JavaDoc className, final byte[] bytecode, final ClassLoader JavaDoc loader) {
110     this(className, bytecode, loader, SystemDefinitionContainer.getDefinitionsFor(loader));
111   }
112
113   public String JavaDoc getClassName() {
114     return m_className;
115   }
116
117   /**
118    * Returns the initial bytecode.
119    *
120    * @return bytecode
121    */

122   public byte[] getInitialBytecode() {
123     return m_initialBytecode;
124   }
125
126   /**
127    * Returns the current bytecode.
128    *
129    * @return bytecode
130    */

131   public byte[] getCurrentBytecode() {
132     return m_currentBytecode;
133   }
134
135   /**
136    * Sets the current bytecode.
137    *
138    * @param bytecode
139    */

140   public void setCurrentBytecode(final byte[] bytecode) {
141     m_currentBytecode = bytecode;
142   }
143
144   /**
145    * Returns the class loader.
146    *
147    * @return the class loader
148    */

149   public ClassLoader JavaDoc getLoader() {
150     return m_loader;
151   }
152
153   /**
154    * The definitions context (with hierarchical structure)
155    *
156    * @return
157    */

158   public Set JavaDoc getDefinitions() {
159     return m_definitions;
160   }
161
162   /**
163    * Marks the class being transformed as advised. The marker can at most be set once per class per transformer
164    */

165   public void markAsAdvised() {
166     m_advised = true;
167   }
168
169   /**
170    * Marks the class as made advisable.
171    */

172   public void markMadeAdvisable() {
173     m_madeAdvisable = true;
174   }
175
176   /**
177    * Resets the isAdviced flag.
178    */

179   public void resetAdvised() {
180     m_advised = false;
181   }
182
183   /**
184    * Is the class being transformed a proxy or not?
185    */

186   public boolean isProxy() {
187     return m_isProxy;
188   }
189
190   /**
191    * Marks the class being transformed as a proxy.
192    */

193   public void markAsProxy() {
194     m_isProxy = true;
195   }
196
197   /**
198    * Checks if the class being transformed has beed advised.
199    *
200    * @return boolean
201    */

202   public boolean isAdvised() {
203     return m_advised;
204   }
205
206   /**
207    * Checks if the class has been made advisable.
208    *
209    * @return
210    */

211   public boolean isMadeAdvisable() {
212     return m_madeAdvisable;
213   }
214
215   /**
216    * Marks the context as read-only.
217    */

218   public void markAsReadOnly() {
219     m_readOnly = true;
220   }
221
222   /**
223    * Checks if the context is read-only.
224    *
225    * @return boolean
226    */

227   public boolean isReadOnly() {
228     return m_readOnly;
229   }
230
231   /**
232    * Returns meta-data for the transformation.
233    *
234    * @param key the key
235    * @return the value
236    */

237   public Object JavaDoc getMetaData(final Object JavaDoc key) {
238     return m_metaData.get(key);
239   }
240
241   /**
242    * Adds new meta-data for the transformation.
243    *
244    * @param key the key
245    * @param value the value
246    */

247   public void addMetaData(final Object JavaDoc key, final Object JavaDoc value) {
248     if (m_readOnly) {
249       throw new IllegalStateException JavaDoc("context is read only");
250     }
251     m_metaData.put(key, value);
252   }
253
254   /**
255    * Dumps the class to specific directory.
256    *
257    * @param dumpDir
258    */

259   public void dump(final String JavaDoc dumpDir) {
260     try {
261       int lastSegmentIndex = m_className.lastIndexOf('/');
262       if (lastSegmentIndex < 0) {
263         lastSegmentIndex = 0;
264       }
265       File JavaDoc dir = new File JavaDoc(dumpDir + File.separator + m_className.substring(0, lastSegmentIndex));
266       dir.mkdirs();
267       FileOutputStream JavaDoc os = new FileOutputStream JavaDoc(
268               dumpDir
269                       + File.separator
270                       + m_className.replace('.', '/')
271                       + ".class"
272       );
273       os.write(m_currentBytecode);
274       os.close();
275     } catch (Exception JavaDoc e) {
276       System.err.println("failed to dump " + m_className);
277       e.printStackTrace();
278     }
279   }
280
281   /**
282    * Adds a new EmittedJoinPoint
283    *
284    * @param jp
285    */

286   public void addEmittedJoinPoint(final EmittedJoinPoint jp) {
287     m_emittedJoinPoints.add(jp);
288   }
289
290   /**
291    * Returns all the EmittedJoinPoints
292    *
293    * @return
294    */

295   public List JavaDoc getEmittedJoinPoints() {
296     return m_emittedJoinPoints;
297   }
298
299   public void setSerialVerUid(long initialSerialVerUid) {
300     m_serialVerUid = initialSerialVerUid;
301   }
302
303   public long getSerialVerUid() {
304     return m_serialVerUid;
305   }
306
307   public void addLineNumberInfo(Label label, int lineNumber) {
308     m_labelTolineNumbers.put(label, new Integer JavaDoc(lineNumber));
309   }
310
311   /**
312    * Tries to resolve the line number from the given label
313    *
314    * @param label
315    * @return
316    */

317   public int resolveLineNumberInfo(Label label) {
318     Integer JavaDoc info = (Integer JavaDoc) m_labelTolineNumbers.get(label);
319     return info==null ? 0 : info.intValue();
320   }
321
322   public static boolean isAWProxy(final String JavaDoc className) {
323     return className.indexOf(ProxySubclassingStrategy.PROXY_SUFFIX) != -1
324             || className.indexOf(ProxyDelegationStrategy.PROXY_SUFFIX) != -1;
325   }
326
327   public static boolean isCGLIBProxy(final String JavaDoc className) {
328     return className.indexOf("$$EnhancerByCGLIB$$") != -1
329             || className.indexOf("$$FastClassByCGLIB$$") != -1;
330   }
331
332   private boolean isDynamicProxy(final String JavaDoc className) {
333     return className.startsWith("$Proxy");
334   }
335 }
Popular Tags