Version 9

    Firstly please remember that any automated conversion will be suboptimal, and should really be a bootstrap process as the start of your migration. The reason for this is, other than class-field which maps to a literal constraint, using eval is much slow than using literal and bound variable constraints on a column - we cannot index evals. How much slower? About 10 to 20 times slower. I have tried to detail some simpler optimisations, I would work on automating these after the initial converter is built.

     

    parameter:

     

    <parameter identifier="foo">
        <class>Foo</class>
    <parameter>
    

    ---

    foo : Foo()
    

     

    condition:

     

    <java:condition>foo.getValue().equals("bar")</java:condition>
    

    ---

    eval(foo.getValue().equals("bar"))
    

     

    If at all possible I'd apply some further automated analysis to it converts very simple, and easy to recognise, conditions to literal and bound variable:

    <parameter identifier="foo">
        <class>Foo</class>
    <parameter>
    
    <java:condition>foo.getValue().equals("bar")<java:condition>
    

    ---

    foo : Foo(value == "bar")
    

     

    If  "foo" is not used other than in that condition, that I'd avoid binding the column to a variable.

     

     

    Its not possible to bind fields in Drools 2.x, but if you do an equality check on a parameter - that can map to a bound variable constraint. Remeber that you must declare a variable, before using it - so if it defines foo and then bar, you must correct that as appropriate.

    <parameter identifier="foo">
        <class>Foo</class>
    <parameter>
    <parameter identifier="bar">
        <class>Bar</class>
    <parameter>
    
    <java:condition>foo.equals(bar)<java:condition>
    

    ---

    bar : Bar()
    foo : Foo(value == bar)
    

     

    class-field:

     

    <class-field field="name" value="A">State</class-field>
    

    ---

    state : State(name == "A")
    

     

    semaphore:

     

    you will need to copy/paste old semaphore classes from drools 2.x to your own classpath

    http://fisheye.codehaus.org/browse/drools/drools/drools-base/src/main/org/drools/semantics/base

     

    Notice that the type is concatenated onto Sempahore, type="String" becomes StringSemaphore(...).

     

    There is no value for a semaphore, that is controlled in a later java condition.

    <parameter identifier="state">
        <semaphore type="String" ></semaphore>
    </parameter>
    

    ---

    StringSemaphore(identifier == "state")
    

     

    functions:

     

    This cannot be done in pure xslt. In Drools 2.5 basically produced a class body inside a <java:functions: block. In Drools 3.0 we now have a real function definition. So this will need to be done in two stages, maybe the first stage can produce a marked up block that can then be fixed with some regexp in the second phase - or maybe you can apply regexp search/replace within xslt.

    <java:functions>
        public static boolean amHappy(Something something) {
            return something.isHappy();
        }
    
        public static void log(String message) {
            System.out.println(message);
        }
    </java:functions>
    

    ---

    function boolean amHappy(Something something) {
            return something.isHappy();
    }
    function void log(String message) {
            System.out.println(message);
    }
    

     

    duration:

     

    This is now an attribute, which must be converted to a single long.

     

    -


    Drools 2 to 4 XML rule conversion:

     

    I upgraded my drools 2 rules to version 4 recently, would like to share this conversion application here. you can download Converter.zip from bottom of this page.

     

     

    This Converter.zip file contains one readme file and two jars:

     

    1. Readme.htm file showing the structure and how to run;

    2. The compiled class RuleConverter.jar which converts given file or directory to new one;

    3. The Eclipse project jar ConvertProject.jar for anyone might be interested;

     

     

    Simply run java -jar RuleConverter.jar your file, it will convert Drools 2 XML rules to version 4 XML format, the default format is XML. Please read readMe file for mroe information.

     

     

    For example, the version 2 rules is :

     

    <rule-set name="Tests assignment rules" xmlns="http://drools.org/rules"
         xmlns:java="http://drools.org/semantics/java"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
         <java:import>demo.Machine</java:import>
         <java:import>demo.Test</java:import>
         <java:import>demo.TestDAO</java:import>
         <java:import>java.util.Calendar</java:import>
         <java:import>java.sql.Timestamp</java:import>      
         <java:import>java.lang.String</java:import>      
         <java:functions>
              public static void setTestsDueTime(Machine machine, int numberOfDays) {
                   setTestsDueTime(machine, Calendar.DATE, numberOfDays);
              } 
              
              public static void setTestsDueTime(Machine machine, int field, int amount) {
                   Calendar calendar = Calendar.getInstance();
                   calendar.setTime(machine.getCreationTs());
                   calendar.add(field, amount);
                   machine.setTestsDueTime(new Timestamp(calendar.getTimeInMillis()));
              }
         </java:functions>     
    
         <rule name="Tests for type1 machine" salience="100">
              <parameter identifier="machine">
                   <java:class>
                        Machine
                   </java:class>
              </parameter>
              <java:condition>machine.getType().equals("Type1")</java:condition>
                    <java:condition>function.equals("Router")</java:condition>     
              <java:consequence>
                   Test test1 = testDAO.findByKey(Test.TEST1);
                   Test test2 = testDAO.findByKey(Test.TEST2);
                   Test test5 = testDAO.findByKey(Test.TEST5);
                   machine.getTests().add(test1);
                   machine.getTests().add(test2);
                   machine.getTests().add(test5);
                   drools.assertObject(test1);
                   drools.assertObject(test2);
                   drools.assertObject(test5);
              </java:consequence>
         </rule>
         </rule-set>
    

     

    The converted version 4 XML rule:

     

    <package xmlns:xs="http://www.w3.org/2001/XMLSchema" 
        xmlns:java="http://drools.org/semantics/java" 
        xmlns:fn="http://www.w3.org/2005/xpath-functions" 
        xmlns="http://drools.org/drools-4.0" 
        name="com.sample">
         <import name="demo.Machine"></import>
         <import name="demo.Test"></import>
         <import name="demo.TestDAO"></import>
         <import name="java.util.Calendar"></import>
         <import name="java.sql.Timestamp"></import>
         <import name="java.lang.String"></import>      
         <function name="setTestsDueTime" return-type="void">
              <parameter identifier="machine" type="Machine"></parameter>
              <parameter identifier="numberOfDays" type="int"></parameter>
              <body>
                   setTestsDueTime(machine, Calendar.DATE, numberOfDays);
              </body>
         </function>
         <function name="setTestsDueTime" return-type="void">
              <parameter identifier="machine" type="Machine"></parameter>
              <parameter identifier="field" type="int"></parameter>
              <parameter identifier="amount" type="int"></parameter>
              <body>
                   Calendar calendar = Calendar.getInstance();
                   calendar.setTime(machine.getCreationTs());
                   calendar.add(field, amount);
                   machine.setTestsDueTime(new Timestamp(calendar.getTimeInMillis()));
              </body>
         </function>
         <rule name="Tests for type1 machine">
              <lhs>
                   <and-conditional-element>
                        <eval>machine.getType().equals("Type1")</eval>
                                    <eval>function.equals("Router")</eval>
                   </and-conditional-element>
              </lhs>
              <rhs>
                   Test test1 = testDAO.findByKey(Test.TEST1);
                   Test test2 = testDAO.findByKey(Test.TEST2);
                   Test test5 = testDAO.findByKey(Test.TEST5);
                   machine.getTests().add(test1);
                   machine.getTests().add(test2);
                   machine.getTests().add(test5);
                   drools.assertObject(test1);
                   drools.assertObject(test2);
                   drools.assertObject(test5);
              </rhs>
         </rule>
    </package>
    

     

     

    I only implemented XML version, but have interface for any other version, please refer the readMe file and feel free add yours.