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.DeploymentModel;
007: import com.tc.aspectwerkz.exception.DefinitionException;
008: import com.tc.aspectwerkz.exception.WrappedRuntimeException;
009:
010: import java.lang.reflect.InvocationTargetException;
011: import java.util.Map;
012: import java.util.WeakHashMap;
013:
014: /**
015: * Abstract base class for the mixin factory implementations.
016: *
017: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
018: * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
019: */
020: public class DefaultMixinFactory extends AbstractMixinFactory {
021:
022: private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
023:
024: private Object m_perJVM = null;
025:
026: private Map m_perClassMixins = new WeakHashMap();
027:
028: private Map m_perInstanceMixins = new WeakHashMap();
029:
030: /**
031: * Creates a new default mixin factory.
032: *
033: * @param mixinClass
034: * @param deploymentModel
035: */
036: public DefaultMixinFactory(final Class mixinClass,
037: final DeploymentModel deploymentModel) {
038: super (mixinClass, deploymentModel);
039: }
040:
041: /**
042: * Creates a new perJVM mixin instance.
043: *
044: * @return the mixin instance
045: */
046: public Object mixinOf() {
047: if (m_perJVM != null) {
048: return m_perJVM;
049: }
050: synchronized (this ) {
051: final Object mixin;
052: if (m_deploymentModel == DeploymentModel.PER_JVM) {
053: try {
054: mixin = m_defaultConstructor
055: .newInstance(EMPTY_OBJECT_ARRAY);
056: } catch (InvocationTargetException e) {
057: throw new WrappedRuntimeException(e
058: .getTargetException());
059: } catch (Exception e) {
060: throw new WrappedRuntimeException(e);
061: }
062: } else {
063: throw new DefinitionException(
064: "Mixins.mixinOf() is can not be invoked for mixin deployed using as "
065: + m_deploymentModel);
066: }
067: m_perJVM = mixin;
068: }
069: return m_perJVM;
070: }
071:
072: /**
073: * Creates a new perClass mixin instance.
074: *
075: * @param klass
076: * @return the mixin instance
077: */
078: public Object mixinOf(final Class klass) {
079: if (m_perClassMixins.containsKey(klass)) {
080: return m_perClassMixins.get(klass);
081: }
082: synchronized (m_perClassMixins) {
083: if (!m_perClassMixins.containsKey(klass)) {
084: final Object mixin;
085: if (m_deploymentModel == DeploymentModel.PER_CLASS) {
086: try {
087: if (m_perClassConstructor != null) {
088: mixin = m_perClassConstructor
089: .newInstance(new Object[] { klass });
090: } else if (m_defaultConstructor != null) {
091: mixin = m_defaultConstructor
092: .newInstance(new Object[] {});
093: } else {
094: throw new DefinitionException(
095: "no valid constructor found for mixin ["
096: + m_mixinClass.getName()
097: + "]");
098: }
099: } catch (InvocationTargetException e) {
100: throw new WrappedRuntimeException(e
101: .getTargetException());
102: } catch (Exception e) {
103: throw new WrappedRuntimeException(e);
104: }
105: } else {
106: throw new DefinitionException(
107: "Mixins.mixinOf(Class) is can not be invoked for mixin deployed using as "
108: + m_deploymentModel);
109: }
110: m_perClassMixins.put(klass, mixin);
111: }
112: return m_perClassMixins.get(klass);
113: }
114: }
115:
116: /**
117: * Creates a new perInstance mixin instance.
118: *
119: * @param instance
120: * @return the mixin instance
121: */
122: public Object mixinOf(final Object instance) {
123: if (m_perInstanceMixins.containsKey(instance)) {
124: return m_perInstanceMixins.get(instance);
125: }
126: synchronized (m_perInstanceMixins) {
127: if (!m_perInstanceMixins.containsKey(instance)) {
128: final Object mixin;
129: if (m_deploymentModel == DeploymentModel.PER_INSTANCE) {
130: try {
131: if (m_perInstanceConstructor != null) {
132: mixin = m_perInstanceConstructor
133: .newInstance(new Object[] { instance });
134: } else if (m_defaultConstructor != null) {
135: mixin = m_defaultConstructor
136: .newInstance(new Object[] {});
137: } else {
138: throw new DefinitionException(
139: "no valid constructor found for mixin ["
140: + m_mixinClass.getName()
141: + "]");
142: }
143: } catch (InvocationTargetException e) {
144: throw new WrappedRuntimeException(e
145: .getTargetException());
146: } catch (Exception e) {
147: throw new WrappedRuntimeException(e);
148: }
149: } else {
150: throw new DefinitionException(
151: "Mixins.mixinOf(Object) is can not be invoked for mixin deployed using as "
152: + m_deploymentModel);
153: }
154: m_perInstanceMixins.put(instance, mixin);
155: }
156: return m_perInstanceMixins.get(instance);
157: }
158: }
159: }
|