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
262 }
263 }