View Javadoc

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('/', '.');//TODO change this to only have "/" based.
77          m_loader = loader;
78          m_initialBytecode = bytecode;
79  
80          m_classAbstraction = new Klass(className, bytecode, loader);
81  
82          // Note: we are not using a lazy loading for the definitions since it is cached anyway
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         // does nothing for this context impl, is handled by the class abstraction
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 }