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 }