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;
9   
10  import org.codehaus.aspectwerkz.aspect.AspectContainer;
11  import org.codehaus.aspectwerkz.aspect.management.Aspects;
12  import org.codehaus.aspectwerkz.definition.AspectDefinition;
13  
14  import java.io.ObjectInputStream;
15  import java.io.Serializable;
16  import java.util.HashMap;
17  import java.util.Map;
18  import java.lang.ref.WeakReference;
19  
20  /***
21   * Contains information about and for classes that has been defined as cross-cutting.
22   *
23   * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
24   */
25  public final class AspectContext implements Serializable {
26      /***
27       * An empty <code>Object</code> array.
28       */
29      public static final Object[] EMPTY_OBJECT_ARRAY = new Object[]{};
30  
31      /***
32       * The name for the cross-cuttable class.
33       */
34      private String m_name;
35  
36      /***
37       * The qualified name of the aspect
38       */
39      private String m_qName;
40  
41      /***
42       * The aspect class, wrapped in a weak reference since is a key of aspect container referenced by this object.
43       */
44      private transient WeakReference m_aspectClassRef;
45  
46      /***
47       * The container.
48       */
49      private transient AspectContainer m_container = null;
50  
51      /***
52       * Holds the deployment model.
53       */
54      private DeploymentModel m_deploymentModel;
55  
56      /***
57       * Holds the parameters passed to the aspect.
58       */
59      private Map m_parameters = new HashMap();
60  
61      /***
62       * Holds the metadata.
63       */
64      private Map m_metaData = new HashMap();
65  
66      /***
67       * The UUID for the system.
68       */
69      private String m_uuid;
70  
71      /***
72       * The aspect definition.
73       */
74      private transient AspectDefinition m_aspectDefinition;
75  
76      /***
77       * Creates a new cross-cutting info instance.
78       *
79       * @param uuid
80       * @param aspectClass
81       * @param deploymentModel
82       * @param aspectDef
83       * @param parameters
84       */
85      public AspectContext(final String uuid,
86                           final Class aspectClass,
87                           final String name,
88                           final DeploymentModel deploymentModel,
89                           final AspectDefinition aspectDef,
90                           final Map parameters) {
91          m_uuid = uuid;
92          m_aspectClassRef = new WeakReference(aspectClass);
93          m_name = name;
94          m_qName = aspectDef.getQualifiedName();
95          m_deploymentModel = deploymentModel;
96          m_aspectDefinition = aspectDef;
97          if (parameters != null) {
98              m_parameters = parameters;
99          }
100     }
101 
102     /***
103      * Copy constructor - creates a clone of the cross-cutting info.
104      * Creates a new instance of the cross-cutting class it holds.
105      *
106      * @return a clone of the cross-cutting info
107      */
108     public static AspectContext newInstance(final AspectContext prototype) {
109         try {
110             return new AspectContext(
111                     prototype.m_uuid,
112                     (Class) prototype.m_aspectClassRef.get(),
113                     prototype.m_name,
114                     prototype.m_deploymentModel,
115                     prototype.m_aspectDefinition,
116                     prototype.m_parameters
117             );
118         } catch (Exception e) {
119             throw new RuntimeException(
120                     "could not clone cross-cutting info ["
121                     + prototype.getName()
122                     + "]: "
123                     + e.toString()
124             );
125         }
126     }
127 
128     /***
129      * Returns the UUID for the system.
130      *
131      * @return the UUID for the system
132      */
133     public String getUuid() {
134         return m_uuid;
135     }
136 
137     /***
138      * Returns the name of the aspect.
139      *
140      * @return the name of the aspect
141      */
142     public String getName() {
143         return m_name;
144     }
145 
146     /***
147      * Returns the deployment model.
148      *
149      * @return the deployment model
150      */
151     public DeploymentModel getDeploymentModel() {
152         return m_deploymentModel;
153     }
154 
155     /***
156      * Returns the cross-cuttable class.
157      *
158      * @return the cross-cuttable class
159      */
160     public Class getAspectClass() {
161         return (Class) m_aspectClassRef.get();
162     }
163 
164     /***
165      * Sets the container.
166      *
167      * @param container the container
168      */
169     public void setContainer(final AspectContainer container) {
170         m_container = container;
171     }
172 
173     /***
174      * Returns the container.
175      *
176      * @return the container
177      */
178     public AspectContainer getContainer() {
179         return m_container;
180     }
181 
182     /***
183      * Returns the aspect definition.
184      * <p/>
185      * Will return null after deserialization.
186      *
187      * @return the aspect definition
188      */
189     public AspectDefinition getAspectDefinition() {
190         return m_aspectDefinition;
191     }
192 
193     /***
194      * Sets a parameter.
195      *
196      * @param name  the name of the parameter
197      * @param value the value of the parameter
198      */
199     public void setParameter(final String name, final String value) {
200         m_parameters.put(name, value);
201     }
202 
203     /***
204      * Returns the value of a parameter.
205      *
206      * @param name the name of the parameter
207      * @return the value of the parameter or null if not specified
208      */
209     public String getParameter(final String name) {
210         return (String) m_parameters.get(name);
211     }
212 
213     /***
214      * Adds metadata.
215      *
216      * @param key   the key
217      * @param value the value
218      */
219     public void addMetaData(final Object key, final Object value) {
220         m_metaData.put(key, value);
221     }
222 
223     /***
224      * Returns the metadata for a specific key.
225      *
226      * @param key the key
227      * @return the value
228      */
229     public Object getMetaData(final Object key) {
230         return m_metaData.get(key);
231     }
232 
233     /***
234      * Return true if the AspectContext has not yet the AspectContainer set, that means this is the prototype init time
235      */
236     public boolean isPrototype() {
237         return (m_container == null);
238     }
239 
240     /***
241      * Provides custom deserialization.
242      *
243      * @param stream the object input stream containing the serialized object
244      * @throws Exception in case of failure
245      */
246     private void readObject(final ObjectInputStream stream) throws Exception {
247         ObjectInputStream.GetField fields = stream.readFields();
248         m_uuid = (String) fields.get("m_uuid", null);
249         m_name = (String) fields.get("m_name", null);
250         m_qName = (String) fields.get("m_qName", null);
251         Class aspectClass = Class.forName(m_name);
252         m_aspectClassRef = new WeakReference(aspectClass);
253         m_deploymentModel = (DeploymentModel) fields.get("m_deploymentModel", DeploymentModel.PER_JVM);
254         m_parameters = (Map) fields.get("m_parameters", new HashMap());
255         m_metaData = (Map) fields.get("m_metaData", new HashMap());
256 
257         String containerClassName = Aspects.getAspectQNameContainerClassName(Thread.currentThread().getContextClassLoader(), m_qName)[1];
258         Class containerClass = Class.forName(containerClassName);
259         m_container = Aspects.getContainerQNamed(Thread.currentThread().getContextClassLoader(), containerClass, m_qName);
260 
261         //TODO aspectDef
262     }
263 }