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.aspect;
    9
    10  import java.lang.reflect.InvocationTargetException;
    11  import java.util.WeakHashMap;
    12  import java.util.Map;
    13
    14  import org.codehaus.aspectwerkz.exception.DefinitionException;
    15  import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;
    16  import org.codehaus.aspectwerkz.DeploymentModel;
    17
    18  /***
    19   * Abstract base class for the mixin factory implementations.
    20   *
    21   * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
    22   * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
    23   */
    24  public class DefaultMixinFactory extends AbstractMixinFactory {
    25
    26      private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
    27
    28      private Object m_perJVM = null;
    29
    30      private Map m_perClassMixins = new WeakHashMap();
    31
    32      private Map m_perInstanceMixins = new WeakHashMap();
    33
    34      /***
    35       * Creates a new default mixin factory.
    36       *
    37       * @param mixinClass
    38       * @param deploymentModel
    39       */
    40      public DefaultMixinFactory(final Class mixinClass, final DeploymentModel deploymentModel) {
    41          super(mixinClass, deploymentModel);
    42      }
    43
    44      /***
    45       * Creates a new perJVM mixin instance.
    46       *
    47       * @return the mixin instance
    48       */
    49      public Object mixinOf() {
    50          if (m_perJVM != null) {
    51              return m_perJVM;
    52          }
    53          synchronized (this) {
    54              final Object mixin;
    55              if (m_deploymentModel == DeploymentModel.PER_JVM) {
    56                  try {
    57                      mixin = m_defaultConstructor.newInstance(EMPTY_OBJECT_ARRAY);
    58                  } catch (InvocationTargetException e) {
    59                      throw new WrappedRuntimeException(e.getTargetException());
    60                  } catch (Exception e) {
    61                      throw new WrappedRuntimeException(e);
    62                  }
    63              } else {
    64                  throw new DefinitionException(
    65                          "Mixins.mixinOf() is can not be invoked for mixin deployed using as " +
    66                          m_deploymentModel
    67                  );
    68              }
    69              m_perJVM = mixin;
    70          }
    71          return m_perJVM;
    72      }
    73
    74      /***
    75       * Creates a new perClass mixin instance.
    76       *
    77       * @param klass
    78       * @return the mixin instance
    79       */
    80      public Object mixinOf(final Class klass) {
    81          if (m_perClassMixins.containsKey(klass)) {
    82              return m_perClassMixins.get(klass);
    83          }
    84          synchronized (m_perClassMixins) {
    85              if (!m_perClassMixins.containsKey(klass)) {
    86                  final Object mixin;
    87                  if (m_deploymentModel == DeploymentModel.PER_CLASS) {
    88                      try {
    89                          if (m_perClassConstructor != null) {
    90                              mixin = m_perClassConstructor.newInstance(new Object[]{klass});
    91                          } else if (m_defaultConstructor != null) {
    92                              mixin = m_defaultConstructor.newInstance(new Object[]{});
    93                          } else {
    94                              throw new DefinitionException(
    95                                      "no valid constructor found for mixin [" + m_mixinClass.getName() + "]"
    96                              );
    97                          }
    98                      } catch (InvocationTargetException e) {
    99                          throw new WrappedRuntimeException(e.getTargetException());
    100                     } catch (Exception e) {
    101                         throw new WrappedRuntimeException(e);
    102                     }
    103                 } else {
    104                     throw new DefinitionException(
    105                             "Mixins.mixinOf(Class) is can not be invoked for mixin deployed using as " +
    106                             m_deploymentModel
    107                     );
    108                 }
    109                 m_perClassMixins.put(klass, mixin);
    110             }
    111             return m_perClassMixins.get(klass);
    112         }
    113     }
    114
    115     /***
    116      * Creates a new perInstance mixin instance.
    117      *
    118      * @param instance
    119      * @return the mixin instance
    120      */
    121     public Object mixinOf(final Object instance) {
    122         if (m_perInstanceMixins.containsKey(instance)) {
    123             return m_perInstanceMixins.get(instance);
    124         }
    125         synchronized (m_perInstanceMixins) {
    126             if (!m_perInstanceMixins.containsKey(instance)) {
    127                 final Object mixin;
    128                 if (m_deploymentModel == DeploymentModel.PER_INSTANCE) {
    129                     try {
    130                         if (m_perInstanceConstructor != null) {
    131                             mixin = m_perInstanceConstructor.newInstance(new Object[]{instance});
    132                         } else if (m_defaultConstructor != null) {
    133                             mixin = m_defaultConstructor.newInstance(new Object[]{});
    134                         } else {
    135                             throw new DefinitionException(
    136                                     "no valid constructor found for mixin [" + m_mixinClass.getName() + "]"
    137                             );
    138                         }
    139                     } catch (InvocationTargetException e) {
    140                         throw new WrappedRuntimeException(e.getTargetException());
    141                     } catch (Exception e) {
    142                         throw new WrappedRuntimeException(e);
    143                     }
    144                 } else {
    145                     throw new DefinitionException(
    146                             "Mixins.mixinOf(Object) is can not be invoked for mixin deployed using as " +
    147                             m_deploymentModel
    148                     );
    149                 }
    150                 m_perInstanceMixins.put(instance, mixin);
    151             }
    152             return m_perInstanceMixins.get(instance);
    153         }
    154     }
    155 }