/************************************************************************************** * Copyright (c) Jonas Bon�r, 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.aspect; import java.lang.reflect.InvocationTargetException; import java.util.WeakHashMap; import java.util.Map; import org.codehaus.aspectwerkz.exception.DefinitionException; import org.codehaus.aspectwerkz.exception.WrappedRuntimeException; import org.codehaus.aspectwerkz.DeploymentModel; /** * Abstract base class for the mixin factory implementations. * * @author <a href="mailto:jboner@codehaus.org">Jonas Bon�r </a> * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> */ public class DefaultMixinFactory extends AbstractMixinFactory { private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; private Object m_perJVM = null; private Map m_perClassMixins = new WeakHashMap(); private Map m_perInstanceMixins = new WeakHashMap(); /** * Creates a new default mixin factory. * * @param mixinClass * @param deploymentModel */ public DefaultMixinFactory(final Class mixinClass, final DeploymentModel deploymentModel) { super(mixinClass, deploymentModel); } /** * Creates a new perJVM mixin instance. * * @return the mixin instance */ public Object mixinOf() { if (m_perJVM != null) { return m_perJVM; } synchronized (this) { final Object mixin; if (m_deploymentModel == DeploymentModel.PER_JVM) { try { mixin = m_defaultConstructor.newInstance(EMPTY_OBJECT_ARRAY); } catch (InvocationTargetException e) { throw new WrappedRuntimeException(e.getTargetException()); } catch (Exception e) { throw new WrappedRuntimeException(e); } } else { throw new DefinitionException( "Mixins.mixinOf() is can not be invoked for mixin deployed using as " + m_deploymentModel ); } m_perJVM = mixin; } return m_perJVM; } /** * Creates a new perClass mixin instance. * * @param klass * @return the mixin instance */ public Object mixinOf(final Class klass) { if (m_perClassMixins.containsKey(klass)) { return m_perClassMixins.get(klass); } synchronized (m_perClassMixins) { if (!m_perClassMixins.containsKey(klass)) { final Object mixin; if (m_deploymentModel == DeploymentModel.PER_CLASS) { try { if (m_perClassConstructor != null) { mixin = m_perClassConstructor.newInstance(new Object[]{klass}); } else if (m_defaultConstructor != null) { mixin = m_defaultConstructor.newInstance(new Object[]{}); } else { throw new DefinitionException( "no valid constructor found for mixin [" + m_mixinClass.getName() + "]" ); } } catch (InvocationTargetException e) { throw new WrappedRuntimeException(e.getTargetException()); } catch (Exception e) { throw new WrappedRuntimeException(e); } } else { throw new DefinitionException( "Mixins.mixinOf(Class) is can not be invoked for mixin deployed using as " + m_deploymentModel ); } m_perClassMixins.put(klass, mixin); } return m_perClassMixins.get(klass); } } /** * Creates a new perInstance mixin instance. * * @param instance * @return the mixin instance */ public Object mixinOf(final Object instance) { if (m_perInstanceMixins.containsKey(instance)) { return m_perInstanceMixins.get(instance); } synchronized (m_perInstanceMixins) { if (!m_perInstanceMixins.containsKey(instance)) { final Object mixin; if (m_deploymentModel == DeploymentModel.PER_INSTANCE) { try { if (m_perInstanceConstructor != null) { mixin = m_perInstanceConstructor.newInstance(new Object[]{instance}); } else if (m_defaultConstructor != null) { mixin = m_defaultConstructor.newInstance(new Object[]{}); } else { throw new DefinitionException( "no valid constructor found for mixin [" + m_mixinClass.getName() + "]" ); } } catch (InvocationTargetException e) { throw new WrappedRuntimeException(e.getTargetException()); } catch (Exception e) { throw new WrappedRuntimeException(e); } } else { throw new DefinitionException( "Mixins.mixinOf(Object) is can not be invoked for mixin deployed using as " + m_deploymentModel ); } m_perInstanceMixins.put(instance, mixin); } return m_perInstanceMixins.get(instance); } } }