package net.sf.dobo; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; /** * Context Implementation Object Proxy. * * @author arif * @version 1.0 */ public class ContextImplementationObjectProxyCglib implements MethodInterceptor { /** * Method buffer will buffer the binding between context interface and * context implementation object */ private Map contextInterfaceToContextImplementationObject = new HashMap(); /** * Context object */ private Class context; /** * Context Implementation of target object */ private Object contextImplementationObject; /** * Factory method creating instance * * @param contextImplementationObject * @param context * * @return proxy instance */ public static Object newInstance(final Object contextImplementationObject, final Class context) { try { Dobo.check(contextImplementationObject.getClass()); ContextImplementationObjectProxyCglib interceptor = new ContextImplementationObjectProxyCglib(); interceptor.context = context; interceptor.contextImplementationObject = contextImplementationObject; Class contextInterface = context.getAnnotation(Context.class).value(); Enhancer e = new Enhancer(); e.setSuperclass(contextInterface); e.setCallback(interceptor); Object bean = e.create(); return bean; } catch (final Throwable e) { e.printStackTrace(); throw new Error(e.getMessage()); } } /** * @see net.sf.dobo.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, * java.lang.reflect.Method, java.lang.Object[], * net.sf.dobo.cglib.proxy.MethodProxy) */ public Object intercept(final Object obj, final Method m, final Object[] args, final MethodProxy proxy) throws Throwable { Object retValFromSuper = null; try { if (!contextInterfaceToContextImplementationObject.containsKey(m)) { Class markedAnnotation = Dobo.getContextMemberMatchWith(context, m); if (markedAnnotation != null) { Method method = Dobo.getMethodAnnotatedWith(markedAnnotation, contextImplementationObject.getClass()); contextInterfaceToContextImplementationObject.put(m, method); } else { contextInterfaceToContextImplementationObject.put(m, m); } } Method targetMethod = contextInterfaceToContextImplementationObject.get(m); retValFromSuper = (targetMethod != m) ? targetMethod.invoke(contextImplementationObject, args) : proxy.invokeSuper(obj, args); } catch (final InvocationTargetException e) { throw e.getTargetException(); } catch (final Exception e) { e.printStackTrace(); } return retValFromSuper; } }