rulebook-core/src/main/java/com/deliveredtechnologies/rulebook/StandardRule.java
@Override
  @SuppressWarnings("unchecked")
  public void run(Object... otherArgs) {
    try {
      //only use facts of the specified type
      FactMap<T> typeFilteredFacts = new FactMap<T>((Map<String, NameValueReferable<T>>)_facts.values().stream()
          .filter((Object fact) -> _factType.isAssignableFrom(((Fact)fact).getValue().getClass()))
          .collect(Collectors.toMap(fact -> ((Fact)fact).getName(), fact -> (Fact<T>)fact)));
      //invoke then() action(s) if when() is true or if when() was never specified
      if (getWhen() == null || getWhen().test(typeFilteredFacts)) {

        //iterate through the then() actions specified
        List<Object> actionList = getThen();
        for (int i = 0; i < (getThen()).size(); i++) {
          Object action = actionList.get(i);
          List<String> factNames = _factNameMap.get(i);

          //if using() fact names were specified for the specific then(), use only those facts specified
          FactMap<T> usingFacts;
          if (factNames != null) {
            usingFacts = new FactMap<T>(factNames.stream()
                .filter(typeFilteredFacts::containsKey)
                .collect(Collectors.toMap(name -> name, name -> _facts.get(name))));
          } else {
            usingFacts = typeFilteredFacts;
          }

          //invoke the action
          Stream.of(action.getClass().getMethods())
              .filter(method -> method.getName().equals("accept"))
              .findFirst()
              .ifPresent(method -> {
                try {
                  method.setAccessible(true);
                  method.invoke(action,
                      ArrayUtils.combine(new Object[]{usingFacts}, otherArgs, method.getParameterCount()));
                } catch (IllegalAccessException | InvocationTargetException err) {
                  LOGGER.error("Error invoking action on " + action.getClass(), err);
                }
              });
        }

        //if stop() was invoked, stop the rule chain after then is finished executing
        if (_ruleState == BREAK) {
          return;
        }
      }
    } catch (Exception ex) {

      //catch errors in case something like one rule was chained expecting a Fact that doesn't exist
      //eventually, we'll have to resolve that kind of issue ahead of time
      LOGGER.error("Error occurred when trying to evaluate rule!", ex);
    }

    //continue down the rule chain
    _nextRule.ifPresent(rule -> rule.given(_facts));
    _nextRule.ifPresent(Rule::run);
  }
@Override
  @SuppressWarnings("unchecked")
  public void run(Object... otherArgs) {
    try {
      //only use facts of the specified type
      FactMap<T> typeFilteredFacts = new FactMap<T>((Map<String, NameValueReferable<T>>)_facts.values().stream()
          .filter((Object fact) -> _factType.isAssignableFrom(((Fact)fact).getValue().getClass()))
          .collect(Collectors.toMap(fact -> ((Fact)fact).getName(), fact -> (Fact<T>)fact)));
      //invoke then() action(s) if when() is true or if when() was never specified
      if (getWhen() == null || getWhen().test(typeFilteredFacts)) {

        //iterate through the then() actions specified
        List<Object> actionList = getThen();
        for (int i = 0; i < (getThen()).size(); i++) {
          Object action = actionList.get(i);
          List<String> factNames = _factNameMap.get(i);

          //if using() fact names were specified for the specific then(), use only those facts specified
          FactMap<T> usingFacts;
          if (factNames != null) {
            usingFacts = new FactMap<T>(factNames.stream()
                .filter(typeFilteredFacts::containsKey)
                .collect(Collectors.toMap(name -> name, name -> _facts.get(name))));
          } else {
            usingFacts = typeFilteredFacts;
          }

          //invoke the action
          Stream.of(action.getClass().getMethods())
              .filter(method -> method.getName().equals("accept"))
              .findFirst()
              .ifPresent(method -> {
                try {
                  method.setAccessible(true);
                  method.invoke(action,
                      ArrayUtils.combine(new Object[]{usingFacts}, otherArgs, method.getParameterCount()));
                } catch (IllegalAccessException | InvocationTargetException err) {
                  LOGGER.error("Error invoking action on " + action.getClass(), err);
                }
              });
        }

        //if stop() was invoked, stop the rule chain after then is finished executing
        if (_ruleState == BREAK) {
          return;
        }
      }
    } catch (Exception ex) {

      //catch errors in case something like one rule was chained expecting a Fact that doesn't exist
      //eventually, we'll have to resolve that kind of issue ahead of time
      LOGGER.error("Error occurred when trying to evaluate rule!", ex);
    }

    //continue down the rule chain
    _nextRule.ifPresent(rule -> rule.given(_facts));
    _nextRule.ifPresent(Rule::run);
  }
@ Override @ SuppressWarnings ( "unchecked" ) public void run ( Object ... otherArgs ) { try { //only use facts of the specified type FactMap < T > typeFilteredFacts = new FactMap < T > ( ( Map < String , NameValueReferable < T > > ) _facts . values ( ) . stream ( ) . filter ( ( Object fact ) -> _factType . isAssignableFrom ( ( ( Fact ) fact ) . getValue ( ) . getClass ( ) ) ) . collect ( Collectors . toMap ( fact -> ( ( Fact ) fact ) . getName ( ) , fact -> ( Fact < T > ) fact ) ) ) ; //invoke then() action(s) if when() is true or if when() was never specified if ( getWhen ( ) == null || getWhen ( ) . test ( typeFilteredFacts ) ) { //iterate through the then() actions specified List < Object > actionList = getThen ( ) ; for ( int i = 0 ; i < ( getThen ( ) ) . size ( ) ; i ++ ) { Object action = actionList . get ( i ) ; List < String > factNames = _factNameMap . get ( i ) ; //if using() fact names were specified for the specific then(), use only those facts specified FactMap < T > usingFacts ; if ( factNames != null ) { usingFacts = new FactMap < T > ( factNames . stream ( ) . filter ( typeFilteredFacts :: containsKey ) . collect ( Collectors . toMap ( name -> name , name -> _facts . get ( name ) ) ) ) ; } else { usingFacts = typeFilteredFacts ; } //invoke the action Stream . of ( action . getClass ( ) . getMethods ( ) ) . filter ( method -> method . getName ( ) . equals ( "accept" ) ) . findFirst ( ) . ifPresent ( method -> { try { method . setAccessible ( true ) ; method . invoke ( action , ArrayUtils . combine ( new Object [ ] { usingFacts } , otherArgs , method . getParameterCount ( ) ) ) ; } catch ( IllegalAccessException | InvocationTargetException err ) { LOGGER . error ( "Error invoking action on " + action . getClass ( ) , err ) ; } } ) ; } //if stop() was invoked, stop the rule chain after then is finished executing if ( _ruleState == BREAK ) { return ; } } } catch ( Exception ex ) { //catch errors in case something like one rule was chained expecting a Fact that doesn't exist //eventually, we'll have to resolve that kind of issue ahead of time LOGGER . error ( "Error occurred when trying to evaluate rule!" , ex ) ; } //continue down the rule chain _nextRule . ifPresent ( rule -> rule . given ( _facts ) ) ; _nextRule . ifPresent ( Rule :: run ) ; }
The run(Object[]) method runs the {@link Predicate} supplied by the when() method. <br/>
If it evaluates to true then the action(s) supplied by the then() method(s) are executed. <br/>
If the stop() method was invoked then no further rules are evaluated. <br/>
Otherwise, the next rule in the chain is evaluated.
The run ( Object [] ) method runs the {