[jboss-svn-commits] JBL Code SVN: r6246 - in labs/jbossrules/trunk/drools-decisiontables/src: main/java/org/drools/decisiontable main/java/org/drools/decisiontable/model main/java/org/drools/decisiontable/parser test/java/org/drools/decisiontable test/java/org/drools/decisiontable/parser
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Sat Sep 16 07:50:27 EDT 2006
Author: stevearoonie
Date: 2006-09-16 07:50:08 -0400 (Sat, 16 Sep 2006)
New Revision: 6246
Added:
labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultRuleSheetListener.java
Removed:
labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetListener.java
Modified:
labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/SpreadsheetCompiler.java
labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/model/Rule.java
labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ActionType.java
labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetParserUtil.java
labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetCompilerUnitTest.java
labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RulesheetUtil.java
Log:
JBRULES-483 - extract RuleSheetListener interface from default implementation and allow custom listeners to be used to parse spreadsheets. Added new custom listener for matrix style spreadsheets
Modified: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/SpreadsheetCompiler.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/SpreadsheetCompiler.java 2006-09-15 17:46:32 UTC (rev 6245)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/SpreadsheetCompiler.java 2006-09-16 11:50:08 UTC (rev 6246)
@@ -23,6 +23,7 @@
import org.drools.decisiontable.model.DRLOutput;
import org.drools.decisiontable.model.Package;
import org.drools.decisiontable.parser.DecisionTableParser;
+import org.drools.decisiontable.parser.DefaultRuleSheetListener;
import org.drools.decisiontable.parser.RuleSheetListener;
import org.drools.decisiontable.parser.xls.ExcelParser;
@@ -44,8 +45,28 @@
*/
public String compile(final InputStream xlsStream,
final InputType type) {
- final RuleSheetListener listener = getRuleSheetListener( xlsStream,
- type );
+ return compile( xlsStream,
+ type,
+ new DefaultRuleSheetListener() );
+ }
+
+ /**
+ * Generates DRL from the input stream containing the spreadsheet.
+ *
+ * @param xlsStream
+ * The stream to the spreadsheet. Uses the first worksheet found
+ * for the decision tables, ignores others.
+ * @param type
+ * The type of the file - InputType.CSV or InputType.XLS
+ * @param listener
+ *
+ * @return DRL xml, ready for use in drools.
+ */
+ public String compile(final InputStream xlsStream,
+ final InputType type,
+ final RuleSheetListener listener) {
+ final DecisionTableParser parser = type.createParser( listener );
+ parser.parseFile( xlsStream );
final Package rulePackage = listener.getRuleSet();
final DRLOutput out = new DRLOutput();
rulePackage.renderDRL( out );
@@ -67,7 +88,7 @@
final InputStream stream = this.getClass().getResourceAsStream( classPathResource );
try {
final String drl = compile( stream,
- inputType );
+ inputType );
return drl;
} finally {
closeStream( stream );
@@ -87,7 +108,7 @@
public String compile(final InputStream stream,
final String worksheetName) {
final RuleSheetListener listener = getRuleSheetListener( stream,
- worksheetName );
+ worksheetName );
final Package rulePackage = listener.getRuleSet();
final DRLOutput out = new DRLOutput();
rulePackage.renderDRL( out );
@@ -95,17 +116,8 @@
}
private RuleSheetListener getRuleSheetListener(final InputStream stream,
- final InputType type) {
- final RuleSheetListener listener = new RuleSheetListener();
-
- final DecisionTableParser parser = type.createParser( listener );
- parser.parseFile( stream );
- return listener;
- }
-
- private RuleSheetListener getRuleSheetListener(final InputStream stream,
final String worksheetName) {
- final RuleSheetListener listener = new RuleSheetListener();
+ final RuleSheetListener listener = new DefaultRuleSheetListener();
final Map listeners = new HashMap();
listeners.put( worksheetName,
listener );
Modified: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/model/Rule.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/model/Rule.java 2006-09-15 17:46:32 UTC (rev 6245)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/model/Rule.java 2006-09-16 11:50:08 UTC (rev 6246)
@@ -17,13 +17,10 @@
*/
import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
-import org.drools.decisiontable.parser.SourceBuilder;
-
/**
* @author <a href="mailto:michael.neale at gmail.com"> Michael Neale </a>
*
@@ -52,12 +49,15 @@
private String _activationGroup; // RIK: New variable to the Rule class (Set the
// activation-group parameter of the rule tag)
+ private String _agendaGroup; // SJW: New variable to the Rule class (Set the
+ // agenda-group parameter of the rule tag
+
private List _lhs;
private List _rhs;
private int _spreadsheetRow;
-
+
/**
* Create a new rule. Note that the rule name should be post-fixed with the row number,
* as one way of providing tracability for errors back to the originating spreadsheet.
@@ -78,7 +78,6 @@
this._rhs = new LinkedList();
this._spreadsheetRow = spreadsheetRow;
}
-
public void addCondition(final Condition con) {
this._lhs.add( con );
@@ -102,6 +101,9 @@
if ( this._activationGroup != null ) {
out.writeLine( "\tactivation-group " + this._activationGroup );
}
+ if ( this._agendaGroup != null ) {
+ out.writeLine( "\tagenda-group " + this._agendaGroup );
+ }
if ( this._noLoop != null ) {
out.writeLine( "\tno-loop " + this._noLoop );
}
@@ -225,7 +227,7 @@
return this._duration.getSnippet();
}
- public void setActivationrGroup(final String value) // Set the duration of the rule
+ public void setActivationGroup(final String value) // Set the duration of the rule
{
this._activationGroup = value;
}
@@ -234,12 +236,20 @@
return this._activationGroup;
}
+ public String getAgendaGroup() {
+ return _agendaGroup;
+ }
+
+ public void setAgendaGroup(String group) // Set the agenda-group of the rule
+ {
+ _agendaGroup = group;
+ }
+
public void setNoLoop(final String value) // Set the no-loop attribute of the rule
{
this._noLoop = value;
}
-
/**
* @return The row in the spreadsheet this represents.
* This can be handy when mapping a line error from Parser back to the rule row.
Modified: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ActionType.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ActionType.java 2006-09-15 17:46:32 UTC (rev 6245)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ActionType.java 2006-09-16 11:50:08 UTC (rev 6246)
@@ -18,8 +18,6 @@
import java.util.Map;
-import org.drools.decisiontable.model.SnippetBuilder;
-
/**
* Simple holder class identifying a condition or action column etc.
* This is stored in a map in the main listener class, to track what type of values
@@ -54,6 +52,10 @@
// XOR-GROUP is used to set the activation-group parameter of a rule tag
public static final int ACTIVATIONGROUP = 7;
+ // 14 September 2006 SJW: Add new Agenda Group ActionType
+ // AGENDA-GROUP is used to set the agenda-group parameter of a rule tag
+ public static final int AGENDAGROUP = 8;
+
int type;
private SourceBuilder sourceBuilder = null;
@@ -97,6 +99,15 @@
{
actionTypeMap.put( new Integer( column ),
new ActionType( ActionType.NOLOOP ) );
+ } else if ( value.toUpperCase().equals( "AGENDA-GROUP" ) ) // if the title cell
+ // value equals "AGENDA-GROUP"
+ // then put a
+ // ActionType.AGENDAGROUP
+ // to the _actions
+ // list
+ {
+ actionTypeMap.put( new Integer( column ),
+ new ActionType( ActionType.AGENDAGROUP ) );
} else if ( value.toUpperCase().startsWith( "X" ) || value.toUpperCase().equals( "ACTIVATION-GROUP" ) ) // if the title cell
// value starts with
// "X" then put a
Copied: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultRuleSheetListener.java (from rev 6245, labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetListener.java)
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetListener.java 2006-09-15 17:46:32 UTC (rev 6245)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultRuleSheetListener.java 2006-09-16 11:50:08 UTC (rev 6246)
@@ -0,0 +1,574 @@
+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 at gmail.com"> Shaun Addison </a><a
+ * href="mailto:michael.neale at 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;
+
+ }
+ }
+
+ private void processNonRuleCell(final int row,
+ final int column,
+ final String value) {
+ if ( value.startsWith( DefaultRuleSheetListener.RULE_TABLE_TAG ) ) {
+ initRuleTable( row,
+ column,
+ value );
+ } else {
+ this._propertiesListner.newCell( row,
+ column,
+ value, SheetListener.NON_MERGED);
+ }
+ }
+
+ private void processRuleCell(final int row,
+ final int column,
+ final String value,
+ final int mergedColStart) {
+ if ( value.startsWith( DefaultRuleSheetListener.RULE_TABLE_TAG ) ) {
+ finishRuleTable();
+ initRuleTable( row,
+ column,
+ value );
+ return;
+ }
+
+ // Ignore any comments cells preceeding the first rule table column
+ if ( column < this._ruleStartColumn ) {
+ return;
+ }
+
+ // Ignore any further cells from the rule def row
+ if ( row == this._ruleStartRow ) {
+ return;
+ }
+
+ switch ( row - this._ruleStartRow ) {
+ case ACTION_ROW :
+ ActionType.addNewActionType( this._actions,
+ value,
+ column,
+ row );
+ break;
+ case OBJECT_TYPE_ROW :
+ objectTypeRow( row,
+ column,
+ value,
+ mergedColStart);
+ break;
+ case CODE_ROW :
+ codeRow( row,
+ column,
+ value );
+ break;
+ case LABEL_ROW :
+ labelRow( row,
+ column,
+ value );
+ break;
+ default :
+ nextDataCell( row,
+ column,
+ value );
+ break;
+ }
+ }
+
+ /**
+ * This is for handling a row where an object declaration may appear,
+ * this is the row immediately above the snippets.
+ * It may be blank, but there has to be a row here.
+ *
+ * Merged cells have "special meaning" which is why this is so freaking hard.
+ * A future refactor may be to move away from an "event" based listener.
+ */
+ private void objectTypeRow(final int row,
+ final int column,
+ final String value,
+ final int mergedColStart) {
+ if (value.indexOf( "$param" ) > -1 || value.indexOf( "$1" ) > -1) {
+ throw new DecisionTableParseException("It looks like you have snippets in the row that is " +
+ "meant for column declarations." +
+ " Please insert an additional row before the snippets." +
+ " Row number: " + (row + 1));
+ }
+ ActionType action = getActionForColumn( row, column );
+ if (mergedColStart == SheetListener.NON_MERGED) {
+ if (action.type == ActionType.CONDITION) {
+ SourceBuilder src = new LhsBuilder(value);
+ action.setSourceBuilder(src);
+ this.sourceBuilders.add(src);
+
+ } else if (action.type == ActionType.ACTION) {
+ SourceBuilder src = new RhsBuilder(value);
+ action.setSourceBuilder(src);
+ this.sourceBuilders.add(src);
+ }
+ } else {
+ if (column == mergedColStart) {
+ if (action.type == ActionType.CONDITION) {
+ action.setSourceBuilder(new LhsBuilder(value));
+ this.sourceBuilders.add( action.getSourceBuilder() );
+ } else if (action.type == ActionType.ACTION) {
+ action.setSourceBuilder(new RhsBuilder(value));
+ this.sourceBuilders.add( action.getSourceBuilder() );
+ }
+ } else {
+ ActionType startOfMergeAction = getActionForColumn( row, mergedColStart );
+ action.setSourceBuilder( startOfMergeAction.getSourceBuilder() );
+ }
+
+ }
+ }
+
+ private void codeRow(final int row,
+ final int column,
+ final String value) {
+ final ActionType actionType = getActionForColumn( row, column );
+ if (actionType.getSourceBuilder() == null) {
+ if (actionType.type == ActionType.CONDITION) {
+ actionType.setSourceBuilder( new LhsBuilder(null) );
+ this.sourceBuilders.add( actionType.getSourceBuilder() );
+ } else if (actionType.type == ActionType.ACTION) {
+ actionType.setSourceBuilder( new RhsBuilder(null) );
+ this.sourceBuilders.add( actionType.getSourceBuilder() );
+ }
+ }
+ if ( value.trim().equals( "" ) && (actionType.type == ActionType.ACTION || actionType.type == ActionType.CONDITION) ) {
+ throw new DecisionTableParseException( "Code description - row:" + (row + 1) + " cell number:" + (column + 1) + " - does not contain any code specification. It should !" );
+ }
+
+ actionType.addTemplate(column, value);
+ }
+
+ private void labelRow(final int row,
+ final int column,
+ final String value) {
+ final ActionType actionType = getActionForColumn( row,
+ column );
+
+ if ( !value.trim().equals( "" ) && (actionType.type == ActionType.ACTION || actionType.type == ActionType.CONDITION) ) {
+ this._cellComments.put( new Integer( column ),
+ value );
+ } else {
+ this._cellComments.put( new Integer( column ),
+ "From column: " + Rule.convertColNumToColName( column ) );
+ }
+ }
+
+ private ActionType getActionForColumn(final int row,
+ final int column) {
+ final ActionType actionType = (ActionType) this._actions.get( new Integer( column ) );
+
+ if ( actionType == null ) {
+ throw new DecisionTableParseException( "Code description - row number:" + (row + 1) + " cell number:" + (column + 1) + " - does not have an 'ACTION' or 'CONDITION' column header." );
+ }
+
+ return actionType;
+ }
+
+ private void nextDataCell(final int row,
+ final int column,
+ final String value) {
+ final ActionType actionType = getActionForColumn( row,
+ column );
+
+ if ( row - this._ruleRow > 1 ) {
+ // Encountered a row gap from the last rule.
+ // This is not part of the ruleset.
+ finishRuleTable();
+ processNonRuleCell( row,
+ column,
+ value );
+ return;
+ }
+
+ if ( row > this._ruleRow ) {
+ // In a new row/rule
+ this._currentRule = createNewRuleForRow( row );
+
+ this._ruleList.add( this._currentRule );
+ this._ruleRow++;
+ }
+
+ //if the rule set is not sequential and the actionType type is PRIORITY then set the current Rule's salience paramenter with the value got from the cell
+ if ( actionType.type == ActionType.PRIORITY && !this._currentSequentialFlag ) {
+ this._currentRule.setSalience( new Integer( value ) );
+ } else if ( actionType.type == ActionType.NAME ) // if the actionType
+ // type is PRIORITY then
+ // set the current
+ // Rule's name
+ // paramenter with the
+ // value got from the
+ // cell
+ {
+ this._currentRule.setName( value );
+ } else if ( actionType.type == ActionType.DESCRIPTION ) // if the
+ // actionType
+ // type is
+ // DESCRIPTION
+ // then set the
+ // current
+ // Rule's
+ // description
+ // paramenter
+ // with the
+ // value got
+ // from the cell
+ {
+ this._currentRule.setDescription( value );
+ } else if ( actionType.type == ActionType.ACTIVATIONGROUP ) // if the actionType
+ // type is NOLOOP
+ // then set the
+ // current Rule's
+ // no-loop
+ // paramenter with
+ // the value got
+ // from the cell
+ {
+ this._currentRule.setActivationGroup( value );
+ } else if ( actionType.type == ActionType.NOLOOP ) // if the actionType
+ // type is NOLOOP
+ // then set the
+ // current Rule's
+ // no-loop
+ // paramenter with
+ // the value got
+ // from the cell
+ {
+ this._currentRule.setNoLoop( value );
+ } else if ( actionType.type == ActionType.DURATION ) // if the actionType
+ // type is DURATION
+ // then creates a
+ // new duration tag
+ // with the value
+ // got from the cell
+ {
+ createDuration( column,
+ value,
+ actionType );
+ } else if ( actionType.type == ActionType.CONDITION || actionType.type == ActionType.ACTION ) {
+ actionType.addCellValue( column, value );
+ }
+
+ }
+
+ private Rule createNewRuleForRow(final int row) {
+
+
+ Integer salience = null;
+ if ( this._currentSequentialFlag ) {
+ salience = new Integer( Rule.calcSalience( row ) );
+ }
+ final int spreadsheetRow = row + 1;
+ final String name = this._currentRulePrefix + "_" + spreadsheetRow;
+ final Rule rule = new Rule( name,
+ salience,
+ spreadsheetRow );
+ rule.setComment( "From row number: " + (spreadsheetRow) );
+
+ return rule;
+
+ }
+
+
+ // 08 - 16 - 2005 RIK: This function creates a new DURATION
+ private void createDuration(final int column,
+ final String value,
+ final ActionType actionType) {
+
+ final Duration dur = new Duration();
+ dur.setSnippet( value );
+ dur.setComment( cellComment( column ) );
+ this._currentRule.setDuration( dur );
+ }
+
+
+ private boolean isCellValueEmpty(final String value) {
+ return value == null || "".equals( value.trim() );
+ }
+
+ private String cellComment(final int column) {
+ return "From column: " + Rule.convertColNumToColName( column );
+ }
+
+}
\ No newline at end of file
Deleted: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetListener.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetListener.java 2006-09-15 17:46:32 UTC (rev 6245)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetListener.java 2006-09-16 11:50:08 UTC (rev 6246)
@@ -1,543 +0,0 @@
-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 at gmail.com"> Shaun Addison </a><a
- * href="mailto:michael.neale at 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 RuleSheetListener
- implements
- SheetListener {
-
- //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();
-
- /**
- * Return the rule sheet properties
- */
- public Properties getProperties() {
- return this._propertiesListner.getProperties();
- }
-
- /**
- * Build the final ruleset as parsed.
- */
- public Package getRuleSet() {
- if ( this._ruleList.isEmpty() ) {
- throw new DecisionTableParseException( "No RuleTable's were found in spreadsheet." );
- }
- final Package ruleset = buildRuleSet();
- return ruleset;
- }
-
- private Package buildRuleSet() {
- final String rulesetName = getProperties().getProperty( RuleSheetListener.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( RuleSheetListener.IMPORT_TAG ) );
- for ( final Iterator it = importList.iterator(); it.hasNext(); ) {
- ruleset.addImport( (Import) it.next() );
- }
- final List variableList = RuleSheetParserUtil.getVariableList( getProperties().getProperty( RuleSheetListener.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( RuleSheetListener.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) {
-
- this._isInRuleTable = true;
- this._actions = new HashMap();
- this.sourceBuilders = new ArrayList();
- this._ruleStartColumn = column;
- this._ruleStartRow = row;
- this._ruleRow = row + RuleSheetListener.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 );
-
- }
-
- private boolean getSequentialFlag() {
- final String seqFlag = getProperties().getProperty( RuleSheetListener.SEQUENTIAL_FLAG );
- return RuleSheetParserUtil.isStringMeaningTrue( seqFlag );
- }
-
- private void finishRuleTable() {
- if ( this._isInRuleTable ) {
- this._currentSequentialFlag = false;
- this._isInRuleTable = false;
-
- }
- }
-
- private void processNonRuleCell(final int row,
- final int column,
- final String value) {
- if ( value.startsWith( RuleSheetListener.RULE_TABLE_TAG ) ) {
- initRuleTable( row,
- column,
- value );
- } else {
- this._propertiesListner.newCell( row,
- column,
- value, SheetListener.NON_MERGED);
- }
- }
-
- private void processRuleCell(final int row,
- final int column,
- final String value,
- final int mergedColStart) {
- if ( value.startsWith( RuleSheetListener.RULE_TABLE_TAG ) ) {
- finishRuleTable();
- initRuleTable( row,
- column,
- value );
- return;
- }
-
- // Ignore any comments cells preceeding the first rule table column
- if ( column < this._ruleStartColumn ) {
- return;
- }
-
- // Ignore any further cells from the rule def row
- if ( row == this._ruleStartRow ) {
- return;
- }
-
- switch ( row - this._ruleStartRow ) {
- case ACTION_ROW :
- ActionType.addNewActionType( this._actions,
- value,
- column,
- row );
- break;
- case OBJECT_TYPE_ROW :
- objectTypeRow( row,
- column,
- value,
- mergedColStart);
- break;
- case CODE_ROW :
- codeRow( row,
- column,
- value );
- break;
- case LABEL_ROW :
- labelRow( row,
- column,
- value );
- break;
- default :
- nextDataCell( row,
- column,
- value );
- break;
- }
- }
-
- /**
- * This is for handling a row where an object declaration may appear,
- * this is the row immediately above the snippets.
- * It may be blank, but there has to be a row here.
- *
- * Merged cells have "special meaning" which is why this is so freaking hard.
- * A future refactor may be to move away from an "event" based listener.
- */
- private void objectTypeRow(final int row,
- final int column,
- final String value,
- final int mergedColStart) {
- if (value.indexOf( "$param" ) > -1 || value.indexOf( "$1" ) > -1) {
- throw new DecisionTableParseException("It looks like you have snippets in the row that is " +
- "meant for column declarations." +
- " Please insert an additional row before the snippets." +
- " Row number: " + (row + 1));
- }
- ActionType action = getActionForColumn( row, column );
- if (mergedColStart == SheetListener.NON_MERGED) {
- if (action.type == ActionType.CONDITION) {
- SourceBuilder src = new LhsBuilder(value);
- action.setSourceBuilder(src);
- this.sourceBuilders.add(src);
-
- } else if (action.type == ActionType.ACTION) {
- SourceBuilder src = new RhsBuilder(value);
- action.setSourceBuilder(src);
- this.sourceBuilders.add(src);
- }
- } else {
- if (column == mergedColStart) {
- if (action.type == ActionType.CONDITION) {
- action.setSourceBuilder(new LhsBuilder(value));
- this.sourceBuilders.add( action.getSourceBuilder() );
- } else if (action.type == ActionType.ACTION) {
- action.setSourceBuilder(new RhsBuilder(value));
- this.sourceBuilders.add( action.getSourceBuilder() );
- }
- } else {
- ActionType startOfMergeAction = getActionForColumn( row, mergedColStart );
- action.setSourceBuilder( startOfMergeAction.getSourceBuilder() );
- }
-
- }
- }
-
- private void codeRow(final int row,
- final int column,
- final String value) {
- final ActionType actionType = getActionForColumn( row, column );
- if (actionType.getSourceBuilder() == null) {
- if (actionType.type == ActionType.CONDITION) {
- actionType.setSourceBuilder( new LhsBuilder(null) );
- this.sourceBuilders.add( actionType.getSourceBuilder() );
- } else if (actionType.type == ActionType.ACTION) {
- actionType.setSourceBuilder( new RhsBuilder(null) );
- this.sourceBuilders.add( actionType.getSourceBuilder() );
- }
- }
- if ( value.trim().equals( "" ) && (actionType.type == ActionType.ACTION || actionType.type == ActionType.CONDITION) ) {
- throw new DecisionTableParseException( "Code description - row:" + (row + 1) + " cell number:" + (column + 1) + " - does not contain any code specification. It should !" );
- }
-
- actionType.addTemplate(column, value);
- }
-
- private void labelRow(final int row,
- final int column,
- final String value) {
- final ActionType actionType = getActionForColumn( row,
- column );
-
- if ( !value.trim().equals( "" ) && (actionType.type == ActionType.ACTION || actionType.type == ActionType.CONDITION) ) {
- this._cellComments.put( new Integer( column ),
- value );
- } else {
- this._cellComments.put( new Integer( column ),
- "From column: " + Rule.convertColNumToColName( column ) );
- }
- }
-
- private ActionType getActionForColumn(final int row,
- final int column) {
- final ActionType actionType = (ActionType) this._actions.get( new Integer( column ) );
-
- if ( actionType == null ) {
- throw new DecisionTableParseException( "Code description - row number:" + (row + 1) + " cell number:" + (column + 1) + " - does not have an 'ACTION' or 'CONDITION' column header." );
- }
-
- return actionType;
- }
-
- private void nextDataCell(final int row,
- final int column,
- final String value) {
- final ActionType actionType = getActionForColumn( row,
- column );
-
- if ( row - this._ruleRow > 1 ) {
- // Encountered a row gap from the last rule.
- // This is not part of the ruleset.
- finishRuleTable();
- processNonRuleCell( row,
- column,
- value );
- return;
- }
-
- if ( row > this._ruleRow ) {
- // In a new row/rule
- this._currentRule = createNewRuleForRow( row );
-
- this._ruleList.add( this._currentRule );
- this._ruleRow++;
- }
-
- //if the rule set is not sequential and the actionType type is PRIORITY then set the current Rule's salience paramenter with the value got from the cell
- if ( actionType.type == ActionType.PRIORITY && !this._currentSequentialFlag ) {
- this._currentRule.setSalience( new Integer( value ) );
- } else if ( actionType.type == ActionType.NAME ) // if the actionType
- // type is PRIORITY then
- // set the current
- // Rule's name
- // paramenter with the
- // value got from the
- // cell
- {
- this._currentRule.setName( value );
- } else if ( actionType.type == ActionType.DESCRIPTION ) // if the
- // actionType
- // type is
- // DESCRIPTION
- // then set the
- // current
- // Rule's
- // description
- // paramenter
- // with the
- // value got
- // from the cell
- {
- this._currentRule.setDescription( value );
- } else if ( actionType.type == ActionType.ACTIVATIONGROUP ) // if the actionType
- // type is NOLOOP
- // then set the
- // current Rule's
- // no-loop
- // paramenter with
- // the value got
- // from the cell
- {
- this._currentRule.setActivationrGroup( value );
- } else if ( actionType.type == ActionType.NOLOOP ) // if the actionType
- // type is NOLOOP
- // then set the
- // current Rule's
- // no-loop
- // paramenter with
- // the value got
- // from the cell
- {
- this._currentRule.setNoLoop( value );
- } else if ( actionType.type == ActionType.DURATION ) // if the actionType
- // type is DURATION
- // then creates a
- // new duration tag
- // with the value
- // got from the cell
- {
- createDuration( column,
- value,
- actionType );
- } else if ( actionType.type == ActionType.CONDITION || actionType.type == ActionType.ACTION ) {
- actionType.addCellValue( column, value );
- }
-
- }
-
- private Rule createNewRuleForRow(final int row) {
-
-
- Integer salience = null;
- if ( this._currentSequentialFlag ) {
- salience = new Integer( Rule.calcSalience( row ) );
- }
- final int spreadsheetRow = row + 1;
- final String name = this._currentRulePrefix + "_" + spreadsheetRow;
- final Rule rule = new Rule( name,
- salience,
- spreadsheetRow );
- rule.setComment( "From row number: " + (spreadsheetRow) );
-
- return rule;
-
- }
-
-
- // 08 - 16 - 2005 RIK: This function creates a new DURATION
- private void createDuration(final int column,
- final String value,
- final ActionType actionType) {
-
- final Duration dur = new Duration();
- dur.setSnippet( value );
- dur.setComment( cellComment( column ) );
- this._currentRule.setDuration( dur );
- }
-
-
- private boolean isCellValueEmpty(final String value) {
- return value == null || "".equals( value.trim() );
- }
-
- private String cellComment(final int column) {
- return "From column: " + Rule.convertColNumToColName( column );
- }
-
-}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetParserUtil.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetParserUtil.java 2006-09-15 17:46:32 UTC (rev 6245)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetParserUtil.java 2006-09-16 11:50:08 UTC (rev 6246)
@@ -35,12 +35,12 @@
}
public static String getRuleName(final String ruleRow) {
- final int left = ruleRow.indexOf( RuleSheetListener.RULE_TABLE_TAG );
+ final int left = ruleRow.indexOf( DefaultRuleSheetListener.RULE_TABLE_TAG );
if ( ruleRow.indexOf( '(' ) > -1 || ruleRow.indexOf( ')' ) > -1 ) {
invalidRuleTableDef( ruleRow );
}
- return ruleRow.substring( left + RuleSheetListener.RULE_TABLE_TAG.length() ).trim();
+ return ruleRow.substring( left + DefaultRuleSheetListener.RULE_TABLE_TAG.length() ).trim();
}
private static void invalidRuleTableDef(final String ruleRow) {
Modified: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetCompilerUnitTest.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetCompilerUnitTest.java 2006-09-15 17:46:32 UTC (rev 6245)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetCompilerUnitTest.java 2006-09-16 11:50:08 UTC (rev 6246)
@@ -22,6 +22,8 @@
import junit.framework.TestCase;
+import org.drools.decisiontable.parser.RuleMatrixSheetListener;
+
/**
* @author <a href="mailto:michael.neale at gmail.com"> Michael Neale</a>
*
@@ -35,7 +37,7 @@
public void testLoadFromClassPath() {
final SpreadsheetCompiler converter = new SpreadsheetCompiler();
final String drl = converter.compile( "/data/MultiSheetDST.xls",
- InputType.XLS );
+ InputType.XLS );
assertNotNull( drl );
@@ -48,49 +50,62 @@
final SpreadsheetCompiler converter = new SpreadsheetCompiler();
final InputStream stream = this.getClass().getResourceAsStream( "/data/MultiSheetDST.xls" );
final String drl = converter.compile( stream,
- "Another Sheet" );
+ "Another Sheet" );
assertNotNull( drl );
}
+ public void testLoadCustomListener() {
+ final SpreadsheetCompiler converter = new SpreadsheetCompiler();
+ final InputStream stream = this.getClass().getResourceAsStream( "/data/CustomWorkbook.xls" );
+ final String drl = converter.compile( stream,
+ InputType.XLS,
+ new RuleMatrixSheetListener() );
+ assertNotNull( drl );
+ assertTrue( drl.indexOf( "\"matrix\"" ) != -1 );
+ assertTrue( drl.indexOf( "$v : FundVisibility" ) != -1 );
+ assertTrue( drl.indexOf( "FundType" ) != -1 );
+ assertTrue( drl.indexOf( "Role" ) != -1 );
+ }
+
public void testLoadCsv() {
final SpreadsheetCompiler converter = new SpreadsheetCompiler();
final InputStream stream = this.getClass().getResourceAsStream( "/data/ComplexWorkbook.csv" );
final String drl = converter.compile( stream,
- InputType.CSV );
+ InputType.CSV );
assertNotNull( drl );
-
- System.out.println(drl);
-
+
+ System.out.println( drl );
+
assertTrue( drl.indexOf( "myObject.setIsValid(1, 2)" ) > 0 );
- assertTrue( drl.indexOf( "myObject.size () > 50" ) > 0 );
-
- assertTrue( drl.indexOf("Foo(myObject.getColour().equals(red), myObject.size () > 1)") > 0);
+ assertTrue( drl.indexOf( "myObject.size () > 50" ) > 0 );
+
+ assertTrue( drl.indexOf( "Foo(myObject.getColour().equals(red), myObject.size () > 1)" ) > 0 );
}
public void testLoadBasicWithMergedCells() {
final SpreadsheetCompiler converter = new SpreadsheetCompiler();
final InputStream stream = this.getClass().getResourceAsStream( "/data/BasicWorkbook.xls" );
final String drl = converter.compile( stream,
- InputType.XLS );
+ InputType.XLS );
assertNotNull( drl );
-
- Pattern p = Pattern.compile(".*setIsValid\\(Y\\).*setIsValid\\(Y\\).*setIsValid\\(Y\\).*",Pattern.DOTALL | Pattern.MULTILINE);
- Matcher m = p.matcher(drl);
- assertTrue(m.matches());
-
+
+ Pattern p = Pattern.compile( ".*setIsValid\\(Y\\).*setIsValid\\(Y\\).*setIsValid\\(Y\\).*",
+ Pattern.DOTALL | Pattern.MULTILINE );
+ Matcher m = p.matcher( drl );
+ assertTrue( m.matches() );
+
assertTrue( drl.indexOf( "This is a function block" ) > -1 );
assertTrue( drl.indexOf( "global Class1 obj1;" ) > -1 );
assertTrue( drl.indexOf( "myObject.setIsValid(10-Jul-1974)" ) > -1 );
assertTrue( drl.indexOf( "myObject.getColour().equals(blue)" ) > -1 );
assertTrue( drl.indexOf( "Foo(myObject.getColour().equals(red), myObject.size () > 1)" ) > -1 );
-
+
assertTrue( drl.indexOf( "b: Bar() eval(myObject.size() < 3)" ) > -1 );
assertTrue( drl.indexOf( "b: Bar() eval(myObject.size() < 9)" ) > -1 );
-
- assertTrue( drl.indexOf( "Foo(myObject.getColour().equals(red), myObject.size () > 1)" ) <
- drl.indexOf( "b: Bar() eval(myObject.size() < 3)" ));
-
+
+ assertTrue( drl.indexOf( "Foo(myObject.getColour().equals(red), myObject.size () > 1)" ) < drl.indexOf( "b: Bar() eval(myObject.size() < 3)" ) );
+
}
}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RulesheetUtil.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RulesheetUtil.java 2006-09-15 17:46:32 UTC (rev 6245)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RulesheetUtil.java 2006-09-16 11:50:08 UTC (rev 6246)
@@ -34,7 +34,7 @@
*/
public static RuleSheetListener getRuleSheetListener(final InputStream stream) throws IOException {
final Map listners = new HashMap();
- final RuleSheetListener listener = new RuleSheetListener();
+ final RuleSheetListener listener = new DefaultRuleSheetListener();
listners.put( ExcelParser.DEFAULT_RULESHEET_NAME,
listener );
final ExcelParser parser = new ExcelParser( listners );
More information about the jboss-svn-commits
mailing list