/************************************************************************************** * 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 org.codehaus.aspectwerkz.AspectContext; import org.codehaus.aspectwerkz.definition.AspectDefinition; import org.codehaus.aspectwerkz.definition.SystemDefinition; import org.codehaus.aspectwerkz.definition.SystemDefinitionContainer; import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.util.Iterator; import java.util.Map; /** * Abstract base class for an aspect container implementations that is passing an AspectContext when * creating the aspect instance if there is such a single arg constructor in the aspect. * <p/> * Provides support for getting the AspectDefinition. * <p/> * Can be used as a base class for user defined container. * * @author <a href="mailto:jboner@codehaus.org">Jonas Bon�r </a> * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> */ public abstract class AbstractAspectContainer implements AspectContainer { protected Class m_aspectClass; protected Reference m_classLoader; protected String m_uuid; protected String m_qualifiedName; private AspectDefinition m_aspectDefinitionLazy; public static final int ASPECT_CONSTRUCTION_TYPE_UNKNOWN = 0; public static final int ASPECT_CONSTRUCTION_TYPE_DEFAULT = 1; public static final int ASPECT_CONSTRUCTION_TYPE_ASPECT_CONTEXT = 2; public static final Object[] EMPTY_OBJECT_ARRAY = new Object[]{}; /** * The aspect construction type. Defaults to unknown */ protected int m_constructionType = ASPECT_CONSTRUCTION_TYPE_UNKNOWN; /** * Create a new container * * @param aspectClass * @param aopSystemClassLoader the classloader of the defining system (not necessary the one of the aspect class) * @param uuid * @param qualifiedName * @param parameters */ public AbstractAspectContainer(Class aspectClass, ClassLoader aopSystemClassLoader, String uuid, String qualifiedName, Map parameters) { m_aspectClass = aspectClass;// we hold a strong ref this the container is hold by the aspect factory only m_classLoader = new WeakReference(aopSystemClassLoader); m_uuid = uuid; m_qualifiedName = qualifiedName; } /** * Lazy getter for the aspect definition * * @return */ public AspectDefinition getAspectDefinition() { if (m_aspectDefinitionLazy == null) { SystemDefinition def = SystemDefinitionContainer.getDefinitionFor(getDefiningSystemClassLoader(), m_uuid); if (def == null) { throw new RuntimeException( "Definition " + m_uuid + " not found from " + getDefiningSystemClassLoader() ); } for (Iterator iterator = def.getAspectDefinitions().iterator(); iterator.hasNext();) { AspectDefinition aspectDefinition = (AspectDefinition) iterator.next(); if (m_qualifiedName.equals(aspectDefinition.getQualifiedName())) { m_aspectDefinitionLazy = aspectDefinition; } } if (m_aspectDefinitionLazy == null) { throw new RuntimeException( "Aspect definition not found " + m_qualifiedName + " from " + getDefiningSystemClassLoader() ); } } return m_aspectDefinitionLazy; } /** * @return the classloader of the system defining the aspect handled by that container instance */ public ClassLoader getDefiningSystemClassLoader() { return ((ClassLoader) m_classLoader.get()); } public Object aspectOf() { return createAspect(getContext(null)); } public Object aspectOf(Class klass) { return createAspect(getContext(klass)); } public Object aspectOf(Object instance) { return createAspect(getContext(instance)); } public Object aspectOf(Thread thread) { return createAspect(getContext(thread)); } /** * To be implemented by the concrete aspect containers. * <p/> * Should return a new aspect instance. * * @return a new aspect instance */ protected abstract Object createAspect(AspectContext aspectContext); /** * Create a new AspectContext associated with the given instance (class/instance/thread/null) * * @param associated * @return */ protected AspectContext getContext(Object associated) { AspectDefinition aspectDefinition = getAspectDefinition(); return new AspectContext( m_uuid, m_aspectClass, aspectDefinition.getName(), aspectDefinition.getDeploymentModel(), aspectDefinition, aspectDefinition.getParameters(), associated ); } /** * Returns the aspect class * * @return */ public Class getAspectClass() { return m_aspectClass; } }