001: /*****************************************************************************
002: * Copyright (c) PicoContainer Organization. All rights reserved. *
003: * ------------------------------------------------------------------------- *
004: * The software in this package is published under the terms of the BSD *
005: * style license a copy of which has been included with this distribution in *
006: * the LICENSE.txt file. *
007: * *
008: *****************************************************************************/package org.picocontainer.behaviors;
009:
010: import org.picocontainer.ComponentAdapter;
011: import org.picocontainer.PicoContainer;
012:
013: import java.util.Map;
014: import java.util.HashMap;
015: import java.lang.reflect.Method;
016: import java.lang.reflect.InvocationTargetException;
017: import java.io.Serializable;
018:
019: /** @author Paul Hammant */
020: public class Intercepted<T> extends HiddenImplementation {
021:
022: private final Map<Class, Object> pres = new HashMap<Class, Object>();
023: private final Map<Class, Object> posts = new HashMap<Class, Object>();
024: private Controller controller = new ControllerWrapper(
025: new InterceptorThreadLocal());
026:
027: public Intercepted(ComponentAdapter delegate) {
028: super (delegate);
029: }
030:
031: public void addPreInvocation(Class type, Object interceptor) {
032: pres.put(type, interceptor);
033: }
034:
035: public void addPostInvocation(Class type, Object interceptor) {
036: posts.put(type, interceptor);
037: }
038:
039: protected Object invokeMethod(Method method, Object[] args,
040: PicoContainer container) throws Throwable {
041: Object componentInstance = getDelegate().getComponentInstance(
042: container);
043: try {
044: controller.clear();
045: controller.instance(componentInstance);
046: Object pre = pres.get(method.getDeclaringClass());
047: if (pre != null) {
048: Object rv = method.invoke(pre, args);
049: if (controller.isVetoed()) {
050: return rv;
051: }
052: }
053: Object result = method.invoke(componentInstance, args);
054: controller.setOriginalRetVal(result);
055: Object post = posts.get(method.getDeclaringClass());
056: if (post != null) {
057: Object rv = method.invoke(post, args);
058: if (controller.isOverridden()) {
059: return rv;
060: }
061: }
062: return result;
063: } catch (final InvocationTargetException ite) {
064: throw ite.getTargetException();
065: }
066: }
067:
068: public Controller getController() {
069: return controller;
070: }
071:
072: public static class InterceptorThreadLocal extends ThreadLocal
073: implements Serializable {
074: protected Object initialValue() {
075: return new ControllerImpl();
076: }
077: }
078:
079: public interface Controller {
080: void veto();
081:
082: void clear();
083:
084: boolean isVetoed();
085:
086: void setOriginalRetVal(Object retVal);
087:
088: boolean isOverridden();
089:
090: void instance(Object instance);
091:
092: Object getOriginalRetVal();
093:
094: void override();
095: }
096:
097: public static class ControllerImpl implements Controller {
098: private boolean vetoed;
099: private Object retVal;
100: private boolean overridden;
101: private Object instance;
102:
103: public void veto() {
104: vetoed = true;
105: }
106:
107: public void clear() {
108: vetoed = false;
109: overridden = false;
110: retVal = null;
111: instance = null;
112: }
113:
114: public boolean isVetoed() {
115: return vetoed;
116: }
117:
118: public void setOriginalRetVal(Object retVal) {
119: this .retVal = retVal;
120: }
121:
122: public Object getOriginalRetVal() {
123: return retVal;
124: }
125:
126: public boolean isOverridden() {
127: return overridden;
128: }
129:
130: public void instance(Object instance) {
131: this .instance = instance;
132: }
133:
134: public void override() {
135: overridden = true;
136: }
137: }
138:
139: public class ControllerWrapper implements Controller {
140: private final ThreadLocal threadLocal;
141:
142: public ControllerWrapper(ThreadLocal threadLocal) {
143: this .threadLocal = threadLocal;
144: }
145:
146: public void veto() {
147: ((Controller) threadLocal.get()).veto();
148: }
149:
150: public void clear() {
151: ((Controller) threadLocal.get()).clear();
152: }
153:
154: public boolean isVetoed() {
155: return ((Controller) threadLocal.get()).isVetoed();
156: }
157:
158: public void setOriginalRetVal(Object retVal) {
159: ((Controller) threadLocal.get()).setOriginalRetVal(retVal);
160: }
161:
162: public Object getOriginalRetVal() {
163: return ((Controller) threadLocal.get()).getOriginalRetVal();
164: }
165:
166: public boolean isOverridden() {
167: return ((Controller) threadLocal.get()).isOverridden();
168: }
169:
170: public void instance(Object instance) {
171: ((Controller) threadLocal.get()).instance(instance);
172:
173: }
174:
175: public void override() {
176: ((Controller) threadLocal.get()).override();
177: }
178: }
179:
180: public String getDescriptor() {
181: return "Intercepted";
182: }
183: }
|