[jboss-svn-commits] JBL Code SVN: r8396 - in labs/jbossrules/trunk/drools-decisiontables/src: main/java/org/drools/decisiontable main/java/org/drools/decisiontable/parser main/java/org/drools/decisiontable/parser/csv main/java/org/drools/decisiontable/parser/xls test/java/org/drools/decisiontable test/java/org/drools/decisiontable/parser test/java/org/drools/decisiontable/parser/csv test/resources test/resources/templates

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Dec 19 07:04:25 EST 2006


Author: stevearoonie
Date: 2006-12-19 07:03:53 -0500 (Tue, 19 Dec 2006)
New Revision: 8396

Added:
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/ExternalSpreadsheetCompiler.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ArrayColumn.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Cell.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Column.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ColumnFactory.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultGenerator.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultTemplateContainer.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultTemplateRuleBase.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ExternalSheetListener.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Generator.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Row.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleTemplate.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/TemplateContainer.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/TemplateRuleBase.java
   labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerIntegrationTest.java
   labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerUnitTest.java
   labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ArrayColumnTest.java
   labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ColumnFactoryTest.java
   labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/DefaultGeneratorTest.java
   labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/DefaultTemplateContainerTest.java
   labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ExternalSheetListenerTest.java
   labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleTemplateTest.java
   labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/
   labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_integration.drl
   labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_pricing1.drl
   labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_pricing2.drl
   labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template1.drl
   labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template2.drl
   labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template3.drl
   labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template_simple.drl
Modified:
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/InputType.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/csv/CsvParser.java
   labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/ExcelParser.java
   labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/Cheese.java
   labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/Person.java
   labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvParserTest.java
Log:
Initial commit of new decision table processor

Added: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/ExternalSpreadsheetCompiler.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/ExternalSpreadsheetCompiler.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/ExternalSpreadsheetCompiler.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,139 @@
+package org.drools.decisiontable;
+
+/*
+ * 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.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.decisiontable.parser.DecisionTableParser;
+import org.drools.decisiontable.parser.ExternalSheetListener;
+import org.drools.decisiontable.parser.DefaultTemplateContainer;
+import org.drools.decisiontable.parser.TemplateContainer;
+import org.drools.decisiontable.parser.xls.ExcelParser;
+
+public class ExternalSpreadsheetCompiler {
+
+	public String compile(final String xls, final String template,
+			int startRow, int startCol) {
+		return compile(xls, template, InputType.XLS, startRow, startCol);
+
+	}
+
+	public String compile(final String xls, final String template,
+			InputType type, int startRow, int startCol) {
+		final InputStream xlsStream = this.getClass().getResourceAsStream(xls);
+		final InputStream templateStream = this.getClass().getResourceAsStream(
+				template);
+		return compile(xlsStream, templateStream, type, startRow, startCol);
+
+	}
+
+	public String compile(final String xls, final String worksheetName,
+			final String template, int startRow, int startCol) {
+		final InputStream xlsStream = this.getClass().getResourceAsStream(xls);
+		final InputStream templateStream = this.getClass().getResourceAsStream(
+				template);
+		return compile(xlsStream, worksheetName, templateStream, startRow,
+				startCol);
+
+	}
+
+	public String compile(final InputStream xlsStream,
+			final InputStream templateStream, InputType type, int startRow,
+			int startCol) {
+		TemplateContainer tc = new DefaultTemplateContainer(templateStream);
+		closeStream(templateStream);
+		return compile(xlsStream, type, new ExternalSheetListener(startRow,
+				startCol, tc));
+	}
+
+	public String compile(final InputStream xlsStream,
+			final String worksheetName, final InputStream templateStream,
+			int startRow, int startCol) {
+		TemplateContainer tc = new DefaultTemplateContainer(templateStream);
+		closeStream(templateStream);
+		return compile(xlsStream, worksheetName, new ExternalSheetListener(
+				startRow, startCol, tc));
+	}
+
+	public void compile(final String xls, InputType type, final List listeners) {
+		final InputStream xlsStream = this.getClass().getResourceAsStream(xls);
+		compile(xlsStream, type, listeners);
+	}
+
+	public void compile(final String xls, final Map listeners) {
+		final InputStream xlsStream = this.getClass().getResourceAsStream(xls);
+		compile(xlsStream, listeners);
+	}
+
+	public void compile(final InputStream xlsStream, InputType type,
+			final List listeners) {
+		final DecisionTableParser parser = type.createParser(listeners);
+		parser.parseFile(xlsStream);
+		closeStream(xlsStream);
+	}
+
+	public void compile(final InputStream xlsStream, final Map listeners) {
+		final DecisionTableParser parser = new ExcelParser(listeners);
+		parser.parseFile(xlsStream);
+		closeStream(xlsStream);
+	}
+
+	/**
+	 * 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.
+	 * @throws IOException
+	 */
+	public String compile(final InputStream xlsStream, final InputType type,
+			final ExternalSheetListener listener) {
+		List listeners = new ArrayList();
+		listeners.add(listener);
+		compile(xlsStream, type, listeners);
+		return listener.renderDRL();
+	}
+
+	public String compile(final InputStream xlsStream,
+			final String worksheetName, final ExternalSheetListener listener) {
+		Map listeners = new HashMap();
+		List l = new ArrayList();
+		l.add(listener);
+		listeners.put(worksheetName, l);
+		compile(xlsStream, listeners);
+		return listener.renderDRL();
+	}
+
+	private void closeStream(final InputStream stream) {
+		try {
+			stream.close();
+		} catch (final Exception e) {
+			System.err.print("WARNING: Wasn't able to "
+					+ "correctly close stream for decision table. "
+					+ e.getMessage());
+		}
+	}
+
+}

Modified: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/InputType.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/InputType.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/InputType.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -16,6 +16,8 @@
  * limitations under the License.
  */
 
+import java.util.List;
+
 import org.drools.decisiontable.parser.DecisionTableParser;
 import org.drools.decisiontable.parser.SheetListener;
 import org.drools.decisiontable.parser.csv.CsvLineParser;
@@ -41,6 +43,7 @@
      * @return The appropriate Parser. 
      */
     public abstract DecisionTableParser createParser(SheetListener listener);
+    public abstract DecisionTableParser createParser(List listeners);
 
 }
 
@@ -49,6 +52,9 @@
     public DecisionTableParser createParser(final SheetListener listener) {
         return new ExcelParser( listener );
     }
+    public DecisionTableParser createParser(final List listeners) {
+    	return new ExcelParser( listeners );
+    }
 
 }
 
@@ -59,4 +65,9 @@
                               new CsvLineParser() );
     }
 
+    public DecisionTableParser createParser(final List listeners) {
+    	return new CsvParser( listeners,
+    			new CsvLineParser() );
+    }
+    
 }
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ArrayColumn.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ArrayColumn.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ArrayColumn.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,39 @@
+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 org.antlr.stringtemplate.StringTemplate;
+import org.apache.commons.lang.StringUtils;
+
+public class ArrayColumn extends Column {
+
+	public void addValue(StringTemplate t, Object value) {
+
+		String[] values = ((String[]) value);
+		for (int i = 0; i < values.length; i++) {
+			t.setAttribute(getName() + i, values[i]);
+		}
+	}
+
+	public ArrayColumn(String n) {
+		super(n);
+	}
+
+	public Object getValue(String cellValue) {
+		return StringUtils.split(cellValue, ",");
+	}
+
+}

