View Javadoc
1   package net.secodo.jcircuitbreaker.breakhandler.helper;
2   
3   import java.lang.reflect.Constructor;
4   
5   import net.secodo.jcircuitbreaker.breakhandler.BreakHandler;
6   import net.secodo.jcircuitbreaker.breakhandler.BreakHandlerFactory;
7   import net.secodo.jcircuitbreaker.breakhandler.exception.BreakHandlerException;
8   
9   
10  /**
11   * Helper class which role is to create new instances of given {@link BreakHandler} class.
12   * The class given needs to have a public one-argument constructor.
13   *
14   */
15  public class InstantiationHelper {
16    /**
17     * Creates new instances of given {@link BreakHandler} class. The class given needs to have a publicly accessible(!)
18     * one-argument constructor.
19     *
20     * @param handlerClass the class representing break handler which should be created
21     * @param constructorParam constructor parameter of break handler which should be created
22     * @param <R> the return type of real-method for which a <i>break handler</i> is created
23     * @param <P> the type of constructor parameter which is used to create new instance of break handler
24     *
25     * @return new instance of {@link BreakHandler} constructed using single parameter constructor with given parameter
26     *         value
27     *
28     * @throws BreakHandlerException in case instantiation failed
29     */
30    @SuppressWarnings("rawtypes")
31    public static <R, P> BreakHandler<R> constructSingleParamInstance(Class<? extends BreakHandler> handlerClass,
32                                                                      P constructorParam) throws BreakHandlerException {
33      final BreakHandler<R> breakHandler;
34      try {
35        Constructor<? extends BreakHandler> constructor = null;
36        try {
37          Class<P> parameterClass = getConstructorParamClass(constructorParam);
38          constructor = handlerClass.getConstructor(parameterClass);
39  
40        } catch (NoSuchMethodException originalException) {
41          // try to find matching constructor containing primitive type
42  
43          try {
44            if (Integer.class.isInstance(constructorParam)) {
45              constructor = handlerClass.getConstructor(int.class);
46            } else if (Long.class.isInstance(constructorParam)) {
47              constructor = handlerClass.getConstructor(long.class);
48            } else if (Float.class.isInstance(constructorParam)) {
49              constructor = handlerClass.getConstructor(float.class);
50            } else if (Double.class.isInstance(constructorParam)) {
51              constructor = handlerClass.getConstructor(double.class);
52            } else if (Short.class.isInstance(constructorParam)) {
53              constructor = handlerClass.getConstructor(short.class);
54            } else if (Byte.class.isInstance(constructorParam)) {
55              constructor = handlerClass.getConstructor(byte.class);
56            } else {
57              throw originalException;
58            }
59          } catch (NoSuchMethodException anotherException) {
60            throw originalException;
61          }
62        }
63  
64        breakHandler = instantiate(constructor, constructorParam);
65  
66      } catch (Exception ex) {
67        throw new BreakHandlerException(
68          "Unable to create new instance of break handler of class: " + handlerClass + " " +
69          "by using constructor with parameter: " + constructorParam + ". The constructor must be public - otherwise " +
70          "you need to create custom " + BreakHandlerFactory.class.getSimpleName() + " instead of using " +
71          InstantiationHelper.class.getSimpleName() + " to instantiate handler class)",
72          ex);
73      }
74  
75      return breakHandler;
76    }
77  
78    @SuppressWarnings({ "unchecked", "rawtypes" })
79    private static <R, P> BreakHandler<R> instantiate(Constructor<? extends BreakHandler> constructor,
80                                                      P constructorParam)
81                                               throws InstantiationException, IllegalAccessException,
82                                                      java.lang.reflect.InvocationTargetException {
83      return constructor.newInstance(constructorParam);
84    }
85  
86    @SuppressWarnings("unchecked")
87    private static <P> Class<P> getConstructorParamClass(P constructorParam) {
88      return (Class<P>) constructorParam.getClass();
89    }
90  
91  }