[jboss-svn-commits] JBL Code SVN: r29117 - in labs/jbossrules/trunk/drools-templates/src: main/java/org/drools/template/jdbc and 3 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Aug 31 04:01:10 EDT 2009


Author: michael.neale at jboss.com
Date: 2009-08-31 04:01:09 -0400 (Mon, 31 Aug 2009)
New Revision: 29117

Added:
   labs/jbossrules/trunk/drools-templates/src/main/java/org/drools/template/jdbc/
   labs/jbossrules/trunk/drools-templates/src/main/java/org/drools/template/jdbc/ResultSetGenerator.java
   labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/
   labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/Cheese.java
   labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/Person.java
   labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/ResultSetGeneratorTest.java
   labs/jbossrules/trunk/drools-templates/src/test/resources/templates/Cheese.drt
Log:
JBRULES-2261 JDBC ResultSet to DRL generator (via drools-templates).

Added: labs/jbossrules/trunk/drools-templates/src/main/java/org/drools/template/jdbc/ResultSetGenerator.java
===================================================================
--- labs/jbossrules/trunk/drools-templates/src/main/java/org/drools/template/jdbc/ResultSetGenerator.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-templates/src/main/java/org/drools/template/jdbc/ResultSetGenerator.java	2009-08-31 08:01:09 UTC (rev 29117)
@@ -0,0 +1,153 @@
+package org.drools.template.jdbc;
+
+import org.drools.template.parser.TemplateContainer;
+import org.drools.template.parser.DefaultTemplateContainer;
+import org.drools.template.parser.TemplateDataListener;
+import org.drools.template.parser.DataListener;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+/**
+ * <p> A Drools template compiler which takes a ResultSet and compiles it into
+ * a template using DefaultTemplateContainer.</p>
+ *
+ * To use simply you need a JDBC ResultSet - with the field names mapping to the field names used in the template !
+ *
+ * @author <a href="mailto:javatestcase at yahoo.com">Bill Tarr</a>
+ */
+public class ResultSetGenerator {
+
+/**
+ * Generates DRL from a data provider for the spreadsheet data and templates.
+ *
+ * @param rs       the resultset for the table data
+ * @param template the string containing the template resource name
+ * @return the generated DRL text as a String
+ */
+public String compile(final ResultSet rs,
+                      final String template) {
+    final InputStream templateStream = this.getClass().getResourceAsStream(template);
+    return compile(rs,
+            templateStream);
+}
+
+/**
+ * Generates DRL from a data provider for the spreadsheet data and templates.
+ *
+ * @param rs             the resultset for the table data
+ * @param templateStream the InputStream for reading the templates
+ * @return the generated DRL text as a String
+ */
+public String compile(final ResultSet rs,
+                      final InputStream templateStream) {
+    TemplateContainer tc = new DefaultTemplateContainer(templateStream);
+    closeStream(templateStream);
+    return compile(rs,
+            new TemplateDataListener(tc));
+}
+
+/**
+ * Generates DRL from a data provider for the spreadsheet data and templates.
+ *
+ * @param rs       the resultset for the table data
+ * @param listener a template data listener
+ * @return the generated DRL text as a String
+ */
+public String compile(final ResultSet rs,
+                      final TemplateDataListener listener) {
+    List<DataListener> listeners = new ArrayList<DataListener>();
+    listeners.add(listener);
+    processData(rs,
+            listeners);
+    return listener.renderDRL();
+}
+
+/**
+ * Iterate through the resultset.
+ * @param rs       the resultset for the table data
+ * @param listeners list of template data listener
+ */
+private void processData(final ResultSet rs,
+                         List<DataListener> listeners) {
+
+    try {
+        ResultSetMetaData rsmd = rs.getMetaData();
+        int colCount = rsmd.getColumnCount();
+
+        int i = 0;
+
+        while (rs.next()) {
+            newRow(listeners, i, colCount);
+            for (int cellNum = 1; cellNum < colCount + 1; cellNum++) {
+                String cell;
+
+                int sqlType = rsmd.getColumnType(cellNum);
+                switch (sqlType) {
+                    case java.sql.Types.DATE:
+                        cell = rs.getDate(cellNum).toString();
+                        break;
+                    case java.sql.Types.INTEGER:
+                    case java.sql.Types.DOUBLE:
+                        cell = String.valueOf(rs.getInt(cellNum));
+                        break;
+                    default:
+                        cell = rs.getString(cellNum);
+                }
+
+                newCell(listeners,
+                        i,
+                        cellNum -1,
+                        cell,
+                        DataListener.NON_MERGED);
+            }
+            i++;
+        }
+
+    } catch (SQLException e) {
+         //TODO: you need to throw or handle
+    }
+
+    finishData(listeners);
+}
+
+private void finishData(List<DataListener> listeners) {
+    for (DataListener listener : listeners) {
+        listener.finishSheet();
+    }
+}
+
+private void newRow(List<DataListener> listeners,
+                    int row,
+                    int cols) {
+    for (DataListener listener : listeners) {
+        listener.newRow(row,
+                cols);
+    }
+}
+
+public void newCell(List<DataListener> listeners,
+                    int row,
+                    int column,
+                    String value,
+                    int mergedColStart) {
+    for (DataListener listener : listeners) {
+        listener.newCell(row,
+                column,
+                value,
+                mergedColStart);
+    }
+}
+
+protected void closeStream(final InputStream stream) {
+    try {
+        stream.close();
+    } catch (final Exception e) {
+        System.err.print("WARNING: Wasn't able to correctly close stream for rule template. " + e.getMessage());
+    }
+}
+}


