package com.philemonworks.critter.rule; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.philemonworks.critter.action.Action; import com.philemonworks.critter.condition.Condition; public class Rule implements Condition, Action { private static final Logger LOG = LoggerFactory.getLogger(Rule.class); public String id; public boolean enabled = true; public boolean tracing = false; protected List<Condition> conditions = new ArrayList<Condition>(); protected List<Action> actions = new ArrayList<Action>(); public boolean invalid = false; public List<Condition> getConditions() { if (conditions == null) conditions = new ArrayList<Condition>(); return conditions; } public List<Action> getActions() { if (actions == null) actions = new ArrayList<Action>(); return actions; } @Override public boolean test(RuleContext context) { if (invalid) return false; if (conditions == null) return true; context.rule = this; for (Condition each : conditions) { final boolean matches = each.test(context); if (tracing) { LOG.info("rule={} condition={} matches={}", id, each.explain(), matches); } if (!matches) return false; } return true; } @Override public void perform(RuleContext context) { if (actions == null) return; context.rule = this; for (Action each : actions) { if (tracing) { LOG.info("rule={} perform={}", id, each.explain()); } each.perform(context); } } public void ensureId() { if (null != id) return; this.id = Long.toString(System.currentTimeMillis()); } public String conditionsString() { StringBuilder sb = new StringBuilder(); sb.append("IF "); for (int i = 0; i < this.getConditions().size(); ++i) { if (i > 0) { sb.append("\nAND "); } Condition each = this.getConditions().get(i); sb.append(each.explain()); } return sb.toString(); } public String actionsString() { StringBuilder sb = new StringBuilder(); sb.append("THEN "); for (int i = 0; i < this.getActions().size(); ++i) { if (i > 0) { sb.append("\nTHEN "); } Action each = this.getActions().get(i); sb.append(each.explain()); } return sb.toString(); } @Override public String explain() { return this.conditionsString() + "\n" + this.actionsString(); } }