Package rulesystem

Source Code of rulesystem.Rule

package rulesystem;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import rulesystem.ruleinput.RuleInput;
import rulesystem.ruleinput.RuleInputMetaData;
import rulesystem.ruleinput.RuleInputMetaData.DataType;

/**
* This class models a rule in the rule system. It has input columns and an
* output value which the rule system maps these inputs to.
*
* @author Kislay
*
*/
public class Rule implements Serializable {

    private Map<String, RuleInput> fieldMap;
    // This list is to keep the order (priority order) of inputs
    private List<RuleInputMetaData> inputColumnList;
    private String uniqueIdColumnName = "id";
    private String uniqueOutputColumnName = "rule_output_id";
    private static final int UNIQUE_ID_INPUT_ID = -1;
    private static final int UNIQUE_OUTPUT_ID_INPUT_ID = -2;

    /**
     * This constructor takes the list of columns in the rule system and a map
     * of value to populate the fields of this rule. Any fields missing in the
     * input are set to blank (meaning 'Any').
     *
     * If you are extending the rule class, be sure to call this constructor.
     *
     * @param colNames
     * @param inputMap
     * @param uniqueIdColName [OPTIONAL] Name of the column containing unique id
     * for the rule. "id" will be used by default.
     * @param uniqueOutputColName [OPTIONAL] Name of the column containing the
     * output of the rule system. "rule_output_id" will be used by default.
     *
     * @throws Exception
     */
    public Rule(List<RuleInputMetaData> columns,
            Map<String, String> inputMap,
            String uniqueIdColName,
            String uniqueOutputColName) throws Exception {
        this.inputColumnList = columns;
        if (uniqueIdColName != null) {
            this.uniqueIdColumnName = uniqueIdColName;
        }
        if (uniqueOutputColName != null) {
            this.uniqueOutputColumnName = uniqueOutputColName;
        }

        fieldMap = new HashMap<>();
        for (RuleInputMetaData col : columns) {
            String inputVal = inputMap.get(col.getName());
            this.fieldMap.put(col.getName(),
                    RuleInput.createRuleInput(col.getId(),
                    col.getRuleSystemId(),
                    col.getName(),
                    col.getPriority(),
                    col.getDataType(),
                    (inputVal == null) ? "" : inputVal));
        }

        String ruleId = inputMap.get(this.uniqueIdColumnName);
        this.fieldMap.put(this.uniqueIdColumnName,
                RuleInput.createRuleInput(UNIQUE_ID_INPUT_ID,
                inputColumnList.get(0).getRuleSystemId(),
                this.uniqueIdColumnName,
                UNIQUE_ID_INPUT_ID,
                DataType.VALUE,
                (ruleId == null) ? "" : ruleId));

        String ruleOutputId = inputMap.get(this.uniqueOutputColumnName);
        this.fieldMap.put(this.uniqueOutputColumnName,
                RuleInput.createRuleInput(UNIQUE_OUTPUT_ID_INPUT_ID,
                inputColumnList.get(0).getRuleSystemId(),
                this.uniqueOutputColumnName,
                UNIQUE_OUTPUT_ID_INPUT_ID,
                DataType.VALUE,
                (ruleOutputId == null) ? "" : ruleOutputId));
    }

    /**
     * This method accepts a column name to column value mapping and return if
     * the mapping is true for this rule. i.e. It returns true if this rule is
     * applicable for the input values and false otherwise.
     *
     * The method returns true if one the following criteria are met for each
     * column: 1. Both rule and input are equal (same value or both being 'Any')
     * 2. Rule is any.
     *
     * In all other cases false is returned.
     *
     * @param inputMap
     * @return
     */
    public boolean evaluate(Map<String, String> inputMap) {
        // For each input column in order, get the value from the rule and compare against input.
        for (RuleInputMetaData col : this.inputColumnList) {
            String colName = col.getName();

            if (colName.equals(this.uniqueIdColumnName)
                    || colName.equals(this.uniqueOutputColumnName)) {
                continue;
            }

            String inputValue = inputMap.get(colName);
            RuleInput ruleInput = this.fieldMap.get(colName);

            // Actual comparison is determined by the input types. So over to them.
            if (ruleInput.evaluate(inputValue)) {
                continue;
            } else {
                return false;
            }
        }

        return true;
    }

    public boolean isConflicting(Rule rule) throws Exception {
        for (RuleInputMetaData col : this.inputColumnList) {
            String colName = col.getName();

            if (colName.equals(this.uniqueIdColumnName)
                    || colName.equals(this.uniqueOutputColumnName)) {
                continue;
            }

            RuleInput thisInput = this.fieldMap.get(colName);
            RuleInput ruleInput = rule.getColumnData(colName);

            // Mark as not conflicting if any field is not conflicting
            if (!ruleInput.isConflicting(thisInput)) {
                return false;
            }
        }

        return true;
    }

    public RuleInput getColumnData(String colName) {
        return this.fieldMap.get(colName);
    }

    /**
     * This method is used to modify the values of rule inputs in a rule. To
     * prevent someone from accidentally modifying column values which propagate
     * throughout the system, this method creates a copy of the current rule,
     * overwrites the specified column with the given value, and returns a new
     * rule. This keeps rule objects unmodifiable to a reasonable extent.
     *
     * @param colName
     * @param value
     * @return
     * @throws Exception
     */
    public Rule setColumnData(String colName, String value) throws Exception {
        Map<String, String> inputMap = new HashMap<>();
        for (Map.Entry<String, RuleInput> ruleInput : this.fieldMap.entrySet()) {
            String column = ruleInput.getKey();
            if (column.equals(colName)) {
                inputMap.put(column, value);
            } else {
                inputMap.put(column, ruleInput.getValue().getValue());
            }
        }

        return new Rule(inputColumnList, inputMap, uniqueIdColumnName, uniqueOutputColumnName);
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("\n");
        builder.append(this.uniqueIdColumnName)
                .append(":")
                .append(getColumnData(this.uniqueIdColumnName).getValue())
                .append("\t");

        for (RuleInputMetaData col : this.inputColumnList) {
            builder.append(col.getName())
                    .append(":")
                    .append(getColumnData(col.getName()).getValue())
                    .append("\t");
        }

        builder.append(this.uniqueOutputColumnName)
                .append(":")
                .append(getColumnData(this.uniqueOutputColumnName).getValue())
                .append("\t");

        return builder.toString();
    }
}
TOP

Related Classes of rulesystem.Rule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.