[jboss-svn-commits] JBL Code SVN: r36699 - in labs/jbossrules/tags/5.2.0.M1: drools-decisiontables and 33 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Feb 24 10:37:23 EST 2011
Author: ge0ffrey
Date: 2011-02-24 10:37:22 -0500 (Thu, 24 Feb 2011)
New Revision: 36699
Added:
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/.gitignore
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/build.properties
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/pom.xml
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/DecisionTableProviderImpl.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/ExternalSpreadsheetCompiler.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/InputType.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/SourcePackageProvider.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/SpreadsheetCompiler.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ActionType.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DecisionTableParser.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultRuleSheetListener.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/LhsBuilder.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RhsBuilder.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleMatrixSheetListener.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetListener.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetParserUtil.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/SourceBuilder.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/csv/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/csv/CsvLineParser.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/csv/CsvParser.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/ExcelParser.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/NullSheetListener.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/PropertiesSheetListener.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/osgi/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/osgi/decisiontables/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/osgi/decisiontables/Activator.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/org/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/org/drools/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/org/drools/decisiontable/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/org/drools/decisiontable/package.html
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/Example.xls
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/README.txt
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/pydt.py
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/pydt_test.py
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/insurance/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/insurance/Driver.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/insurance/Policy.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/insurance/launcher/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/insurance/launcher/PricingRuleLauncher.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/ChangeSetTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/Cheese.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerIntegrationTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerUnitTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/Person.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/SourcePackageProviderTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetCompilerUnitTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetIntegrationTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ActionTypeTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ColumnFactoryTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/LhsBuilderTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/PropertiesSheetListenerTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RhsBuilderTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleSheetParserUtilTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseLargeTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RulesheetUtil.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvLineParserTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvParserTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/xls/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/xls/ExcelParserTest.java
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/BasicWorkbook.xls
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/ComplexWorkbook.csv
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/ComplexWorkbook.xls
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/CustomWorkbook.xls
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/ExamplePolicyPricing.xls
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/IntegrationExampleTest.xls
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/MultiSheetDST.xls
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/TeamAllocationExample_TYPICAL_EXAMPLE.xls
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/TestCsv.csv
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/VeryLargeWorkbook.xls
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/drools/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/drools/decisiontable/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/drools/decisiontable/changeset1Test.drl
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/drools/decisiontable/changeset1Test.xml
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/drools/decisiontable/changeset2Test.drl
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_integration.drl
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_pricing1.drl
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_pricing2.drl
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template1.drl
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template2.drl
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template3.drl
labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template4.drl
Log:
All monolothic build versions (<= 5.2.0.M1) stay in subversion
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/.gitignore
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/.gitignore (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/.gitignore 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,13 @@
+/target
+/local
+
+# Eclipse, Netbeans and IntelliJ files
+/.*
+!.gitignore
+/nbproject
+/*.ipr
+/*.iws
+/*.iml
+
+# The META-INF directory is generated by the maven-felix-plugin
+META-INF
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/build.properties
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/build.properties (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/build.properties 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,12 @@
+src.includes = .,\
+ build.properties,\
+ META-INF/,\
+ src/,\
+ pom.xml
+bin.includes = .,\
+ META-INF/,\
+ build.properties
+source.. = src/main/java/,\
+ src/main/resources/
+output.. = target/classes/
+jars.compile.order = .
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/pom.xml
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/pom.xml (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/pom.xml 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.drools</groupId>
+ <artifactId>drools</artifactId>
+ <version>5.2.0.M1</version>
+ </parent>
+ <artifactId>drools-decisiontables</artifactId>
+ <packaging>jar</packaging>
+ <name>Drools :: Decision Tables</name>
+
+ <dependencies>
+ <!-- Internal dependencies -->
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-compiler</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-templates</artifactId>
+ </dependency>
+ <!-- External dependencies -->
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>net.sourceforge.jexcelapi</groupId>
+ <artifactId>jxl</artifactId>
+ </dependency>
+
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>META-INF/MANIFEST.MF</manifestFile>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <executions>
+ <execution>
+ <id>manifest</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>manifest</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <manifestLocation>META-INF</manifestLocation>
+ <instructions>
+ <Bundle-SymbolicName>org.drools.decisiontables;singleton:=true</Bundle-SymbolicName>
+ <_removeheaders>Ignore-Package</_removeheaders>
+ <Require-Bundle>org.drools.core;bundle-version="5.2.0.M1"</Require-Bundle>
+ <Import-Package>!org.drools.*, *</Import-Package>
+ <Export-Package>org.drools.*</Export-Package>
+ <DynamicImport-Package>org.drools.*</DynamicImport-Package>
+ <Bundle-Activator>org.drools.osgi.decisiontables.Activator</Bundle-Activator>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/DecisionTableProviderImpl.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/DecisionTableProviderImpl.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/DecisionTableProviderImpl.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,238 @@
+package org.drools.decisiontable;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+import org.drools.builder.DecisionTableConfiguration;
+import org.drools.compiler.DecisionTableProvider;
+import org.drools.core.util.StringUtils;
+
+public class DecisionTableProviderImpl
+ implements
+ DecisionTableProvider {
+
+ public String loadFromInputStream(InputStream is,
+ DecisionTableConfiguration configuration) {
+
+ return compileStream( is,
+ configuration );
+ }
+
+ private String compileStream(InputStream is,
+ DecisionTableConfiguration configuration) {
+ SpreadsheetCompiler compiler = new SpreadsheetCompiler();
+ switch ( configuration.getInputType() ) {
+ case XLS : {
+ if ( StringUtils.isEmpty( configuration.getWorksheetName() ) ) {
+ return compiler.compile( is,
+ InputType.XLS );
+ } else {
+ return compiler.compile( is,
+ configuration.getWorksheetName() );
+ }
+ }
+ case CSV : {
+ return compiler.compile( is,
+ InputType.CSV );
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Adapts a <code>Reader</code> as an <code>InputStream</code>.
+ * Adapted from <CODE>StringInputStream</CODE>.
+ *
+ */
+ public static class ReaderInputStream extends InputStream {
+
+ /** Source Reader */
+ private Reader in;
+
+ private String encoding = System.getProperty( "file.encoding" );
+
+ private byte[] slack;
+
+ private int begin;
+
+ /**
+ * Construct a <CODE>ReaderInputStream</CODE>
+ * for the specified <CODE>Reader</CODE>.
+ *
+ * @param reader <CODE>Reader</CODE>. Must not be <code>null</code>.
+ */
+ public ReaderInputStream(Reader reader) {
+ in = reader;
+ }
+
+ /**
+ * Construct a <CODE>ReaderInputStream</CODE>
+ * for the specified <CODE>Reader</CODE>,
+ * with the specified encoding.
+ *
+ * @param reader non-null <CODE>Reader</CODE>.
+ * @param encoding non-null <CODE>String</CODE> encoding.
+ */
+ public ReaderInputStream(Reader reader,
+ String encoding) {
+ this( reader );
+ if ( encoding == null ) {
+ throw new IllegalArgumentException( "encoding must not be null" );
+ } else {
+ this.encoding = encoding;
+ }
+ }
+
+ /**
+ * Reads from the <CODE>Reader</CODE>, returning the same value.
+ *
+ * @return the value of the next character in the <CODE>Reader</CODE>.
+ *
+ * @exception IOException if the original <code>Reader</code> fails to be read
+ */
+ public synchronized int read() throws IOException {
+ if ( in == null ) {
+ throw new IOException( "Stream Closed" );
+ }
+
+ byte result;
+ if ( slack != null && begin < slack.length ) {
+ result = slack[begin];
+ if ( ++begin == slack.length ) {
+ slack = null;
+ }
+ } else {
+ byte[] buf = new byte[1];
+ if ( read( buf,
+ 0,
+ 1 ) <= 0 ) {
+ result = -1;
+ }
+ result = buf[0];
+ }
+
+ if ( result < -1 ) {
+ result += 256;
+ }
+
+ return result;
+ }
+
+ /**
+ * Reads from the <code>Reader</code> into a byte array
+ *
+ * @param b the byte array to read into
+ * @param off the offset in the byte array
+ * @param len the length in the byte array to fill
+ * @return the actual number read into the byte array, -1 at
+ * the end of the stream
+ * @exception IOException if an error occurs
+ */
+ public synchronized int read(byte[] b,
+ int off,
+ int len) throws IOException {
+ if ( in == null ) {
+ throw new IOException( "Stream Closed" );
+ }
+
+ while ( slack == null ) {
+ char[] buf = new char[len]; // might read too much
+ int n = in.read( buf );
+ if ( n == -1 ) {
+ return -1;
+ }
+ if ( n > 0 ) {
+ slack = new String( buf,
+ 0,
+ n ).getBytes( encoding );
+ begin = 0;
+ }
+ }
+
+ if ( len > slack.length - begin ) {
+ len = slack.length - begin;
+ }
+
+ System.arraycopy( slack,
+ begin,
+ b,
+ off,
+ len );
+
+ if ( (begin += len) >= slack.length ) {
+ slack = null;
+ }
+
+ return len;
+ }
+
+ /**
+ * Marks the read limit of the StringReader.
+ *
+ * @param limit the maximum limit of bytes that can be read before the
+ * mark position becomes invalid
+ */
+ public synchronized void mark(final int limit) {
+ try {
+ in.mark( limit );
+ } catch ( IOException ioe ) {
+ throw new RuntimeException( ioe.getMessage() );
+ }
+ }
+
+ /**
+ * @return the current number of bytes ready for reading
+ * @exception IOException if an error occurs
+ */
+ public synchronized int available() throws IOException {
+ if ( in == null ) {
+ throw new IOException( "Stream Closed" );
+ }
+ if ( slack != null ) {
+ return slack.length - begin;
+ }
+ if ( in.ready() ) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * @return false - mark is not supported
+ */
+ public boolean markSupported() {
+ return false; // would be imprecise
+ }
+
+ /**
+ * Resets the StringReader.
+ *
+ * @exception IOException if the StringReader fails to be reset
+ */
+ public synchronized void reset() throws IOException {
+ if ( in == null ) {
+ throw new IOException( "Stream Closed" );
+ }
+ slack = null;
+ in.reset();
+ }
+
+ /**
+ * Closes the Stringreader.
+ *
+ * @exception IOException if the original StringReader fails to be closed
+ */
+ public synchronized void close() throws IOException {
+ if ( in != null ) {
+ in.close();
+ slack = null;
+ in = null;
+ }
+ }
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/ExternalSpreadsheetCompiler.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/ExternalSpreadsheetCompiler.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/ExternalSpreadsheetCompiler.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable;
+
+import java.io.IOException;
+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.xls.ExcelParser;
+import org.drools.template.parser.DataListener;
+import org.drools.template.parser.DefaultTemplateContainer;
+import org.drools.template.parser.TemplateContainer;
+import org.drools.template.parser.TemplateDataListener;
+
+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,
+ int startRow,
+ int startCol) {
+ return compile( xlsStream,
+ templateStream,
+ InputType.XLS,
+ 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 TemplateDataListener( 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 TemplateDataListener( startRow,
+ startCol,
+ tc ) );
+ }
+
+ public void compile(final String xls,
+ InputType type,
+ final List<DataListener> listeners) {
+ final InputStream xlsStream = this.getClass().getResourceAsStream( xls );
+ compile( xlsStream,
+ type,
+ listeners );
+ }
+
+ public void compile(final String xls,
+ final Map<String, List<DataListener>> listeners) {
+ final InputStream xlsStream = this.getClass().getResourceAsStream( xls );
+ compile( xlsStream,
+ listeners );
+ }
+
+ public void compile(final InputStream xlsStream,
+ InputType type,
+ final List<DataListener> listeners) {
+ final DecisionTableParser parser = type.createParser( listeners );
+ parser.parseFile( xlsStream );
+ closeStream( xlsStream );
+ }
+
+ public void compile(final InputStream xlsStream,
+ final Map<String, List<DataListener>> 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 TemplateDataListener listener) {
+ ArrayList<DataListener> listeners = new ArrayList<DataListener>();
+ listeners.add( listener );
+ compile( xlsStream,
+ type,
+ listeners );
+ return listener.renderDRL();
+ }
+
+ public String compile(final InputStream xlsStream,
+ final String worksheetName,
+ final TemplateDataListener listener) {
+ Map<String, List<DataListener>> listeners = new HashMap<String, List<DataListener>>();
+ List<DataListener> l = new ArrayList<DataListener>();
+ 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() );
+ }
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/InputType.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/InputType.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/InputType.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable;
+
+import java.util.List;
+
+import org.drools.decisiontable.parser.DecisionTableParser;
+import org.drools.decisiontable.parser.csv.CsvLineParser;
+import org.drools.decisiontable.parser.csv.CsvParser;
+import org.drools.decisiontable.parser.xls.ExcelParser;
+import org.drools.template.parser.DataListener;
+
+/**
+ * Provides valid input types for decision tables.
+ * (which also serve as parser factories).
+ *
+ * @author Michael Neale
+ */
+public abstract class InputType {
+ public static final InputType XLS = new XlsInput();
+ public static final InputType CSV = new CsvInput();
+
+ protected InputType() {
+
+ }
+
+ /**
+ * @param listener
+ * @return The appropriate Parser.
+ */
+ public abstract DecisionTableParser createParser(DataListener listener);
+ public abstract DecisionTableParser createParser(List<DataListener> listeners);
+
+}
+
+class XlsInput extends InputType {
+
+ public DecisionTableParser createParser(final DataListener listener) {
+ return new ExcelParser( listener );
+ }
+ public DecisionTableParser createParser(final List<DataListener> listeners) {
+ return new ExcelParser( listeners );
+ }
+
+}
+
+class CsvInput extends InputType {
+
+ public DecisionTableParser createParser(final DataListener listener) {
+ return new CsvParser( listener,
+ new CsvLineParser() );
+ }
+
+ public DecisionTableParser createParser(final List<DataListener> listeners) {
+ return new CsvParser( listeners,
+ new CsvLineParser() );
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/SourcePackageProvider.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/SourcePackageProvider.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/SourcePackageProvider.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,48 @@
+package org.drools.decisiontable;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+
+import org.drools.RuntimeDroolsException;
+import org.drools.agent.FileLoader;
+import org.drools.compiler.DroolsParserException;
+import org.drools.compiler.PackageBuilder;
+import org.drools.rule.Package;
+
+/**
+ * This is used by the agent when a source file is encountered.
+ *
+ * @author Toni Rikkola
+ *
+ */
+public class SourcePackageProvider
+ implements
+ FileLoader {
+
+ public Package loadPackage(File rm) throws IOException {
+ final FileInputStream fin = new FileInputStream( rm );
+
+ final SpreadsheetCompiler converter = new SpreadsheetCompiler();
+ String drl = converter.compile( fin,
+ InputType.XLS );
+
+ fin.close();
+
+ PackageBuilder b = new PackageBuilder();
+ try {
+ b.addPackageFromDrl( new StringReader( drl ) );
+ if ( b.hasErrors() ) {
+ throw new RuntimeDroolsException( "Error building rules from source: " + b.getErrors() );
+ } else {
+ return b.getPackage();
+ }
+ } catch ( DroolsParserException e ) {
+ throw new RuntimeException( e );
+ }
+
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/SpreadsheetCompiler.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/SpreadsheetCompiler.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/SpreadsheetCompiler.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable;
+
+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.DefaultRuleSheetListener;
+import org.drools.decisiontable.parser.RuleSheetListener;
+import org.drools.decisiontable.parser.xls.ExcelParser;
+import org.drools.template.model.DRLOutput;
+import org.drools.template.model.Package;
+import org.drools.template.parser.DataListener;
+
+/**
+ * @author <a href="mailto:michael.neale at gmail.com"> Michael Neale </a>
+ *
+ * This class handles the input XLS and CSV and extracts the rule DRL, ready for
+ * pumping into drools.
+ */
+public class SpreadsheetCompiler {
+
+ /**
+ * Generates DRL from the input stream containing the spreadsheet.
+ *
+ * @param showPackage
+ * tells it to print or not print any package statements in the spreadsheet.
+ * @param xlsStream
+ * The stream to the spreadsheet. Uses the first worksheet found
+ * for the decision tables, ignores others.
+ * @return DRL xml, ready for use in drools.
+ */
+ public String compile(boolean showPackage,
+ final InputStream xlsStream,
+ final InputType type) {
+ return compile( xlsStream,
+ type,
+ new DefaultRuleSheetListener( showPackage ) );
+ }
+
+ /**
+ * 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.
+ * @return DRL xml, ready for use in drools.
+ */
+ public String compile(final InputStream xlsStream,
+ final InputType 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 );
+ return out.getDRL();
+ }
+
+ /**
+ * Convenience implementation, taking rules from the classpath. It is
+ * recommended to use the stream version, as you can then change rules
+ * dynamically. (that is a lot of the benefit of rule engines !).
+ *
+ * @param classPathResource
+ * full class path to the spreadsheet you wish to convert to DRL.
+ * Uses the first worksheet for the decision tables.
+ * @return DRL.
+ */
+ public String compile(final String classPathResource,
+ final InputType inputType) {
+ final InputStream stream = this.getClass().getResourceAsStream( classPathResource );
+ try {
+ final String drl = compile( stream,
+ inputType );
+ return drl;
+ } finally {
+ closeStream( stream );
+ }
+ }
+
+ /**
+ * Looks for a named worksheet to find the decision tables on. Only works
+ * with XLS format spreadsheets (as they have multiple worksheets).
+ *
+ * @param stream
+ * The stream of the decision tables (spreadsheet) IN XLS format !!
+ * @param worksheetName
+ * The name of the worksheet that the decision tables live on.
+ * @return DRL, ready to go.
+ */
+ public String compile(final InputStream stream,
+ final String worksheetName) {
+ final RuleSheetListener listener = getRuleSheetListener( stream,
+ worksheetName );
+ final Package rulePackage = listener.getRuleSet();
+ final DRLOutput out = new DRLOutput();
+ rulePackage.renderDRL( out );
+ return out.getDRL();
+ }
+
+ private RuleSheetListener getRuleSheetListener(final InputStream stream,
+ final String worksheetName) {
+ final RuleSheetListener listener = new DefaultRuleSheetListener();
+ final Map<String, List<DataListener>> sheetListeners = new HashMap<String, List<DataListener>>();
+ final List<DataListener> listeners = new ArrayList<DataListener>();
+ listeners.add(listener);
+ sheetListeners.put( worksheetName,
+ listeners );
+ final ExcelParser parser = new ExcelParser( sheetListeners );
+ parser.parseFile( stream );
+ return listener;
+ }
+
+ 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/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ActionType.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ActionType.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ActionType.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser;
+
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.drools.template.parser.DecisionTableParseException;
+
+/**
+ * Simple holder class identifying a condition, action or attribute column, also
+ * including the rule name and a comment (called "description").
+ * Its objects are stored in a map in the main listener class, to track what type of values
+ * you can expect to see in the rows directly below the column header, identified
+ * by an ActionType.Code.
+ *
+ * @author Michael Neale
+ */
+public class ActionType {
+
+ public enum Code {
+ CONDITION( "CONDITION", "C" ),
+ ACTION( "ACTION", "A" ),
+ NAME( "NAME", "N", 1 ),
+ DESCRIPTION( "DESCRIPTION", "I" ),
+ SALIENCE( "PRIORITY", "P", 1 ),
+ DURATION( "DURATION", "D", 1 ),
+ NOLOOP( "NO-LOOP", "U", 1 ),
+ LOCKONACTIVE( "LOCK-ON-ACTIVE", "L", 1 ),
+ AUTOFOCUS( "AUTO-FOCUS", "F", 1 ),
+ ACTIVATIONGROUP( "ACTIVATION-GROUP", "X", 1 ),
+ AGENDAGROUP( "AGENDA-GROUP", "G", 1 ),
+ RULEFLOWGROUP( "RULEFLOW-GROUP", "R", 1 ),
+ METADATA( "METADATA", "@" );
+
+ private String colHeader;
+ private String colShort;
+ private int maxCount;
+
+ /**
+ * Constructor.
+ * @param colHeader the column header
+ * @param colShort a single letter, recognized as initial
+ * @param maxCount maximum number of permitted columns
+ */
+ Code( String colHeader, String colShort, int maxCount ){
+ this.colHeader = colHeader;
+ this.colShort = colShort;
+ this.maxCount = maxCount;
+ }
+
+
+ Code( String colHeader, String colShort ){
+ this( colHeader, colShort, Integer.MAX_VALUE );
+ }
+
+ public String getColHeader(){
+ return colHeader;
+ }
+ public String getColShort(){
+ return colShort;
+ }
+ public int getMaxCount() {
+ return maxCount;
+ }
+ }
+
+ public static final EnumSet<Code> ATTRIBUTE_CODE_SET = EnumSet.range( Code.SALIENCE, Code.RULEFLOWGROUP );
+
+ private static final Map<String,Code> tag2code = new HashMap<String,Code>();
+ static {
+ for( Code code: EnumSet.allOf( Code.class ) ){
+ tag2code.put( code.colHeader, code );
+ tag2code.put( code.colShort, code );
+ }
+ }
+
+ private Code code;
+ private SourceBuilder sourceBuilder = null;
+
+ /**
+ * Constructor.
+ * @param actionTypeCode code identifying the column
+ */
+ ActionType( Code actionTypeCode) {
+ this.code = actionTypeCode;
+ }
+
+ public static EnumSet<Code> getAttributeCodeSet() {
+ return ATTRIBUTE_CODE_SET;
+ }
+
+ public static Map<String, Code> getTag2code() {
+ return tag2code;
+ }
+
+ /**
+ * Retrieves the code.
+ * @return an enum Code value
+ */
+ public Code getCode(){
+ return this.code;
+ }
+
+ /**
+ * This is only set for LHS or RHS building.
+ */
+ public void setSourceBuilder(SourceBuilder src) {
+ this.sourceBuilder = src;
+ }
+
+ public SourceBuilder getSourceBuilder() {
+ return this.sourceBuilder;
+ }
+
+ /**
+ * Create a new action type that matches this cell, and add it to the map,
+ * keyed on that column.
+ */
+ public static void addNewActionType(final Map<Integer, ActionType> actionTypeMap,
+ final String value,
+ final int column, final int row) {
+ final String ucValue = value.toUpperCase();
+
+ Code code = tag2code.get( ucValue );
+ if( code == null ) code = tag2code.get( ucValue.substring( 0, 1 ) );
+ if( code != null ){
+
+ int count = 0;
+ for( ActionType at: actionTypeMap.values() ){
+ if( at.getCode() == code ) count++;
+ }
+ if( count >= code.getMaxCount() ){
+ throw new DecisionTableParseException( "Maximum number of " +
+ code.getColHeader() + "/" + code.getColShort() + " columns is " +
+ code.getMaxCount() + ", in cell " + RuleSheetParserUtil.rc2name(row, column) );
+ }
+ actionTypeMap.put( new Integer( column ), new ActionType( code ) );
+ } else {
+ throw new DecisionTableParseException(
+ "Invalid column header: " + value + ", should be CONDITION, ACTION or attribute, " +
+ "in cell " + RuleSheetParserUtil.rc2name(row, column) );
+ }
+ }
+
+ /**
+ * This is where a code snippet template is added.
+ */
+ public void addTemplate(int row, int column, String content) {
+ if( this.sourceBuilder == null ){
+ throw new DecisionTableParseException(
+ "Unexpected content \"" + content + "\" in cell " +
+ RuleSheetParserUtil.rc2name(row, column) + ", leave this cell blank" );
+ }
+ this.sourceBuilder.addTemplate( row, column, content );
+ }
+
+ /**
+ * Values are added to populate the template.
+ * The source builder contained needs to be "cleared" when the resultant snippet is extracted.
+ */
+ public void addCellValue(int row, int column, String content) {
+ //Michael Neale:
+ // For single standard quotes we escape them - eg they may mean "inches"
+ // as in "I want a Stonehenge replica 19" tall"
+ int idx = content.indexOf("\"");
+ if (idx > 0 && content.indexOf("\"", idx) > -1) {
+ content = content.replace("\"", "\\\"");
+ }
+// if( this.sourceBuilder != null ){
+ this.sourceBuilder.addCellValue( row, column, content );
+// }
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DecisionTableParser.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DecisionTableParser.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DecisionTableParser.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser;
+
+import java.io.InputStream;
+
+/**
+ * Generic interface for all input parsers.
+ *
+ * @author <a href="mailto:michael.neale at gmail.com"> Michael Neale</a>
+ *
+ */
+public interface DecisionTableParser {
+ /**
+ * Parse an input stream, store the resulting rulebase.
+ */
+ public void parseFile(InputStream inStream);
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultRuleSheetListener.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultRuleSheetListener.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/DefaultRuleSheetListener.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,631 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.decisiontable.parser.xls.PropertiesSheetListener;
+import org.drools.decisiontable.parser.xls.PropertiesSheetListener.CaseInsensitiveMap;
+import org.drools.template.model.Condition;
+import org.drools.template.model.Consequence;
+import org.drools.template.model.Global;
+import org.drools.template.model.Import;
+import org.drools.template.model.Package;
+import org.drools.template.model.Rule;
+import org.drools.template.parser.DecisionTableParseException;
+import static org.drools.decisiontable.parser.ActionType.Code;
+
+/**
+ * An object of this class is prepared to receive calls passing it the
+ * contents of a spreadsheet containing one or more decision tables.
+ * Each of these tables is then expanded into a set of similar rules,
+ * varying to a degree with respect to the patterns and actions.
+ *
+ * A "rule set" starts with some overall definitions such as imports,
+ * globals, functions and queries.
+ *
+ * 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 pattern of
+ * the condition or an action for the consequence, or an attribute.
+ *
+ * The second row contains optional pattern type declarations. If cells in
+ * this row are merged, then all snippets below the merged stretch become part of
+ * the same pattern, as separate constraints.
+ *
+ * The third row identifies the java code block associated with the condition
+ * or consequence. This code block should include one or more parameter markers
+ * for the insertion of values defined in cells of that column.
+ *
+ * The third row is available for comments on the purpose of the column.
+ *
+ * All subsequent rows identify rules with the set, providing values to be
+ * inserted where there are markers in the code snippets defined in the third
+ * row, or for the attribute identified by the column header.
+ *
+ * @author <a href="mailto:shaun.addison at gmail.com"> Shaun Addison </a><a
+ * href="mailto:michael.neale at gmail.com"> Michael Neale </a>
+ */
+public class DefaultRuleSheetListener
+implements RuleSheetListener {
+
+ //keywords
+ public static final String QUERIES_TAG = "Queries";
+ 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<Integer, ActionType> _actions;
+ private final HashMap<Integer, String> _cellComments = new HashMap<Integer, String>();
+ private final List<Rule> _ruleList = new LinkedList<Rule>();
+
+ //need to keep an ordered list of this to make conditions appear in the right order
+ private List<SourceBuilder> sourceBuilders = new ArrayList<SourceBuilder>();
+
+ private final PropertiesSheetListener _propertiesListener = new PropertiesSheetListener();
+
+ private boolean showPackage;
+
+ /**
+ * Constructor.
+ */
+ public DefaultRuleSheetListener() {
+ this( true );
+ }
+
+ /**
+ * Constructor.
+ * @param showPackage if true, the rule set name is passed to the resulting package
+ */
+ public DefaultRuleSheetListener(boolean showPackage) {
+ this.showPackage = showPackage;
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.decisiontable.parser.RuleSheetListener#getProperties()
+ */
+ public CaseInsensitiveMap getProperties() {
+ return this._propertiesListener.getProperties();
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.decisiontable.parser.RuleSheetListener#getRuleSet()
+ */
+ public Package getRuleSet() {
+ if ( this._ruleList.isEmpty() ) {
+ throw new DecisionTableParseException( "No RuleTable cells 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 defaultPackageName = "rule_table";
+ final String rulesetName =
+ getProperties().getSingleProperty( RULESET_TAG, defaultPackageName );
+
+ final Package ruleset = new Package( (showPackage) ? rulesetName : null );
+ for ( Rule rule : this._ruleList ) {
+ ruleset.addRule( rule );
+ }
+
+ final List<Import> importList = RuleSheetParserUtil.getImportList( getProperties().getProperty( IMPORT_TAG ) );
+ for ( Import import1 : importList ) {
+ ruleset.addImport( import1 );
+ }
+
+ final List<Global> variableList = RuleSheetParserUtil.getVariableList( getProperties().getProperty( VARIABLES_TAG ) );
+ for ( Global global : variableList ) {
+ ruleset.addVariable( global );
+ }
+
+ final List<String> functions = getProperties().getProperty( FUNCTIONS_TAG );
+ if( functions != null ){
+ for( String function: functions ){
+ ruleset.addFunctions( function );
+ }
+ }
+
+ final List<String> queries = getProperties().getProperty( QUERIES_TAG );
+ if( queries != null ){
+ for( String query: queries ){
+ ruleset.addQueries( query );
+ }
+ }
+
+ for( Code code: ActionType.ATTRIBUTE_CODE_SET ){
+ List<String> values = getProperties().getProperty( code.getColHeader() );
+ if( values != null ){
+ if( values.size() > 1 ){
+ List<String> cells = getProperties().getPropertyCells( code.getColHeader() );
+ throw new DecisionTableParseException( "Multiple values for " + code.getColHeader() +
+ " in cells " + cells.toString() );
+ }
+ String value = values.get( 0 );
+ switch( code ){
+ case SALIENCE:
+ try {
+ ruleset.setSalience( new Integer( value ) );
+ } catch( NumberFormatException nfe ){
+ throw new DecisionTableParseException( "Priority is not an integer literal, in cell " +
+ getProperties().getSinglePropertyCell( code.getColHeader() ) );
+ }
+ break;
+ case DURATION:
+ try {
+ ruleset.setDuration( new Long( value ) );
+ } catch( NumberFormatException nfe ){
+ throw new DecisionTableParseException( "Duration is not an integer literal, in cell " +
+ getProperties().getSinglePropertyCell( code.getColHeader() ) );
+ }
+ break;
+ case NOLOOP:
+ ruleset.setNoLoop( RuleSheetParserUtil.isStringMeaningTrue( value ) );
+ break;
+ case LOCKONACTIVE:
+ ruleset.setLockOnActive( RuleSheetParserUtil.isStringMeaningTrue( value ) );
+ break;
+ case AUTOFOCUS:
+ ruleset.setAutoFocus( RuleSheetParserUtil.isStringMeaningTrue( value ) );
+ break;
+ case ACTIVATIONGROUP:
+ ruleset.setActivationGroup( value );
+ break;
+ case AGENDAGROUP:
+ ruleset.setAgendaGroup( value );
+ break;
+ case RULEFLOWGROUP:
+ ruleset.setRuleFlowGroup( value );
+ break;
+ }
+ }
+ }
+
+ 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._propertiesListener.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<SourceBuilder> iter = sourceBuilders.iterator(); iter.hasNext(); ) {
+ SourceBuilder src = iter.next();
+ if ( src.hasValues() ) {
+ switch( src.getActionTypeCode() ){
+ case CONDITION:
+ Condition cond = new Condition();
+ cond.setSnippet( src.getResult() );
+ _currentRule.addCondition( cond );
+ break;
+ case ACTION:
+ Consequence cons = new Consequence();
+ cons.setSnippet( src.getResult() );
+ _currentRule.addConsequence( cons );
+ break;
+ case METADATA:
+ _currentRule.addMetadata( src.getResult() );
+ break;
+ }
+ 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<Integer, ActionType>();
+ this.sourceBuilders = new ArrayList<SourceBuilder>();
+ this._ruleStartColumn = column;
+ this._ruleStartRow = row;
+ this._ruleRow = row + 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();
+
+ String headCell = RuleSheetParserUtil.rc2name( this._ruleStartRow, this._ruleStartColumn );
+ String ruleCell = RuleSheetParserUtil.rc2name( this._ruleRow, this._ruleStartColumn );
+ this._currentRule = createNewRuleForRow( this._ruleRow, headCell, ruleCell );
+
+ 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().getSingleProperty( SEQUENTIAL_FLAG, "false" );
+ 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) {
+ String testVal = value.trim().toLowerCase();
+ if ( testVal.startsWith( RULE_TABLE_TAG ) ) {
+ initRuleTable( row, column, value.trim() );
+ } else {
+ this._propertiesListener.newCell( row, column, value, RuleSheetListener.NON_MERGED );
+ }
+ }
+
+ private void processRuleCell(final int row,
+ final int column,
+ final String value,
+ final int mergedColStart) {
+ String trimVal = value.trim();
+ String testVal = trimVal.toLowerCase();
+ if ( testVal.startsWith( RULE_TABLE_TAG ) ) {
+ finishRuleTable();
+ initRuleTable( row, column, trimVal );
+ return;
+ }
+
+ // Ignore any comments cells preceding 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, trimVal, column, row );
+ break;
+
+ case OBJECT_TYPE_ROW :
+ objectTypeRow( row, column, trimVal, mergedColStart );
+ break;
+
+ case CODE_ROW :
+ codeRow( row, column, trimVal );
+ break;
+
+ case LABEL_ROW :
+ labelRow( row, column, trimVal );
+ break;
+
+ default :
+ nextDataCell( row, column, trimVal );
+ 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 object declarations." + " Please insert an additional row before the snippets, " +
+ "at cell " + RuleSheetParserUtil.rc2name( row, column ) );
+ }
+ ActionType action = getActionForColumn( row, column );
+ if ( mergedColStart == RuleSheetListener.NON_MERGED ) {
+ if ( action.getCode() == Code.CONDITION ) {
+ SourceBuilder src = new LhsBuilder( row-1, column, value );
+ action.setSourceBuilder( src );
+ this.sourceBuilders.add( src );
+
+ } else if ( action.getCode() == Code.ACTION ) {
+ SourceBuilder src = new RhsBuilder( Code.ACTION, row-1, column, value );
+ action.setSourceBuilder( src );
+ this.sourceBuilders.add( src );
+ }
+ } else {
+ if ( column == mergedColStart ) {
+ if ( action.getCode() == Code.CONDITION ) {
+ action.setSourceBuilder( new LhsBuilder( row-1, column, value ) );
+ this.sourceBuilders.add( action.getSourceBuilder() );
+ } else if ( action.getCode() == Code.ACTION ) {
+ action.setSourceBuilder( new RhsBuilder( Code.ACTION, row-1, column, 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.getCode() == Code.CONDITION ) {
+ actionType.setSourceBuilder( new LhsBuilder( row-2, column, null ) );
+ this.sourceBuilders.add( actionType.getSourceBuilder() );
+ } else if ( actionType.getCode() == Code.ACTION ) {
+ actionType.setSourceBuilder( new RhsBuilder( Code.ACTION, row-2, column, null ) );
+ this.sourceBuilders.add( actionType.getSourceBuilder() );
+ } else if ( actionType.getCode() == Code.SALIENCE ) {
+ actionType.setSourceBuilder( new LhsBuilder( row-2, column, null ) );
+ this.sourceBuilders.add( actionType.getSourceBuilder() );
+ } else if ( actionType.getCode() == Code.METADATA ) {
+ actionType.setSourceBuilder( new RhsBuilder( Code.METADATA, row-2, column, null ) );
+ this.sourceBuilders.add( actionType.getSourceBuilder() );
+ }
+ }
+
+ if ( value.trim().equals( "" ) &&
+ (actionType.getCode() == Code.ACTION ||
+ actionType.getCode() == Code.CONDITION ||
+ actionType.getCode() == Code.METADATA) ) {
+ throw new DecisionTableParseException( "Code description in cell " +
+ RuleSheetParserUtil.rc2name( row, column ) +
+ " does not contain any code specification. It should!" );
+ }
+
+ actionType.addTemplate( row, 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.getCode() == Code.ACTION ||
+ actionType.getCode() == Code.CONDITION) ) {
+ this._cellComments.put( new Integer( column ), value );
+ } else {
+ this._cellComments.put( new Integer( column ),
+ "From cell: " + RuleSheetParserUtil.rc2name( row, column ) );
+ }
+ }
+
+ private ActionType getActionForColumn(final int row,
+ final int column) {
+ final ActionType actionType = this._actions.get( new Integer( column ) );
+
+ if ( actionType == null ) {
+ throw new DecisionTableParseException( "Code description in cell " +
+ RuleSheetParserUtil.rc2name( row, column ) +
+ " 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
+ String headCell = RuleSheetParserUtil.rc2name( this._ruleStartRow, this._ruleStartColumn );
+ String ruleCell = RuleSheetParserUtil.rc2name( row, this._ruleStartColumn );
+ this._currentRule = createNewRuleForRow( row, headCell, ruleCell );
+ this._ruleList.add( this._currentRule );
+ this._ruleRow++;
+ }
+
+ switch( actionType.getCode() ){
+ case CONDITION:
+ case ACTION:
+ case METADATA:
+ actionType.addCellValue( row, column, value );
+ break;
+ case SALIENCE:
+ // Only if rule set is not sequential!
+ if( ! this._currentSequentialFlag ){
+ if( value.startsWith( "(" ) && value.endsWith( ")" ) ){
+ this._currentRule.setSalience( value );
+ } else {
+ try {
+ this._currentRule.setSalience( new Integer( value ) );
+ } catch( NumberFormatException nfe ){
+ throw new DecisionTableParseException( "Priority is not an integer literal, in cell " +
+ RuleSheetParserUtil.rc2name( row, column ) );
+ }
+ }
+ }
+ break;
+ case NAME:
+ this._currentRule.setName( value );
+ break;
+ case DESCRIPTION:
+ this._currentRule.setDescription( value );
+ break;
+ case ACTIVATIONGROUP:
+ this._currentRule.setActivationGroup( value );
+ break;
+ case AGENDAGROUP:
+ this._currentRule.setAgendaGroup( value );
+ break;
+ case RULEFLOWGROUP:
+ this._currentRule.setRuleFlowGroup( value );
+ break;
+ case NOLOOP:
+ this._currentRule.setNoLoop( RuleSheetParserUtil.isStringMeaningTrue( value ) );
+ break;
+ case LOCKONACTIVE:
+ this._currentRule.setLockOnActive( RuleSheetParserUtil.isStringMeaningTrue( value ) );
+ break;
+ case AUTOFOCUS:
+ this._currentRule.setLockOnActive( RuleSheetParserUtil.isStringMeaningTrue( value ) );
+ break;
+ case DURATION:
+ try {
+ this._currentRule.setDuration( new Long( value ) );
+ } catch( NumberFormatException nfe ){
+ throw new DecisionTableParseException( "Duration is not an integer literal, in cell " +
+ RuleSheetParserUtil.rc2name( row, column ) );
+ }
+ break;
+ }
+ }
+
+ private Rule createNewRuleForRow(final int row, final String headCell, final String ruleCell ) {
+ 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( " rule values at " + ruleCell + ", header at " + headCell );
+
+ return rule;
+ }
+
+ private boolean isCellValueEmpty(final String value) {
+ return value == null || "".equals( value.trim() );
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/LhsBuilder.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/LhsBuilder.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/LhsBuilder.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,219 @@
+package org.drools.decisiontable.parser;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.drools.template.model.SnippetBuilder;
+import org.drools.template.parser.DecisionTableParseException;
+
+/**
+ * This utility will build up a list of constraints for a column.
+ * For instance, the column has been spanned across multiple cells, and the cells below
+ * contain the constraints.
+ * @author Michael Neale
+ *
+ */
+public class LhsBuilder implements SourceBuilder {
+
+ private int headerRow;
+ private int headerCol;
+ private String colDefPrefix;
+ private String colDefSuffix;
+ private boolean multiple;
+ private String andop;
+ private Map<Integer, String> constraints;
+ private List<String> values;
+ private boolean hasValues;
+ private static Set<String> operators;
+
+ static {
+ operators = new HashSet<String>();
+ operators.add( "==" );
+ operators.add( "=" );
+ operators.add( "!=" );
+ operators.add( "<" );
+ operators.add( ">" );
+ operators.add( "<=" );
+ operators.add( ">=" );
+ operators.add( "contains" );
+ operators.add( "matches" );
+ operators.add( "memberOf" );
+ operators.add( "str[startsWith]" );
+ operators.add( "str[endsWith]" );
+ operators.add( "str[length]" );
+ }
+
+ private static final Pattern patParFrm = Pattern.compile( "\\(\\s*\\)\\s*from\\b" );
+ private static final Pattern patFrm = Pattern.compile( "\\s+from\\s+" );
+ private static final Pattern patPar = Pattern.compile( "\\(\\s*\\)" );
+ private static final Pattern patEval = Pattern.compile( "\\beval\\s*(?:\\(\\s*\\)\\s*)?$" );
+
+
+ /**
+ * @param colDefinition The initial column definition that is shared via merged cells.
+ */
+ public LhsBuilder( int row, int column, String colDefinition ) {
+ this.headerRow = row;
+ this.headerCol = column;
+ this.constraints = new HashMap<Integer, String>();
+ this.values = new ArrayList<String>();
+
+ String colDef = colDefinition == null ? "" : colDefinition;
+ if( "".equals( colDef ) ){
+ colDefPrefix = colDefSuffix = "";
+ multiple = false;
+ andop = "";
+ return;
+ }
+ multiple = true;
+
+ // ...eval
+ Matcher matEval = patEval.matcher( colDef );
+ if( matEval.find() ){
+ colDefPrefix = colDef.substring( 0, matEval.start() ) + "eval(";
+ colDefSuffix = ")";
+ andop = " && ";
+ return;
+ }
+ andop = ", ";
+
+ // ...(<b> ) from...
+ Matcher matParFrm = patParFrm.matcher( colDef );
+ if( matParFrm.find() ){
+ colDefPrefix = colDef.substring( 0, matParFrm.start() ) + '(';
+ colDefSuffix = ") from" + colDef.substring( matParFrm.end() );
+ return;
+ }
+
+ // ...from...
+ Matcher matFrm = patFrm.matcher( colDef );
+ if( matFrm.find() ){
+ colDefPrefix = colDef.substring( 0, matFrm.start() ) + "(";
+ colDefSuffix = ") from " + colDef.substring( matFrm.end() );
+ return;
+ }
+
+ // ...(<b> )...
+ Matcher matPar = patPar.matcher( colDef );
+ if( matPar.find() ){
+ colDefPrefix = colDef.substring( 0, matPar.start() ) + '(';
+ colDefSuffix = ")" + colDef.substring( matPar.end() );
+ return;
+ }
+
+ // <a>
+ colDefPrefix = colDef + '(';
+ colDefSuffix = ")";
+ }
+
+ public ActionType.Code getActionTypeCode(){
+ return ActionType.Code.CONDITION;
+ }
+
+ public void addTemplate(int row, int column, String content) {
+ Integer key = new Integer( column );
+ content = content.trim();
+ if ( constraints.containsKey( key ) ) {
+ throw new IllegalArgumentException( "Internal error: Can't have a constraint added twice to one spreadsheet col." );
+ }
+
+ //we can wrap all values in quotes, it all works
+ FieldType fieldType = calcFieldType( content );
+ if (fieldType == FieldType.NORMAL_FIELD || ! isMultipleConstraints()) {
+ constraints.put( key, content );
+ } else if (fieldType == FieldType.SINGLE_FIELD) {
+ constraints.put( key, content + " == \"" + SnippetBuilder.PARAM_STRING + "\"" );
+ } else if (fieldType == FieldType.OPERATOR_FIELD) {
+ constraints.put( key, content + " \"" + SnippetBuilder.PARAM_STRING + "\"" );
+ }
+ }
+
+ public void clearValues() {
+ this.hasValues = false;
+ this.values.clear();
+ }
+
+ public void addCellValue(int row, int column, String value) {
+ this.hasValues = true;
+ Integer key = new Integer( column );
+ String content = (String) this.constraints.get( key );
+ if( content == null ){
+ throw new DecisionTableParseException( "No code snippet for CONDITION in cell " +
+ RuleSheetParserUtil.rc2name( this.headerRow + 2, this.headerCol ) );
+ }
+ SnippetBuilder snip = new SnippetBuilder( content );
+ String result = snip.build( value );
+ this.values.add( result );
+ }
+
+ public String getResult() {
+ StringBuffer buf = new StringBuffer();
+ if ( ! isMultipleConstraints() ) {
+ String nl = "";
+ for( String content: values ){
+ buf.append( nl ).append( content );
+ nl = "\n";
+ }
+ return buf.toString();
+ } else {
+ buf.append( this.colDefPrefix );
+ String sep = "";
+ for( String constraint: values ) {
+ buf.append( sep ).append( constraint );
+ sep = this.andop;
+ }
+ buf.append( colDefSuffix );
+ return buf.toString();
+ }
+ }
+
+ /** Returns true if this is building up multiple constraints as in:
+ * Foo(a ==b, c == d) etc...
+ * If not, then it it really just like the "classic" style DTs.
+ */
+ boolean isMultipleConstraints() {
+ return multiple;
+ }
+
+ /**
+ * Work out the type of "field" that is being specified,
+ * as in :
+ * age
+ * age <
+ * age == $param
+ * age == $1 || age == $2
+ * forall{age < $}{,}
+ *
+ * etc. as we treat them all differently.
+ */
+ public FieldType calcFieldType(String content) {
+ if (!SnippetBuilder.getType(content).equals(
+ SnippetBuilder.SnippetType.SINGLE)) {
+ return FieldType.NORMAL_FIELD;
+ }
+ for ( String op : operators ) {
+ if (content.endsWith( op )) {
+ return FieldType.OPERATOR_FIELD;
+ }
+ }
+ return FieldType.SINGLE_FIELD;
+ }
+
+ static class FieldType {
+ public static final FieldType SINGLE_FIELD = new FieldType();
+ public static final FieldType OPERATOR_FIELD = new FieldType();
+ public static final FieldType NORMAL_FIELD = new FieldType();
+ }
+
+ public boolean hasValues() {
+ return hasValues;
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RhsBuilder.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RhsBuilder.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RhsBuilder.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,92 @@
+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 org.drools.template.model.SnippetBuilder;
+import org.drools.template.parser.DecisionTableParseException;
+
+/**
+ * Builds up a consequence entry.
+ * @author Michael Neale
+ *
+ */
+public class RhsBuilder implements SourceBuilder {
+
+ private int headerRow;
+ private int headerCol;
+ private ActionType.Code actionTypeCode;
+ private Map<Integer, String> templates;
+ private String variable;
+ private List<String> values;
+ private boolean hasValues;
+
+ /**
+ * @param boundVariable Pass in a bound variable if there is one.
+ * Any cells below then will be called as methods on it.
+ * Leaving it blank will make it work in "classic" mode.
+ */
+ public RhsBuilder( ActionType.Code code, int row, int column, String boundVariable ) {
+ this.actionTypeCode = code;
+ this.headerRow = row;
+ this.headerCol = column;
+ this.variable = boundVariable == null ? "" : boundVariable.trim();
+ this.templates = new HashMap<Integer, String>();
+ this.values = new ArrayList<String>();
+ }
+
+
+ public ActionType.Code getActionTypeCode(){
+ return this.actionTypeCode;
+ }
+
+
+ public void addTemplate(int row, int column, String content) {
+ Integer key = new Integer( column );
+ content = content.trim();
+ if ( isBoundVar() ) {
+ content = variable + "." + content + ";";
+ }
+ this.templates.put( key, content );
+ }
+
+ private boolean isBoundVar() {
+ return !("".equals( variable ));
+ }
+
+ public void addCellValue(int row, int column, String value) {
+ hasValues = true;
+ String template = (String) this.templates.get( new Integer( column ) );
+ if( template == null ){
+ throw new DecisionTableParseException( "No code snippet for " +
+ this.actionTypeCode + ", above cell " +
+ RuleSheetParserUtil.rc2name( this.headerRow + 2, this.headerCol ) );
+ }
+ SnippetBuilder snip = new SnippetBuilder(template);
+ this.values.add(snip.build( value ));
+ }
+
+ public void clearValues() {
+ this.hasValues = false;
+ this.values.clear();
+ }
+
+ public String getResult() {
+ StringBuffer buf = new StringBuffer();
+ for ( Iterator<String> iter = this.values.iterator(); iter.hasNext(); ) {
+ buf.append( iter.next() );
+ if (iter.hasNext()) {
+ buf.append( '\n' );
+ }
+ }
+ return buf.toString();
+ }
+
+ public boolean hasValues() {
+ return hasValues;
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleMatrixSheetListener.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleMatrixSheetListener.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleMatrixSheetListener.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.core.util.StringUtils;
+import org.drools.decisiontable.parser.DefaultRuleSheetListener;
+import org.drools.template.model.Condition;
+import org.drools.template.model.Consequence;
+import org.drools.template.model.Rule;
+import org.drools.template.model.SnippetBuilder;
+
+/**
+ * @author <a href="mailto:stevearoonie at gmail.com"> Steven Williams </a><a
+ * href="mailto:michael.neale at gmail.com"> Michael Neale </a>
+ *
+ * Define a ruleset spreadsheet which contains a matrix style decision tables.
+ *
+ * This is an example of a custom RuleSheetListener. It differs from the standard
+ * decision table in the following ways:
+ * - AgendaGroup property so that all rules fall within the same agenda-group
+ * - Precondition property which specifies a condition that is always included
+ * if a rule is being generated
+ * - Action property. Each cell within the decision table causes this action
+ * to be triggered
+ * - HorizontalCondition property. Each column header in the matrix
+ * applies this condition
+ * - VerticalCondition property. Each row header in the matrix applies this
+ * condition
+ *
+ * A table is identifed by a cell beginning with the text "RuleTable".
+ * The cells after RuleTable in the same row identify the Horizontal Conditions.
+ * The cells after RuleTable in the same column identify the Vertical Conditions.
+ * The cells with the matrix identify the actions.
+ * Wherever an action cell exists for a Vertical/Horizontal condition intersection
+ * the following rule is created:
+ * rule "rule_row_col"
+ * agenda-group AgendaGroup
+ * when
+ * Precondition
+ * VerticalCondition
+ * HorizontalCondition
+ * then
+ * Action
+ * end
+ */
+public class RuleMatrixSheetListener extends DefaultRuleSheetListener {
+
+ //keywords
+ public static final String AGENDAGROUP_TAG = "AgendaGroup";
+ public static final String PRECONDITION_TAG = "Precondition";
+ public static final String ACTION_TAG = "Action";
+ public static final String HORIZONTALCONDITION_TAG = "HorizontalCondition";
+ public static final String VERTICALCONDITION_TAG = "VerticalCondition";
+
+ //state machine variables for this parser
+ private int ruleTableRow;
+ private int ruleTableColumn;
+ private String _currentAgendaGroup;
+ private Condition _currentPrecondition;
+ private String _action;
+ private String _horizontalCondition;
+ private String _verticalCondition;
+ private List<Condition> _horizontalConditions = new ArrayList<Condition>();
+ private Condition _currentVerticalCondition;
+ private boolean isInRuleTable;
+ private Rule firstRule;
+
+ public void newCell(final int row,
+ final int column,
+ final String value,
+ final int mergedColStart) {
+ // if we aren't in the rule table just use the default handling
+ // (add a property)
+ if ( ! isInRuleTable ) {
+ super.newCell( row, column, value, mergedColStart );
+ return;
+ }
+ // ignore empty cells
+ if ( StringUtils.isEmpty( value ) ) {
+ return;
+ }
+
+ //Horizontal header column
+ //Create a new condition using HorizontalCondition as the template
+ //and save it for later use
+ if ( row == (ruleTableRow) && column > ruleTableColumn ) {
+ _horizontalConditions.add( createCondition( value, _horizontalCondition ) );
+ }
+ //Vertical header column
+ //Create a new condition using VerticalCondition as the template
+ //and set it as the current condition
+ else if ( row > (ruleTableRow) && column == ruleTableColumn ) {
+ _currentVerticalCondition = createCondition( value, _verticalCondition );
+ }
+ //Intersection column
+ //Create a new Consequence
+ else if ( row > (ruleTableRow) && column > ruleTableColumn ) {
+ createRule( row, column, value );
+ }
+ }
+
+ private void createRule(final int row,
+ final int column,
+ final String value) {
+ final Consequence consequence = createConsequence( value );
+
+ Rule rule = firstRule;
+ if ( rule == null ) {
+ rule = new Rule( "rule_" + row + "_" + column,
+ null,
+ row );
+ addRule( rule );
+ } else {
+ firstRule = null;
+ rule.setName( "rule_" + row + "_" + column );
+ }
+ rule.setAgendaGroup( this._currentAgendaGroup );
+ rule.addCondition( this._currentPrecondition );
+ rule.addCondition( _currentVerticalCondition );
+ rule.addCondition( (Condition) _horizontalConditions.get( column - (ruleTableColumn + 1) ) );
+ rule.addConsequence( consequence );
+ }
+
+ private Consequence createConsequence(final String value) {
+ final SnippetBuilder snip = new SnippetBuilder( _action );
+ final String result = snip.build( value );
+ final Consequence consequence = new Consequence();
+ consequence.setSnippet( result );
+ return consequence;
+ }
+
+ private Condition createCondition(final String value,
+ final String conditionTemplate) {
+ SnippetBuilder snip = new SnippetBuilder( conditionTemplate );
+ String result = snip.build( value );
+ Condition condition = new Condition();
+ condition.setSnippet( result );
+ return condition;
+ }
+
+ public void newRow(int rowNumber,
+ int columns) {
+ // nothing to do here
+ }
+
+ public void finishSheet() {
+ // nothing to do here
+ }
+
+ protected void postInitRuleTable(int row,
+ int column,
+ String value) {
+ this.firstRule = getCurrentRule();
+ }
+
+ /**
+ * This gets called each time a "new" rule table is found.
+ */
+ protected void preInitRuleTable(final int row,
+ final int column,
+ final String value) {
+ this.ruleTableColumn = column;
+ this.ruleTableRow = row;
+ this.isInRuleTable = true;
+ this._currentAgendaGroup = getProperties().getSingleProperty( AGENDAGROUP_TAG );
+ this._action = getProperties().getSingleProperty( ACTION_TAG );
+ this._horizontalCondition = getProperties().getSingleProperty( HORIZONTALCONDITION_TAG );
+ this._verticalCondition = getProperties().getSingleProperty( VERTICALCONDITION_TAG );
+ String precondition = getProperties().getSingleProperty( PRECONDITION_TAG );
+ if ( precondition != null ) {
+ this._currentPrecondition = new Condition();
+ this._currentPrecondition.setSnippet( precondition );
+ }
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetListener.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetListener.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetListener.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser;
+
+import java.util.Properties;
+
+import org.drools.decisiontable.parser.xls.PropertiesSheetListener.CaseInsensitiveMap;
+import org.drools.template.model.Package;
+import org.drools.template.parser.DataListener;
+
+/**
+ * @author <a href="mailto:stevearoonie at gmail.com"> Steven Williams</a>
+ *
+ * SheetListener used for creating rules
+ */
+public interface RuleSheetListener extends DataListener {
+
+ /**
+ * Return the rule sheet properties
+ */
+ public abstract CaseInsensitiveMap getProperties();
+
+ /**
+ * Build the final ruleset as parsed.
+ */
+ public abstract Package getRuleSet();
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetParserUtil.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetParserUtil.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/RuleSheetParserUtil.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.drools.template.model.Global;
+import org.drools.template.model.Import;
+import org.drools.template.parser.DecisionTableParseException;
+
+/**
+ * @author <a href="mailto:michael.neale at gmail.com"> Michael Neale </a>
+ *
+ * Parking lot for utility methods that don't belong anywhere else.
+ */
+public class RuleSheetParserUtil {
+
+ private RuleSheetParserUtil() {
+ // strictly util
+ }
+
+ public static String getRuleName(final String ruleRow) {
+ String testVal = ruleRow.toLowerCase();
+ final int left = testVal.indexOf( DefaultRuleSheetListener.RULE_TABLE_TAG );
+ return ruleRow.substring( left + DefaultRuleSheetListener.RULE_TABLE_TAG.length() ).trim();
+ }
+
+ private static void invalidRuleTableDef(final String ruleRow) {
+ throw new IllegalArgumentException( "Invalid rule table header cell. Should be in the format of 'RuleTable YourRuleName'. " + "It was: \n [" + ruleRow + "] \n" );
+ }
+
+ /**
+ * Create a list of Import model objects from cell contents.
+ * @param importCells The cells containing text for all the classes to import.
+ * @return A list of Import classes, which can be added to the ruleset.
+ */
+ public static List<Import> getImportList(final List<String> importCells) {
+ final List<Import> importList = new ArrayList<Import>();
+ if ( importCells == null ) return importList;
+
+ for( String importCell: importCells ){
+ final StringTokenizer tokens = new StringTokenizer( importCell, "," );
+ while ( tokens.hasMoreTokens() ) {
+ final Import imp = new Import();
+ imp.setClassName( tokens.nextToken().trim() );
+ importList.add( imp );
+ }
+ }
+ return importList;
+ }
+
+ /**
+ * Create a list of Global model objects from cell contents.
+ * @param variableCella The cells containing text for all the global variables to set.
+ * @return A list of Variable classes, which can be added to the ruleset.
+ */
+ public static List<Global> getVariableList( final List<String> variableCells ){
+ final List<Global> variableList = new ArrayList<Global>();
+ if ( variableCells == null ) return variableList;
+
+ for( String variableCell: variableCells ){
+ final StringTokenizer tokens = new StringTokenizer( variableCell, "," );
+ while ( tokens.hasMoreTokens() ) {
+ final String token = tokens.nextToken();
+ final Global vars = new Global();
+ final StringTokenizer paramTokens = new StringTokenizer( token, " " );
+ vars.setClassName( paramTokens.nextToken() );
+ if ( !paramTokens.hasMoreTokens() ) {
+ throw new DecisionTableParseException( "The format for global variables is incorrect. " + "It should be: [Class name, Class otherName]. But it was: [" + variableCell + "]" );
+ }
+ vars.setIdentifier( paramTokens.nextToken() );
+ variableList.add( vars );
+ }
+ }
+ return variableList;
+ }
+
+ /**
+ * @return true is the String could possibly mean true. False otherwise !
+ */
+ public static boolean isStringMeaningTrue(String property) {
+ if ( property == null ) {
+ return false;
+ } else {
+ property = property.trim();
+ if ( property.equalsIgnoreCase( "true" ) ) {
+ return true;
+ } else if ( property.startsWith( "Y" ) ) {
+ return true;
+ } else if ( property.startsWith( "y" ) ) {
+ return true;
+ } else if ( property.equalsIgnoreCase( "on" ) ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Convert spreadsheet row, column numbers to a cell name.
+ * @param row row number
+ * @param col the column number. Start with zero.
+ * @return The spreadsheet name for this cell, "A" to "ZZZ".
+ */
+ public static String rc2name( int row, int col ){
+ StringBuilder sb = new StringBuilder();
+ int b = 26;
+ int p = 1;
+ if( col >= b ){
+ col -= b;
+ p *= b;
+ }
+ if( col >= b*b ){
+ col -= b*b;
+ p *= b;
+ }
+ while( p > 0 ){
+ sb.append( (char)(col/p + (int)'A') );
+ col %= p;
+ p /= b;
+ }
+ sb.append( row + 1 );
+ return sb.toString();
+ }
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/SourceBuilder.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/SourceBuilder.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/SourceBuilder.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,14 @@
+package org.drools.decisiontable.parser;
+
+/**
+ * This is for building up LHS and RHS code for a rule row.
+ * @author Michael Neale
+ */
+public interface SourceBuilder {
+ ActionType.Code getActionTypeCode();
+ String getResult();
+ void addTemplate(int row, int col, String content);
+ void addCellValue(int row, int col, String value);
+ void clearValues();
+ boolean hasValues();
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/csv/CsvLineParser.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/csv/CsvLineParser.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/csv/CsvLineParser.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser.csv;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author <a href="mailto:michael.neale at gmail.com"> Michael Neale</a> Break up
+ * a CSV line, with all the normal CSV features.
+ */
+public class CsvLineParser {
+ private ICsvParser lineParser;
+
+ public CsvLineParser() {
+ this.lineParser = new CsvParserImpl();
+ }
+
+ /**
+ * Use the current lineParser implementation to return a CSV line as a List
+ * of cells. (Strings).
+ */
+ public List<String> parse(final CharSequence line) {
+ return this.lineParser.parse( line.toString() );
+ }
+
+ /**
+ * This is insurance incase I need to replace it with more complex Csv
+ * handlers in the future.
+ */
+ static interface ICsvParser {
+ public List<String> parse(String line);
+ }
+
+ /**
+ * Parse comma-separated values (CSV), a common Windows file format. Sample
+ * input: "LU",86.25,"11/4/1998","2:19PM",+4.0625
+ * <p>
+ * Inner logic adapted from a C++ original that was Copyright (C) 1999
+ * Lucent Technologies Excerpted from 'The Practice of Programming' by Brian
+ * W. Kernighan and Rob Pike.
+ * <p>
+ * Included by permission of the http://tpop.awl.com/ web site, which says:
+ * "You may use this code for any purpose, as long as you leave the
+ * copyright notice and book citation attached." I have done so.
+ *
+ * @author Brian W. Kernighan and Rob Pike (C++ original)
+ * @author Ian F. Darwin (translation into Java and removal of I/O)
+ * @author Ben Ballard (rewrote advQuoted to handle '""' and for
+ * readability)
+ */
+ static class CsvParserImpl
+ implements
+ ICsvParser {
+
+ public static final char DEFAULT_SEP = ',';
+
+ /** Construct a CSV parser, with the default separator (','). */
+ public CsvParserImpl() {
+ this( CsvParserImpl.DEFAULT_SEP );
+ }
+
+ /**
+ * Construct a CSV parser with a given separator.
+ *
+ * @param sep
+ * The single char for the separator (not a list of separator
+ * characters)
+ */
+ public CsvParserImpl(final char sep) {
+ this.fieldSep = sep;
+ }
+
+ /** The fields in the current String */
+ protected List<String> list = new ArrayList<String>();
+
+ /** the separator char for this parser */
+ protected char fieldSep;
+
+ /**
+ * parse: break the input String into fields
+ *
+ * @return java.util.Iterator containing each field from the original as
+ * a String, in order.
+ */
+ public List<String> parse(final String line) {
+ final StringBuffer sb = new StringBuffer();
+ this.list.clear(); // recycle to initial state
+ int i = 0;
+
+ if ( line.length() == 0 ) {
+ this.list.add( line );
+ return this.list;
+ }
+
+ do {
+ sb.setLength( 0 );
+ if ( i < line.length() && line.charAt( i ) == '"' ) {
+ i = advQuoted( line,
+ sb,
+ ++i ); // skip
+ } else {
+ i = advPlain( line,
+ sb,
+ i );
+ }
+ this.list.add( sb.toString() );
+ i++;
+ } while ( i < line.length() );
+
+ return this.list;
+ }
+
+ /** advQuoted: quoted field; return index of next separator */
+ protected int advQuoted(final String s,
+ final StringBuffer sb,
+ final int i) {
+ int j;
+ final int len = s.length();
+ for ( j = i; j < len; j++ ) {
+ if ( s.charAt( j ) == '"' && j + 1 < len ) {
+ if ( s.charAt( j + 1 ) == '"' ) {
+ j++; // skip escape char
+ } else if ( s.charAt( j + 1 ) == this.fieldSep ) { // next delimeter
+ j++; // skip end quotes
+ break;
+ }
+ } else if ( s.charAt( j ) == '"' && j + 1 == len ) { // end quotes at end of line
+ break; // done
+ }
+ sb.append( s.charAt( j ) ); // regular character.
+ }
+ return j;
+ }
+
+ /** advPlain: unquoted field; return index of next separator */
+ protected int advPlain(final String s,
+ final StringBuffer sb,
+ final int i) {
+ int j;
+
+ j = s.indexOf( this.fieldSep,
+ i ); // look for separator
+ if ( j == -1 ) { // none found
+ sb.append( s.substring( i ) );
+ return s.length();
+ } else {
+ sb.append( s.substring( i,
+ j ) );
+ return j;
+ }
+ }
+
+ }
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/csv/CsvParser.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/csv/CsvParser.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/csv/CsvParser.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser.csv;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.decisiontable.parser.DecisionTableParser;
+import org.drools.template.parser.DataListener;
+import org.drools.template.parser.DecisionTableParseException;
+
+/**
+ * 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.
+ *
+ *
+ *
+ * @author <a href="mailto:michael.neale at gmail.com"> Michael Neale</a>
+ */
+public class CsvParser implements DecisionTableParser {
+
+ private List<DataListener> _listeners;
+
+ private CsvLineParser _lineParser;
+
+ public CsvParser(final DataListener listener,
+ final CsvLineParser lineParser) {
+ _listeners = new ArrayList<DataListener>();
+ _listeners.add(listener);
+ this._lineParser = lineParser;
+ }
+
+ public CsvParser(final List<DataListener> listeners, final CsvLineParser lineParser) {
+ this._listeners = listeners;
+ this._lineParser = lineParser;
+ }
+
+ 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);
+ }
+ }
+
+ private void startSheet() {
+ for ( DataListener listener : _listeners ) {
+ listener.startSheet("csv");
+ }
+ }
+
+ private void finishSheet() {
+ for ( DataListener listener : _listeners ) {
+ listener.finishSheet();
+ }
+ }
+
+ private void newRow(final int row, final int numCells) {
+ for ( DataListener listener : _listeners ) {
+ listener.newRow(row, numCells);
+ }
+ }
+
+ private void newCell(final int row, final int column, final String value,
+ final int mergedColStart) {
+ for ( DataListener listener : _listeners ) {
+ listener.newCell(row, column, value, mergedColStart);
+ }
+ }
+
+ private void processRows(final BufferedReader reader) throws IOException {
+ String line = reader.readLine();
+
+ int row = 0;
+ while (line != null) {
+
+ final List<String> cells = this._lineParser.parse(line);
+ // remove the trailing empty "cells" which some tools smatter around
+ // trimCells(cells);
+ newRow(row, cells.size());
+
+ int startMergeCol = DataListener.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 != DataListener.NON_MERGED) {
+ cell = cell.substring(0, cell.length() - 3);
+ }
+ return cell;
+ }
+
+ int calcStartMerge(int startMergeCol, int col, String cell) {
+ if (cell.endsWith("...") && startMergeCol == DataListener.NON_MERGED) {
+ startMergeCol = col;
+ } else if (!cell.endsWith("...")) {
+ startMergeCol = DataListener.NON_MERGED;
+ }
+ return startMergeCol;
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/ExcelParser.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/ExcelParser.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/ExcelParser.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser.xls;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import jxl.Cell;
+import jxl.Range;
+import jxl.Sheet;
+import jxl.Workbook;
+import jxl.read.biff.BiffException;
+
+import org.drools.decisiontable.parser.DecisionTableParser;
+import org.drools.template.parser.DataListener;
+import org.drools.template.parser.DecisionTableParseException;
+
+/**
+ * @author <a href="mailto:michael.neale at gmail.com"> Michael Neale </a>
+ * Parse an excel spreadsheet, pusing cell info into the SheetListener interface.
+ */
+public class ExcelParser
+ implements
+ DecisionTableParser {
+
+ public static final String DEFAULT_RULESHEET_NAME = "Decision Tables";
+ private Map<String, List<DataListener>> _listeners = new HashMap<String, List<DataListener>>();
+ private boolean _useFirstSheet;
+
+ /**
+ * Define a map of sheet name to listner handlers.
+ *
+ * @param sheetListeners
+ * map of String to SheetListener
+ */
+ public ExcelParser(final Map<String, List<DataListener>> sheetListeners) {
+ this._listeners = sheetListeners;
+ }
+
+ public ExcelParser(final List<DataListener> sheetListeners) {
+ this._listeners.put( ExcelParser.DEFAULT_RULESHEET_NAME,
+ sheetListeners );
+ this._useFirstSheet = true;
+ }
+
+ public ExcelParser(final DataListener listener) {
+ List<DataListener> listeners = new ArrayList<DataListener>();
+ listeners.add( listener );
+ this._listeners.put( ExcelParser.DEFAULT_RULESHEET_NAME,
+ listeners );
+ this._useFirstSheet = true;
+ }
+
+ public void parseFile(InputStream inStream) {
+ try {
+ Workbook workbook = Workbook.getWorkbook( inStream );
+
+ if ( _useFirstSheet ) {
+ Sheet sheet = workbook.getSheet( 0 );
+ processSheet( sheet,
+ _listeners.get( DEFAULT_RULESHEET_NAME ) );
+ } else {
+ for ( String sheetName : _listeners.keySet() ) {
+ Sheet sheet = workbook.getSheet( sheetName );
+ processSheet( sheet,
+ _listeners.get( sheetName ) );
+
+ }
+ }
+ } catch ( BiffException e ) {
+ throw new DecisionTableParseException( "An error occured opening the workbook. It is possible that the encoding of the document did not match the encoding of the reader.",
+ e );
+
+ } catch ( IOException e ) {
+ throw new DecisionTableParseException( "Failed to open Excel stream, " + "please check that the content is xls97 format.",
+ e );
+ }
+
+ }
+
+ private void processSheet(Sheet sheet,
+ List< ? extends DataListener> listeners) {
+ int maxRows = sheet.getRows();
+
+ Range[] mergedRanges = sheet.getMergedCells();
+
+ for ( int i = 0; i < maxRows; i++ ) {
+ Cell[] row = sheet.getRow( i );
+ newRow( listeners,
+ i,
+ row.length );
+ for ( int cellNum = 0; cellNum < row.length; cellNum++ ) {
+ Cell cell = row[cellNum];
+
+ Range merged = getRangeIfMerged( cell,
+ mergedRanges );
+
+ if ( merged != null ) {
+ Cell topLeft = merged.getTopLeft();
+ newCell( listeners,
+ i,
+ cellNum,
+ topLeft.getContents(),
+ topLeft.getColumn() );
+ } else {
+ newCell( listeners,
+ i,
+ cellNum,
+ cell.getContents(),
+ DataListener.NON_MERGED );
+ }
+ }
+ }
+ finishSheet( listeners );
+ }
+
+ Range getRangeIfMerged(Cell cell,
+ Range[] mergedRanges) {
+ for ( int i = 0; i < mergedRanges.length; i++ ) {
+ Range r = mergedRanges[i];
+ Cell topLeft = r.getTopLeft();
+ Cell bottomRight = r.getBottomRight();
+ if ( cell.getRow() >= topLeft.getRow() && cell.getRow() <= bottomRight.getRow() && cell.getColumn() >= topLeft.getColumn() && cell.getColumn() <= bottomRight.getColumn() ) {
+ return r;
+ }
+ }
+ return null;
+ }
+
+ static String removeTrailingZero(String stringVal) {
+ if ( stringVal.endsWith( ".0" ) ) {
+ stringVal = stringVal.substring( 0,
+ stringVal.length() - 2 );
+ }
+ return stringVal;
+ }
+
+ private void finishSheet(List< ? extends DataListener> listeners) {
+ for ( DataListener listener : listeners ) {
+ listener.finishSheet();
+ }
+ }
+
+ private void newRow(List< ? extends DataListener> listeners,
+ int row,
+ int cols) {
+ for ( DataListener listener : listeners ) {
+ listener.newRow( row,
+ cols );
+ }
+ }
+
+ public void newCell(List< ? extends DataListener> listeners,
+ int row,
+ int column,
+ String value,
+ int mergedColStart) {
+ for ( DataListener listener : listeners ) {
+ listener.newCell( row,
+ column,
+ value,
+ mergedColStart );
+ }
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/NullSheetListener.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/NullSheetListener.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/NullSheetListener.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser.xls;
+
+import org.drools.template.parser.DataListener;
+
+/**
+ * @author <a href="mailto:shaun.addison at gmail.com"> Shaun Addison </a>
+ *
+ * Null listner.
+ */
+public class NullSheetListener
+ implements
+ DataListener {
+
+ public void startSheet(final String name) {
+ }
+
+ public void finishSheet() {
+ }
+
+ public void newRow(final int rowNumber,
+ final int columns) {
+ }
+
+ public void newCell(final int row,
+ final int column,
+ final String value,
+ final int mergedColstart) {
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/PropertiesSheetListener.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/PropertiesSheetListener.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/xls/PropertiesSheetListener.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser.xls;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.decisiontable.parser.RuleSheetParserUtil;
+import org.drools.template.parser.DataListener;
+
+/**
+ * Reads an Excel sheet as key-value properties.
+ *
+ * Treats the first non-empty cell on a row as a key and any subsequent
+ * non-empty cell as a value. Any cells defined after the second cell are
+ * ignored as comments.
+ *
+ * Could be easily adapted to accept multiple values per key but the semantics
+ * were kept in line with Properties.
+ *
+ * @author <a href="mailto:shaun.addison at gmail.com"> Shaun Addison </a>
+ *
+ */
+public class PropertiesSheetListener implements DataListener {
+
+ private static final String EMPTY_STRING = "";
+
+ private final Map<Integer, String[]> _rowProperties = new HashMap<Integer, String[]>();
+
+ private final CaseInsensitiveMap _properties = new CaseInsensitiveMap();
+
+ /**
+ * Return the key value pairs. If this is called before the sheet is
+ * finished, then it will build the properties map with what is known.
+ * Subsequent calls will update the properties map.
+ *
+ * @return properties
+ */
+ public CaseInsensitiveMap getProperties() {
+ finishSheet(); // MN allows this to be called before the sheet is
+ // finished, as
+ // some properties are used whilst the sheet is being parsed.
+ return this._properties;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see my.hssf.util.SheetListener#startSheet(java.lang.String)
+ */
+ public void startSheet(final String name) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see my.hssf.util.SheetListener#finishSheet()
+ */
+ public void finishSheet() {
+ for ( String[] keyValue : _rowProperties.values() ) {
+ this._properties.addProperty( keyValue[0], new String[]{ keyValue[1], keyValue[2] } );
+ }
+ // Discard to avoid repeated addition of properties,
+ // since finishSheet may be called more than once.
+ _rowProperties.clear();
+ }
+
+ /**
+ * Enter a new row. This is ignored.
+ *
+ * @param rowNumber
+ * The row number.
+ * @param columns
+ * The Colum number.
+ */
+ public void newRow(final int rowNumber,
+ final int columns) {
+ // nothing to do.
+ }
+
+ /*
+ * (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,
+ final int mergedColStart) {
+ if ( emptyCellValue( value ) ) {
+ return;
+ }
+ final Integer rowInt = new Integer( row );
+ if ( this._rowProperties.containsKey( rowInt ) ) {
+ final String[] keyValue = (String[]) this._rowProperties.get( rowInt );
+ if ( keyValue[1] == PropertiesSheetListener.EMPTY_STRING ) {
+ keyValue[1] = value;
+ keyValue[2] = RuleSheetParserUtil.rc2name(row, column);
+ }
+ } else {
+ final String[] keyValue = {value, PropertiesSheetListener.EMPTY_STRING, RuleSheetParserUtil.rc2name(row, column+1) };
+ this._rowProperties.put( rowInt, keyValue );
+ }
+ }
+
+ private boolean emptyCellValue(final String value) {
+ return value == null || value.trim().equals( "" );
+ }
+
+ @SuppressWarnings("serial")
+ public static class CaseInsensitiveMap extends HashMap<String,List<String[]>> {
+
+ private List<String[]> getPropertyCell(String key) {
+ return super.get( key.toLowerCase() );
+ }
+
+ public void addProperty( String key, String[] value ){
+ key = key.toLowerCase();
+ List<String[]> r = getPropertyCell( key );
+ if( r == null ){
+ r = new ArrayList<String[]>();
+ }
+ r.add( value );
+ super.put( key, r );
+ }
+
+ private List<String> getList( String key, int index ) {
+ List<String[]> pcList = getPropertyCell( key );
+ if( pcList == null ) return null;
+ List<String> r = new ArrayList<String>();
+ for( String[] pc: pcList ){
+ r.add( pc[index] );
+ }
+ return r;
+ }
+
+ public List<String> getProperty(String key) {
+ return getList( key, 0 );
+ }
+
+ public List<String> getPropertyCells(String key) {
+ return getList( key, 1 );
+ }
+
+ private String getSingle( String key, int index ){
+ List<String[]> r = getPropertyCell( key );
+ if( r == null || r.size() == 0 ) return null;
+ return r.get( 0 )[index];
+ }
+
+ public String getSingleProperty( String key ){
+ return getSingle( key, 0 );
+ }
+
+ public String getSinglePropertyCell( String key ){
+ return getSingle( key, 1 );
+ }
+
+ public String getSingleProperty( String key, String defaultValue ){
+ String r = getSingleProperty( key );
+ if( r == null || r == "" ) r = defaultValue;
+ return r;
+ }
+
+ }
+}
+
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/osgi/decisiontables/Activator.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/osgi/decisiontables/Activator.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/java/org/drools/osgi/decisiontables/Activator.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,35 @@
+package org.drools.osgi.decisiontables;
+
+import java.util.Hashtable;
+
+
+//import org.drools.KnowledgeBaseFactoryService;
+//import org.drools.builder.KnowledgeBuilderFactoryService;
+//import org.drools.builder.impl.KnowledgeBuilderFactoryServiceImpl;
+//import org.drools.impl.KnowledgeBaseFactoryServiceImpl;
+//import org.drools.io.ResourceFactoryService;
+//import org.drools.io.impl.ResourceFactoryServiceImpl;
+import org.drools.Service;
+import org.drools.compiler.DecisionTableProvider;
+import org.drools.decisiontable.DecisionTableProviderImpl;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+public class Activator
+ implements
+ BundleActivator {
+ private ServiceRegistration kdtableReg;
+
+ public void start(BundleContext bc) throws Exception {
+ System.out.println( "registering decision tables drools services" );
+ this.kdtableReg = bc.registerService( new String[]{ DecisionTableProvider.class.getName(), Service.class.getName()},
+ new DecisionTableProviderImpl(),
+ new Hashtable() );
+ System.out.println( "drools decision tables services registered" );
+ }
+
+ public void stop(BundleContext bc) throws Exception {
+ this.kdtableReg.unregister();
+ }
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/org/drools/decisiontable/package.html
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/org/drools/decisiontable/package.html (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/org/drools/decisiontable/package.html 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,3 @@
+<body>
+ This it a utility for using spreadsheets to manage rules. Use SpreasheetCompiler.
+</body>
\ No newline at end of file
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/Example.xls
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/Example.xls
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/README.txt
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/README.txt (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/README.txt 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,8 @@
+-- Python decision tables --
+
+To use XLS format, the xlrd module is required to be available/installed.
+You can get this from:http://www.lexicon.net/sjmachin/xlrd.htm
+To install, you will unzip the xlrd package, and then run pythong setup.py install.
+
+Michael Neale
+www.michaelneale.net
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/pydt.py
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/pydt.py (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/pydt.py 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,95 @@
+#this is PyDT - Python Decision Tables
+# (c) 2007 Michael Neale (michael at michaelneale.net)
+# Use entirely at your own risk !
+#
+# 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.
+
+
+
+#this is the actual "engine" if you can call it that.
+def process_dt(fact, table) :
+ def make_header(hdr) :
+ splut = hdr[1].split(' ')
+ if len(splut) > 1 :
+ #if hdr[1].contains(' ') :
+ #itms = hdr[1].split(' ')
+ return [hdr[0], fact[splut[0]] + ' ' + splut[1]]
+ else :
+ return [hdr[0], fact[hdr[1]]]
+ #calc the headers
+ headers = map(make_header, table['condition_headers'])
+ #lets try a map based approach
+ def eval_table(row) :
+ #go through all the conditions, evaluating
+ def check_condition(condition) :
+ #for condition in headers :
+ col_index = condition[0]
+ if not row.has_key(col_index) :
+ return False
+ cell_value = row[col_index]
+ predicate = str(condition[1]) + str(cell_value)
+ return not eval(predicate)
+ size = len(filter(check_condition,headers))
+ if size == 0 :
+ #for action in table['action_headers'] :
+ def apply_actions(action) :
+ col_label = action[0]
+ if (row.has_key(col_label)) :
+ fact[action[1]] = row[col_label]
+ map(apply_actions, table['action_headers'])
+ map(eval_table, table['data'])
+
+
+
+
+# Load a XLS into a decision table structure for processing
+def load_xls(file_name) :
+ import xlrd
+ book = xlrd.open_workbook(file_name)
+ sh = book.sheet_by_index(0)
+ condition_headers, action_headers, data = [],[],[]
+ for rx in range(sh.nrows):
+ if rx == 0 :
+ divider = 0
+ for cx in range(sh.ncols):
+ cv = sh.cell_value(rowx=rx, colx=cx)
+ if cv == "" :
+ continue
+ if cv == "*" or cv == 'actions:' :
+ divider = cx
+ else:
+ if divider == 0 : #we are in conditions
+ condition_headers.append([cx, cv])
+ else: #we are in actions
+ action_headers.append([cx, cv])
+ else:
+ data_row = {}
+ #print condition_headers
+ for cx in range(sh.ncols):
+ cv = sh.cell_value(rowx=rx, colx=cx)
+ if cv != "":
+ data_row[cx] = cv
+ if len(data_row) > 0 :
+ data.append(data_row)
+ return {
+ "condition_headers" : condition_headers,
+ "action_headers" : action_headers,
+ "data" : data
+ }
+
+
+
+
+
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/pydt_test.py
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/pydt_test.py (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/main/resources/python-dt/pydt_test.py 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,44 @@
+import pydt
+
+test_fact = { "Age" : 42, "Risk" : "'HIGH'", "PolicyType" : "'COMPREHENSIVE'" }
+
+test_table = {
+ "condition_headers" : [ ["A" , "Age"], ["B", "Risk =="], ["C", "PolicyType =="]],
+ "action_headers" : [ ["F","Premium"], ["G","Log"]],
+
+
+ "data" : [
+ {"row" : 2, "A" : "> 2", "B" : "'HIGH'", "C": "'COMPREHENSIVE'", "F" : "245"},
+ {"row" : 3, "A" : "< 25 ", "B" : "'LOW'", "F" : "390"}
+ ]
+
+}
+
+
+#and now some crude test code
+pydt.process_dt(test_fact, test_table)
+print "RESULT: " + str(test_fact)
+if not test_fact.has_key("Premium") :
+ print("ERROR: no premium was calculated")
+if test_fact["Premium"] == '245' :
+ print("PASSED STEP 1")
+else :
+ print("FAILED STEP 1: Premium was " + test_fact["Premium"])
+
+#some simple test
+tbl = pydt.load_xls("Example.xls")
+if tbl['condition_headers'][0][1] == "Age" :
+ print "PASSED STEP 2"
+else:
+ print "FAILED STEP 2"
+
+#now test it all, end to end
+test_fact = { "Age" : 42, "Risk" : "'HIGH'", "PolicyType" : "'COMPREHENSIVE'" }
+pydt.process_dt(test_fact, tbl)
+if not test_fact.has_key("Premium") :
+ print("ERROR: no premium was calculated")
+premium = test_fact["Premium"]
+if premium == 245 :
+ print("PASSED STEP 3")
+else :
+ print("FAILED STEP 3: Premium was " + test_fact["Premium"])
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/insurance/Driver.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/insurance/Driver.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/insurance/Driver.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,41 @@
+package org.acme.insurance;
+
+/**
+ * This represents obviously a driver who is applying for an insurance Policy.
+ * @author Michael Neale
+ *
+ */
+public class Driver {
+
+ private String name = "Mr Joe Blogs";
+ private Integer age = new Integer(30);
+ private Integer priorClaims = new Integer(0);
+ private String locationRiskProfile = "LOW";
+
+ public Integer getAge() {
+ return age;
+ }
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+ public String getLocationRiskProfile() {
+ return locationRiskProfile;
+ }
+ public void setLocationRiskProfile(String locationRiskProfile) {
+ this.locationRiskProfile = locationRiskProfile;
+ }
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public Integer getPriorClaims() {
+ return priorClaims;
+ }
+ public void setPriorClaims(Integer priorClaims) {
+ this.priorClaims = priorClaims;
+ }
+
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/insurance/Policy.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/insurance/Policy.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/insurance/Policy.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,49 @@
+package org.acme.insurance;
+
+/**
+ * This represents a policy that a driver is applying for.
+ *
+ * Obviously in the real world, there are actuaries to mess things up, but lets just pretend there is
+ * some simple base price and discount that we can calculate with relatively simple rules !
+ *
+ * @author Michael Neale
+ */
+public class Policy {
+
+ private String type = "COMPREHENSIVE";
+ private boolean approved = false;
+ private int discountPercent = 0;
+ private int basePrice;
+
+ public boolean isApproved() {
+ return approved;
+ }
+ public void setApproved(boolean approved) {
+ this.approved = approved;
+ }
+ public int getDiscountPercent() {
+ return discountPercent;
+ }
+ public void setDiscountPercent(int discountPercent) {
+ this.discountPercent = discountPercent;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public void applyDiscount(int discount) {
+ discountPercent += discount;
+ }
+ public int getBasePrice() {
+ return basePrice;
+ }
+ public void setBasePrice(int basePrice) {
+ this.basePrice = basePrice;
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/insurance/launcher/PricingRuleLauncher.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/insurance/launcher/PricingRuleLauncher.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/acme/insurance/launcher/PricingRuleLauncher.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,92 @@
+package org.acme.insurance.launcher;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+
+import org.acme.insurance.Driver;
+import org.acme.insurance.Policy;
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.RuleBase;
+import org.drools.RuleBaseFactory;
+import org.drools.WorkingMemory;
+import org.drools.builder.DecisionTableConfiguration;
+import org.drools.builder.DecisionTableInputType;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.builder.ResourceType;
+import org.drools.compiler.DroolsParserException;
+import org.drools.compiler.PackageBuilder;
+import org.drools.decisiontable.InputType;
+import org.drools.decisiontable.SpreadsheetCompiler;
+import org.drools.io.ResourceFactory;
+import org.drools.runtime.StatefulKnowledgeSession;
+
+/**
+ * This is a sample file to launch a rule package from a rule source file.
+ */
+public class PricingRuleLauncher {
+
+ public static final void main(String[] args) throws Exception {
+ PricingRuleLauncher launcher = new PricingRuleLauncher();
+ launcher.executeExample();
+ }
+
+ public int executeExample() throws Exception {
+ KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+
+ DecisionTableConfiguration dtconf = KnowledgeBuilderFactory.newDecisionTableConfiguration();
+ dtconf.setInputType( DecisionTableInputType.XLS );
+
+ kbuilder.add( ResourceFactory.newClassPathResource( "/data/ExamplePolicyPricing.xls", getClass() ),
+ ResourceType.DTABLE,
+ dtconf );
+
+ if ( kbuilder.hasErrors() ) {
+ throw new RuntimeException( kbuilder.getErrors().toString() );
+ }
+
+ //BUILD RULEBASE
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+
+ //NEW WORKING MEMORY
+ final StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession();
+
+ //now create some test data
+ Driver driver = new Driver();
+ Policy policy = new Policy();
+
+ session.insert( driver );
+ session.insert( policy );
+
+ session.fireAllRules();
+
+ System.out.println( "BASE PRICE IS: " + policy.getBasePrice() );
+ System.out.println( "DISCOUNT IS: " + policy.getDiscountPercent() );
+
+ return policy.getBasePrice();
+
+ }
+
+ /** Build the rule base from the generated DRL */
+ private RuleBase buildRuleBase(String drl) throws DroolsParserException,
+ IOException,
+ Exception {
+ //now we build the rule package and rulebase, as if they are normal rules
+ PackageBuilder builder = new PackageBuilder();
+ builder.addPackageFromDrl( new StringReader( drl ) );
+
+ //add the package to a rulebase (deploy the rule package).
+ RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+ ruleBase.addPackage( builder.getPackage() );
+ return ruleBase;
+ }
+
+ private InputStream getSpreadsheetStream() {
+ return this.getClass().getResourceAsStream( "/data/ExamplePolicyPricing.xls" );
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/ChangeSetTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/ChangeSetTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/ChangeSetTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,80 @@
+package org.drools.decisiontable;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.builder.DecisionTableConfiguration;
+import org.drools.builder.DecisionTableInputType;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.builder.ResourceType;
+import org.drools.compiler.PackageBuilderConfiguration;
+import org.drools.core.util.FileManager;
+import org.drools.io.ResourceFactory;
+import org.drools.io.impl.ClassPathResource;
+import org.drools.io.impl.KnowledgeResource;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.xml.XmlChangeSetReader;
+import org.xml.sax.SAXException;
+
+public class ChangeSetTest {
+
+ FileManager fileManager;
+
+ @Before
+ public void setUp() throws Exception {
+ fileManager = new FileManager();
+ fileManager.setUp();
+ ResourceFactory.getResourceChangeNotifierService().start();
+ ResourceFactory.getResourceChangeScannerService().start();
+ }
+
+
+ @After
+ public void tearDown() throws Exception {
+ fileManager.tearDown();
+ ResourceFactory.getResourceChangeNotifierService().stop();
+ ResourceFactory.getResourceChangeScannerService().stop();
+ }
+
+ @Test
+ public void testIntegregation() {
+ KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+ kbuilder.add( ResourceFactory.newClassPathResource( "changeset1Test.xml", getClass()), ResourceType.CHANGE_SET );
+ assertFalse( kbuilder.hasErrors() );
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+ StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+ List list = new ArrayList();
+ ksession.setGlobal( "list", list );
+
+ ksession.insert( new Cheese( "cheddar",
+ 42 ) );
+ ksession.insert( new Person( "michael",
+ "stilton",
+ 25 ) );
+
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals( 3, list.size() );
+
+ assertEquals( "Young man cheddar",
+ list.get( 0 ) );
+
+ assertEquals( "rule1",
+ list.get( 1 ) );
+ assertEquals( "rule2",
+ list.get( 2 ) );
+ }
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/Cheese.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/Cheese.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/Cheese.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable;
+
+public class Cheese {
+ private String type;
+ private int price;
+
+ public Cheese() {
+
+ }
+ public Cheese(final String type,
+ final int price) {
+ super();
+ this.type = type;
+ this.price = price;
+ }
+
+ public int getPrice() {
+ return this.price;
+ }
+
+ public String getType() {
+ return this.type;
+ }
+
+ public void setPrice(final int price) {
+ this.price = price;
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerIntegrationTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerIntegrationTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerIntegrationTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+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.rule.Package;
+import org.drools.template.parser.DataListener;
+import org.drools.template.parser.TemplateDataListener;
+
+/**
+ * @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 {
+ @Test
+ 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
+ System.out.println( drl );
+ final PackageBuilder builder = new PackageBuilder();
+ builder.addPackageFromDrl( new StringReader( drl ) );
+
+ final Package pkg = builder.getPackage();
+ assertNotNull( pkg );
+ assertEquals( 0,
+ builder.getErrors().getErrors().length );
+
+ //BUILD RULEBASE
+ final RuleBase rb = RuleBaseFactory.newRuleBase();
+ rb.addPackage( pkg );
+
+ //NEW WORKING MEMORY
+ final WorkingMemory wm = rb.newStatefulSession();
+
+ //ASSERT AND FIRE
+ wm.insert( new Cheese( "stilton",
+ 42 ) );
+ wm.insert( new Person( "michael",
+ "stilton",
+ 42 ) );
+ final List<String> list = new ArrayList<String>();
+ wm.setGlobal( "list",
+ list );
+ wm.fireAllRules();
+ assertEquals( 1,
+ list.size() );
+
+
+ }
+
+ @Test
+ public void testPricing() throws Exception
+ {
+ final ExternalSpreadsheetCompiler converter = new ExternalSpreadsheetCompiler();
+ final List<DataListener> listeners = new ArrayList<DataListener>();
+ TemplateDataListener l1 = new TemplateDataListener(10, 3, "/templates/test_pricing1.drl");
+ listeners.add(l1);
+ TemplateDataListener l2 = new TemplateDataListener(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().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.newStatefulSession();
+
+ //now create some test data
+ Driver driver = new Driver();
+ Policy policy = new Policy();
+
+ wm.insert(driver);
+ wm.insert(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/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerUnitTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerUnitTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerUnitTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ * @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 {
+ @Test
+ 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 );
+ }
+
+ @Test
+ public void testLoadSpecificWorksheet() {
+ final ExternalSpreadsheetCompiler converter = new ExternalSpreadsheetCompiler();
+ final String drl = converter.compile( "/data/MultiSheetDST.xls",
+ "Another Sheet",
+ "/templates/test_template1.drl",
+ 11,
+ 2 );
+ // System.out.println(drl);
+ assertNotNull( drl );
+ }
+
+ @Test
+ 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 );
+ }
+
+ @Test
+ 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() > 12\")" ) > -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)" ) );
+
+ }
+
+ @Test
+ public void testLoadBasicWithExtraCells() {
+ final ExternalSpreadsheetCompiler compiler = new ExternalSpreadsheetCompiler();
+ final String drl = compiler.compile( "/data/BasicWorkbook.xls",
+ "/templates/test_template4.drl",
+ InputType.XLS,
+ 10,
+ 2 );
+ assertNotNull( drl );
+
+ assertTrue( drl.indexOf( "This is a function block" ) > -1 );
+ assertTrue( drl.indexOf( "global Class1 obj1;" ) > -1 );
+ assertTrue( drl.indexOf( "myObject.getColour().equals(blue)" ) > -1 );
+ assertTrue( drl.indexOf( "Foo(myObject.getColour().equals(red), myObject.size() > 12\")" ) > -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)" ) );
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/Person.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/Person.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/Person.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable;
+
+public class Person {
+ private String name;
+ private String likes;
+ private int age;
+
+ private char sex;
+
+ private boolean alive;
+
+ private String status;
+
+ public Person() {
+
+ }
+ public Person(final String name) {
+ this( name,
+ "",
+ 0 );
+ }
+
+ public Person(final String name,
+ final String likes) {
+ this( name,
+ likes,
+ 0 );
+ }
+
+ public Person(final String name,
+ final String likes,
+ final int age) {
+ this.name = name;
+ this.likes = likes;
+ this.age = age;
+ }
+
+ public String getStatus() {
+ return this.status;
+ }
+
+ public void setStatus(final String status) {
+ this.status = status;
+ }
+
+ public String getLikes() {
+ return this.likes;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public int getAge() {
+ return this.age;
+ }
+
+ public boolean isAlive() {
+ return this.alive;
+ }
+
+ public void setAlive(final boolean alive) {
+ this.alive = alive;
+ }
+
+ public char getSex() {
+ return this.sex;
+ }
+
+ public void setSex(final char sex) {
+ this.sex = sex;
+ }
+
+ public String toString() {
+ return "[Person name='" + this.name + "']";
+ }
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/SourcePackageProviderTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/SourcePackageProviderTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/SourcePackageProviderTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,92 @@
+package org.drools.decisiontable;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Properties;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import org.drools.RuleBase;
+import org.drools.agent.RuleAgent;
+
+public class SourcePackageProviderTest {
+
+ @Test
+ public void testSourceProvider() throws Exception {
+ new SourcePackageProvider();
+
+ File dir = getTempDirectory();
+
+ InputStream in = this.getClass().getResourceAsStream( "/data/ExamplePolicyPricing.xls" );
+
+ File target = new File( dir,
+ "Something.xls" );
+
+ OutputStream out = new FileOutputStream( target );
+
+ byte[] buf = new byte[1024];
+ int len;
+ while ( (len = in.read( buf )) > 0 ) {
+ out.write( buf,
+ 0,
+ len );
+ }
+ in.close();
+ out.close();
+
+ Properties config = new Properties();
+ config.setProperty( RuleAgent.FILES,
+ target.getPath() );
+
+ RuleAgent ag = RuleAgent.newRuleAgent( config );
+
+ assertNotNull( ag );
+
+ RuleBase rb = ag.getRuleBase();
+ assertNotNull( rb );
+ }
+
+ public static File getTempDirectory() {
+ File f = tempDir();
+ if ( f.exists() ) {
+ if ( f.isFile() ) {
+ throw new IllegalStateException( "The temp directory exists as a file. Nuke it now !" );
+ }
+ deleteDir( f );
+ f.mkdir();
+ } else {
+ f.mkdir();
+ }
+ return f;
+ }
+
+ private static File tempDir() {
+ File tmp = new File( System.getProperty( "java.io.tmpdir" ) );
+
+ return new File( tmp,
+ "__temp_test_drools_packages" );
+ }
+
+ public static boolean deleteDir(File dir) {
+
+ if ( dir.isDirectory() ) {
+ String[] children = dir.list();
+ for ( int i = 0; i < children.length; i++ ) {
+ boolean success = deleteDir( new File( dir,
+ children[i] ) );
+ if ( !success ) {
+ //throw new RuntimeException("Unable to delete !");
+ return false;
+ }
+ }
+ }
+
+ // The directory is now empty so delete it
+ return dir.delete();
+ }
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetCompilerUnitTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetCompilerUnitTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetCompilerUnitTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable;
+
+import java.io.InputStream;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import org.drools.decisiontable.parser.RuleMatrixSheetListener;
+
+/**
+ * @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 SpreadsheetCompilerUnitTest {
+
+ @Test
+ public void testLoadFromClassPath() {
+ final SpreadsheetCompiler converter = new SpreadsheetCompiler();
+ String drl = converter.compile( "/data/MultiSheetDST.xls",
+ InputType.XLS );
+
+ assertNotNull( drl );
+
+ assertTrue( drl.indexOf( "rule \"How cool am I_12\"" ) > drl.indexOf( "rule \"How cool am I_11\"" ) );
+ assertTrue( drl.indexOf( "import example.model.User;" ) > -1 );
+ assertTrue( drl.indexOf( "import example.model.Car;" ) > -1 );
+ assertTrue( drl.indexOf("package ") > -1);
+ InputStream ins = this.getClass().getResourceAsStream("/data/MultiSheetDST.xls");
+
+ drl = converter.compile( false, ins,
+ InputType.XLS );
+
+ assertNotNull( drl );
+
+ assertTrue( drl.indexOf( "rule \"How cool am I_12\"" ) > 0 );
+ assertTrue( drl.indexOf( "import example.model.User;" ) > -1 );
+ assertTrue( drl.indexOf( "import example.model.Car;" ) > -1 );
+ assertTrue( drl.indexOf("package ") == -1);
+
+ }
+
+ @Test
+ public void testLoadSpecificWorksheet() {
+ final SpreadsheetCompiler converter = new SpreadsheetCompiler();
+ final InputStream stream = this.getClass().getResourceAsStream( "/data/MultiSheetDST.xls" );
+ final String drl = converter.compile( stream,
+ "Another Sheet" );
+ assertNotNull( drl );
+ }
+
+ @Test
+ 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 );
+ }
+
+ @Test
+ 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 );
+ assertNotNull( 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 );
+ }
+
+ @Test
+ 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 );
+
+ assertNotNull( drl );
+
+ System.out.println(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( 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 () > 12\\\")" ) > -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( "myObject.setIsValid(\"19-Jul-1992\")" ) > -1 );
+
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetIntegrationTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetIntegrationTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetIntegrationTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable;
+
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import org.acme.insurance.launcher.PricingRuleLauncher;
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.builder.DecisionTableConfiguration;
+import org.drools.builder.DecisionTableInputType;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.builder.ResourceType;
+import org.drools.io.ResourceFactory;
+import org.drools.runtime.StatefulKnowledgeSession;
+
+public class SpreadsheetIntegrationTest {
+
+ @Test
+ public void testExecute() throws Exception {
+ KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+
+ DecisionTableConfiguration dtconf = KnowledgeBuilderFactory.newDecisionTableConfiguration();
+ dtconf.setInputType( DecisionTableInputType.XLS );
+
+ kbuilder.add( ResourceFactory.newClassPathResource( "/data/IntegrationExampleTest.xls", getClass() ),
+ ResourceType.DTABLE,
+ dtconf );
+
+ assertFalse( kbuilder.hasErrors() );
+
+ //BUILD RULEBASE
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+
+ //NEW WORKING MEMORY
+ final StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession();
+
+ //ASSERT AND FIRE
+ session.insert( new Cheese( "stilton",
+ 42 ) );
+ session.insert( new Person( "michael",
+ "stilton",
+ 42 ) );
+ final List<String> list = new ArrayList<String>();
+ session.setGlobal( "list",
+ list );
+ session.fireAllRules();
+ assertEquals( 1,
+ list.size() );
+ assertEquals( "Old man stilton",
+ list.get( 0 ) );
+ }
+
+ @Test
+ public void testNamedWorksheet() throws Exception {
+ KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+
+ DecisionTableConfiguration dtconf = KnowledgeBuilderFactory.newDecisionTableConfiguration();
+ dtconf.setInputType( DecisionTableInputType.XLS );
+ dtconf.setWorksheetName( "Tables_2" );
+
+ kbuilder.add( ResourceFactory.newClassPathResource( "/data/IntegrationExampleTest.xls", getClass() ),
+ ResourceType.DTABLE,
+ dtconf );
+
+ assertFalse( kbuilder.hasErrors() );
+
+ //BUILD RULEBASE
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+
+ //NEW WORKING MEMORY
+ final StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession();
+
+ //ASSERT AND FIRE
+ session.insert( new Cheese( "cheddar",
+ 42 ) );
+ session.insert( new Person( "michael",
+ "stilton",
+ 25 ) );
+ final List<String> list = new ArrayList<String>();
+ session.setGlobal( "list",
+ list );
+ session.fireAllRules();
+ assertEquals( 1,
+ list.size() );
+ assertEquals( "Young man cheddar",
+ list.get( 0 ) );
+ }
+
+ /**
+ * A smoke test mainly.
+ */
+ @Test
+ public void testInsuranceExample() throws Exception {
+ PricingRuleLauncher launcher = new PricingRuleLauncher();
+ assertEquals( 120,
+ launcher.executeExample() );
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ActionTypeTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ActionTypeTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ActionTypeTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,51 @@
+package org.drools.decisiontable.parser;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import org.drools.decisiontable.parser.ActionType;
+import static org.drools.decisiontable.parser.ActionType.Code;
+
+public class ActionTypeTest {
+
+ @Test
+ public void testChooseActionType() {
+ Map<Integer, ActionType> actionTypeMap = new HashMap<Integer, ActionType>();
+ ActionType.addNewActionType( actionTypeMap, "C", 0, 1 );
+
+ ActionType type = (ActionType) actionTypeMap.get( new Integer(0) );
+ assertEquals( Code.CONDITION, type.getCode() );
+
+
+ actionTypeMap = new HashMap<Integer, ActionType>();
+ ActionType.addNewActionType( actionTypeMap, "A", 0, 1 );
+ type = (ActionType) actionTypeMap.get( new Integer(0) );
+ assertEquals(Code.ACTION, type.getCode());
+
+ actionTypeMap = new HashMap<Integer, ActionType>();
+ ActionType.addNewActionType( actionTypeMap, "X", 0, 1 );
+ type = (ActionType) actionTypeMap.get( new Integer(0) );
+ assertEquals(Code.ACTIVATIONGROUP, type.getCode());
+
+ actionTypeMap = new HashMap<Integer, ActionType>();
+ ActionType.addNewActionType( actionTypeMap, "ACTIVATION-GROUP", 0, 1 );
+ type = (ActionType) actionTypeMap.get( new Integer(0) );
+ assertEquals(Code.ACTIVATIONGROUP, type.getCode());
+
+ actionTypeMap = new HashMap<Integer, ActionType>();
+ ActionType.addNewActionType( actionTypeMap, "NO-LOOP", 0, 1 );
+ type = (ActionType) actionTypeMap.get( new Integer(0) );
+ assertEquals(Code.NOLOOP, type.getCode());
+
+ actionTypeMap = new HashMap<Integer, ActionType>();
+ ActionType.addNewActionType( actionTypeMap, "RULEFLOW-GROUP", 0, 1 );
+ type = (ActionType) actionTypeMap.get( new Integer(0) );
+ assertEquals(Code.RULEFLOWGROUP, type.getCode());
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ColumnFactoryTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ColumnFactoryTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ColumnFactoryTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,71 @@
+package org.drools.decisiontable.parser;
+
+import org.drools.template.parser.ArrayColumn;
+import org.drools.template.parser.Column;
+import org.drools.template.parser.ColumnFactory;
+import org.drools.template.parser.LongColumn;
+import org.drools.template.parser.StringColumn;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class ColumnFactoryTest {
+
+ @Test
+ public void testGetColumn() {
+ ColumnFactory f = new ColumnFactory();
+ Column column = f.getColumn("column");
+ assertTrue(column instanceof StringColumn);
+ assertEquals("column", column.getName());
+ }
+
+ @Test
+ public void testGetStringArrayColumn() {
+ ColumnFactory f = new ColumnFactory();
+ Column column = f.getColumn("column: String[]");
+ assertTrue(column instanceof ArrayColumn);
+ assertEquals("column", column.getName());
+ assertEquals("StringCell", ((ArrayColumn)column).getCellType());
+ }
+
+ @Test
+ public void testGetLongArrayColumn() {
+ ColumnFactory f = new ColumnFactory();
+ Column column = f.getColumn("column: Long[]");
+ assertTrue(column instanceof ArrayColumn);
+ assertEquals("column", column.getName());
+ assertEquals("LongCell", ((ArrayColumn)column).getCellType());
+ }
+
+ @Test
+ public void testGetArrayColumnSimple() {
+ ColumnFactory f = new ColumnFactory();
+ Column column = f.getColumn("column[]");
+ assertTrue(column instanceof ArrayColumn);
+ assertEquals("column", column.getName());
+ assertEquals("StringCell", ((ArrayColumn)column).getCellType());
+
+ }
+
+ @Test
+ public void testGetLongColumn() {
+ ColumnFactory f = new ColumnFactory();
+ Column column = f.getColumn("column: Long");
+ assertTrue(column instanceof LongColumn);
+ assertEquals("column", column.getName());
+ }
+
+ @Test
+ public void testInvalidGetColumn() {
+ try {
+ ColumnFactory f = new ColumnFactory();
+ f.getColumn("column$");
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/LhsBuilderTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/LhsBuilderTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/LhsBuilderTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,223 @@
+package org.drools.decisiontable.parser;
+
+import org.drools.decisiontable.parser.LhsBuilder.FieldType;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class LhsBuilderTest {
+
+ @Test
+ public void testBuildItUp() throws Exception {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "Person" );
+
+ builder.addTemplate(10, 1, "age");
+ builder.addTemplate(10, 2, "size != $param");
+ builder.addTemplate(10, 3, "date <");
+
+ builder.addCellValue(11, 1, "42");
+ builder.addCellValue(11, 2, "20");
+ builder.addCellValue(11, 3, "30");
+
+
+ assertEquals("Person(age == \"42\", size != 20, date < \"30\")", builder.getResult());
+
+ builder.clearValues();
+
+ builder.addCellValue(12, 2, "42" );
+ assertEquals("Person(size != 42)", builder.getResult());
+ }
+
+ @Test
+ public void testEmptyCells() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "Person" );
+ assertFalse(builder.hasValues());
+ }
+
+ @Test
+ public void testClassicMode() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "" );
+ builder.addTemplate( 10, 1, "Person(age < $param)");
+ builder.addCellValue( 11, 1, "42" );
+
+ assertEquals("Person(age < 42)", builder.getResult());
+
+ builder = new LhsBuilder( 9, 3, null );
+ builder.addTemplate( 10, 3, "Foo(bar == $param)");
+ builder.addTemplate( 10, 4, "eval(true)");
+
+ builder.addCellValue( 11, 3, "42" );
+ builder.addCellValue( 11, 4, "Y" );
+
+ assertEquals("Foo(bar == 42)\neval(true)", builder.getResult());
+ }
+
+ @Test
+ public void testForAllAndFucntion() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "" );
+ builder.addTemplate( 10, 1, "forall(&&){Foo(bar != $)}");
+ builder.addCellValue( 11, 1, "42,43");
+ assertEquals("Foo(bar != 42) && Foo(bar != 43)", builder.getResult());
+ }
+
+ @Test
+ public void testForAllOr() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "Person" );
+ builder.addTemplate( 10, 1, "forall(||){age < $}");
+ builder.addCellValue( 11, 1, "42");
+ assertEquals("Person(age < 42)", builder.getResult());
+ }
+
+ @Test
+ public void testForAllOrPrefix() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "Person" );
+ builder.addTemplate( 10, 1, "age < 10 && forall(||){age < $}");
+ builder.addCellValue( 11, 1, "42");
+ assertEquals("Person(age < 10 && age < 42)", builder.getResult());
+ }
+
+ @Test
+ public void testForAllOrCSV() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "Person" );
+ builder.addTemplate( 10, 1, "forall(||){age < $}");
+ builder.addCellValue( 11, 1, "42, 43, 44");
+ assertEquals("Person(age < 42 || age < 43 || age < 44)", builder.getResult());
+ }
+
+ @Test
+ public void testForAllAnd() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "Person" );
+ builder.addTemplate(10, 1, "forall(&&){age < $}");
+ builder.addCellValue(11, 1, "42");
+ assertEquals("Person(age < 42)", builder.getResult());
+ }
+
+ @Test
+ public void testForAllAndCSV() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "Person" );
+ builder.addTemplate(10, 1, "forall(&&){age < $}");
+ builder.addCellValue(11, 1, "42, 43, 44");
+ assertEquals("Person(age < 42 && age < 43 && age < 44)", builder
+ .getResult());
+ }
+
+ @Test
+ public void testForAllAndForAllOrCSVMultiple() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "Person" );
+ builder.addTemplate(10, 1, "forall(&&){age < $ || age == $}");
+ builder.addCellValue(11, 1, "42, 43, 44");
+ assertEquals(
+ "Person(age < 42 || age == 42 && age < 43 || age == 43 && age < 44 || age == 44)",
+ builder.getResult());
+ }
+
+ @Test
+ public void testForAllsAndForAllOrCSVMultiple() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "Person" );
+ builder.addTemplate(10, 1, "forall(&&){age < $ || age == $} && forall(&&){age < $ || age == $}");
+ builder.addCellValue(11, 1, "42, 43, 44");
+ assertEquals(
+ "Person(age < 42 || age == 42 && age < 43 || age == 43 && age < 44 || age == 44 && age < 42 || age == 42 && age < 43 || age == 43 && age < 44 || age == 44)",
+ builder.getResult());
+ }
+
+ @Test
+ public void testIdentifyFieldTypes() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "" );
+ assertEquals(FieldType.SINGLE_FIELD, builder.calcFieldType("age"));
+ assertEquals(FieldType.OPERATOR_FIELD, builder.calcFieldType("age <"));
+ assertEquals(FieldType.NORMAL_FIELD, builder.calcFieldType("age < $param"));
+ assertEquals(FieldType.NORMAL_FIELD, builder.calcFieldType("forall(||){age < $}"));
+ assertEquals(FieldType.NORMAL_FIELD, builder.calcFieldType("forall(&&){age < $}"));
+ assertEquals(FieldType.NORMAL_FIELD, builder.calcFieldType("forall(,){age < $}"));
+ assertEquals(FieldType.NORMAL_FIELD, builder.calcFieldType("forall(){age < $}"));
+ assertEquals(FieldType.NORMAL_FIELD, builder.calcFieldType("forall(){age < $} && forall(){age == $}"));
+ assertEquals(FieldType.NORMAL_FIELD, builder.calcFieldType("x && forall(){age < $} && forall(){age == $}"));
+ assertEquals(FieldType.NORMAL_FIELD, builder.calcFieldType("x && forall(){age < $} && forall(){age == $} && y"));
+ assertEquals(FieldType.SINGLE_FIELD, builder.calcFieldType("age < $para"));
+ assertEquals(FieldType.SINGLE_FIELD, builder.calcFieldType("forall{||}{age < $}"));
+ assertEquals(FieldType.SINGLE_FIELD, builder.calcFieldType("forall(){}"));
+ assertEquals(FieldType.SINGLE_FIELD, builder.calcFieldType("forall(){age < $"));
+ assertEquals(FieldType.SINGLE_FIELD, builder.calcFieldType("forall(){,"));
+ assertEquals(FieldType.SINGLE_FIELD, builder.calcFieldType("forall({})"));
+ assertEquals(FieldType.SINGLE_FIELD, builder.calcFieldType("forall({}){test})"));
+ assertEquals(FieldType.SINGLE_FIELD, builder.calcFieldType("forall(&&){{}})"));
+ assertEquals(FieldType.SINGLE_FIELD, builder.calcFieldType("forall(&&){{})"));
+ }
+
+ @Test
+ public void testIdentifyColumnCorrectly() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, null );
+ assertFalse(builder.isMultipleConstraints());
+
+ //will be added to Foo
+ builder = new LhsBuilder( 9, 1, "Foo" );
+ assertTrue(builder.isMultipleConstraints());
+
+ //will be added to eval
+ builder = new LhsBuilder( 9, 1, "f:Foo() eval " );
+ assertTrue(builder.isMultipleConstraints());
+
+ // will just be verbatim
+ builder = new LhsBuilder( 9, 1, "f: Foo()" );
+ assertTrue(builder.isMultipleConstraints());
+ }
+
+ @Test
+ public void testTypeConst3() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "Type" );
+ builder.addTemplate( 10, 1, "flda");
+ builder.addTemplate( 10, 2, "fldb >");
+ builder.addTemplate( 10, 3, "fldc str[startsWith]");
+ builder.addCellValue( 11, 1, "good");
+ builder.addCellValue( 11, 2, "42");
+ builder.addCellValue( 11, 3, "abc");
+ assertEquals("Type(flda == \"good\", fldb > \"42\", fldc str[startsWith] \"abc\")", builder.getResult());
+ }
+
+ @Test
+ public void testTypeParConst2() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "Type()" );
+ builder.addTemplate( 10, 1, "flda");
+ builder.addTemplate( 10, 2, "fldb >");
+ builder.addCellValue( 11, 1, "good");
+ builder.addCellValue( 11, 2, "42");
+ assertEquals("Type(flda == \"good\", fldb > \"42\")", builder.getResult());
+ }
+
+ @Test
+ public void testTypeConstFrom() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "Type from $west" );
+ builder.addTemplate( 10, 1, "flda");
+ builder.addCellValue( 11, 1, "good");
+ assertEquals("Type(flda == \"good\") from $west", builder.getResult());
+ }
+
+ @Test
+ public void testTypeEvalExp2() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "Type($a:a,$b:b) eval" );
+ builder.addTemplate( 10, 1, "$a > $param");
+ builder.addTemplate( 10, 2, "$b < $param");
+ builder.addCellValue( 11, 1, "1");
+ builder.addCellValue( 11, 2, "99");
+ assertEquals("Type($a:a,$b:b) eval($a > 1 && $b < 99)", builder.getResult());
+ }
+
+ @Test
+ public void testEvalExp2() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, "eval()" );
+ builder.addTemplate( 10, 1, "$a > $param");
+ builder.addTemplate( 10, 2, "$b < $param");
+ builder.addCellValue( 11, 1, "1");
+ builder.addCellValue( 11, 2, "99");
+ assertEquals("eval($a > 1 && $b < 99)", builder.getResult());
+ }
+
+ @Test
+ public void testTypeParPlain() {
+ LhsBuilder builder = new LhsBuilder( 9, 1, null );
+ builder.addTemplate( 10, 1, "Type()");
+ builder.addCellValue( 11, 1, "x");
+ assertEquals("Type()", builder.getResult());
+ }
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/PropertiesSheetListenerTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/PropertiesSheetListenerTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/PropertiesSheetListenerTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser;
+
+import java.util.Properties;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import org.drools.decisiontable.parser.xls.PropertiesSheetListener;
+import org.drools.decisiontable.parser.xls.PropertiesSheetListener.CaseInsensitiveMap;
+import org.drools.template.parser.DataListener;
+
+public class PropertiesSheetListenerTest {
+
+ @Test
+ public void testProperties() {
+ final PropertiesSheetListener listener = new PropertiesSheetListener();
+ listener.startSheet( "test" );
+
+ listener.newRow( 0, 4 );
+
+ listener.newCell( 0, 0,
+ "", DataListener.NON_MERGED );
+
+ listener.newCell( 0, 1,
+ "key1", DataListener.NON_MERGED );
+ listener.newCell( 0, 2,
+ "value1", DataListener.NON_MERGED );
+
+ listener.newRow( 1, 4 );
+ listener.newCell( 1, 1,
+ "key2", DataListener.NON_MERGED );
+ listener.newCell( 1, 3,
+ "value2", DataListener.NON_MERGED );
+
+ final CaseInsensitiveMap props = listener.getProperties();
+
+ listener.newRow( 2, 4 );
+ listener.newCell( 1, 1,
+ "key3", DataListener.NON_MERGED );
+
+ assertEquals( "value1", props.getSingleProperty( "Key1" ) );
+ assertEquals( "value2", props.getSingleProperty( "key2" ) );
+
+ }
+
+ @Test
+ public void testCaseInsensitive() {
+ CaseInsensitiveMap map = new PropertiesSheetListener.CaseInsensitiveMap();
+ map.addProperty("x3", new String[]{ "hey", "B2" } );
+ map.addProperty("x4", new String[]{ "wHee", "C3" } );
+ map.addProperty("XXx", new String[]{ "hey2", "D4" } );
+
+ assertNull( map.getProperty("x") );
+ assertEquals("hey", map.getSingleProperty("x3"));
+ assertEquals("hey", map.getSingleProperty("X3"));
+ assertEquals("wHee", map.getSingleProperty("x4"));
+ assertEquals("hey2", map.getSingleProperty("xxx"));
+ assertEquals("hey2", map.getSingleProperty("XXX"));
+ assertEquals("hey2", map.getSingleProperty("XXx"));
+
+ assertEquals("Whee2", map.getSingleProperty("x", "Whee2"));
+
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RhsBuilderTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RhsBuilderTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RhsBuilderTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,58 @@
+package org.drools.decisiontable.parser;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class RhsBuilderTest {
+
+ @Test
+ public void testConsBuilding() {
+ RhsBuilder builder = new RhsBuilder( ActionType.Code.ACTION, 9, 1, "foo");
+ builder.addTemplate( 10, 1, "setFoo($param)");
+ builder.addCellValue( 10,1, "42" );
+
+
+ assertEquals("foo.setFoo(42);", builder.getResult());
+
+ builder.clearValues();
+ builder.addCellValue( 10, 1, "33" );
+ assertEquals("foo.setFoo(33);", builder.getResult());
+ }
+
+ @Test
+ public void testClassicMode() {
+ RhsBuilder builder = new RhsBuilder( ActionType.Code.ACTION, 9, 1, "");
+ builder.addTemplate( 10, 1, "p.setSomething($param);" );
+ builder.addTemplate( 10, 2, "drools.clearAgenda();" );
+
+ builder.addCellValue( 12, 1, "42" );
+
+ assertEquals("p.setSomething(42);", builder.getResult());
+
+ builder.addCellValue( 12, 2, "Y" );
+ assertEquals("p.setSomething(42);\ndrools.clearAgenda();", builder.getResult());
+ }
+
+ @Test
+ public void testMetadata() {
+ RhsBuilder builder = new RhsBuilder( ActionType.Code.METADATA, 9, 1, "");
+ builder.addTemplate( 10, 1, "Author($param)" );
+
+ builder.addCellValue( 12, 1, "A. U. Thor" );
+ assertEquals("Author(A. U. Thor)", builder.getResult());
+ builder.clearValues();
+
+ builder.addCellValue( 13, 1, "P. G. Wodehouse" );
+ assertEquals("Author(P. G. Wodehouse)", builder.getResult());
+ }
+
+ @Test
+ public void testEmptyCellData() {
+ RhsBuilder builder = new RhsBuilder( ActionType.Code.ACTION, 9, 1, "Foo");
+ builder.addTemplate( 10, 1, "p.setSomething($param);" );
+ assertFalse(builder.hasValues());
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleSheetParserUtilTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleSheetParserUtilTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleSheetParserUtilTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.template.model.Global;
+import org.drools.template.model.Import;
+import org.drools.template.parser.DecisionTableParseException;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * @author <a href="mailto:michael.neale at gmail.com"> Michael Neale</a>
+ *
+ * Nuff said...
+ */
+public class RuleSheetParserUtilTest {
+
+ @Test
+ public void testRuleName() {
+ final String row = " RuleTable This is my rule name";
+ final String result = RuleSheetParserUtil.getRuleName( row );
+ assertEquals( "This is my rule name",
+ result );
+ }
+
+ /**
+ * This is here as the old way was to do this.
+ */
+ @Ignore
+ @Test
+ public void testInvalidRuleName() {
+ final String row = "RuleTable This is my rule name (type class)";
+ try {
+ final String result = RuleSheetParserUtil.getRuleName( row );
+ fail( "should have failed, but get result: " + result );
+ } catch ( final IllegalArgumentException e ) {
+ assertNotNull( e.getMessage() );
+ }
+ }
+
+ @Test
+ public void testIsStringMeaningTrue() {
+ assertTrue( RuleSheetParserUtil.isStringMeaningTrue( "true" ) );
+ assertTrue( RuleSheetParserUtil.isStringMeaningTrue( "TRUE" ) );
+ assertTrue( RuleSheetParserUtil.isStringMeaningTrue( "yes" ) );
+ assertTrue( RuleSheetParserUtil.isStringMeaningTrue( "oN" ) );
+
+ assertFalse( RuleSheetParserUtil.isStringMeaningTrue( "no" ) );
+ assertFalse( RuleSheetParserUtil.isStringMeaningTrue( "false" ) );
+ assertFalse( RuleSheetParserUtil.isStringMeaningTrue( null ) );
+ }
+
+ @Test
+ public void testListImports() {
+ List<String> cellVals = null;
+
+ List<Import> list = RuleSheetParserUtil.getImportList( cellVals );
+ assertNotNull( list );
+ assertEquals( 0, list.size() );
+
+ cellVals = new ArrayList<String>();
+ cellVals.add( "" );
+ assertEquals( 0, RuleSheetParserUtil.getImportList( cellVals ).size() );
+
+ cellVals.add( 0, "com.something.Yeah, com.something.No,com.something.yeah.*" );
+ list = RuleSheetParserUtil.getImportList( cellVals );
+ assertEquals( 3, list.size() );
+ assertEquals( "com.something.Yeah", (list.get( 0 )).getClassName() );
+ assertEquals( "com.something.No", (list.get( 1 )).getClassName() );
+ assertEquals( "com.something.yeah.*", (list.get( 2 )).getClassName() );
+ }
+
+ @Test
+ public void testListVariables() {
+ List<String> varCells = new ArrayList<String>();
+ varCells.add( "Var1 var1, Var2 var2,Var3 var3" );
+ final List<Global> varList = RuleSheetParserUtil.getVariableList( varCells );
+ assertNotNull( varList );
+ assertEquals( 3,
+ varList.size() );
+ Global var = varList.get( 0 );
+ assertEquals( "Var1",
+ var.getClassName() );
+ var = varList.get( 2 );
+ assertEquals( "Var3",
+ var.getClassName() );
+ assertEquals( "var3",
+ var.getIdentifier() );
+ }
+
+ @Test
+ public void testBadVariableFormat() {
+ List<String> varCells = new ArrayList<String>();
+ varCells.add( "class1, object2" );
+ try {
+ RuleSheetParserUtil.getVariableList( varCells );
+ fail( "should not work" );
+ } catch ( final DecisionTableParseException e ) {
+ assertNotNull( e.getMessage() );
+ }
+ }
+
+ @Test
+ public void testRowColumnToCellNAme() {
+ String cellName = RuleSheetParserUtil.rc2name( 0, 0 );
+ assertEquals( "A1", cellName );
+
+ cellName = RuleSheetParserUtil.rc2name( 0, 10 );
+ assertEquals( "K1", cellName );
+
+ cellName = RuleSheetParserUtil.rc2name( 0, 42 );
+ assertEquals( "AQ1", cellName );
+
+ cellName = RuleSheetParserUtil.rc2name( 9, 27 );
+ assertEquals( "AB10", cellName );
+
+ cellName = RuleSheetParserUtil.rc2name( 99, 53 );
+ assertEquals( "BB100", cellName );
+ }
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseLargeTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseLargeTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseLargeTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser;
+
+import java.io.InputStream;
+
+import org.drools.template.model.Package;
+import org.junit.Ignore;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ * @author <a href="mailto:michael.neale at gmail.com"> Michael Neale</a>
+ *
+ * A special test for parsing a large workbook, to see how it scales.
+ *
+ */
+public class RuleWorksheetParseLargeTest {
+
+ private long startTimer;
+
+ private long endTimer;
+
+ /**
+ * Tests parsing a large spreadsheet into an in memory ruleset. This doesn't
+ * really do anything much at present. Takes a shed-load of memory to dump
+ * out this much XML as a string, so really should think of using a stream
+ * in some cases... (tried StringWriter, but is still in memory, so doesn't
+ * help).
+ *
+ * Stream to a temp file would work: return a stream from that file
+ * (decorate FileInputStream such that when you close it, it deletes the
+ * temp file).... must be other options.
+ *
+ * @throws Exception
+ */
+ @Ignore @Test
+ public void testLargeWorkSheetParseToRuleset() throws Exception {
+ // Test removed until have streaming sorted in future. No one using Uber Tables just yet !
+ InputStream stream = RuleWorksheetParseLargeTest.class.getResourceAsStream( "/data/VeryLargeWorkbook.xls" );
+
+ startTimer( );
+ RuleSheetListener listener = RuleWorksheetParseTest.getRuleSheetListener( stream );
+ stopTimer( );
+
+ System.out.println( "Time to parse large table : " + getTime() + "ms" );
+ Package ruleset = listener.getRuleSet( );
+ assertNotNull( ruleset );
+
+// startTimer();
+// String xml = ...; // toXml() not in Package any more.
+// System.out.println( xml );
+// stopTimer();
+// System.out.println("Time taken for rendering: " + getTime() + "ms");
+ }
+
+ private void startTimer() {
+ this.startTimer = System.currentTimeMillis();
+ }
+
+
+ private void stopTimer() {
+ this.endTimer = System.currentTimeMillis();
+ }
+
+ private long getTime() {
+ return this.endTimer - this.startTimer;
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,484 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser;
+
+import static org.junit.Assert.*;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+
+
+import org.drools.decisiontable.parser.xls.PropertiesSheetListener.CaseInsensitiveMap;
+import org.drools.template.model.Condition;
+import org.drools.template.model.Consequence;
+import org.drools.template.model.DRLOutput;
+import org.drools.template.model.Import;
+import org.drools.template.model.Package;
+import org.drools.template.model.Rule;
+import org.drools.template.parser.DataListener;
+import org.drools.template.parser.DecisionTableParseException;
+
+/**
+ * @author Shaun Addison, Michael Neale
+ *
+ * Test an excel file.
+ *
+ * Assumes it has a sheet called "Decision Tables" with a rule table identified
+ * by a "RuleTable" cell
+ */
+public class RuleWorksheetParseTest {
+
+ @Test
+ public void testBasicWorkbookProperties() throws Exception {
+
+ final InputStream stream = RuleWorksheetParseTest.class.getResourceAsStream( "/data/BasicWorkbook.xls" );
+
+ final RuleSheetListener listener = getRuleSheetListener( stream );
+
+ final CaseInsensitiveMap props = listener.getProperties();
+ assertNotNull( props );
+ assertEquals( "myruleset", props.getSingleProperty( "RuleSet" ) );
+ assertEquals( "someMisc", props.getSingleProperty( "misc" ) );
+ /*
+ * System.out.println("Here are the global properties...");
+ * listener.getProperties().list(System.out);
+ */
+ }
+
+ @Test
+ public void testComplexWorkbookProperties() throws Exception {
+ final InputStream stream = RuleWorksheetParseTest.class.getResourceAsStream( "/data/ComplexWorkbook.xls" );
+ final RuleSheetListener listener = getRuleSheetListener( stream );
+
+ final CaseInsensitiveMap props = listener.getProperties();
+ assertNotNull( props );
+ final String ruleSetName = props.getSingleProperty( "RuleSet" );
+ assertEquals( "ruleSetName", ruleSetName );
+ }
+
+ @Test
+ public void testWorkbookParse() throws Exception {
+ final InputStream stream = RuleWorksheetParseTest.class.getResourceAsStream( "/data/BasicWorkbook.xls" );
+ final RuleSheetListener listener = getRuleSheetListener( stream );
+
+ final Package ruleset = listener.getRuleSet();
+ assertNotNull( ruleset );
+
+ final Rule firstRule = (Rule) ruleset.getRules().get( 0 );
+ assertNotNull( firstRule.getSalience() );
+ assertTrue( Integer.parseInt( firstRule.getSalience() ) > 0 );
+
+ // System.out.println(ruleset.toXML());
+
+ assertEquals( "myruleset", ruleset.getName() );
+ assertEquals( 3, ruleset.getImports().size() );
+ assertEquals( 6, ruleset.getRules().size() );
+
+ // check imports
+ Import imp = (Import) ruleset.getImports().get( 0 );
+ assertEquals( "blah.class1", imp.getClassName() );
+ imp = (Import) ruleset.getImports().get( 1 );
+ assertEquals( "blah.class2", imp.getClassName() );
+ imp = (Import) ruleset.getImports().get( 2 );
+ assertEquals( "lah.di.dah", imp.getClassName() );
+
+ // check rules
+ Rule rule = (Rule) ruleset.getRules().get( 0 );
+ Condition cond = (Condition) rule.getConditions().get( 0 );
+ assertEquals( "Foo(myObject.getColour().equals(red), myObject.size () > 12\\\")",
+ cond.getSnippet() );
+
+ Consequence cons = (Consequence) rule.getConsequences().get( 0 );
+ assertNotNull( cons );
+ assertEquals( "myObject.setIsValid(Y);", cons.getSnippet() );
+
+ rule = (Rule) ruleset.getRules().get( 5 );
+ cond = (Condition) rule.getConditions().get( 1 );
+ assertEquals( "myObject.size () > 7", cond.getSnippet() );
+ cons = (Consequence) rule.getConsequences().get( 0 );
+ assertEquals( "myObject.setIsValid(10-Jul-1974)", cons.getSnippet() );
+
+ }
+
+ private RuleSheetListener listener;
+ private int row;
+
+ private void makeRuleSet(){
+ listener = new DefaultRuleSheetListener();
+ listener.startSheet( "bad_sheet" );
+ row = 1;
+ listener.newRow( row, 2 );
+ listener.newCell( row, 1, "RuleSet", DataListener.NON_MERGED );
+ listener.newCell( row, 2, "myRuleSet", DataListener.NON_MERGED );
+ }
+
+ private void makeAttribute( String key, String val){
+ row++;
+ listener.newRow( row, 2 );
+ listener.newCell( row, 1, key, DataListener.NON_MERGED );
+ listener.newCell( row, 2, val, DataListener.NON_MERGED );
+ }
+
+ private void makeRuleTable(){
+ listener.newRow( 10, 1 );
+ listener.newCell(10, 1, "RuleTable myRuleTable", DataListener.NON_MERGED );
+ }
+
+ private void makeRow( int row, String... values ) throws DecisionTableParseException {
+ listener.newRow( row, values.length );
+ for( int i = 0; i < values.length; i++ ){
+ if( values[i] != null ){
+ listener.newCell( row, i+1, values[i], DataListener.NON_MERGED );
+ }
+ }
+ }
+
+ /**
+ * Duplications of several columns are not permitted: NO-LOOP/U.
+ */
+ @Test
+ public void testTooManyColumnsNoLoop() {
+ try {
+ makeRuleSet();
+ makeRuleTable();
+ makeRow( 11, "C", "C", "A", "U", "U" );
+ listener.finishSheet();
+ fail( "should have failed" );
+ } catch( DecisionTableParseException e ) {
+ String badCell = RuleSheetParserUtil.rc2name( 11, 5 );
+ System.err.println( e.getMessage() );
+ assertTrue( e.getMessage().contains( badCell ) );
+ }
+ }
+
+ /**
+ * Duplications of several columns are not permitted : PRIORITY/P.
+ */
+ @Test
+ public void testTooManyColumnsPriority() {
+ try {
+ makeRuleSet();
+ makeRuleTable();
+ makeRow( 11, "C", "C", "A", "PRIORITY", "P" );
+ listener.finishSheet();
+ fail( "should have failed" );
+ } catch( DecisionTableParseException e ) {
+ String badCell = RuleSheetParserUtil.rc2name( 11, 5 );
+ System.err.println( e.getMessage() );
+ assertTrue( e.getMessage().contains( badCell ) );
+ }
+ }
+
+ /**
+ * Column headers must be valid.
+ */
+ @Test
+ public void testBadColumnHeader() {
+ try {
+ makeRuleSet();
+ makeRuleTable();
+ makeRow( 11, "Condition", "CONDITION", "A", "BLURB", "P" );
+ listener.finishSheet();
+ fail( "should have failed" );
+ } catch( DecisionTableParseException e ) {
+ String badCell = RuleSheetParserUtil.rc2name( 11, 4 );
+ System.err.println( e.getMessage() );
+ assertTrue( e.getMessage().contains( badCell ) );
+ }
+ }
+
+ /**
+ * Must have a type for pattern below a condition, not a snippet.
+ */
+ @Test
+ public void testMissingCondition() {
+ try {
+ makeRuleSet();
+ makeRuleTable();
+ makeRow( 11, "C", "C", "C", "A", "A" );
+ makeRow( 12, "attr == $param", "attr == $param", "attr == $param", "action();", "action();" );
+ listener.finishSheet();
+ fail( "should have failed" );
+ } catch( DecisionTableParseException e ) {
+ String badCell = RuleSheetParserUtil.rc2name( 12, 1 );
+ System.err.println( e.getMessage() );
+ assertTrue( e.getMessage().contains( badCell ) );
+ }
+ }
+
+ /**
+ * Must have a code snippet in a condition.
+ */
+ @Test
+ public void testMissingCodeSnippetCondition() {
+ try {
+ makeRuleSet();
+ makeRuleTable();
+ makeRow( 11, "C", "C", "C", "A", "A" );
+ makeRow( 12, "Foo", "Foo", "Foo" );
+ makeRow( 13, "attr == $param", "attr == $param", "", "action();", "action();" );
+ makeRow( 15, "1", "2", "3", "", "" );
+ listener.finishSheet();
+ fail( "should have failed" );
+ } catch( DecisionTableParseException e ) {
+ String badCell = RuleSheetParserUtil.rc2name( 13, 3 );
+ System.err.println( e.getMessage() );
+ assertTrue( e.getMessage().contains( badCell ) );
+ }
+ }
+
+ /**
+ * Spurious code snippet.
+ */
+ @Test
+ public void testSpuriousCodeSnippet() {
+ try {
+ makeRuleSet();
+ makeRuleTable();
+ makeRow( 11, "C", "C", "A" );
+ makeRow( 12, "Foo", "Foo" );
+ makeRow( 13, "attr == $param", "attr == $param", "action();", "attr > $param" );
+ makeRow( 15, "1", "2", "" );
+ listener.finishSheet();
+ fail( "should have failed" );
+ } catch( DecisionTableParseException e ) {
+ String badCell = RuleSheetParserUtil.rc2name( 13, 4 );
+ System.err.println( e.getMessage() );
+ assertTrue( e.getMessage().contains( badCell ) );
+ }
+ }
+
+ /**
+ * Incorrect priority - not numeric
+ */
+ @Test
+ public void testIncorrectPriority() {
+ try {
+ makeRuleSet();
+ makeRuleTable();
+ makeRow( 11, "C", "A", "P" );
+ makeRow( 12, "Foo", "Foo" );
+ makeRow( 13, "attr == $param", "x" );
+ makeRow( 15, "1", "show()", "12E" );
+ listener.finishSheet();
+ fail( "should have failed" );
+ } catch( DecisionTableParseException e ) {
+ String badCell = RuleSheetParserUtil.rc2name( 15, 3 );
+ System.err.println( e.getMessage() );
+ assertTrue( e.getMessage().contains( badCell ) );
+ }
+ }
+
+ /**
+ * Must not have snippet for attribute
+ */
+ @Test
+ public void testSnippetForAttribute() {
+ try {
+ makeRuleSet();
+ makeRuleTable();
+ makeRow( 11, "C", "A", "G" );
+ makeRow( 12, "Foo", "Foo" );
+ makeRow( 13, "attr == $param", "x", "XXX" );
+ makeRow( 15, "1", "show()", "10" );
+ listener.finishSheet();
+ fail( "should have failed" );
+ } catch( DecisionTableParseException e ) {
+ String badCell = RuleSheetParserUtil.rc2name( 13, 3 );
+ System.err.println( e.getMessage() );
+ assertTrue( e.getMessage().contains( badCell ) );
+ }
+ }
+
+ /**
+ * Check correct rendering of string-valued attribute
+ */
+ @Test
+ public void testRuleAttributeRendering() {
+ makeRuleSet();
+ makeRuleTable();
+ makeRow( 11, "C", "A", "G" );
+ makeRow( 12, "Foo", "Foo" );
+ makeRow( 13, "attr == $param", "x" );
+ makeRow( 15, "1", "show()", "foo bar" );
+ makeRow( 16, "2", "list()", "\"10\" group\"" );
+ listener.finishSheet();
+ Package p = listener.getRuleSet();
+ DRLOutput dout = new DRLOutput();
+ p.renderDRL(dout);
+ String drl = dout.getDRL();
+ // System.out.println( drl );
+ assertTrue( drl.contains( "agenda-group \"foo bar\"" ) );
+ assertTrue( drl.contains( "agenda-group \"10\\\" group\"" ) );
+ }
+
+ /**
+ * Duplicate package level attribute
+ */
+ @Test
+ public void testDuplicatePackageAttribute() {
+ try {
+ makeRuleSet();
+ makeAttribute( "agenda-group", "agroup" ); // B3, C3
+ makeAttribute( "agenda-group", "bgroup" ); // B3. B4
+ makeRuleTable();
+ makeRow( 11, "C", "A", "P" );
+ makeRow( 12, "Foo", "Foo" );
+ makeRow( 13, "attr == $param", "x" );
+ makeRow( 15, "1", "show()", "10" );
+ listener.finishSheet();
+ Package p = listener.getRuleSet();
+ DRLOutput dout = new DRLOutput();
+ p.renderDRL(dout);
+ String drl = dout.getDRL();
+ // System.out.println( drl );
+ fail( "should have failed" );
+ } catch( DecisionTableParseException e ) {
+ System.err.println( e.getMessage() );
+ assertTrue( e.getMessage().contains( "C3, C4" ) );
+ }
+ }
+
+ /**
+ * Check correct rendering of package level attributes
+ */
+ @Test
+ public void testPackageAttributeRendering() {
+ makeRuleSet();
+ makeAttribute( "NO-LOOP", "true" );
+ makeAttribute( "agenda-group", "agroup" );
+ makeRuleTable();
+ makeRow( 11, "C", "A", "P" );
+ makeRow( 12, "foo:Foo", "foo" );
+ makeRow( 13, "attr == $param", "x($param)" );
+ makeRow( 15, "1", "1", "100" );
+ listener.finishSheet();
+ Package p = listener.getRuleSet();
+ DRLOutput dout = new DRLOutput();
+ p.renderDRL(dout);
+ String drl = dout.getDRL();
+ // System.out.println( drl );
+ assertTrue( drl.contains( "no-loop true" ) );
+ assertTrue( drl.contains( "agenda-group \"agroup\"" ) );
+ }
+
+ /**
+ * Must have a code snippet in an action.
+ */
+ @Test
+ public void testMissingCodeSnippetAction() {
+ try {
+ makeRuleSet();
+ makeRuleTable();
+ makeRow( 11, "C", "A" );
+ makeRow( 12, "foo: Foo", "Bar()" );
+ makeRow( 13, "attr == $param" );
+ makeRow( 15, "1", "1" );
+ makeRow( 16, "2", "2" );
+ listener.finishSheet();
+ Package p = listener.getRuleSet();
+ DRLOutput dout = new DRLOutput();
+ p.renderDRL(dout);
+ String drl = dout.getDRL();
+ System.out.println( drl );
+ fail( "should have failed" );
+ } catch( DecisionTableParseException e ) {
+ String badCell = RuleSheetParserUtil.rc2name( 13, 2 );
+ System.err.println( e.getMessage() );
+ assertTrue( e.getMessage().contains( badCell ) );
+ }
+ }
+
+ @Test
+ public void testMetadata() {
+ makeRuleSet();
+ makeRuleTable();
+ makeRow( 11, "C", "A", "@", "@" );
+ makeRow( 12, "foo: Foo", "foo" );
+ makeRow( 13, "attr == $param", "goaway($param)", "Author($param)", "Version($1-$2)" );
+ makeRow( 15, "1", "1", "J.W.Goethe", "3,14" );
+ makeRow( 16, "2", "2", "", "" );
+ listener.finishSheet();
+ Package p = listener.getRuleSet();
+ DRLOutput dout = new DRLOutput();
+ p.renderDRL(dout);
+ String drl = dout.getDRL();
+
+ assertTrue( drl.contains( "@Author(J.W.Goethe)" ) );
+ assertTrue( drl.contains( "@Version(3-14)" ) );
+ assertFalse( drl.contains( "@Author()" ) );
+ assertFalse( drl.contains( "@Version(-)" ) );
+ }
+
+
+ /**
+ * See if it can cope with odd shaped rule table, including missing
+ * conditions. Also is not "sequential".
+ */
+ @Test
+ public void testComplexWorksheetMissingConditionsInLocaleEnUs() throws Exception {
+ Locale originalDefaultLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ doComplexWorksheetMissingConditions();
+ Locale.setDefault(originalDefaultLocale);
+ }
+
+ @Test @Ignore // TODO JBRULES-2880 TIRELLI: Ignore test while we decide what to do in order to solve i18n issues
+ public void testComplexWorksheetMissingConditionsInLocaleFrFr() throws Exception {
+ Locale originalDefaultLocale = Locale.getDefault();
+ Locale.setDefault(Locale.FRANCE);
+ doComplexWorksheetMissingConditions();
+ Locale.setDefault(originalDefaultLocale);
+ }
+
+ private void doComplexWorksheetMissingConditions() throws IOException {
+ final InputStream stream = RuleWorksheetParseTest.class.getResourceAsStream( "/data/ComplexWorkbook.xls" );
+ final RuleSheetListener listener = getRuleSheetListener( stream );
+
+ final Package ruleset = listener.getRuleSet();
+ assertEquals( 6, ruleset.getRules().size() );
+ assertEquals( 0, ruleset.getImports().size() );
+
+ Rule rule = (Rule) ruleset.getRules().get( 0 );
+ assertEquals( 3, rule.getConditions().size() );
+ assertEquals( 2, rule.getConsequences().size() );
+ final Consequence cons = (Consequence) rule.getConsequences().get( 1 );
+ assertEquals( "myObject.setIsValid(1, 2)", cons.getSnippet() );
+ final Condition con = (Condition) rule.getConditions().get( 2 );
+ assertEquals( "myObject.size() < $3.00", con.getSnippet() );
+
+ rule = (Rule) ruleset.getRules().get( 4 );
+
+ // this should have less conditions
+ assertEquals( 1, rule.getConditions().size() );
+
+ rule = (Rule) ruleset.getRules().get( 5 );
+ assertEquals( 2, rule.getConditions().size() );
+ assertEquals( 1, rule.getConsequences().size() );
+ }
+
+ /**
+ * Utility method showing how to get a rule sheet listener from a stream.
+ */
+ public static RuleSheetListener getRuleSheetListener(final InputStream stream) throws IOException {
+ return RulesheetUtil.getRuleSheetListener( stream );
+ }
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RulesheetUtil.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RulesheetUtil.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RulesheetUtil.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser;
+
+import java.io.IOException;
+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.xls.ExcelParser;
+import org.drools.template.parser.DataListener;
+
+/**
+ * @author <a href="mailto:michael.neale at gmail.com"> Michael Neale</a>
+ *
+ */
+public class RulesheetUtil {
+
+ /**
+ * Utility method showing how to get a rule sheet listener from a stream.
+ */
+ public static RuleSheetListener getRuleSheetListener(final InputStream stream) throws IOException {
+ final Map<String, List<DataListener>> sheetListeners = new HashMap<String, List<DataListener>>();
+ final List<DataListener> listeners = new ArrayList<DataListener>();
+ final RuleSheetListener listener = new DefaultRuleSheetListener();
+ listeners.add(listener);
+ sheetListeners.put( ExcelParser.DEFAULT_RULESHEET_NAME,
+ listeners );
+ final ExcelParser parser = new ExcelParser( sheetListeners );
+ try {
+ parser.parseFile( stream );
+ } finally {
+ stream.close();
+ }
+ stream.close();
+ return listener;
+ }
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvLineParserTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvLineParserTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvLineParserTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser.csv;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class CsvLineParserTest {
+
+ @Test
+ public void testSimpleLineParse() {
+ final CsvLineParser parser = new CsvLineParser();
+ final String s = "a,b,c";
+ final List<String> list = parser.parse( s );
+ assertEquals( 3,
+ list.size() );
+
+ assertEquals( "a",
+ list.get( 0 ) );
+ assertEquals( "b",
+ list.get( 1 ) );
+ assertEquals( "c",
+ list.get( 2 ) );
+ }
+
+ @Test
+ public void testLineParse() {
+ final CsvLineParser parser = new CsvLineParser();
+ final String s = "a,\"b\",c";
+ final List<String> list = parser.parse( s );
+ assertEquals( 3,
+ list.size() );
+
+ assertEquals( "a",
+ list.get( 0 ) );
+ assertEquals( "b",
+ list.get( 1 ) );
+ assertEquals( "c",
+ list.get( 2 ) );
+ }
+
+ @Test
+ public void testDoubleQuotes() {
+ final CsvLineParser parser = new CsvLineParser();
+ final String s = "a,\"\"\"b\"\"\",c";
+ final List<String> list = parser.parse( s );
+ assertEquals( 3,
+ list.size() );
+
+ assertEquals( "a",
+ list.get( 0 ) );
+ assertEquals( "\"b\"",
+ list.get( 1 ) );
+ assertEquals( "c",
+ list.get( 2 ) );
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvParserTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvParserTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvParserTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser.csv;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import org.drools.template.parser.DataListener;
+
+public class CsvParserTest {
+
+ @Test
+ public void testCsv() {
+ final MockSheetListener listener = new MockSheetListener();
+ final CsvLineParser lineParser = new CsvLineParser();
+ final CsvParser parser = new CsvParser( listener,
+ lineParser );
+
+ parser.parseFile( getClass().getResourceAsStream( "/data/TestCsv.csv" ) );
+ assertEquals( "A",
+ listener.getCell( 0,
+ 0 ) );
+ assertEquals( "B",
+ listener.getCell( 0,
+ 1 ) );
+ assertEquals( "",
+ listener.getCell( 2,
+ 0 ) );
+ assertEquals( "C",
+ listener.getCell( 1,
+ 0 ) );
+ assertEquals( "D",
+ listener.getCell( 1,
+ 1 ) );
+ assertEquals( "E",
+ listener.getCell( 1,
+ 3 ) );
+
+ }
+
+ /**
+ * Test the handling of merged cells.
+ */
+ @Test
+ public void testCellMergeHandling() {
+ CsvParser parser = new CsvParser( (DataListener) null,
+ null );
+ assertEquals( DataListener.NON_MERGED,
+ parser.calcStartMerge( DataListener.NON_MERGED,
+ 1,
+ "foo" ) );
+ assertEquals( 42,
+ parser.calcStartMerge( DataListener.NON_MERGED,
+ 42,
+ "..." ) );
+
+ assertEquals( 42,
+ parser.calcStartMerge( 42,
+ 43,
+ "..." ) );
+
+ assertEquals( DataListener.NON_MERGED,
+ parser.calcStartMerge( 42,
+ 44,
+ "VanHalen" ) );
+
+ assertEquals( "VanHalen",
+ parser.calcCellText( DataListener.NON_MERGED,
+ "VanHalen" ) );
+ assertEquals( "VanHalen",
+ parser.calcCellText( 42,
+ "VanHalen..." ) );
+ assertEquals( "",
+ parser.calcCellText( 42,
+ "..." ) );
+
+ }
+
+ static class MockSheetListener
+ implements
+ DataListener {
+
+ Map<String, String> data = new HashMap<String, String>();
+
+ public String getCell(final int row,
+ final int col) {
+ return this.data.get( cellKey( row,
+ col ) );
+ }
+
+ public void startSheet(final String name) {
+ }
+
+ public void finishSheet() {
+ }
+
+ public void newRow(final int rowNumber,
+ final int columns) {
+
+ }
+
+ public void newCell(final int row,
+ final int column,
+ final String value,
+ final int mergeCellStart) {
+
+ this.data.put( cellKey( row,
+ column ),
+ value );
+ }
+
+ String cellKey(final int row,
+ final int column) {
+ return "R" + row + "C" + column;
+ }
+ }
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/xls/ExcelParserTest.java
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/xls/ExcelParserTest.java (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/xls/ExcelParserTest.java 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.decisiontable.parser.xls;
+
+import java.util.List;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+import jxl.Cell;
+import jxl.CellType;
+import jxl.Range;
+import jxl.format.CellFormat;
+
+import org.drools.template.parser.DataListener;
+
+/**
+ * @author <a href="mailto:michael.neale at gmail.com"> Michael Neale</a>
+ *
+ * Some unit tests for the corners of ExcelParser that are not explicitly
+ * covered by integration tests.
+ */
+public class ExcelParserTest {
+
+ @Test
+ public void testRemoveTrailingZero() {
+ String test = "1.0";
+ assertEquals( "1",
+ ExcelParser.removeTrailingZero( test ) );
+
+ test = "42.0";
+ assertEquals( "42",
+ ExcelParser.removeTrailingZero( test ) );
+
+ test = "42";
+ assertEquals( "42",
+ ExcelParser.removeTrailingZero( test ) );
+
+ }
+
+ /**
+ * This should test to see if a cell is in a certain range or not.
+ * If it is in a merged range, then it should return the top left cell.
+ * @throws Exception
+ */
+ @Test
+ public void testCellMerge() throws Exception {
+ ExcelParser parser = new ExcelParser((Map<String, List<DataListener>>) null);
+
+ Range[] ranges = new Range[1];
+
+ MockRange r1 = new MockRange();
+ ranges[0] = r1;
+ r1.topLeft = new MockCell();
+ r1.topLeft.row = 2;
+ r1.topLeft.column = 2;
+ r1.topLeft.contents = "first";
+
+
+
+ r1.bottomRight = new MockCell();
+ r1.bottomRight.column = 5;
+ r1.bottomRight.row = 7;
+ r1.bottomRight.contents = "last";
+
+
+ MockCell cell = new MockCell();
+ cell.contents = "test";
+ cell.row = 1;
+ cell.column = 1;
+
+ assertNull(parser.getRangeIfMerged( cell, ranges));
+
+ cell = new MockCell();
+ cell.contents = "wrong";
+ cell.row = 2;
+ cell.column = 5;
+
+ assertEquals("first", parser.getRangeIfMerged( cell, ranges).getTopLeft().getContents());
+
+ }
+
+ static class MockCell<CellFeatures> implements Cell {
+
+ int column;
+ int row;
+ String contents;
+
+
+ public CellFormat getCellFormat() {
+ return null;
+ }
+
+ public int getColumn() {
+ return column;
+ }
+
+ public String getContents() {
+ return contents;
+ }
+
+ public int getRow() {
+ return row;
+ }
+
+ public CellType getType() {
+ return null;
+ }
+
+ public boolean isHidden() {
+ return false;
+ }
+
+ public jxl.CellFeatures getCellFeatures() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ }
+
+ static class MockRange implements Range {
+
+ MockCell bottomRight;
+ MockCell topLeft;
+
+ public Cell getBottomRight() {
+ return bottomRight;
+ }
+
+ public int getFirstSheetIndex() {
+ return 0;
+ }
+
+ public int getLastSheetIndex() {
+ return 0;
+ }
+
+ public Cell getTopLeft() {
+ return topLeft;
+ }
+
+ }
+
+}
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/BasicWorkbook.xls
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/BasicWorkbook.xls
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/ComplexWorkbook.csv
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/ComplexWorkbook.csv (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/ComplexWorkbook.csv 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,21 @@
+,"RuleSet","ruleSetName",,,
+,,,,,
+,,,,,
+,,,,,
+,"RuleTable - Mine",,,,
+,"C","C","C","A","A"
+,"Foo...","Foo...",,,
+,"myObject.getColour().equals($param)","myObject.size () > $param","myObject.size() < $param","myObject.setIsValid($param)","myObject.setIsValid($1, $2)"
+,"Colour Type","Object size","Object size","Valid Object","Valid Object"
+"some stuff","red",1,3,TRUE,"1,2"
+"more to ignore","yellow",2,6,FALSE,"1,2"
+,"blue",7,9,"N","1,3"
+,,,,,
+"RuleTable - freddy2",,,,,
+"C","C","C","A",,
+,,,,,
+"myObject.getColour().equals($param)","myObject.size () > $param","myObject.size() < $param","myObject.setIsValid($param)",,
+"Colour Type","Object size","Object size","Valid Object",,
+"red",10,20,"Y",,
+"yellow"," ",,"Y",,
+,50,60,"Y",,
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/ComplexWorkbook.xls
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/ComplexWorkbook.xls
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/CustomWorkbook.xls
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/CustomWorkbook.xls
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/ExamplePolicyPricing.xls
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/ExamplePolicyPricing.xls
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/IntegrationExampleTest.xls
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/IntegrationExampleTest.xls
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/MultiSheetDST.xls
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/MultiSheetDST.xls
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/TeamAllocationExample_TYPICAL_EXAMPLE.xls
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/TeamAllocationExample_TYPICAL_EXAMPLE.xls
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/TestCsv.csv
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/TestCsv.csv (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/TestCsv.csv 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,3 @@
+A,B,
+C,D,,E
+,X
\ No newline at end of file
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/VeryLargeWorkbook.xls
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/data/VeryLargeWorkbook.xls
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/drools/decisiontable/changeset1Test.drl
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/drools/decisiontable/changeset1Test.drl (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/drools/decisiontable/changeset1Test.drl 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,10 @@
+package org.drools.test
+
+global java.util.List list;
+
+rule "rule1"
+ salience 10
+when
+then
+ list.add( "rule1" );
+end
\ No newline at end of file
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/drools/decisiontable/changeset1Test.xml
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/drools/decisiontable/changeset1Test.xml (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/drools/decisiontable/changeset1Test.xml 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,13 @@
+<change-set xmlns='http://drools.org/drools-5.0/change-set'
+ xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'
+ xs:schemaLocation='http://drools.org/drools-5.0/change-set http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd' >
+
+ <add>
+
+ <resource source='classpath:org/drools/decisiontable/changeset1Test.drl' type='DRL' />
+ <resource source='classpath:data/IntegrationExampleTest.xls' type="DTABLE">
+ <decisiontable-conf input-type="XLS" worksheet-name="Tables_2" />
+ </resource>
+ <resource source='classpath:org/drools/decisiontable/changeset2Test.drl' type='DRL' />
+ </add>
+</change-set>
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/drools/decisiontable/changeset2Test.drl
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/drools/decisiontable/changeset2Test.drl (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/org/drools/decisiontable/changeset2Test.drl 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,10 @@
+package org.drools.test
+
+global java.util.List list;
+
+rule "rule2"
+ salience 5
+when
+then
+ list.add( "rule2" );
+end
\ No newline at end of file
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_integration.drl
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_integration.drl (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_integration.drl 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,24 @@
+template header
+age: Long
+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 > 21 && < 43
+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/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_pricing1.drl
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_pricing1.drl (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_pricing1.drl 2011-02-24 15:37:22 UTC (rev 36699)
@@ -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/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_pricing2.drl
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_pricing2.drl (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_pricing2.drl 2011-02-24 15:37:22 UTC (rev 36699)
@@ -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/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template1.drl
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template1.drl (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template1.drl 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,39 @@
+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() >= @{age0} && user.getAge() <= @{age1}
+ then
+ System.out.println( "@{log}" );
+ user.setCoolness("@{coolness}");
+end
+end template
+template "uncoolness"
+name
+age
+log
+rule "How uncool is @{name} @{row.rowNumber}"
+ when
+ user.getName().equals("@{name}")
+ user.getAge() >= @{age0} && user.getAge() <= @{age1}
+ then
+ System.out.println( "@{log}" );
+ user.setCoolness("Not so cool"); //@{coolness} putting the column in the comments makes the line conditionally display
+end
+end template
+
Added: labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template2.drl
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template2.drl (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template2.drl 2011-02-24 15:37:22 UTC (rev 36699)
@@ -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/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template3.drl
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template3.drl (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template3.drl 2011-02-24 15:37:22 UTC (rev 36699)
@@ -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/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template4.drl
===================================================================
--- labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template4.drl (rev 0)
+++ labs/jbossrules/tags/5.2.0.M1/drools-decisiontables/src/test/resources/templates/test_template4.drl 2011-02-24 15:37:22 UTC (rev 36699)
@@ -0,0 +1,29 @@
+template header
+colour
+minSize
+maxSize
+
+
+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
+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(true);
+end
+end template
+
More information about the jboss-svn-commits
mailing list