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.definition.AspectDefinition;
12  import org.codehaus.aspectwerkz.definition.StartupManager;
13  import org.codehaus.aspectwerkz.exception.DefinitionException;
14  
15  import java.io.ObjectInputStream;
16  import java.io.Serializable;
17  import java.util.HashMap;
18  import java.util.Map;
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 CrossCuttingInfo 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 cross-cuttable class.
38       */
39      private Class m_aspectClass;
40  
41      /***
42       * The container.
43       */
44      private transient AspectContainer m_container = null;
45  
46      /***
47       * Holds the deployment model.
48       */
49      private int m_deploymentModel;
50  
51      /***
52       * Holds the parameters passed to the aspect.
53       */
54      private Map m_parameters = new HashMap();
55  
56      /***
57       * Holds the metadata.
58       */
59      private Map m_metaData = new HashMap();
60  
61      /***
62       * The UUID for the system.
63       */
64      private String m_uuid;
65  
66      /***
67       * A reference to the AspectWerkz system housing this cross-cuttable class.
68       */
69      private transient AspectSystem m_system;
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 CrossCuttingInfo(final String uuid,
86                              final Class aspectClass,
87                              final String name,
88                              final int deploymentModel,
89                              final AspectDefinition aspectDef,
90                              final Map parameters) {
91          m_uuid = uuid;
92          m_aspectClass = aspectClass;
93          m_name = name;
94          m_deploymentModel = deploymentModel;
95          m_aspectDefinition = aspectDef;
96          m_parameters = parameters;
97      }
98  
99      /***
100      * Copy constructor - creates a clone of the cross-cutting info. Creates a new instance of the cross-cutting class
101      * it holds.
102      * 
103      * @return a clone of the cross-cutting info
104      */
105     public static CrossCuttingInfo newInstance(final CrossCuttingInfo prototype) {
106         try {
107             return new CrossCuttingInfo(
108                 prototype.m_uuid,
109                 prototype.m_aspectClass,
110                 prototype.m_name,
111                 prototype.m_deploymentModel,
112                 prototype.m_aspectDefinition,
113                 prototype.m_parameters);
114         } catch (Exception e) {
115             throw new RuntimeException("could not clone cross-cutting info ["
116                 + prototype.getName()
117                 + "]: "
118                 + e.toString());
119         }
120     }
121 
122     /***
123      * Returns the AspectWerkz system housing this cross-cuttable class.
124      * 
125      * @return the system
126      */
127     public AspectSystem getSystem() {
128         if (m_system == null) {
129             m_system = SystemLoader.getSystem(getAspectClass()); //AVAOPC CRAP
130             m_system.initialize();
131         }
132         return m_system;
133     }
134 
135     /***
136      * Returns the UUID for the system.
137      * 
138      * @return the UUID for the system
139      */
140     public String getUuid() {
141         return m_uuid;
142     }
143 
144     /***
145      * Returns the name of the aspect.
146      * 
147      * @return the name of the aspect
148      */
149     public String getName() {
150         return m_name;
151     }
152 
153     /***
154      * Returns the deployment model.
155      * 
156      * @return the deployment model
157      */
158     public int getDeploymentModel() {
159         return m_deploymentModel;
160     }
161 
162     /***
163      * Changes the deployment model.
164      * 
165      * @param deploymentModel the new deployment model
166      */
167     public void setDeploymentModel(final int deploymentModel) {
168         m_deploymentModel = deploymentModel;
169     }
170 
171     /***
172      * Returns the cross-cuttable class.
173      * 
174      * @return the cross-cuttable class
175      */
176     public Class getAspectClass() {
177         return m_aspectClass;
178     }
179 
180     /***
181      * Sets the container.
182      * 
183      * @param container the container
184      */
185     public void setContainer(final AspectContainer container) {
186         m_container = container;
187     }
188 
189     /***
190      * Returns the container.
191      * 
192      * @return the container
193      */
194     public AspectContainer getContainer() {
195         return m_container;
196     }
197 
198     /***
199      * Returns the aspect definition.
200      * <p/>
201      * Will return null after deserialization.
202      *
203      * @return the aspect definition
204      */
205     public AspectDefinition getAspectDefinition() {
206         return m_aspectDefinition;
207     }
208 
209     /***
210      * Sets a parameter.
211      * 
212      * @param name the name of the parameter
213      * @param value the value of the parameter
214      */
215     public void setParameter(final String name, final String value) {
216         m_parameters.put(name, value);
217     }
218 
219     /***
220      * Returns the value of a parameter.
221      * 
222      * @param name the name of the parameter
223      * @return the value of the parameter or null if not found
224      */
225     public String getParameter(final String name) {
226         return (String) m_parameters.get(name);
227     }
228 
229     /***
230      * Adds metadata.
231      * 
232      * @param key the key
233      * @param value the value
234      */
235     public void addMetaData(final Object key, final Object value) {
236         m_metaData.put(key, value);
237     }
238 
239     /***
240      * Returns the metadata for a specific key.
241      * 
242      * @param key the key
243      * @return the value
244      */
245     public Object getMetaData(final Object key) {
246         return m_metaData.get(key);
247     }
248 
249     /***
250      * Returns the target instance for the mixin of given name which is defined from within this aspect (mixin can have
251      * different deployment model from aspect)
252      * 
253      * @param mixinImpl miximImplementation aka "this" when called from within the mixin impl
254      * @return the target instance or null if not compliant deployment model
255      */
256     public Object getMixinTargetInstance(final Object mixinImpl) {
257         return getMixinTargetInstance(mixinImpl.getClass().getName(), mixinImpl);
258     }
259 
260     /***
261      * Returns the target class for the mixin of given name which is defined from within this aspect (mixin can have
262      * different deployment model from aspect)
263      * 
264      * @param mixinImpl miximImplementation aka "this" when called from within the mixin impl
265      * @return the target class or null if not compliant deployment model
266      */
267     public Class getMixinTargetClass(final Object mixinImpl) {
268         return getMixinTargetClass(mixinImpl.getClass().getName(), mixinImpl);
269     }
270 
271     /***
272      * Returns the target instance for the mixin of given name which is defined from within this aspect (mixin can have
273      * different deployment model from aspect)
274      * 
275      * @param mixinName of the mixin
276      * @param mixinImpl miximImplementation aka "this" when called from within the mixin impl
277      * @return the target instance or null if not compliant deployment model
278      */
279     public Object getMixinTargetInstance(final String mixinName, final Object mixinImpl) {
280         return m_container.getIntroductionContainer(mixinName).getTargetInstance(mixinImpl);
281     }
282 
283     /***
284      * Returns the target class for the mixin of given name which is defined from within this aspect (mixin can have
285      * different deployment model from aspect)
286      * 
287      * @param mixinName of the mixin
288      * @param mixinImpl miximImplementation aka "this" when called from within the mixin impl
289      * @return the target class or null if not compliant deployment model
290      */
291     public Class getMixinTargetClass(final String mixinName, final Object mixinImpl) {
292         return m_container.getIntroductionContainer(mixinName).getTargetClass(mixinImpl);
293     }
294 
295     /***
296      * Return true if the CrossCuttingInfo has not yet the AspectContainer set, that means this is the prototype init
297      * time
298      */
299     public boolean isPrototype() {
300         return (m_container == null);
301     }
302 
303     /***
304      * Provides custom deserialization.
305      * 
306      * @param stream the object input stream containing the serialized object
307      * @throws Exception in case of failure
308      */
309     private void readObject(final ObjectInputStream stream) throws Exception {
310         ObjectInputStream.GetField fields = stream.readFields();
311         m_uuid = (String) fields.get("m_uuid", null);
312         m_name = (String) fields.get("m_name", null);
313         m_aspectClass = (Class) fields.get("m_aspectClass", null);
314         m_deploymentModel = fields.get("m_deploymentModel", DeploymentModel.PER_JVM);
315         m_parameters = (Map) fields.get("m_parameters", new HashMap());
316         m_metaData = (Map) fields.get("m_metaData", new HashMap());
317         m_container = StartupManager.createAspectContainer(this);
318         m_system = SystemLoader.getSystem(m_aspectClass);
319         m_system.initialize();
320     }
321 }