📄 defaultrulesheetlistener.java
字号:
package org.drools.decisiontable.parser;
/*
* 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.
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.drools.decisiontable.model.Condition;
import org.drools.decisiontable.model.Consequence;
import org.drools.decisiontable.model.Duration;
import org.drools.decisiontable.model.Global;
import org.drools.decisiontable.model.Import;
import org.drools.decisiontable.model.Package;
import org.drools.decisiontable.model.Rule;
import org.drools.decisiontable.parser.xls.PropertiesSheetListener;
/**
* @author <a href="mailto:shaun.addison@gmail.com"> Shaun Addison </a><a
* href="mailto:michael.neale@gmail.com"> Michael Neale </a>
*
* Define a ruleset spreadsheet which contains one or more decision tables.
*
* Stay calm, deep breaths... this is a little bit scary, its where it all
* happens.
*
* A table is identifed by a cell beginning with the text "RuleTable". The first
* row after the table identifier defines the column type: either a condition
* ("C") or consequence ("A" for action), and so on.
*
* The second row contains ObjectType declarations (optionally, or can be left blank).
* If cells are merged, then all snippets below the merged bit will become part of
* the same column as seperate constraints.
*
* The third row identifies the java code block associated with the condition
* or consequence. This code block will include a parameter marker for the
* attribute defined by that column.
*
* The third row is a label for the attribute associated with that column.
*
* All subsequent rows identify rules with the set.
*/
public class DefaultRuleSheetListener
implements
RuleSheetListener {
//keywords
public static final String FUNCTIONS_TAG = "Functions";
public static final String IMPORT_TAG = "Import";
public static final String SEQUENTIAL_FLAG = "Sequential";
public static final String VARIABLES_TAG = "Variables";
public static final String RULE_TABLE_TAG = "RuleTable";
public static final String RULESET_TAG = "RuleSet";
private static final int ACTION_ROW = 1;
private static final int OBJECT_TYPE_ROW = 2;
private static final int CODE_ROW = 3;
private static final int LABEL_ROW = 4;
//state machine variables for this parser
private boolean _isInRuleTable = false;
private int _ruleRow;
private int _ruleStartColumn;
private int _ruleStartRow;
private Rule _currentRule;
private String _currentRulePrefix;
private boolean _currentSequentialFlag = false; // indicates that we are in sequential mode
//accumulated output
private Map _actions;
private final HashMap _cellComments = new HashMap();
private final List _ruleList = new LinkedList();
//need to keep an ordered list of this to make conditions appear in the right order
private List sourceBuilders = new ArrayList();
private final PropertiesSheetListener _propertiesListner = new PropertiesSheetListener();
/* (non-Javadoc)
* @see org.drools.decisiontable.parser.RuleSheetListener#getProperties()
*/
public Properties getProperties() {
return this._propertiesListner.getProperties();
}
/* (non-Javadoc)
* @see org.drools.decisiontable.parser.RuleSheetListener#getRuleSet()
*/
public Package getRuleSet() {
if ( this._ruleList.isEmpty() ) {
throw new DecisionTableParseException( "No RuleTable's were found in spreadsheet." );
}
final Package ruleset = buildRuleSet();
return ruleset;
}
/**
* Add a new rule to the current list of rules
* @param rule
*/
protected void addRule(final Rule newRule) {
this._ruleList.add( newRule );
}
private Package buildRuleSet() {
final String rulesetName = getProperties().getProperty( DefaultRuleSheetListener.RULESET_TAG,
"rule_table" );
final Package ruleset = new Package( rulesetName );
for ( final Iterator it = this._ruleList.iterator(); it.hasNext(); ) {
ruleset.addRule( (Rule) it.next() );
}
final List importList = RuleSheetParserUtil.getImportList( getProperties().getProperty( DefaultRuleSheetListener.IMPORT_TAG ) );
for ( final Iterator it = importList.iterator(); it.hasNext(); ) {
ruleset.addImport( (Import) it.next() );
}
final List variableList = RuleSheetParserUtil.getVariableList( getProperties().getProperty( DefaultRuleSheetListener.VARIABLES_TAG ) ); // Set the list of variables to
// be added to the
// application-data tags
for ( final Iterator it = variableList.iterator(); it.hasNext(); ) {
ruleset.addVariable( (Global) it.next() );
}
final String functions = getProperties().getProperty( DefaultRuleSheetListener.FUNCTIONS_TAG );
ruleset.addFunctions( functions );
return ruleset;
}
/*
* (non-Javadoc)
*
* @see my.hssf.util.SheetListener#startSheet(java.lang.String)
*/
public void startSheet(final String name) {
// nothing to see here... move along..
}
/*
* (non-Javadoc)
*
* @see my.hssf.util.SheetListener#finishSheet()
*/
public void finishSheet() {
this._propertiesListner.finishSheet();
finishRuleTable();
flushRule();
}
/*
* (non-Javadoc)
*
* @see my.hssf.util.SheetListener#newRow()
*/
public void newRow(final int rowNumber,
final int columns) {
if (_currentRule != null)
flushRule();
// nothing to see here... these aren't the droids your looking for..
// move along...
}
/**
* This makes sure that the rules have all their components added.
* As when there are merged/spanned cells, they may be left out.
*/
private void flushRule() {
for ( Iterator iter = sourceBuilders.iterator(); iter.hasNext(); ) {
SourceBuilder src = (SourceBuilder) iter.next();
if (src.hasValues()) {
if (src instanceof LhsBuilder) {
Condition con = new Condition();
con.setSnippet( src.getResult() );
_currentRule.addCondition( con );
} else if (src instanceof RhsBuilder ) {
Consequence con = new Consequence();
con.setSnippet( src.getResult() );
_currentRule.addConsequence( con );
}
src.clearValues();
}
}
}
/*
* (non-Javadoc)
*
* @see my.hssf.util.SheetListener#newCell(int, int, java.lang.String)
*/
public void newCell(final int row,
final int column,
final String value,
int mergedColStart) {
if ( isCellValueEmpty( value ) ) {
return;
}
if (_isInRuleTable && row == this._ruleStartRow) {
return;
}
if ( this._isInRuleTable ) {
processRuleCell( row,
column,
value,
mergedColStart);
} else {
processNonRuleCell( row,
column,
value );
}
}
/**
* This gets called each time a "new" rule table is found.
*/
private void initRuleTable(final int row,
final int column,
final String value) {
preInitRuleTable(row, column, value);
this._isInRuleTable = true;
this._actions = new HashMap();
this.sourceBuilders = new ArrayList();
this._ruleStartColumn = column;
this._ruleStartRow = row;
this._ruleRow = row + DefaultRuleSheetListener.LABEL_ROW + 1;
// setup stuff for the rules to come.. (the order of these steps are
// important !)
this._currentRulePrefix = RuleSheetParserUtil.getRuleName( value );
this._currentSequentialFlag = getSequentialFlag();
this._currentRule = createNewRuleForRow( this._ruleRow );
this._ruleList.add( this._currentRule );
postInitRuleTable(row, column, value);
}
/**
* Called before rule table initialisation. Subclasses may
* override this method to do additional processing.
*/
protected void preInitRuleTable(int row,
int column,
String value) {
}
protected Rule getCurrentRule() {
return _currentRule;
}
/**
* Called after rule table initialisation. Subclasses may
* override this method to do additional processing.
*/
protected void postInitRuleTable(int row,
int column,
String value) {
}
private boolean getSequentialFlag() {
final String seqFlag = getProperties().getProperty( DefaultRuleSheetListener.SEQUENTIAL_FLAG );
return RuleSheetParserUtil.isStringMeaningTrue( seqFlag );
}
private void finishRuleTable() {
if ( this._isInRuleTable ) {
this._currentSequentialFlag = false;
this._isInRuleTable = false;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -