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    import java.util.HashMap;
021    import java.util.Map;
022    
023    /**
024     * A proxy for shielding from exception
025     * @author Ivan Hristov
026     * 
027     */
028    public class RuntimeExceptionShield implements InvocationHandler {
029    
030      private static final Map<Class<?>, Object> DEFAULT_RETURN_VALUES = new HashMap<Class<?>, Object>();
031      private final Object target;
032      private final Class<?> exceptionClass;
033    
034      // static init - reference JLS
035      {
036        DEFAULT_RETURN_VALUES.put(byte.class, 0);
037        DEFAULT_RETURN_VALUES.put(short.class, 0);
038        DEFAULT_RETURN_VALUES.put(int.class, 0);
039        DEFAULT_RETURN_VALUES.put(long.class, 0L);
040        DEFAULT_RETURN_VALUES.put(float.class, 0f);
041        DEFAULT_RETURN_VALUES.put(double.class, 0d);
042        DEFAULT_RETURN_VALUES.put(char.class, '\u0000');
043        DEFAULT_RETURN_VALUES.put(boolean.class, false);
044      }
045      
046      public RuntimeExceptionShield(Object target, Class<?> exceptionClass) {
047        this.target = target;
048        this.exceptionClass = exceptionClass;
049      }
050    
051      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
052        try {
053          return method.invoke(target, args);
054        } catch (InvocationTargetException e) {
055          if (!(e.getCause().getClass() == exceptionClass))  throw e.getCause();
056          // shield from specified exceptions
057        }
058        return DEFAULT_RETURN_VALUES.get(method.getReturnType());
059      }
060    
061    }