001    /*
002     * Created on Mar 19, 2012
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
005     * the License. You may obtain a copy of the License at
006     * 
007     * http://www.apache.org/licenses/LICENSE-2.0
008     * 
009     * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
010     * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
011     * specific language governing permissions and limitations under the License.
012     * 
013     * Copyright @2006-2009 the original author or authors.
014     */
015    package org.fest.reflect.field.decorator;
016    
017    import java.lang.reflect.InvocationHandler;
018    import java.lang.reflect.InvocationTargetException;
019    import java.lang.reflect.Method;
020    
021    /**
022     * @author Ivan Hristov
023     * 
024     */
025    public abstract class DecoratorInvocationHandler<T> implements InvocationHandler {
026    
027      private final T target;
028      private T decorator;
029      private boolean returnDecoratorResult = false;
030    
031      public DecoratorInvocationHandler(T target, T decorator) {
032        this.target = target;
033        this.decorator = decorator;
034      }
035    
036      public void setDecorator(T decorator) {
037        this.decorator = decorator;
038      }
039    
040      public T getTarget() {
041        return target;
042      }
043    
044      public T getDecorator() {
045        return decorator;
046      }
047    
048      public final Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
049    
050        Object firstResult = null;
051        try {
052          firstResult = invokeFirst(method, args);
053        } catch (InvocationTargetException e) {
054          throw e.getCause();
055        }
056    
057        Object secondResult = null;
058        try {
059          secondResult = invokeSecond(method, args);
060        } catch (InvocationTargetException e) {
061          throw e.getCause();
062        }
063    
064        return getResult(firstResult, secondResult);
065      }
066    
067      protected abstract Object invokeFirst(Method method, Object[] args) throws IllegalArgumentException,
068          IllegalAccessException, InvocationTargetException;
069    
070      protected abstract Object invokeSecond(Method method, Object[] args) throws IllegalArgumentException,
071          IllegalAccessException, InvocationTargetException;
072    
073      protected abstract Object getResult(Object firstResult, Object secondResult);
074    
075      public void setReturnDecoratorResult(boolean returnDecoratorResult) {
076       this.returnDecoratorResult =  returnDecoratorResult;
077      }
078    
079      protected boolean shouldReturnDecoratorResult(){
080        return returnDecoratorResult;
081      }
082    }