/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleMatrixSheetListener.java
https://gitlab.com/MichelZuniga/drools · Java · 192 lines · 109 code · 17 blank · 66 comment · 17 complexity · ee2f0cd451a3e60abe53192986bf1777 MD5 · raw file
- /*
- * Copyright 2005 JBoss Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.drools.decisiontable.parser;
- import java.util.ArrayList;
- import java.util.List;
- import org.drools.core.util.StringUtils;
- import org.drools.decisiontable.parser.DefaultRuleSheetListener;
- import org.drools.template.model.Condition;
- import org.drools.template.model.Consequence;
- import org.drools.template.model.Rule;
- import org.drools.template.model.SnippetBuilder;
- /**
- * href="mailto:michael.neale@gmail.com"> Michael Neale </a>
- *
- * Define a ruleset spreadsheet which contains a matrix style decision tables.
- *
- * This is an example of a custom RuleSheetListener. It differs from the standard
- * decision table in the following ways:
- * - AgendaGroup property so that all rules fall within the same agenda-group
- * - Precondition property which specifies a condition that is always included
- * if a rule is being generated
- * - Action property. Each cell within the decision table causes this action
- * to be triggered
- * - HorizontalCondition property. Each column header in the matrix
- * applies this condition
- * - VerticalCondition property. Each row header in the matrix applies this
- * condition
- *
- * A table is identifed by a cell beginning with the text "RuleTable".
- * The cells after RuleTable in the same row identify the Horizontal Conditions.
- * The cells after RuleTable in the same column identify the Vertical Conditions.
- * The cells with the matrix identify the actions.
- * Wherever an action cell exists for a Vertical/Horizontal condition intersection
- * the following rule is created:
- * rule "rule_row_col"
- * agenda-group AgendaGroup
- * when
- * Precondition
- * VerticalCondition
- * HorizontalCondition
- * then
- * Action
- * end
- */
- public class RuleMatrixSheetListener extends DefaultRuleSheetListener {
- //keywords
- public static final String AGENDAGROUP_TAG = "AgendaGroup";
- public static final String PRECONDITION_TAG = "Precondition";
- public static final String ACTION_TAG = "Action";
- public static final String HORIZONTALCONDITION_TAG = "HorizontalCondition";
- public static final String VERTICALCONDITION_TAG = "VerticalCondition";
- //state machine variables for this parser
- private int ruleTableRow;
- private int ruleTableColumn;
- private String _currentAgendaGroup;
- private Condition _currentPrecondition;
- private String _action;
- private String _horizontalCondition;
- private String _verticalCondition;
- private List<Condition> _horizontalConditions = new ArrayList<Condition>();
- private Condition _currentVerticalCondition;
- private boolean isInRuleTable;
- private Rule firstRule;
- public void newCell(final int row,
- final int column,
- final String value,
- final int mergedColStart) {
- // if we aren't in the rule table just use the default handling
- // (add a property)
- if ( ! isInRuleTable ) {
- super.newCell( row, column, value, mergedColStart );
- return;
- }
- // ignore empty cells
- if ( StringUtils.isEmpty( value ) ) {
- return;
- }
- //Horizontal header column
- //Create a new condition using HorizontalCondition as the template
- //and save it for later use
- if ( row == (ruleTableRow) && column > ruleTableColumn ) {
- _horizontalConditions.add( createCondition( value, _horizontalCondition ) );
- }
- //Vertical header column
- //Create a new condition using VerticalCondition as the template
- //and set it as the current condition
- else if ( row > (ruleTableRow) && column == ruleTableColumn ) {
- _currentVerticalCondition = createCondition( value, _verticalCondition );
- }
- //Intersection column
- //Create a new Consequence
- else if ( row > (ruleTableRow) && column > ruleTableColumn ) {
- createRule( row, column, value );
- }
- }
- private void createRule(final int row,
- final int column,
- final String value) {
- final Consequence consequence = createConsequence( value );
- Rule rule = firstRule;
- if ( rule == null ) {
- rule = new Rule( "rule_" + row + "_" + column,
- null,
- row );
- addRule( rule );
- } else {
- firstRule = null;
- rule.setName( "rule_" + row + "_" + column );
- }
- rule.setAgendaGroup( this._currentAgendaGroup );
- rule.addCondition( this._currentPrecondition );
- rule.addCondition( _currentVerticalCondition );
- rule.addCondition( (Condition) _horizontalConditions.get( column - (ruleTableColumn + 1) ) );
- rule.addConsequence( consequence );
- }
- private Consequence createConsequence(final String value) {
- final SnippetBuilder snip = new SnippetBuilder( _action );
- final String result = snip.build( value );
- final Consequence consequence = new Consequence();
- consequence.setSnippet( result );
- return consequence;
- }
- private Condition createCondition(final String value,
- final String conditionTemplate) {
- SnippetBuilder snip = new SnippetBuilder( conditionTemplate );
- String result = snip.build( value );
- Condition condition = new Condition();
- condition.setSnippet( result );
- return condition;
- }
- public void newRow(int rowNumber,
- int columns) {
- // nothing to do here
- }
- public void finishSheet() {
- // nothing to do here
- }
- protected void postInitRuleTable(int row,
- int column,
- String value) {
- this.firstRule = getCurrentRule();
- }
- /**
- * This gets called each time a "new" rule table is found.
- */
- protected void preInitRuleTable(final int row,
- final int column,
- final String value) {
- this.ruleTableColumn = column;
- this.ruleTableRow = row;
- this.isInRuleTable = true;
- this._currentAgendaGroup = getProperties().getSingleProperty( AGENDAGROUP_TAG );
- this._action = getProperties().getSingleProperty( ACTION_TAG );
- this._horizontalCondition = getProperties().getSingleProperty( HORIZONTALCONDITION_TAG );
- this._verticalCondition = getProperties().getSingleProperty( VERTICALCONDITION_TAG );
- String precondition = getProperties().getSingleProperty( PRECONDITION_TAG );
- if ( precondition != null ) {
- this._currentPrecondition = new Condition();
- this._currentPrecondition.setSnippet( precondition );
- }
- }
- }