001: /**************************************************************************************
002: * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved. *
003: * http://aspectwerkz.codehaus.org *
004: * ---------------------------------------------------------------------------------- *
005: * The software in this package is published under the terms of the LGPL license *
006: * a copy of which has been included with this distribution in the license.txt file. *
007: **************************************************************************************/package org.codehaus.aspectwerkz;
008:
009: import org.codehaus.aspectwerkz.aspect.AspectContainer;
010: import org.codehaus.aspectwerkz.aspect.management.Aspects;
011: import org.codehaus.aspectwerkz.definition.AspectDefinition;
012:
013: import java.io.ObjectInputStream;
014: import java.io.Serializable;
015: import java.util.HashMap;
016: import java.util.Map;
017: import java.lang.ref.WeakReference;
018:
019: /**
020: * Contains information about and for classes that has been defined as cross-cutting.
021: *
022: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
023: */
024: public final class AspectContext implements Serializable {
025: /**
026: * An empty <code>Object</code> array.
027: */
028: public static final Object[] EMPTY_OBJECT_ARRAY = new Object[] {};
029:
030: /**
031: * The name for the cross-cuttable class.
032: */
033: private String m_name;
034:
035: /**
036: * The qualified name of the aspect
037: */
038: private String m_qName;
039:
040: /**
041: * The aspect class, wrapped in a weak reference since is a key of aspect container referenced by this object.
042: */
043: private transient WeakReference m_aspectClassRef;
044:
045: /**
046: * The container.
047: */
048: private transient AspectContainer m_container = null;
049:
050: /**
051: * Holds the deployment model.
052: */
053: private DeploymentModel m_deploymentModel;
054:
055: /**
056: * Holds the parameters passed to the aspect.
057: */
058: private Map m_parameters = new HashMap();
059:
060: /**
061: * Holds the metadata.
062: */
063: private Map m_metaData = new HashMap();
064:
065: /**
066: * The UUID for the system.
067: */
068: private String m_uuid;
069:
070: /**
071: * The aspect definition.
072: */
073: private transient AspectDefinition m_aspectDefinition;
074:
075: /**
076: * Creates a new cross-cutting info instance.
077: *
078: * @param uuid
079: * @param aspectClass
080: * @param deploymentModel
081: * @param aspectDef
082: * @param parameters
083: */
084: public AspectContext(final String uuid, final Class aspectClass,
085: final String name, final DeploymentModel deploymentModel,
086: final AspectDefinition aspectDef, final Map parameters) {
087: m_uuid = uuid;
088: m_aspectClassRef = new WeakReference(aspectClass);
089: m_name = name;
090: m_qName = aspectDef.getQualifiedName();
091: m_deploymentModel = deploymentModel;
092: m_aspectDefinition = aspectDef;
093: if (parameters != null) {
094: m_parameters = parameters;
095: }
096: }
097:
098: /**
099: * Copy constructor - creates a clone of the cross-cutting info.
100: * Creates a new instance of the cross-cutting class it holds.
101: *
102: * @return a clone of the cross-cutting info
103: */
104: public static AspectContext newInstance(
105: final AspectContext prototype) {
106: try {
107: return new AspectContext(prototype.m_uuid,
108: (Class) prototype.m_aspectClassRef.get(),
109: prototype.m_name, prototype.m_deploymentModel,
110: prototype.m_aspectDefinition,
111: prototype.m_parameters);
112: } catch (Exception e) {
113: throw new RuntimeException(
114: "could not clone cross-cutting info ["
115: + prototype.getName() + "]: "
116: + e.toString());
117: }
118: }
119:
120: /**
121: * Returns the UUID for the system.
122: *
123: * @return the UUID for the system
124: */
125: public String getUuid() {
126: return m_uuid;
127: }
128:
129: /**
130: * Returns the name of the aspect.
131: *
132: * @return the name of the aspect
133: */
134: public String getName() {
135: return m_name;
136: }
137:
138: /**
139: * Returns the deployment model.
140: *
141: * @return the deployment model
142: */
143: public DeploymentModel getDeploymentModel() {
144: return m_deploymentModel;
145: }
146:
147: /**
148: * Returns the cross-cuttable class.
149: *
150: * @return the cross-cuttable class
151: */
152: public Class getAspectClass() {
153: return (Class) m_aspectClassRef.get();
154: }
155:
156: /**
157: * Sets the container.
158: *
159: * @param container the container
160: */
161: public void setContainer(final AspectContainer container) {
162: m_container = container;
163: }
164:
165: /**
166: * Returns the container.
167: *
168: * @return the container
169: */
170: public AspectContainer getContainer() {
171: return m_container;
172: }
173:
174: /**
175: * Returns the aspect definition.
176: * <p/>
177: * Will return null after deserialization.
178: *
179: * @return the aspect definition
180: */
181: public AspectDefinition getAspectDefinition() {
182: return m_aspectDefinition;
183: }
184:
185: /**
186: * Sets a parameter.
187: *
188: * @param name the name of the parameter
189: * @param value the value of the parameter
190: */
191: public void setParameter(final String name, final String value) {
192: m_parameters.put(name, value);
193: }
194:
195: /**
196: * Returns the value of a parameter.
197: *
198: * @param name the name of the parameter
199: * @return the value of the parameter or null if not specified
200: */
201: public String getParameter(final String name) {
202: return (String) m_parameters.get(name);
203: }
204:
205: /**
206: * Adds metadata.
207: *
208: * @param key the key
209: * @param value the value
210: */
211: public void addMetaData(final Object key, final Object value) {
212: m_metaData.put(key, value);
213: }
214:
215: /**
216: * Returns the metadata for a specific key.
217: *
218: * @param key the key
219: * @return the value
220: */
221: public Object getMetaData(final Object key) {
222: return m_metaData.get(key);
223: }
224:
225: /**
226: * Return true if the AspectContext has not yet the AspectContainer set, that means this is the prototype init time
227: */
228: public boolean isPrototype() {
229: return (m_container == null);
230: }
231:
232: /**
233: * Provides custom deserialization.
234: *
235: * @param stream the object input stream containing the serialized object
236: * @throws Exception in case of failure
237: */
238: private void readObject(final ObjectInputStream stream)
239: throws Exception {
240: ObjectInputStream.GetField fields = stream.readFields();
241: m_uuid = (String) fields.get("m_uuid", null);
242: m_name = (String) fields.get("m_name", null);
243: m_qName = (String) fields.get("m_qName", null);
244: Class aspectClass = Class.forName(m_name);
245: m_aspectClassRef = new WeakReference(aspectClass);
246: m_deploymentModel = (DeploymentModel) fields.get(
247: "m_deploymentModel", DeploymentModel.PER_JVM);
248: m_parameters = (Map) fields.get("m_parameters", new HashMap());
249: m_metaData = (Map) fields.get("m_metaData", new HashMap());
250:
251: String containerClassName = Aspects
252: .getAspectQNameContainerClassName(Thread
253: .currentThread().getContextClassLoader(),
254: m_qName)[1];
255: Class containerClass = Class.forName(containerClassName);
256: m_container = Aspects.getContainerQNamed(Thread.currentThread()
257: .getContextClassLoader(), containerClass, m_qName);
258:
259: //TODO aspectDef
260: }
261: }
|