001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.aspectwerkz.aspect;
005:
006: import com.tc.aspectwerkz.AspectContext;
007: import com.tc.aspectwerkz.definition.AspectDefinition;
008: import com.tc.aspectwerkz.definition.SystemDefinition;
009: import com.tc.aspectwerkz.definition.SystemDefinitionContainer;
010:
011: import java.lang.ref.Reference;
012: import java.lang.ref.WeakReference;
013: import java.util.Iterator;
014: import java.util.Map;
015:
016: /**
017: * Abstract base class for an aspect container implementations that is passing an AspectContext when
018: * creating the aspect instance if there is such a single arg constructor in the aspect.
019: * <p/>
020: * Provides support for getting the AspectDefinition.
021: * <p/>
022: * Can be used as a base class for user defined container.
023: *
024: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
025: * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
026: */
027: public abstract class AbstractAspectContainer implements
028: AspectContainer {
029:
030: protected Class m_aspectClass;
031: protected Reference m_classLoader;
032: protected String m_uuid;
033: protected String m_qualifiedName;
034: private AspectDefinition m_aspectDefinitionLazy;
035:
036: public static final int ASPECT_CONSTRUCTION_TYPE_UNKNOWN = 0;
037: public static final int ASPECT_CONSTRUCTION_TYPE_DEFAULT = 1;
038: public static final int ASPECT_CONSTRUCTION_TYPE_ASPECT_CONTEXT = 2;
039: public static final Object[] EMPTY_OBJECT_ARRAY = new Object[] {};
040:
041: /**
042: * The aspect construction type. Defaults to unknown
043: */
044: protected int m_constructionType = ASPECT_CONSTRUCTION_TYPE_UNKNOWN;
045:
046: /**
047: * Create a new container
048: *
049: * @param aspectClass
050: * @param aopSystemClassLoader the classloader of the defining system (not necessary the one of the aspect class)
051: * @param uuid
052: * @param qualifiedName
053: * @param parameters
054: */
055: public AbstractAspectContainer(Class aspectClass,
056: ClassLoader aopSystemClassLoader, String uuid,
057: String qualifiedName, Map parameters) {
058: m_aspectClass = aspectClass;// we hold a strong ref this the container is hold by the aspect factory only
059: m_classLoader = new WeakReference(aopSystemClassLoader);
060: m_uuid = uuid;
061: m_qualifiedName = qualifiedName;
062: }
063:
064: /**
065: * Lazy getter for the aspect definition
066: *
067: * @return the aspect definition
068: */
069: public AspectDefinition getAspectDefinition() {
070: if (m_aspectDefinitionLazy == null) {
071: SystemDefinition def = SystemDefinitionContainer
072: .getDefinitionFor(getDefiningSystemClassLoader(),
073: m_uuid);
074: if (def == null) {
075: throw new RuntimeException("Definition " + m_uuid
076: + " not found from "
077: + getDefiningSystemClassLoader());
078: }
079: for (Iterator iterator = def.getAspectDefinitions()
080: .iterator(); iterator.hasNext();) {
081: AspectDefinition aspectDefinition = (AspectDefinition) iterator
082: .next();
083: if (m_qualifiedName.equals(aspectDefinition
084: .getQualifiedName())) {
085: m_aspectDefinitionLazy = aspectDefinition;
086: }
087: }
088: if (m_aspectDefinitionLazy == null) {
089: throw new RuntimeException(
090: "Aspect definition not found "
091: + m_qualifiedName + " from "
092: + getDefiningSystemClassLoader());
093: }
094: }
095: return m_aspectDefinitionLazy;
096: }
097:
098: /**
099: * @return the classloader of the system defining the aspect handled by that container instance
100: */
101: public ClassLoader getDefiningSystemClassLoader() {
102: return ((ClassLoader) m_classLoader.get());
103: }
104:
105: public Object aspectOf() {
106: return createAspect(getContext(null));
107: }
108:
109: public Object aspectOf(Class klass) {
110: return createAspect(getContext(klass));
111: }
112:
113: public Object aspectOf(Object instance) {
114: return createAspect(getContext(instance));
115: }
116:
117: public Object aspectOf(Thread thread) {
118: return createAspect(getContext(thread));
119: }
120:
121: /**
122: * To be implemented by the concrete aspect containers.
123: * <p/>
124: * Should return a new aspect instance.
125: *
126: * @return a new aspect instance
127: */
128: protected abstract Object createAspect(AspectContext aspectContext);
129:
130: /**
131: * Create a new AspectContext associated with the given instance (class/instance/thread/null)
132: *
133: * @param associated
134: * @return the context
135: */
136: protected AspectContext getContext(Object associated) {
137: AspectDefinition aspectDefinition = getAspectDefinition();
138: return new AspectContext(m_uuid, m_aspectClass,
139: aspectDefinition.getName(), aspectDefinition
140: .getDeploymentModel(), aspectDefinition,
141: aspectDefinition.getParameters(), associated);
142: }
143:
144: /**
145: * Returns the aspect class
146: *
147: * @return the aspect class
148: */
149: public Class getAspectClass() {
150: return m_aspectClass;
151: }
152: }
|