Property changes on: labs/jbossrules/trunk/drools-templates/src/main/java/org/drools/template/jdbc/ResultSetGenerator.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/Cheese.java
===================================================================
--- labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/Cheese.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/Cheese.java	2009-08-31 08:01:09 UTC (rev 29117)
@@ -0,0 +1,32 @@
+package org.drools.template.jdbc;
+
+/**
+ * @author Michael Neale
+ */
+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;
+    }
+
+}


Property changes on: labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/Cheese.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/Person.java
===================================================================
--- labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/Person.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/Person.java	2009-08-31 08:01:09 UTC (rev 29117)
@@ -0,0 +1,93 @@
+package org.drools.template.jdbc;
+
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class 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 + "']";
+    }
+}


Property changes on: labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/Person.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/ResultSetGeneratorTest.java
===================================================================
--- labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/ResultSetGeneratorTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/ResultSetGeneratorTest.java	2009-08-31 08:01:09 UTC (rev 29117)
@@ -0,0 +1,127 @@
+package org.drools.template.jdbc;
+
+import junit.framework.TestCase;
+import org.drools.RuleBase;
+import org.drools.WorkingMemory;
+import org.drools.RuleBaseFactory;
+import org.drools.compiler.PackageBuilder;
+
+import java.sql.*;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.util.List;
+import java.util.ArrayList;
+
+
+/**
+ * /**
+ * <p>A simple example of using the ResultSetGenerator.
+ * The template used is "Cheese.drt" the same used by SimpleRuleTemplateExample.
+ * Rather than use the spreadsheet ExampleCheese.xls, this example reads the data
+ * from an HSQL database (which is created in this example.)</p>
+ * @author Michael Neale
+ * @author Bill Tarr       
+ */
+public class ResultSetGeneratorTest extends TestCase {
+  
+
+
+    public void testResultSet() throws Exception {
+
+        // setup the HSQL database with our rules.
+        Class.forName("org.hsqldb.jdbcDriver");
+        Connection conn = DriverManager.getConnection("jdbc:hsqldb:RULES", "sa", "");
+
+        try {
+            update("CREATE TABLE cheese_rules ( id INTEGER IDENTITY, persons_age INTEGER, birth_date DATE, cheese_type VARCHAR(256), log VARCHAR(256) )", conn);
+
+            update("INSERT INTO cheese_rules(persons_age,birth_date,cheese_type,log) VALUES(42, '1950-01-01', 'stilton', 'Old man stilton')", conn);
+            update("INSERT INTO cheese_rules(persons_age,birth_date,cheese_type,log) VALUES(10, '2009-01-01', 'cheddar', 'Young man cheddar')", conn);
+        } catch (SQLException e) {
+            // catch exception for table already existing
+        }
+
+        // query the DB for the rule rows, convert them using the template.
+
+        Statement sta = conn.createStatement();
+        ResultSet rs = sta.executeQuery("SELECT persons_age, cheese_type, log " +
+                " FROM cheese_rules");
+
+        final ResultSetGenerator converter = new ResultSetGenerator();
+        final String drl1 = converter.compile(rs, getRulesStream());
+
+        System.out.println(drl1);
+
+        sta.close();
+
+        String drl = drl1;
+
+        // test that our rules can execute.
+        final RuleBase rb = buildRuleBase(drl);
+
+        WorkingMemory wm = rb.newStatefulSession();
+
+        //now create some test data
+        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());
+
+    }
+
+    /**
+     * Build the rule base from the generated DRL.
+     * Same method from SimpleRuleTemplateExample.
+     *
+     * @param drls variable length of Drools rules as strings
+     * @return RuleBase built from the rules
+     * @throws Exception Add Exception handling to a real implementation.
+     */
+    private RuleBase buildRuleBase(String... drls) throws Exception {
+        //now we build the rule package and rulebase, as if they are normal rules
+        PackageBuilder builder = new PackageBuilder();
+        for (String drl : drls) {
+            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;
+    }
+
+    /**
+     * simple getter method looks up our template as a Resource
+     *
+     * @return the template as an InputStream
+     */
+    private InputStream getRulesStream() {
+        return this.getClass().getResourceAsStream("/templates/Cheese.drt");
+    }
+
+    /**
+     * An HSQL update wrapper from http://hsqldb.org/doc/guide/apb.html
+     *
+     * @param expression SQL expression
+     * @throws SQLException just rethrowing all the errors for the example
+     */
+    private void update(String expression, Connection conn) throws SQLException {
+        Statement st;
+        st = conn.createStatement();
+        int i = st.executeUpdate(expression);
+        if (i == -1) {
+            System.out.println("db error : " + expression);
+        }
+
+        st.close();
+    }
+
+}


Property changes on: labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/jdbc/ResultSetGeneratorTest.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-templates/src/test/resources/templates/Cheese.drt
===================================================================
--- labs/jbossrules/trunk/drools-templates/src/test/resources/templates/Cheese.drt	                        (rev 0)
+++ labs/jbossrules/trunk/drools-templates/src/test/resources/templates/Cheese.drt	2009-08-31 08:01:09 UTC (rev 29117)
@@ -0,0 +1,19 @@
+template header
+age
+type
+log
+
+package org.drools.template.jdbc;
+
+global java.util.List list;
+
+template "cheesefans"
+
+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


Property changes on: labs/jbossrules/trunk/drools-templates/src/test/resources/templates/Cheese.drt
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the jboss-svn-commits mailing list