/**************************************************************************************
* Copyright (c) Jonas Bonr, Alexandre Vasseur. All rights reserved. *
* http://aspectwerkz.codehaus.org *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the LGPL license *
* a copy of which has been included with this distribution in the license.txt file. *
**************************************************************************************/
package org.codehaus.aspectwerkz;
import org.codehaus.aspectwerkz.aspect.AspectContainer;
import org.codehaus.aspectwerkz.aspect.management.Aspects;
import org.codehaus.aspectwerkz.definition.AspectDefinition;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.lang.ref.WeakReference;
/**
* Contains information about and for classes that has been defined as cross-cutting.
*
* @author <a href="mailto:jboner@codehaus.org">Jonas Bonr </a>
*/
public final class AspectContext implements Serializable {
/**
* An empty <code>Object</code> array.
*/
public static final Object[] EMPTY_OBJECT_ARRAY = new Object[]{};
/**
* The name for the cross-cuttable class.
*/
private String m_name;
/**
* The qualified name of the aspect
*/
private String m_qName;
/**
* The aspect class, wrapped in a weak reference since is a key of aspect container referenced by this object.
*/
private transient WeakReference m_aspectClassRef;
/**
* The container.
*/
private transient AspectContainer m_container = null;
/**
* Holds the deployment model.
*/
private DeploymentModel m_deploymentModel;
/**
* Holds the parameters passed to the aspect.
*/
private Map m_parameters = new HashMap();
/**
* Holds the metadata.
*/
private Map m_metaData = new HashMap();
/**
* The UUID for the system.
*/
private String m_uuid;
/**
* The aspect definition.
*/
private transient AspectDefinition m_aspectDefinition;
/**
* Creates a new cross-cutting info instance.
*
* @param uuid
* @param aspectClass
* @param deploymentModel
* @param aspectDef
* @param parameters
*/
public AspectContext(final String uuid,
final Class aspectClass,
final String name,
final DeploymentModel deploymentModel,
final AspectDefinition aspectDef,
final Map parameters) {
m_uuid = uuid;
m_aspectClassRef = new WeakReference(aspectClass);
m_name = name;
m_qName = aspectDef.getQualifiedName();
m_deploymentModel = deploymentModel;
m_aspectDefinition = aspectDef;
if (parameters != null) {
m_parameters = parameters;
}
}
/**
* Copy constructor - creates a clone of the cross-cutting info.
* Creates a new instance of the cross-cutting class it holds.
*
* @return a clone of the cross-cutting info
*/
public static AspectContext newInstance(final AspectContext prototype) {
try {
return new AspectContext(
prototype.m_uuid,
(Class) prototype.m_aspectClassRef.get(),
prototype.m_name,
prototype.m_deploymentModel,
prototype.m_aspectDefinition,
prototype.m_parameters
);
} catch (Exception e) {
throw new RuntimeException(
"could not clone cross-cutting info ["
+ prototype.getName()
+ "]: "
+ e.toString()
);
}
}
/**
* Returns the UUID for the system.
*
* @return the UUID for the system
*/
public String getUuid() {
return m_uuid;
}
/**
* Returns the name of the aspect.
*
* @return the name of the aspect
*/
public String getName() {
return m_name;
}
/**
* Returns the deployment model.
*
* @return the deployment model
*/
public DeploymentModel getDeploymentModel() {
return m_deploymentModel;
}
/**
* Returns the cross-cuttable class.
*
* @return the cross-cuttable class
*/
public Class getAspectClass() {
return (Class) m_aspectClassRef.get();
}
/**
* Sets the container.
*
* @param container the container
*/
public void setContainer(final AspectContainer container) {
m_container = container;
}
/**
* Returns the container.
*
* @return the container
*/
public AspectContainer getContainer() {
return m_container;
}
/**
* Returns the aspect definition.
* <p/>
* Will return null after deserialization.
*
* @return the aspect definition
*/
public AspectDefinition getAspectDefinition() {
return m_aspectDefinition;
}
/**
* Sets a parameter.
*
* @param name the name of the parameter
* @param value the value of the parameter
*/
public void setParameter(final String name, final String value) {
m_parameters.put(name, value);
}
/**
* Returns the value of a parameter.
*
* @param name the name of the parameter
* @return the value of the parameter or null if not specified
*/
public String getParameter(final String name) {
return (String) m_parameters.get(name);
}
/**
* Adds metadata.
*
* @param key the key
* @param value the value
*/
public void addMetaData(final Object key, final Object value) {
m_metaData.put(key, value);
}
/**
* Returns the metadata for a specific key.
*
* @param key the key
* @return the value
*/
public Object getMetaData(final Object key) {
return m_metaData.get(key);
}
/**
* Return true if the AspectContext has not yet the AspectContainer set, that means this is the prototype init time
*/
public boolean isPrototype() {
return (m_container == null);
}
/**
* Provides custom deserialization.
*
* @param stream the object input stream containing the serialized object
* @throws Exception in case of failure
*/
private void readObject(final ObjectInputStream stream) throws Exception {
ObjectInputStream.GetField fields = stream.readFields();
m_uuid = (String) fields.get("m_uuid", null);
m_name = (String) fields.get("m_name", null);
m_qName = (String) fields.get("m_qName", null);
Class aspectClass = Class.forName(m_name);
m_aspectClassRef = new WeakReference(aspectClass);
m_deploymentModel = (DeploymentModel) fields.get("m_deploymentModel", DeploymentModel.PER_JVM);
m_parameters = (Map) fields.get("m_parameters", new HashMap());
m_metaData = (Map) fields.get("m_metaData", new HashMap());
String containerClassName = Aspects.getAspectQNameContainerClassName(Thread.currentThread().getContextClassLoader(), m_qName)[1];
Class containerClass = Class.forName(containerClassName);
m_container = Aspects.getContainerQNamed(Thread.currentThread().getContextClassLoader(), containerClass, m_qName);
//TODO aspectDef
}
}
|