SimpleHandlerFactory.java

package net.secodo.jcircuitbreaker.breakhandler.impl;

import java.lang.reflect.Constructor;

import java.util.concurrent.Callable;

import net.secodo.jcircuitbreaker.breaker.execution.ExecutionContext;
import net.secodo.jcircuitbreaker.breakhandler.BreakHandler;
import net.secodo.jcircuitbreaker.breakhandler.BreakHandlerFactory;
import net.secodo.jcircuitbreaker.breakhandler.exception.BreakHandlerException;
import net.secodo.jcircuitbreaker.task.Task;


/**
 * An implementation of {@link BreakHandlerFactory} which creates new instance of given {@link BreakHandler} class for
 * each invocation of {@link #makeHandler(Task, ExecutionContext)} . The class given as a constructor param needs
 * to have default constructor which is used to create instance. The constructor must be accessible to 
 * {@link SimpleHandlerFactory}.
 *
 * <p>NOTE: if given handlerClass makes subsequent calls to {@link #makeHandler(Task, ExecutionContext)} during one
 * execution flow of circuit breaker (like for example {@link ReusableRetryHandler} does), new instance of given
 * handler would be created for each call to {@link #makeHandler(Task, ExecutionContext)}, so there will be
 * different instances of {@link BreakHandler} created per execution flow of circuit breaker. If you want only
 * one <i>break handler</i> to be created for single execution of <i>Task</i>, consider implementing
 * {@link net.secodo.jcircuitbreaker.breakhandler.OnePerExecutionHandlerFactory} which creates and returns only one
 * instance per execution. See source code of {@link ReusableRetryHandler} for example of implementing this interface.
 *
 * @param <R> the return type of real-method for which a <i>break handler</i> is created
 */
public class SimpleHandlerFactory<R> implements BreakHandlerFactory<R> {
  private final Class<? extends BreakHandler<R>> handlerClass;

  public SimpleHandlerFactory(Class<? extends BreakHandler<R>> handlerClass) {
    this.handlerClass = handlerClass;
  }

  @Override
  public BreakHandler<R> makeHandler(Task<R> task, ExecutionContext<R> executionContext) {
    final BreakHandler<R> breakHandler;
    try {
      final Constructor<? extends BreakHandler<R>> handlerClassConstructor = handlerClass.getConstructor();
      breakHandler = handlerClassConstructor.newInstance();

    } catch (Exception ex) {
      throw new BreakHandlerException("Unable to create new instance of break handler of class: " + handlerClass, ex);
    }

    return breakHandler;
  }
}