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

com.deliveredtechnologies.rulebook.model.runner.AbstractRuleBookRunner Maven / Gradle / Ivy

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

import com.deliveredtechnologies.rulebook.NameValueReferableMap;
import com.deliveredtechnologies.rulebook.Result;
import com.deliveredtechnologies.rulebook.model.RuleBook;
import com.deliveredtechnologies.rulebook.model.Auditor;
import com.deliveredtechnologies.rulebook.model.Rule;
import com.deliveredtechnologies.rulebook.model.AuditableRule;
import com.deliveredtechnologies.rulebook.model.Auditable;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.InvalidPathException;
import java.util.List;
import java.util.Optional;

import static com.deliveredtechnologies.rulebook.util.AnnotationUtils.getAnnotatedField;
import static com.deliveredtechnologies.rulebook.util.AnnotationUtils.getAnnotation;

/**
 * Declares an abstract class for creating RuleBookRunner derived classes using the template method pattern.
 */
public abstract class AbstractRuleBookRunner extends Auditor implements RuleBook {
  private static Logger LOGGER = LoggerFactory.getLogger(RuleBookRunner.class);

  private Class _prototypeClass;

  @SuppressWarnings("unchecked")
  private Result _result = new Result(null);

  /**
   * Creates a new RuleBookRunner using the RuleBook class.
   * @param prototypeClass a RuleBook class that determines how the RuleBook is run
   */
  public AbstractRuleBookRunner(Class prototypeClass) {
    _prototypeClass = prototypeClass;
  }

  @Override
  public void addRule(Rule rule) {
    throw new UnsupportedOperationException("Rules are only added to a RuleBookRunner on run()!");
  }

  @Override
  @SuppressWarnings("unchecked")
  public void run(NameValueReferableMap facts) {
    getResult().ifPresent(Result::reset);
    try {
      RuleBook ruleBook = _prototypeClass.newInstance();
      List> classes = getPojoRules();
      for (Class rule : classes) {
        try {
          getAnnotatedField(com.deliveredtechnologies.rulebook.annotation.Result.class, rule).ifPresent(field ->
              ruleBook.setDefaultResult(_result.getValue() == null ? new Object() : _result.getValue())
          );
          String name = getAnnotation(com.deliveredtechnologies.rulebook.annotation.Rule.class, rule).name();
          if (name.equals("None")) {
            name = rule.getSimpleName();
          }
          Rule ruleInstance = new AuditableRule(new RuleAdapter(rule.newInstance()), name);
          ruleBook.addRule(ruleInstance);
          ((Auditable)ruleInstance).setAuditor(this);
        } catch (IllegalAccessException | InstantiationException ex) {
          LOGGER.warn("Unable to create instance of rule using '" + rule + "'", ex);
        }
      }
      ruleBook.run(facts);
      Optional result = ruleBook.getResult();
      result.ifPresent(res -> _result.setValue(res.getValue()));
    } catch (IOException | InvalidPathException ex) {
      LOGGER.error("Unable to find rule classes", ex);
    } catch (InstantiationException | IllegalAccessException ex) {
      LOGGER.error("Unable to create an instance of '" + _prototypeClass.getName()
          + "' with the default constructor", ex);
    }
  }

  @Override
  @SuppressWarnings("unchecked")
  public void setDefaultResult(Object result) {
    _result = new Result(result);
  }

  @Override
  @SuppressWarnings("unchecked")
  public Optional getResult() {
    return _result.getValue() == null ? Optional.empty() : Optional.of(_result);
  }

  @Override
  public boolean hasRules() {
    try {
      return getPojoRules().size() > 0;
    } catch (InvalidPathException e) {
      LOGGER.error("Unable to find rule classes", e);
      return false;
    }
  }

  /**
   * Gets the POJO Rules used in the RuleBook.
   * @return  A List of the POJO Rules used in a RuleBook.
   */
  protected abstract List> getPojoRules();
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy