org.picocontainer.behaviors.Intercepted Maven / Gradle / Ivy
The newest version!
/*****************************************************************************
* Copyright (c) PicoContainer Organization. All rights reserved. *
* ------------------------------------------------------------------------- *
* The software in this package is published under the terms of the BSD *
* style license a copy of which has been included with this distribution in *
* the LICENSE.txt file. *
* *
*****************************************************************************/
package org.picocontainer.behaviors;
import org.picocontainer.ComponentAdapter;
import org.picocontainer.PicoContainer;
import java.util.Map;
import java.util.HashMap;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.io.Serializable;
/** @author Paul Hammant */
@SuppressWarnings("serial")
public class Intercepted extends HiddenImplementation {
private final Map pres = new HashMap();
private final Map posts = new HashMap();
private Controller controller = new ControllerWrapper(new InterceptorThreadLocal());
public Intercepted(ComponentAdapter delegate) {
super(delegate);
}
public void addPreInvocation(Class type, Object interceptor) {
pres.put(type, interceptor);
}
public void addPostInvocation(Class type, Object interceptor) {
posts.put(type, interceptor);
}
@Override
protected Object invokeMethod(Object componentInstance, Method method, Object[] args, PicoContainer container) throws Throwable {
try {
controller.clear();
controller.instance(componentInstance);
Object pre = pres.get(method.getDeclaringClass());
if (pre != null) {
Object rv = method.invoke(pre, args);
if (controller.isVetoed()) {
return rv;
}
}
Object result = method.invoke(componentInstance, args);
controller.setOriginalRetVal(result);
Object post = posts.get(method.getDeclaringClass());
if (post != null) {
Object rv = method.invoke(post, args);
if (controller.isOverridden()) {
return rv;
}
}
return result;
} catch (final InvocationTargetException ite) {
throw ite.getTargetException();
}
}
public Controller getController() {
return controller;
}
public static class InterceptorThreadLocal extends ThreadLocal implements Serializable {
protected Object initialValue() {
return new ControllerImpl();
}
}
public interface Controller {
void veto();
void clear();
boolean isVetoed();
void setOriginalRetVal(Object retVal);
boolean isOverridden();
void instance(Object instance);
Object getInstance();
Object getOriginalRetVal();
void override();
}
public static class ControllerImpl implements Controller {
private boolean vetoed;
private Object retVal;
private boolean overridden;
private Object instance;
public void veto() {
vetoed = true;
}
public void clear() {
vetoed = false;
overridden = false;
retVal = null;
instance = null;
}
public boolean isVetoed() {
return vetoed;
}
public void setOriginalRetVal(Object retVal) {
this.retVal = retVal;
}
public Object getOriginalRetVal() {
return retVal;
}
public boolean isOverridden() {
return overridden;
}
public void instance(Object instance) {
this.instance = instance;
}
public Object getInstance() {
return instance;
}
public void override() {
overridden = true;
}
}
public class ControllerWrapper implements Controller {
private final ThreadLocal threadLocal;
public ControllerWrapper(ThreadLocal threadLocal) {
this.threadLocal = threadLocal;
}
public void veto() {
threadLocal.get().veto();
}
public void clear() {
threadLocal.get().clear();
}
public boolean isVetoed() {
return threadLocal.get().isVetoed();
}
public void setOriginalRetVal(Object retVal) {
threadLocal.get().setOriginalRetVal(retVal);
}
public Object getOriginalRetVal() {
return threadLocal.get().getOriginalRetVal();
}
public boolean isOverridden() {
return threadLocal.get().isOverridden();
}
public void instance(Object instance) {
threadLocal.get().instance(instance);
}
public Object getInstance() {
return threadLocal.get().getInstance();
}
public void override() {
threadLocal.get().override();
}
}
public String getDescriptor() {
return "Intercepted";
}
}