Added: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Cell.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Cell.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Cell.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,55 @@
+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 org.antlr.stringtemplate.StringTemplate;
+
+public class Cell {
+	Row row;
+
+	Object value;
+
+	Column column;
+
+	public Cell() {
+		
+	}
+	Cell(Row r, Column c, String v) {
+		row = r;
+		column = c;
+		value = c.getValue(v);
+	}
+
+	public String toString() {
+		return "Cell[" + column + ": " + value + "]";
+	}
+
+	public Row getRow() {
+		return row;
+	}
+
+	public String getColumn() {
+		return column.getName();
+	}
+
+	public Object getValue() {
+		return value;
+	}
+
+	public void addValue(StringTemplate t) {
+		column.addValue(t, value);
+	}
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Column.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Column.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Column.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,39 @@
+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 org.antlr.stringtemplate.StringTemplate;
+
+public class Column {
+	private String name;
+
+	public Column(String n) {
+		this.name = n;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public Object getValue(String cellValue) {
+		return cellValue;
+	}
+
+	public void addValue(StringTemplate t, Object value) {
+		t.setAttribute(name, value);
+	}
+
+}

Added: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ColumnFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ColumnFactory.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ColumnFactory.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,26 @@
+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.
+ */
+public class ColumnFactory {
+
+	public Column getColumn(String value) {
+		if (value.endsWith("[]")) {
+			return new ArrayColumn(value.substring(0, value.length() - 2));
+		}
+		return new Column(value);
+	}
+}

Added: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultGenerator.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultGenerator.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultGenerator.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,87 @@
+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.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.antlr.stringtemplate.StringTemplate;
+
+public class DefaultGenerator implements Generator {
+
+	Map ruleTemplates;
+
+	Map templates = new HashMap();
+
+	List rules = new ArrayList();
+
+	public DefaultGenerator(final Map t) {
+		ruleTemplates = t;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.drools.decisiontable.parser.Generator#generate(java.lang.String,
+	 *      org.drools.decisiontable.parser.Row)
+	 */
+	public void generate(String templateName, Row row) {
+		try {
+			StringTemplate t = getTemplate(templateName);
+			t.setAttribute("row", row);
+
+			for (Iterator it = row.getCells().iterator(); it.hasNext();) {
+				Cell cell = (Cell) it.next();
+				cell.addValue(t);
+			}
+			String drl = t.toString();
+			rules.add(drl);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	private StringTemplate getTemplate(String templateName) throws IOException {
+		String contents = (String) templates.get(templateName);
+		if (contents == null) {
+			RuleTemplate template = (RuleTemplate) ruleTemplates
+					.get(templateName);
+			contents = template.getContents();
+			templates.put(templateName, contents);
+		}
+		StringTemplate t = new StringTemplate(contents);
+		return t;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.drools.decisiontable.parser.Generator#getDrl()
+	 */
+	public String getDrl() {
+		StringBuffer sb = new StringBuffer();
+		for (Iterator it = rules.iterator(); it.hasNext();) {
+			String rule = (String) it.next();
+			sb.append(rule).append("\n");
+		}
+		return sb.toString();
+	}
+
+}

Added: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultTemplateContainer.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultTemplateContainer.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultTemplateContainer.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,138 @@
+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.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class DefaultTemplateContainer implements TemplateContainer {
+	private String header;
+
+	private List columns = new ArrayList();
+
+	private Map templates = new HashMap();
+
+	public DefaultTemplateContainer(final String template) {
+		final InputStream templateStream = this.getClass().getResourceAsStream(
+				template);
+		parseTemplate(templateStream);
+	}
+
+	public DefaultTemplateContainer(final InputStream templateStream) {
+		parseTemplate(templateStream);
+	}
+
+	private void parseTemplate(final InputStream templateStream) {
+		try {
+			final ColumnFactory cf = new ColumnFactory();
+			final BufferedReader templateReader = new BufferedReader(
+					new InputStreamReader(templateStream));
+			String line = null;
+			StringBuffer header = new StringBuffer();
+			boolean inTemplate = false;
+			boolean inHeader = false;
+			boolean inContents = false;
+			RuleTemplate template = null;
+			StringBuffer contents = new StringBuffer();
+			while ((line = templateReader.readLine()) != null) {
+				if (line.trim().length() > 0) {
+					if (line.startsWith("template header")) {
+						inHeader = true;
+					} else if (line.startsWith("template")) {
+						inTemplate = true;
+						String quotedName = line.substring(8).trim();
+						quotedName = quotedName.substring(1, quotedName
+								.length() - 1);
+						template = new RuleTemplate(quotedName);
+						addTemplate(template);
+
+					} else if (line.startsWith("package")) {
+						inHeader = false;
+						header.append(line).append("\n");
+					} else if (inHeader) {
+						addColumn(cf.getColumn(line.trim()));
+					} else if (!inTemplate && !inHeader) {
+						header.append(line).append("\n");
+					} else if (!inContents && line.startsWith("rule")) {
+						inContents = true;
+						contents.append(line).append("\n");
+					} else if (line.equals("end template")) {
+						template.setContents(contents.toString());
+						contents.setLength(0);
+						inTemplate = false;
+						inContents = false;
+					} else if (inContents) {
+						contents.append(line).append("\n");
+					} else if (inTemplate) {
+						template.addColumn(line.trim());
+					}
+				}
+
+			}
+			this.header = header.toString();
+
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		} finally {
+			closeStream(templateStream);
+		}
+	}
+
+	private void addTemplate(RuleTemplate template) {
+		templates.put(template.getName(), template);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.drools.decisiontable.parser.TemplateContainer#getTemplates()
+	 */
+	public Map getTemplates() {
+		return templates;
+	}
+
+	private void addColumn(Column c) {
+		columns.add(c);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.drools.decisiontable.parser.TemplateContainer#getColumns()
+	 */
+	public Column[] getColumns() {
+		return (Column[]) columns.toArray(new Column[columns.size()]);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.drools.decisiontable.parser.TemplateContainer#getHeader()
+	 */
+	public String getHeader() {
+		return header;
+	}
+
+	private void closeStream(final InputStream stream) {
+		try {
+			stream.close();
+		} catch (final Exception e) {
+			System.err.print("WARNING: Wasn't able to "
+					+ "correctly close stream for decision table. "
+					+ e.getMessage());
+		}
+	}
+}

Added: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultTemplateRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultTemplateRuleBase.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultTemplateRuleBase.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,149 @@
+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.io.Reader;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.RuleBase;
+import org.drools.RuleBaseFactory;
+import org.drools.WorkingMemory;
+import org.drools.compiler.PackageBuilder;
+import org.drools.decisiontable.model.Condition;
+import org.drools.decisiontable.model.Consequence;
+import org.drools.decisiontable.model.DRLOutput;
+import org.drools.decisiontable.model.Global;
+import org.drools.decisiontable.model.Import;
+import org.drools.decisiontable.model.Rule;
+import org.drools.decisiontable.model.SnippetBuilder;
+import org.drools.rule.Package;
+
+public class DefaultTemplateRuleBase implements TemplateRuleBase {
+	private RuleBase ruleBase;
+
+	public DefaultTemplateRuleBase(final TemplateContainer tc) {
+		ruleBase = readRule(getDTRules(tc.getTemplates()));
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.drools.decisiontable.parser.TemplateRuleBase#newWorkingMemory()
+	 */
+	public WorkingMemory newWorkingMemory() {
+		return ruleBase.newWorkingMemory();
+	}
+	/**
+	 * 
+	 * @param templates
+	 * @return
+	 */
+	private String getDTRules(Map templates) {
+		org.drools.decisiontable.model.Package p = new org.drools.decisiontable.model.Package(
+				"org.drools.decisiontable.parser");
+		addImports(p);
+		addGlobals(p);
+		int i = 1;
+		for (Iterator it = templates.values().iterator(); it.hasNext();) {
+			RuleTemplate template = (RuleTemplate) it.next();
+
+			Rule rule = new Rule(template.getName(), null, i++);
+			Condition condition = new Condition();
+			condition.setSnippet("r : Row()");
+			rule.addCondition(condition);
+			List templateColumns = template.getColumns();
+			for (Iterator it1 = templateColumns.iterator(); it1.hasNext();) {
+				String column = (String) it1.next();
+				rule.addCondition(createCondition(column));
+			}
+			String[] templateNotColumns = template.getNotColumns();
+			for (int j = 0; j < templateNotColumns.length; j++) {
+				rule.addCondition(createNotCondition(templateNotColumns[j]));
+			}
+			rule.addConsequence(createConsequence(template));
+			p.addRule(rule);
+		}
+		DRLOutput out = new DRLOutput();
+		p.renderDRL(out);
+		return out.getDRL();
+
+	}
+
+
+	private void addGlobals(org.drools.decisiontable.model.Package p) {
+		Global global = new Global();
+		global.setClassName(DefaultGenerator.class.getName());
+		global.setIdentifier("generator");
+		p.addVariable(global);
+	}
+
+	private void addImports(org.drools.decisiontable.model.Package p) {
+		Import drlImport1 = new Import();
+		drlImport1.setClassName(Map.class.getName());
+		Import drlImport2 = new Import();
+		drlImport2.setClassName(HashMap.class.getName());
+		p.addImport(drlImport1);
+		p.addImport(drlImport2);
+	}
+
+	private Consequence createConsequence(RuleTemplate template) {
+		StringBuffer action = new StringBuffer();
+		action.append("generator.generate( \"");
+		action.append(template.getName()).append("\", r);");
+		final Consequence consequence = new Consequence();
+		consequence.setSnippet(action.toString());
+		return consequence;
+	}
+
+	private Condition createCondition(final String value) {
+		SnippetBuilder snip = new SnippetBuilder(
+				"Cell(row == r, column == \"$param\")");
+		String result = snip.build(value);
+		Condition condition = new Condition();
+		condition.setSnippet(result);
+		return condition;
+	}
+
+	private Condition createNotCondition(final String value) {
+		SnippetBuilder snip = new SnippetBuilder(
+				"not Cell(row == r, column == \"$param\")");
+		String result = snip.build(value);
+		Condition condition = new Condition();
+		condition.setSnippet(result);
+		return condition;
+	}
+	private RuleBase readRule(String drl) {
+		try {
+//			System.out.println(drl);
+			// read in the source
+			Reader source = new StringReader(drl);
+			PackageBuilder builder = new PackageBuilder();
+			builder.addPackageFromDrl(source);
+			Package pkg = builder.getPackage();
+
+			// add the package to a rulebase (deploy the rule package).
+			RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+			ruleBase.addPackage(pkg);
+			return ruleBase;
+
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+}

Added: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ExternalSheetListener.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ExternalSheetListener.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ExternalSheetListener.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,131 @@
+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.Properties;
+
+import org.drools.WorkingMemory;
+import org.drools.decisiontable.model.DRLOutput;
+
+/**
+ * SheetListener for creating rules from a template
+ * 
+ * @author <a href="mailto:stevearoonie at gmail.com">Steven Williams</a>
+ */
+public class ExternalSheetListener implements RuleSheetListener {
+
+	private int startRow = -1;
+
+	private boolean tableFinished = false;
+
+	private Row currentRow;
+
+	private Column[] columns;
+
+	private WorkingMemory wm;
+
+	private TemplateContainer templateContainer;
+
+	private int startCol;
+
+	private Generator generator;
+
+	public ExternalSheetListener(final int startRow, final int startCol,
+			final String template) {
+		this(startRow, startCol, new DefaultTemplateContainer(template));
+	}
+
+	public ExternalSheetListener(final int startRow, final int startCol,
+			final TemplateContainer tc) {
+		this(startRow, startCol, tc, new DefaultTemplateRuleBase(tc));
+	}
+
+	public ExternalSheetListener(final int startRow, final int startCol,
+			final TemplateContainer tc, final TemplateRuleBase rb) {
+		this(startRow, startCol, tc, rb,
+				new DefaultGenerator(tc.getTemplates()));
+	}
+
+	public ExternalSheetListener(final int startRow, final int startCol,
+			final TemplateContainer tc, final TemplateRuleBase ruleBase,
+			final Generator generator) {
+		this.startRow = startRow - 1;
+		this.startCol = startCol - 1;
+		columns = tc.getColumns();
+		this.templateContainer = tc;
+		wm = ruleBase.newWorkingMemory();
+		this.generator = generator;
+		wm.setGlobal("generator", generator);
+	}
+
+	public Properties getProperties() {
+		return null;
+	}
+
+	public org.drools.decisiontable.model.Package getRuleSet() {
+		return null;
+	}
+
+	public void finishSheet() {
+		if (currentRow != null) {
+			wm.assertObject(currentRow);
+		}
+		wm.fireAllRules();
+		wm.dispose();
+	}
+
+	public void newCell(int row, int column, String value, int mergedColStart) {
+		if (currentRow != null && column >= startCol && value != null
+				&& value.trim().length() > 0) {
+
+			// System.out.println("asserting cell " + row + ", " + column + ": "
+			// + value);
+			Column col = columns[column - startCol];
+			Cell cell = new Cell(currentRow, col, value);
+			currentRow.addCell(cell);
+			wm.assertObject(cell);
+
+		}
+	}
+
+	public void newRow(int rowNumber, int columns) {
+		if (!tableFinished && rowNumber >= startRow) {
+			if (currentRow != null && currentRow.cells.isEmpty()) {
+				currentRow = null;
+				tableFinished = true;
+			} else {
+				if (currentRow != null)
+					wm.assertObject(currentRow);
+				currentRow = new Row(rowNumber);
+			}
+		}
+	}
+
+	public void startSheet(String name) {
+
+	}
+
+	public String renderDRL() {
+		DRLOutput out = new DRLOutput();
+		out.writeLine(templateContainer.getHeader());
+
+		out.writeLine(generator.getDrl());
+		// System.err.println(out.getDRL());
+		return out.getDRL();
+	}
+
+}

Added: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Generator.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Generator.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Generator.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,24 @@
+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.
+ */
+public interface Generator {
+
+	void generate(String templateName, Row row);
+
+	String getDrl();
+
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Row.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Row.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/Row.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,50 @@
+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.List;
+
+public class Row {
+    int  rowNum;
+    List cells = new ArrayList();
+
+    public Row() {
+    	
+    }
+    
+    Row(int r) {
+        rowNum = r;
+    }
+    
+    public int getRowNumber() {
+        return rowNum;
+    }
+
+    void addCell(Cell cell) {
+        cells.add( cell );
+    }
+    
+    public List getCells() {
+    	return cells;
+    }
+
+    public String toString() {
+        return "Row " + rowNum + cells + "\n";
+    }
+
+
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleTemplate.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleTemplate.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleTemplate.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,121 @@
+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.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+public class RuleTemplate
+{
+    private String name;
+    private String contents;
+    private List columns;
+    private List notColumns;
+
+    public RuleTemplate(final String n)
+    {
+        name = n;
+        columns = new ArrayList();
+        notColumns = new ArrayList();
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public List getColumns()
+    {
+        return columns;
+    }
+
+    public String[] getNotColumns()
+    {
+        return (String[]) notColumns.toArray(new String[notColumns.size()]);
+    }
+    
+    public String getContents()
+    {
+        return contents;
+    }
+
+    public void addColumn(String column)
+    {
+        if (column.startsWith("!"))
+        {
+            this.notColumns.add(column.substring(1));
+        }
+        else
+        {
+            this.columns.add(column);
+        }
+    }
+
+    public void setContents(String contents)
+    {
+        this.contents = replaceOptionals(contents);
+    }
+
+	/**
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return new ToStringBuilder(this).append("name", this.name).append(
+				"notColumns", this.notColumns)
+				.append("contents", this.contents).append("columns",
+						this.columns).toString();
+	}
+	private String replaceOptionals(String contents) {
+		try {
+			final Pattern pattern = Pattern.compile("\\$(.[^\\$]*)\\$");
+			final List columns = new ArrayList(getColumns());
+			columns.add("row.rowNumber");
+			final BufferedReader reader = new BufferedReader(new StringReader(
+					contents));
+			String line = null;
+			final StringBuffer newLine = new StringBuffer();
+			while ((line = reader.readLine()) != null) {
+				final Matcher matcher = pattern.matcher(line);
+				int optCols = 0;
+				while (matcher.find()) {
+					final String c = matcher.group(1);
+					if (!columns.contains(c)) {
+						newLine.append("$if(").append(matcher.group(1)).append(
+								")$");
+						optCols++;
+					}
+				}
+				newLine.append(line);
+				newLine.append(StringUtils.repeat("$endif$", optCols));
+				newLine.append("\n");
+			}
+			// System.out.println("newLine: " + newLine);
+			return newLine.toString();
+
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+	}
+    
+}

Added: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/TemplateContainer.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/TemplateContainer.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/TemplateContainer.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,28 @@
+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.Map;
+
+public interface TemplateContainer {
+
+	Map getTemplates();
+
+	Column[] getColumns();
+
+	String getHeader();
+
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/TemplateRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/TemplateRuleBase.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/TemplateRuleBase.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,24 @@
+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 org.drools.WorkingMemory;
+
+public interface TemplateRuleBase {
+
+	WorkingMemory newWorkingMemory();
+
+}
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/csv/CsvParser.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/csv/CsvParser.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/csv/CsvParser.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -20,6 +20,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
 import org.drools.decisiontable.parser.DecisionTableParseException;
@@ -27,107 +29,133 @@
 import org.drools.decisiontable.parser.SheetListener;
 
 /**
- * Csv implementation.
- * This implementation removes empty "cells" at the end of each line.
- * Different CSV tools may or may not put heaps of empty cells in.
+ * Csv implementation. This implementation removes empty "cells" at the end of
+ * each line. Different CSV tools may or may not put heaps of empty cells in.
  * 
- * Csv format is almost identical to XLS, with the one limitation:
- * Merged cells are not supported. To allow constraints to span across cells for the 
- * one column, this is achieved by using "..." at the end of a cell value.
- * If a cell value ends with "..." then it will be taken as spanned from the previous cell.
+ * Csv format is almost identical to XLS, with the one limitation: Merged cells
+ * are not supported. To allow constraints to span across cells for the one
+ * column, this is achieved by using "..." at the end of a cell value. If a cell
+ * value ends with "..." then it will be taken as spanned from the previous
+ * cell.
  * 
  * 
  * 
  * @author <a href="mailto:michael.neale at gmail.com"> Michael Neale</a>
  */
-public class CsvParser
-    implements
-    DecisionTableParser {
+public class CsvParser implements DecisionTableParser {
 
-    private SheetListener _listener;
-    private CsvLineParser _lineParser;
+	private List _listeners;
 
-    public CsvParser(final SheetListener listener,
-                     final CsvLineParser lineParser) {
-        this._listener = listener;
-        this._lineParser = lineParser;
-    }
+	private CsvLineParser _lineParser;
 
-    public void parseFile(final InputStream inStream) {
-        final BufferedReader reader = new BufferedReader( new InputStreamReader( inStream ) );
-        try {
-            this._listener.startSheet( "csv" );
-            processRows( reader );
-            this._listener.finishSheet();
-        } catch ( final IOException e ) {
-            throw new DecisionTableParseException( "An error occurred reading the CSV data.",
-                                                   e );
-        }
-    }
+	public CsvParser(final SheetListener listener,
+			final CsvLineParser lineParser) {
+		_listeners = new ArrayList();
+		_listeners.add(listener);
+		this._lineParser = lineParser;
+	}
 
-    private void processRows(final BufferedReader reader) throws IOException {
-        String line = reader.readLine();
+	public CsvParser(final List listeners, final CsvLineParser lineParser) {
+		this._listeners = listeners;
+		this._lineParser = lineParser;
+	}
 
-        int row = 0;
-        while ( line != null ) {
+	public void parseFile(final InputStream inStream) {
+		final BufferedReader reader = new BufferedReader(new InputStreamReader(
+				inStream));
+		try {
+			startSheet();
+			processRows(reader);
+			finishSheet();
+		} catch (final IOException e) {
+			throw new DecisionTableParseException(
+					"An error occurred reading the CSV data.", e);
+		}
+	}
 
-            final List cells = this._lineParser.parse( line );
-            //remove the trailing empty "cells" which some tools smatter around
-            //trimCells(cells);
-            this._listener.newRow( row,
-                              cells.size() );
+	private void startSheet() {
+		for (Iterator it = _listeners.iterator(); it.hasNext();) {
+			SheetListener listener = (SheetListener) it.next();
+			listener.startSheet("csv");
+		}
+	}
 
-            int startMergeCol = SheetListener.NON_MERGED;
-            for ( int col = 0; col < cells.size(); col++ ) {
-                String cell = (String) cells.get( col );
+	private void finishSheet() {
+		for (Iterator it = _listeners.iterator(); it.hasNext();) {
+			SheetListener listener = (SheetListener) it.next();
+			listener.finishSheet();
+		}
+	}
 
-                startMergeCol = calcStartMerge( startMergeCol,
-                                                col,
-                                                cell );
-                
-                cell = calcCellText( startMergeCol,
-                                     cell );
-                
-                this._listener.newCell( row,
-                                   col,
-                                   cell, startMergeCol );
-            }
-            row++;
-            line = reader.readLine();
-        }
-        _listener.finishSheet();
-    }
+	private void newRow(final int row, final int numCells) {
+		for (Iterator it = _listeners.iterator(); it.hasNext();) {
+			SheetListener listener = (SheetListener) it.next();
+			listener.newRow(row, numCells);
+		}
+	}
 
-    String calcCellText(int startMergeCol,
-                                String cell) {
-        if (startMergeCol != SheetListener.NON_MERGED) {
-            cell = cell.substring( 0, cell.length() - 3 );
-        }
-        return cell;
-    }
+	private void newCell(final int row, final int column, final String value,
+			final int mergedColStart) {
+		for (Iterator it = _listeners.iterator(); it.hasNext();) {
+			SheetListener listener = (SheetListener) it.next();
+			listener.newCell(row, column, value, mergedColStart);
+		}
+	}
 
-    int calcStartMerge(int startMergeCol,
-                               int col,
-                               String cell) {
-        if (cell.endsWith( "..." ) && startMergeCol == SheetListener.NON_MERGED) {
-            startMergeCol = col;                    
-        } else if (!cell.endsWith( "..." )) {
-            startMergeCol = SheetListener.NON_MERGED;
-        }
-        return startMergeCol;
-    }
+	private void processRows(final BufferedReader reader) throws IOException {
+		String line = reader.readLine();
 
-    /** remove the trailing empty cells */
-    private void trimCells(final List cells) {
-        for ( int i = cells.size() - 1; i > 0; i-- ) {
-            final String cell = (String) cells.get( i );
-            if ( !cell.trim().equals( "" ) ) {
-                return;
-            } else {
-                cells.remove( i );
-            }
-        }
+		int row = 0;
+		while (line != null) {
 
-    }
+			final List cells = this._lineParser.parse(line);
+			// remove the trailing empty "cells" which some tools smatter around
+			// trimCells(cells);
+			newRow(row, cells.size());
 
+			int startMergeCol = SheetListener.NON_MERGED;
+			for (int col = 0; col < cells.size(); col++) {
+				String cell = (String) cells.get(col);
+
+				startMergeCol = calcStartMerge(startMergeCol, col, cell);
+
+				cell = calcCellText(startMergeCol, cell);
+
+				newCell(row, col, cell, startMergeCol);
+			}
+			row++;
+			line = reader.readLine();
+		}
+		finishSheet();
+	}
+
+	String calcCellText(int startMergeCol, String cell) {
+		if (startMergeCol != SheetListener.NON_MERGED) {
+			cell = cell.substring(0, cell.length() - 3);
+		}
+		return cell;
+	}
+
+	int calcStartMerge(int startMergeCol, int col, String cell) {
+		if (cell.endsWith("...") && startMergeCol == SheetListener.NON_MERGED) {
+			startMergeCol = col;
+		} else if (!cell.endsWith("...")) {
+			startMergeCol = SheetListener.NON_MERGED;
+		}
+		return startMergeCol;
+	}
+
+	/** remove the trailing empty cells */
+	private void trimCells(final List cells) {
+		for (int i = cells.size() - 1; i > 0; i--) {
+			final String cell = (String) cells.get(i);
+			if (!cell.trim().equals("")) {
+				return;
+			} else {
+				cells.remove(i);
+			}
+		}
+
+	}
+
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/ExcelParser.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/ExcelParser.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/ExcelParser.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -18,8 +18,10 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -44,8 +46,7 @@
 
     public static final String  DEFAULT_RULESHEET_NAME = "Decision Tables";
     private Map                 _listners              = new HashMap();
-    private SheetListener       _currentSheetListener  = new NullSheetListener();
-	private boolean _useFirstSheet;
+    private boolean _useFirstSheet;
 
 
 
@@ -58,12 +59,18 @@
     public ExcelParser(final Map sheetListners) {
         this._listners = sheetListners;
     }
+    
+    public ExcelParser(final List sheetListners) {
+    	this._listners.put(ExcelParser.DEFAULT_RULESHEET_NAME, sheetListners);
+    	this._useFirstSheet = true;
+    }
 
     public ExcelParser(final SheetListener listener) {
+    	List listeners = new ArrayList();
+    	listeners.add(listener);
         this._listners.put( ExcelParser.DEFAULT_RULESHEET_NAME,
-                       listener );
+                       listeners );
         this._useFirstSheet = true;
-        this._currentSheetListener = listener;
     }
 
 	public void parseFile(InputStream inStream) {
@@ -72,13 +79,13 @@
 			
 			if (_useFirstSheet) {
 				Sheet sheet = workbook.getSheet(0);
-				processSheet(sheet, _currentSheetListener);
+				processSheet(sheet, (List) _listners.get(DEFAULT_RULESHEET_NAME));
 			} else {
 				Set sheetNames = _listners.keySet();
 				for (Iterator iter = sheetNames.iterator(); iter.hasNext();) {
 					String sheetName = (String) iter.next();
 					Sheet sheet = workbook.getSheet(sheetName);
-					processSheet(sheet, (SheetListener)_listners.get(sheetName));
+					processSheet(sheet, (List)_listners.get(sheetName));
 					
 				}
 			}
@@ -94,7 +101,7 @@
 		
 	}
 
-	private void processSheet(Sheet sheet, SheetListener listener) {
+	private void processSheet(Sheet sheet, List listeners) {
 		int maxRows = sheet.getRows();
 		
 		Range[] mergedRanges = sheet.getMergedCells();
@@ -102,7 +109,7 @@
 		
 		for(int i = 0; i < maxRows; i++) {
 			Cell[] row = sheet.getRow(i);
-			listener.newRow(i, row.length);			
+			newRow(listeners, i, row.length);			
 			for (int cellNum = 0; cellNum < row.length; cellNum++) {
 				Cell cell = row[cellNum];
 				
@@ -110,13 +117,13 @@
 											
 				if (merged != null) {
                     Cell topLeft = merged.getTopLeft();
-					listener.newCell(i, cellNum, topLeft.getContents(), topLeft.getColumn());
+					newCell(listeners, i, cellNum, topLeft.getContents(), topLeft.getColumn());
 				} else {
-					listener.newCell(i, cellNum, cell.getContents(), SheetListener.NON_MERGED);
+					newCell(listeners, i, cellNum, cell.getContents(), SheetListener.NON_MERGED);
 				}
 			}
 		}
-        listener.finishSheet();
+        finishSheet(listeners);
 	}
 	
     Range getRangeIfMerged(Cell cell, Range[] mergedRanges) {
@@ -141,9 +148,30 @@
                                              stringVal.length() - 2 );
         }
         return stringVal;
-    }	
+    }
+	
+	private void finishSheet(List listeners) {
+		for (Iterator it = listeners.iterator(); it.hasNext();) {
+			SheetListener listener = (SheetListener) it.next();
+			listener.finishSheet();
+		}
+	}
+	private void newRow(List listeners, int row, int cols) {
+		for (Iterator it = listeners.iterator(); it.hasNext();) {
+			SheetListener listener = (SheetListener) it.next();
+			listener.newRow(row, cols);
+		}
+	}
+    public void newCell(List listeners, int row,
+            int column,
+            String value,
+            int mergedColStart) {
+    	for (Iterator it = listeners.iterator(); it.hasNext();) {
+			SheetListener listener = (SheetListener) it.next();
+			listener.newCell(row, column, value, mergedColStart);
+		}
+    }
 
 
 
-
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/Cheese.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/Cheese.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/Cheese.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -20,6 +20,9 @@
     private String type;
     private int    price;
 
+    public Cheese() {
+    	
+    }
     public Cheese(final String type,
                   final int price) {
         super();

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerIntegrationTest.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerIntegrationTest.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerIntegrationTest.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,127 @@
+package org.drools.decisiontable;
+
+/*
+ * 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.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.acme.insurance.Driver;
+import org.acme.insurance.Policy;
+import org.drools.RuleBase;
+import org.drools.RuleBaseFactory;
+import org.drools.WorkingMemory;
+import org.drools.compiler.DroolsError;
+import org.drools.compiler.PackageBuilder;
+import org.drools.decisiontable.parser.ExternalSheetListener;
+import org.drools.decisiontable.parser.DefaultTemplateContainer;
+import org.drools.rule.Package;
+/**
+ * @author <a href="mailto:stevearoonie at gmail.com">Steven Williams</a> Some basic unit tests for converter utility.
+ *         Note that some of this may still use the drools 2.x syntax, as it is not compiled, only tested that it
+ *         generates DRL in the correct structure (not that the DRL itself is correct).
+ */
+public class ExternalSpreadsheetCompilerIntegrationTest extends TestCase
+{
+    
+    public void testIntegration() throws Exception 
+    {
+        final ExternalSpreadsheetCompiler converter = new ExternalSpreadsheetCompiler();
+        final String drl = converter.compile("/data/IntegrationExampleTest.xls", "/templates/test_integration.drl", 18, 3);
+        //COMPILE
+        final PackageBuilder builder = new PackageBuilder();
+        builder.addPackageFromDrl( new StringReader( drl ) );
+
+        final Package pkg = builder.getPackage();
+        assertNotNull( pkg );
+        assertEquals( 0,
+                      builder.getErrors().length );
+
+        //BUILD RULEBASE
+        final RuleBase rb = RuleBaseFactory.newRuleBase();
+        rb.addPackage( pkg );
+
+        //NEW WORKING MEMORY
+        final WorkingMemory wm = rb.newWorkingMemory();
+
+        //ASSERT AND FIRE
+        wm.assertObject( new Cheese( "stilton",
+                                     42 ) );
+        wm.assertObject( new Person( "michael",
+                                     "stilton",
+                                     42 ) );
+        final List list = new ArrayList();
+        wm.setGlobal( "list",
+                      list );
+        wm.fireAllRules();
+        assertEquals( 1,
+                      list.size() );
+
+        
+    }
+    
+    public void testPricing() throws Exception 
+    {
+        final ExternalSpreadsheetCompiler converter = new ExternalSpreadsheetCompiler();
+        final List listeners = new ArrayList();
+        ExternalSheetListener l1 = new ExternalSheetListener(10, 3, "/templates/test_pricing1.drl");
+		listeners.add(l1);
+        ExternalSheetListener l2 = new ExternalSheetListener(30, 3, "/templates/test_pricing2.drl");
+		listeners.add(l2);
+		converter.compile("/data/ExamplePolicyPricing.xls", InputType.XLS, listeners);
+        //COMPILE
+        final PackageBuilder builder = new PackageBuilder();
+        builder.addPackageFromDrl( new StringReader( l1.renderDRL() ) );
+        builder.addPackageFromDrl( new StringReader( l2.renderDRL() ) );
+
+        final Package pkg = builder.getPackage();
+        assertNotNull( pkg );
+        DroolsError[] errors = builder.getErrors();
+//		for (int i = 0; i < errors.length; i++) {
+//			DroolsError error = errors[i];
+//			System.out.println(error.getMessage());
+//		}
+        assertEquals( 0,
+                      errors.length );
+
+        //BUILD RULEBASE
+        final RuleBase rb = RuleBaseFactory.newRuleBase();
+        rb.addPackage( pkg );
+
+        WorkingMemory wm = rb.newWorkingMemory();
+        
+        //now create some test data
+        Driver driver = new Driver();
+        Policy policy = new Policy();
+        
+        wm.assertObject(driver);
+        wm.assertObject(policy);
+        
+        wm.fireAllRules();
+        
+        System.out.println("BASE PRICE IS: " + policy.getBasePrice());
+        System.out.println("DISCOUNT IS: " + policy.getDiscountPercent());
+        
+        int basePrice = policy.getBasePrice();
+        assertEquals(120, basePrice);
+
+        
+    }
+
+}

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerUnitTest.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerUnitTest.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerUnitTest.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,127 @@
+package org.drools.decisiontable;
+
+/*
+ * 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.regex.Matcher;
+import java.util.regex.Pattern;
+
+import junit.framework.TestCase;
+
+/**
+ * @author <a href="mailto:michael.neale at gmail.com"> Michael Neale</a> Some
+ *         basic unit tests for converter utility. Note that some of this may
+ *         still use the drools 2.x syntax, as it is not compiled, only tested
+ *         that it generates DRL in the correct structure (not that the DRL
+ *         itself is correct).
+ */
+public class ExternalSpreadsheetCompilerUnitTest extends TestCase {
+	// public void testRE() throws Exception
+	// {
+	// String test = "Something(test == \"yes\" OPTIONAL[, $something$ ==
+	// \"$else$\"]) OPTIONAL[Hope(it == \"$works$\")]";
+	// Pattern pattern = Pattern.compile("OPTIONAL\\[(.[^\\]]*)\\]");
+	// Pattern pattern2 = Pattern.compile("\\$(.[^\\$]*)\\$");
+	// Matcher matcher = pattern.matcher(test);
+	// StringBuffer newTest = new StringBuffer();
+	// while (matcher.find()) {
+	// String expression = matcher.group(1);
+	// Matcher matcher2 = pattern2.matcher(expression);
+	// int j = 0;
+	// StringBuffer newExpression = new StringBuffer();
+	// StringBuffer newEndExpression = new StringBuffer();
+	// while (matcher2.find(j)) {
+	// newExpression.append("\\$if(").append(matcher2.group(1)).append(")\\$");
+	// newEndExpression.append("\\$endif\\$");
+	// j = matcher2.end();
+	// }
+	// newExpression.append(escape(expression)).append(newEndExpression);
+	// System.out.println(newExpression);
+	// matcher.appendReplacement(newTest, newExpression.toString());
+	// }
+	// System.out.println(newTest);
+	// }
+	//
+	// private String escape(String expression) {
+	// System.out.println("expression: " + expression);
+	// String newExp = expression.replaceAll("\\$", "\\\\\\$");
+	// System.out.println("newExp: " + newExp);
+	// return newExp;
+	// }
+	public void testLoadFromClassPath() {
+		final ExternalSpreadsheetCompiler converter = new ExternalSpreadsheetCompiler();
+		final String drl = converter.compile("/data/MultiSheetDST.xls",
+				"/templates/test_template1.drl", 11, 2);
+		assertNotNull(drl);
+		
+//		System.out.println(drl);
+
+		assertTrue(drl.indexOf("rule \"How cool is Shaun 12\"") > 0);
+		assertTrue(drl.indexOf("rule \"How cool is Kumar 11\"") > 0);
+		assertTrue(drl.indexOf("import example.model.User;") > -1);
+		assertTrue(drl.indexOf("import example.model.Car;") > -1);
+	}
+
+	public void testLoadSpecificWorksheet() {
+		final ExternalSpreadsheetCompiler converter = new ExternalSpreadsheetCompiler();
+		final String drl = converter.compile("/data/MultiSheetDST.xls",
+				"Another Sheet", "/templates/test_template1.drl", 11, 2);
+		assertNotNull(drl);
+	}
+
+	public void testLoadCsv() {
+		final ExternalSpreadsheetCompiler converter = new ExternalSpreadsheetCompiler();
+		final String drl = converter.compile("/data/ComplexWorkbook.csv",
+				"/templates/test_template2.drl", InputType.CSV, 10, 2);
+		assertNotNull(drl);
+
+
+		assertTrue(drl.indexOf("myObject.setIsValid(1, 2)") > 0);
+		assertTrue(drl.indexOf("myObject.size () > 2") > 0);
+
+		assertTrue(drl
+				.indexOf("Foo(myObject.getColour().equals(red),\n\t\tmyObject.size () > 1") > 0);
+	}
+
+    public void testLoadBasicWithMergedCells() {
+        final ExternalSpreadsheetCompiler converter = new ExternalSpreadsheetCompiler();
+        final String drl = converter.compile( "/data/BasicWorkbook.xls", "/templates/test_template3.drl",
+                                              InputType.XLS, 10, 2 );
+
+        final String drl1 = converter.compile( "/data/BasicWorkbook.xls", "/templates/test_template3.drl",
+        		InputType.XLS, 21, 2 );
+        
+        assertNotNull( drl );
+
+        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( drl1.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()\n\t\teval(myObject.size() < 3)" ) > -1 );
+        assertTrue( drl.indexOf( "b: Bar()\n\t\teval(myObject.size() < 9)" ) > -1 );
+
+        assertTrue( drl.indexOf( "Foo(myObject.getColour().equals(red), myObject.size() > 1)" ) < drl.indexOf( "b: Bar()\n\t\teval(myObject.size() < 3)" ) );
+
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/Person.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/Person.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/Person.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -17,9 +17,9 @@
  */
 
 public class Person {
-    private final String name;
-    private final String likes;
-    private final int    age;
+    private String name;
+    private String likes;
+    private int    age;
 
     private char         sex;
 
@@ -27,6 +27,9 @@
 
     private String       status;
 
+    public Person() {
+    	
+    }
     public Person(final String name) {
         this( name,
               "",

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ArrayColumnTest.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ArrayColumnTest.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ArrayColumnTest.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,49 @@
+package org.drools.decisiontable.parser;
+
+import org.antlr.stringtemplate.StringTemplate;
+
+import junit.framework.TestCase;
+
+public class ArrayColumnTest extends TestCase {
+
+	public void testGetValueSingle() {
+		ArrayColumn ac = new ArrayColumn("array column");
+		String[] value = (String[]) ac.getValue("value1");
+		assertEquals(1, value.length);
+		assertEquals("value1", value[0]);
+	}
+	
+	public void testGetValueTrailingComma() {
+		ArrayColumn ac = new ArrayColumn("array column");
+		String[] value = (String[]) ac.getValue("value1,");
+		assertEquals(1, value.length);
+		assertEquals("value1", value[0]);
+	}
+	
+	public void testGetValueMultiple() {
+		ArrayColumn ac = new ArrayColumn("array column");
+		String[] value = (String[]) ac.getValue("value1,value2,value3");
+		assertEquals(3, value.length);
+		assertEquals("value1", value[0]);
+		assertEquals("value2", value[1]);
+		assertEquals("value3", value[2]);
+	}
+	
+	public void testAddValueSingle() {
+		ArrayColumn ac = new ArrayColumn("array");
+		String[] value = new String[] { "value" };
+		StringTemplate t = new StringTemplate();
+		ac.addValue(t, value);
+		assertEquals("value", t.getAttribute("array0"));
+	}
+
+	public void testAddValueMultiple() {
+		ArrayColumn ac = new ArrayColumn("array");
+		String[] value = new String[] { "value1", "value2" };
+		StringTemplate t = new StringTemplate();
+		ac.addValue(t, value);
+		assertEquals("value1", t.getAttribute("array0"));
+		assertEquals("value2", t.getAttribute("array1"));
+	}
+	
+}

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ColumnFactoryTest.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ColumnFactoryTest.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ColumnFactoryTest.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,21 @@
+package org.drools.decisiontable.parser;
+
+import junit.framework.TestCase;
+
+public class ColumnFactoryTest extends TestCase {
+
+	public void testGetColumn() {
+		ColumnFactory f = new ColumnFactory();
+		Column column = f.getColumn("column");
+		assertTrue(!(column instanceof ArrayColumn));
+		assertEquals("column", column.getName());
+	}
+	
+	public void testGetArrayColumn() {
+		ColumnFactory f = new ColumnFactory();
+		Column column = f.getColumn("column[]");
+		assertTrue(column instanceof ArrayColumn);
+		assertEquals("column", column.getName());
+	}
+
+}

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/DefaultGeneratorTest.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/DefaultGeneratorTest.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/DefaultGeneratorTest.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,48 @@
+package org.drools.decisiontable.parser;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+public class DefaultGeneratorTest extends TestCase {
+	private DefaultGenerator g;
+
+	public void testSelectTemplate() {
+		g.generate("rt2", new Row());
+		String drl = g.getDrl();
+		assertEquals("Test template 2\n\n", drl);
+	}
+	
+	public void testGenerate() {
+		g.generate("rt2", new Row());
+		g.generate("rt1", new Row());
+		String drl = g.getDrl();
+		assertEquals("Test template 2\n\nTest template 1\n\n", drl);
+	}
+	
+	public void testAddColumns() {
+		Row r = new Row(1);
+		r.addCell(new Cell(r, new Column("col1"), "value1"));
+		r.addCell(new Cell(r, new Column("col2"), "value2"));
+		g.generate("rt3", r);
+		String drl = g.getDrl();
+		assertEquals("1 value1 value2\n\n", drl);
+	}
+
+	protected void setUp() throws Exception {
+		Map t = new HashMap();
+		RuleTemplate rt1 = new RuleTemplate("rt1");
+		rt1.setContents("Test template 1");
+		RuleTemplate rt2 = new RuleTemplate("rt2");
+		rt2.setContents("Test template 2");
+		RuleTemplate rt3 = new RuleTemplate("rt3");
+		rt3.addColumn("col1");
+		rt3.addColumn("col2");
+		rt3.setContents("$row.rowNumber$ $col1$ $col2$");
+		t.put("rt1", rt1);
+		t.put("rt2", rt2);
+		t.put("rt3", rt3);
+		g = new DefaultGenerator(t);
+	}
+}

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/DefaultTemplateContainerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/DefaultTemplateContainerTest.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/DefaultTemplateContainerTest.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,25 @@
+package org.drools.decisiontable.parser;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+public class DefaultTemplateContainerTest extends TestCase {
+	public void testParseTemplate() {
+		InputStream is = DefaultTemplateContainerTest.class.getResourceAsStream("/templates/test_template_simple.drl");
+		DefaultTemplateContainer t = new DefaultTemplateContainer(is);
+		assertEquals("package This_is_a_ruleset;\n", t.getHeader());
+		Map templates = t.getTemplates();
+		assertEquals(1, templates.size());
+		RuleTemplate template = (RuleTemplate) templates.get("template1");
+		assertNotNull(template);
+		List columns = template.getColumns();
+		assertEquals(1, columns.size());
+		assertEquals("name", columns.get(0));
+		String contents = template.getContents();
+		assertTrue(contents.startsWith("rule \"How cool is $name$ $row.rowNumber$\""));
+		assertTrue(contents.endsWith("then\nend\n"));
+	}
+}

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ExternalSheetListenerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ExternalSheetListenerTest.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ExternalSheetListenerTest.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,284 @@
+package org.drools.decisiontable.parser;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.drools.Agenda;
+import org.drools.FactException;
+import org.drools.FactHandle;
+import org.drools.NoSuchFactHandleException;
+import org.drools.NoSuchFactObjectException;
+import org.drools.QueryResults;
+import org.drools.RuleBase;
+import org.drools.WorkingMemory;
+import org.drools.event.AgendaEventListener;
+import org.drools.event.WorkingMemoryEventListener;
+import org.drools.spi.AgendaFilter;
+import org.drools.spi.AgendaGroup;
+import org.drools.spi.AsyncExceptionHandler;
+import org.drools.spi.GlobalResolver;
+
+public class ExternalSheetListenerTest extends TestCase {
+
+	private ExternalSheetListener esl;
+
+	private Map assertedRows = new HashMap();
+
+	private List currentRow = new ArrayList();
+
+	protected void setUp() throws Exception {
+		esl = new ExternalSheetListener(2, 2, new TestTemplateContainer(),
+				new TestTemplateRuleBase(), new TestGenerator());
+
+	}
+
+	public void testRenderDrl() {
+		String drl = esl.renderDRL();
+		assertEquals("Test Template Header\nTest Generated DRL\n", drl);
+	}
+
+	public void testRowHandling() {
+		esl.newRow(0, 3);
+		esl.newCell(0, 0, "row0col0", 0);
+		esl.newCell(0, 1, "row0col1", 0);
+		esl.newCell(0, 2, "row0col2", 0);
+		esl.newRow(1, 3);
+		esl.newCell(1, 0, "row1col0", 0);
+		esl.newCell(1, 1, "row1col1", 0);
+		esl.newCell(1, 2, "row1col2", 0);
+		esl.newRow(2, 3);
+		esl.newCell(2, 0, "row2col0", 0);
+		esl.newCell(2, 1, "row2col1", 0);
+		esl.newCell(2, 2, "row2col2", 0);
+		esl.finishSheet();
+		assertEquals(2, assertedRows.size());
+		for (Iterator it = assertedRows.entrySet().iterator(); it.hasNext();) {
+			Map.Entry entry = (Map.Entry) it.next();
+			Row row = (Row)entry.getKey();
+			List cells = (List) entry.getValue();
+			// first column is not part of the decision table
+			int i = 1;
+			for (Iterator it2 = cells.iterator(); it2.hasNext(); i++) {
+				Cell cell = (Cell) it2.next();
+				assertEquals("row" + row.getRowNumber() + "col" + i, cell.getValue());
+				assertEquals("Column " + i, cell.getColumn());
+			}
+		}
+	}
+
+	public void testRowHandlingBlankRows() {
+		esl.newRow(0, 3);
+		esl.newCell(0, 0, "row0col0", 0);
+		esl.newCell(0, 1, "row0col1", 0);
+		esl.newCell(0, 2, "row0col2", 0);
+		esl.newRow(1, 3);
+		esl.newCell(1, 0, "row1col0", 0);
+		esl.newCell(1, 1, "row1col1", 0);
+		esl.newCell(1, 2, "row1col2", 0);
+		esl.newRow(2, 3);
+		esl.newCell(2, 0, "row2col0", 0);
+		esl.newCell(2, 1, "row2col1", 0);
+		esl.newCell(2, 2, "row2col2", 0);
+		esl.newRow(3, 3);
+		esl.newCell(3, 0, "", 0);
+		esl.newCell(3, 1, "", 0);
+		esl.newCell(3, 2, "", 0);
+		esl.newRow(4, 3);
+		esl.newCell(4, 0, "", 0);
+		esl.newCell(4, 1, "", 0);
+		esl.newCell(4, 2, "", 0);
+		
+		esl.finishSheet();
+		assertEquals(2, assertedRows.size());
+	}
+	
+	private class TestTemplateRuleBase implements TemplateRuleBase {
+
+		public WorkingMemory newWorkingMemory() {
+			return new WorkingMemory() {
+
+				public void addEventListener(WorkingMemoryEventListener arg0) {
+
+				}
+
+				public void addEventListener(AgendaEventListener arg0) {
+
+				}
+
+				public FactHandle assertObject(Object fact)
+						throws FactException {
+					if (fact instanceof Row) {
+						assertedRows.put(fact, currentRow);
+						currentRow = new ArrayList();
+					} else {
+						currentRow.add(fact);
+					}
+					return null;
+				}
+
+				public FactHandle assertObject(Object arg0, boolean arg1)
+						throws FactException {
+					return null;
+				}
+
+				public void clearAgenda() {
+
+				}
+
+				public void clearAgendaGroup(String arg0) {
+
+				}
+
+				public void dispose() {
+
+				}
+
+				public void fireAllRules() throws FactException {
+
+				}
+
+				public void fireAllRules(AgendaFilter arg0)
+						throws FactException {
+
+				}
+
+				public Agenda getAgenda() {
+					return null;
+				}
+
+				public List getAgendaEventListeners() {
+					return null;
+				}
+
+				public FactHandle getFactHandle(Object arg0)
+						throws NoSuchFactHandleException {
+					return null;
+				}
+
+				public List getFactHandles() {
+					return null;
+				}
+
+				public AgendaGroup getFocus() {
+					return null;
+				}
+
+				public Object getGlobal(String arg0) {
+					return null;
+				}
+
+				public Map getGlobals() {
+					return null;
+				}
+
+				public Object getObject(FactHandle arg0)
+						throws NoSuchFactObjectException {
+					return null;
+				}
+
+				public List getObjects() {
+					return null;
+				}
+
+				public List getObjects(Class arg0) {
+					return null;
+				}
+
+				public QueryResults getQueryResults(String arg0) {
+					return null;
+				}
+
+				public RuleBase getRuleBase() {
+					return null;
+				}
+
+				public List getWorkingMemoryEventListeners() {
+					return null;
+				}
+
+				public void modifyObject(FactHandle arg0, Object arg1)
+						throws FactException {
+
+				}
+
+				public void removeEventListener(WorkingMemoryEventListener arg0) {
+
+				}
+
+				public void removeEventListener(AgendaEventListener arg0) {
+
+				}
+
+				public void retractObject(FactHandle arg0) throws FactException {
+
+				}
+
+				public void setAsyncExceptionHandler(AsyncExceptionHandler arg0) {
+
+				}
+
+				public void setFocus(String arg0) {
+
+				}
+
+				public void setFocus(AgendaGroup arg0) {
+
+				}
+
+				public void setGlobal(String arg0, Object arg1) {
+
+				}
+
+				public void setGlobalResolver(GlobalResolver globalResolver) {
+					
+				}
+			};
+		}
+	}
+
+	private class TestGenerator implements Generator {
+
+		public void generate(String templateName, Row row) {
+		}
+
+		public String getDrl() {
+			return "Test Generated DRL";
+		}
+
+	}
+
+	private class TestTemplateContainer implements TemplateContainer {
+
+		public void addColumn(Column c) {
+		}
+
+		public void addTemplate(RuleTemplate template) {
+		}
+
+		public Column[] getColumns() {
+			return new Column[] { new Column("Column 1"),
+					new Column("Column 2"), new Column("Column 3") };
+		}
+
+		public String getHeader() {
+			return "Test Template Header";
+		}
+
+		public Map getTemplates() {
+			return null;
+		}
+
+		public void setHeader(String head) {
+		}
+
+		public void setTemplates(Map templates) {
+
+		}
+	}
+
+}

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleTemplateTest.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleTemplateTest.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleTemplateTest.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,11 @@
+package org.drools.decisiontable.parser;
+
+import junit.framework.TestCase;
+
+public class RuleTemplateTest extends TestCase {
+	public void testSetContents() {
+		RuleTemplate rt = new RuleTemplate("rt1");
+		rt.setContents("Test template");
+		assertEquals("Test template\n", rt.getContents());
+	}
+}

Modified: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvParserTest.java
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvParserTest.java	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvParserTest.java	2006-12-19 12:03:53 UTC (rev 8396)
@@ -57,7 +57,7 @@
      * Test the handling of merged cells.
      */
     public void testCellMergeHandling() {
-        CsvParser parser = new CsvParser(null, null);
+        CsvParser parser = new CsvParser((SheetListener)null, null);
         assertEquals(SheetListener.NON_MERGED, parser.calcStartMerge( SheetListener.NON_MERGED, 1, "foo" ));
         assertEquals(42, parser.calcStartMerge( SheetListener.NON_MERGED, 42, "..." ));
         

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_integration.drl
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_integration.drl	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_integration.drl	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,24 @@
+template header
+age
+type
+log
+
+package Some_business_rules;
+#generated from Decision Table
+import org.drools.decisiontable.Cheese;
+import org.drools.decisiontable.Person;
+global java.util.List list;
+
+template "cheesefans"
+age
+type
+log
+
+rule "Cheese fans_$row.rowNumber$"
+	when
+		Person(age == "$age$")
+		Cheese(type == "$type$")
+	then
+		list.add("$log$");
+end
+end template
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_pricing1.drl
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_pricing1.drl	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_pricing1.drl	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,28 @@
+template header
+age[]
+profile
+priorClaims
+policyType
+base
+reason
+
+package org.acme.insurance;
+
+template "Pricing bracket"
+age
+policyType
+base
+
+rule "Pricing bracket_$row.rowNumber$"
+	
+	when
+		Driver(age >= $age0$, age <= $age1$
+			, priorClaims == "$priorClaims$"
+			, locationRiskProfile == "$profile$"
+		)
+		policy: Policy(type == "$policyType$")
+	then
+		policy.setBasePrice($base$);
+		System.out.println("$reason$");
+end
+end template

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_pricing2.drl
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_pricing2.drl	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_pricing2.drl	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,23 @@
+template header
+age[]
+priorClaims
+policyType
+discount
+
+package org.acme.insurance;
+
+template "discounts"
+age
+priorClaims
+policyType
+discount
+
+rule "Discounts_$row.rowNumber$"
+	
+	when
+		Driver(age >= $age0$, age <= $age1$, priorClaims == "$priorClaims$")
+		policy: Policy(type == "$policyType$")
+	then
+		policy.applyDiscount($discount$);
+end
+end template

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template1.drl
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template1.drl	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template1.drl	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,26 @@
+template header
+name
+age[]
+log
+coolness
+
+package This_is_a_ruleset;
+#generated from Decision Table
+import example.model.User;
+import example.model.Car;
+
+template "coolness"
+name
+age
+log
+coolness
+rule "How cool is $name$ $row.rowNumber$"
+	when
+		user.getName().equals("$name$")
+		user.getAge() >= $age1$ && user.getAge() <= $age2$
+	then
+		System.out.println( "$log$" );
+		user.setCoolness("$coolness$");
+end
+end template
+

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template2.drl
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template2.drl	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template2.drl	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,28 @@
+template header
+colour
+minSize
+maxSize
+valida
+validb[]
+
+package rulesetName;
+#generated from Decision Table
+
+
+template "mine"
+colour
+minSize
+maxSize
+valida
+validb
+rule "some stuff $row.rowNumber$"
+	when
+		Foo(myObject.getColour().equals($colour$),
+		myObject.size () > $minSize$,
+		myObject.size () < $maxSize$)
+	then
+		myObject.setIsValid($valida$);
+		myObject.setIsValid($validb0$, $validb1$);
+end
+end template
+

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template3.drl
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template3.drl	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template3.drl	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,31 @@
+template header
+colour
+minSize
+maxSize
+valid
+
+
+package rulesetName;
+#generated from Decision Table
+import blah.class1
+import blah.class2
+
+global Class1 obj1;
+function test() {
+	This is a function block
+}
+template "This_Is_Rule_Name_Prefix"
+colour
+minSize
+maxSize
+valid
+rule "This_Is_Rule_Name_Prefix $row.rowNumber$"
+	when
+		Foo(myObject.getColour().equals($colour$), myObject.size() > $minSize$)
+		b: Bar()
+		eval(myObject.size() < $maxSize$)
+	then
+		myObject.setIsValid($valid$);
+end
+end template
+

Added: labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template_simple.drl
===================================================================
--- labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template_simple.drl	2006-12-19 11:53:16 UTC (rev 8395)
+++ labs/jbossrules/trunk/drools-decisiontables/src/test/resources/templates/test_template_simple.drl	2006-12-19 12:03:53 UTC (rev 8396)
@@ -0,0 +1,14 @@
+template header
+name
+
+package This_is_a_ruleset;
+
+template "template1"
+name
+rule "How cool is $name$ $row.rowNumber$"
+	when
+		user.getName().equals("$name$")
+	then
+end
+end template
+




More information about the jboss-svn-commits mailing list