All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.deliveredtechnologies.rulebook.lang.RuleBookBuilder Maven / Gradle / Ivy

There is a newer version: 0.12
Show newest version
package com.deliveredtechnologies.rulebook.lang;

import com.deliveredtechnologies.rulebook.model.Auditor;
import com.deliveredtechnologies.rulebook.model.Rule;
import com.deliveredtechnologies.rulebook.model.RuleBook;
import com.deliveredtechnologies.rulebook.model.RuleBookAuditor;
import com.deliveredtechnologies.rulebook.model.rulechain.cor.CoRRuleBook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.function.Consumer;

/**
 * The initial builder used to build a RuleBook.
 */
public class RuleBookBuilder implements TerminatingRuleBookBuilder {

  private static Logger LOGGER = LoggerFactory.getLogger(RuleBookBuilder.class);

  private RuleBook _ruleBook;
  private Class _ruleBookClass;
  private Class _resultType = Object.class;

  /**
   * Returns a new RuleBookBuilder for the default RuleBook type.
   * @return  a new RuleBookBuilder
   */
  public static RuleBookBuilder create() {
    return new RuleBookBuilder(CoRRuleBook.class);
  }

  /**
   * Returns a new RuleBookBuilder using the supplied RuleBook class.
   * @param ruleBookClass a RuleBook class to be used in the builder
   * @return              a new RuleBookBuilder
   */
  public static RuleBookBuilder create(Class ruleBookClass) {
    return new RuleBookBuilder(ruleBookClass);
  }

  private RuleBookBuilder(Class ruleBookClass) {
    _ruleBookClass = ruleBookClass;
  }

  @SuppressWarnings("unchecked")
  private RuleBookBuilder(RuleBookBuilder ruleBookBuilder) {
    _resultType = ruleBookBuilder._resultType;
    _ruleBookClass = ruleBookBuilder._ruleBookClass;
    newRuleBook();
  }

  /**
   * Decorates the RuleBook with {@link Auditor} functionality for rules auditing.
   * @return  a builder that can add rules
   */
  public RuleBookAddRuleBuilder asAuditor() {
    return new RuleBookAddRuleBuilder<>(new RuleBookAuditor<>(newRuleBook()));
  }

  /**
   * Specifies the Result type for the RuleBook.
   * @param resultType  result class
   * @param          type of the result class
   * @return            a builder with the new Result type
   */
  public  RuleBookWithResultTypeBuilder withResultType(Class resultType) {
    _resultType = resultType;
    return new RuleBookWithResultTypeBuilder((new RuleBookBuilder(this)).newRuleBook());
  }

  /**
   * Adds a rule to the RuleBook.
   * @param consumer  functional interface that supplies a RuleBookRuleBuilder for building a Rule
   * @return          a builder with the added Rule
   */
  public RuleBookAddRuleBuilder addRule(Consumer> consumer) {
    return new RuleBookAddRuleBuilder<>(newRuleBook(), consumer);
  }

  /**
   * Adds a rule to the RuleBook.
   * @param rule  Rule to be added into the RuleBook
   * @param    the fact type of the Rule
   * @return      RuleBookBuilder with the added Rule
   */
  public  RuleBookAddRuleBuilder addRule(Rule rule) {
    return new RuleBookAddRuleBuilder<>(newRuleBook(), rule);
  }

  /**
   * Builds the RuleBook.
   * @return  a RuleBook
   */
  @Override
  public RuleBook build() {
    return (new RuleBookBuilder(_ruleBookClass)).newRuleBook();
  }

  private RuleBook newRuleBook() {
    if (_ruleBook == null) {
      try {
        _ruleBook = _ruleBookClass.newInstance();
      } catch (IllegalAccessException | InstantiationException e) {
        try {
          Constructor constructor = _ruleBookClass.getConstructor(Class.class);
          _ruleBook = (RuleBook) constructor.newInstance(_resultType);
        } catch (InvocationTargetException
            | NoSuchMethodException
            | InstantiationException
            | IllegalAccessException ex) {
          throw new IllegalStateException("RuleBook of class " + _ruleBookClass + " can not be instantiated", ex);
        }
      }
    }
    return _ruleBook;
  }
}