001 /* 002 * (c) 2003-2005, 2009, 2010 ThoughtWorks Ltd 003 * All rights reserved. 004 * 005 * The software in this package is published under the terms of the BSD 006 * style license a copy of which has been included with this distribution in 007 * the LICENSE.txt file. 008 * 009 * Created on 04-May-2004 010 */ 011 package com.thoughtworks.proxy.toys.decorate; 012 013 import java.lang.reflect.InvocationTargetException; 014 import java.lang.reflect.Method; 015 016 import com.thoughtworks.proxy.Invoker; 017 import com.thoughtworks.proxy.kit.PrivateInvoker; 018 019 020 /** 021 * Invoker implementation for the decorating proxy. The implementation may decorate an object or another {@link Invoker}. 022 * 023 * @author Dan North 024 * @author Aslak Hellesøy 025 * @author Jörg Schaible 026 * @since 0.1 027 */ 028 public class DecoratingInvoker<T> implements Invoker { 029 private static final long serialVersionUID = 8293471912861497447L; 030 private Invoker decorated; 031 private Decorator<T> decorator; 032 033 /** 034 * Construct a DecoratingInvoker decorating another Invoker. 035 * 036 * @param decorated the decorated {@link Invoker}. 037 * @param decorator the decorating instance. 038 * @since 1.0 039 */ 040 public DecoratingInvoker(final Invoker decorated, final Decorator<T> decorator) { 041 this.decorated = decorated; 042 this.decorator = decorator; 043 } 044 045 /** 046 * Construct a DecoratingInvoker decorating another object. 047 * 048 * @param delegate the decorated object. 049 * @param decorator the decorating instance. 050 * @since 1.0 051 */ 052 public DecoratingInvoker(final Object delegate, final Decorator<T> decorator) { 053 this(new PrivateInvoker(delegate), decorator); 054 } 055 056 public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { 057 @SuppressWarnings("unchecked") 058 final T typedProxy = (T)proxy; 059 final Object[] decoratedArgs = decorator.beforeMethodStarts(typedProxy, method, args); 060 try { 061 final Object result = decorated.invoke(proxy, method, decoratedArgs); 062 return decorator.decorateResult(typedProxy, method, decoratedArgs, result); 063 } catch (InvocationTargetException e) { 064 throw decorator.decorateTargetException(typedProxy, method, decoratedArgs, e.getTargetException()); 065 } catch (Exception e) { 066 throw decorator.decorateInvocationException(typedProxy, method, decoratedArgs, e); 067 } 068 } 069 }