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