Saturday, 12 June 2010

Ubuntu Upgrade (8.04->10.04)

I have been upgrading my laptop from Ubuntu 8.04 to 10.04.

The process was fairly simple. My laptop is a Dell Inspiron 9400 and, because I need to ensure maximum uptime, I bought another hard drive (WD Scorpio 250GB WD2500BEKT) to install the new version on. I like to have an easy bail-out strategy for these things and $NZ100-ish is a small price to pay for peace of mind. So I did not run the upgrade script on my existing setup, I installed from clean. This is a good thing to do from time to time anyway because rubbish does accumulate (stuff I thought I would use etc that is too much trouble to hunt down and remove).

How did it go? Very smoothly. After doing the main install I installed everything I needed using the package manager and that was almost all I needed to do. I had to install oracle XE from a separate download and I had a problem on my second monitor. The monitor display was 'wobbly', I could just about read it but certainly not well enough for it to be useful. Googling showed other people were struggling with this problem but the answer was from this guy. Very simple and it worked right away.

I had some minor issues with getting CVSNT working properly after I copied my local repository over but that was just a case of following the instructions closely and doing what they said.

Thunderbird files copied over just fine and set up all my folders and calendars etc. Firefox didn't but I used the export/import for that and it worked.

Things I have not yet verified:
1) Do the VirtualBox machines still see my USB ports? I had issues with that earlier and the answer was to use the non-open version of VirtualBox. No problem, but I'm not sure which version I installed this time.
2) I haven't yet installed my 3G modem. I rarely use it directly, I normally plug it into my wireless router and wireless is working just fine.
3) Phone sync. MyPhoneExplorer, which is a Windows program, was a pain to install on Linux earlier and it never has worked that well under Linux. It is very nice under Windows but when it runs under Wine on Linux enough extra features are crippled for me to look elsewhere for a simple sync program.

But my Java development environment works, email works, open office works etc etc. So I am all set. Now back to Madura Rules development.

Sunday, 6 June 2010

Madura Rules Part 2

My previous post covered how to specify rules for the Madura Rules engine. This post covers how to add Madura Rules to your application.

First, we are assuming that your application is already using Madura Objects and that all we need to do here is build on that.

Add something like this to your ant build script:

<taskdef name="xjr" classname="nz.co.senanque.generate.XJR">
    <classpath>
      <fileset dir="${basedir}/temp/lib" includes="*.jar" />
    </classpath>
</taskdef>

<target name="generateRules">
    <xjr destdir="${basedir}/generated"
    rules="${basedir}/test/nz/co/senanque/rulesparser/ObjectTest.txt"
    schema="${basedir}/sandbox.xsd"
    packageName="nz.co.senanque.objecttestrules"
    xsdpackageName="nz.co.senanque.madura.sandbox"/>
</target>

Some explanation: this defines an ant task in the taskdef tag. We're assuming you copied the MaduraRules jar file and its dependencies into the ${basedir}/temp/lib dir.

Then we've defined a target which generates the rules. The rules file, schema file and target package for the generated Java must be specified. The xsdpackageName should be the same as the package you specified in your XJC when you generated the Java for your business objects. You can omit this if you the two packages are the same.

That will generate a class for each rule. But that would not be all that smart (translating a text file into Java is done by your Java compiler all the time). No, the rules are translated into Java but the engine decides which rules are relevant to fire, and the smart bit is in the engine.

Now let's add some things to your Spring file.

<context:component-scan base-package="nz.co.senanque.objecttestrules"/>
<context:annotation-config/>

Make sure the base-package name agrees with the packageName in your XJR command. This ensures that Spring scans that package looking for rules to gather up and use in this...

<bean id="MaduraRulesPlugin" class="nz.co.senanque.rules.RulesPlugin" init-method="init">
  <property name="operations">
    <bean class="nz.co.senanque.rules.OperationsImpl"/>
  </property>
  <property name="decisionTableDocument">
    <bean class="nz.co.senanque.madura.spring.XMLSpringFactoryBean">
      <property name="fileLocation" value="/choices.xml"/>
    </bean>
  </property>
  <property name="constantsDocument">
    <bean class="nz.co.senanque.madura.spring.XMLSpringFactoryBean">
      <property name="fileLocation" value="/choices.xml"/>
    </bean>
  </property>
</bean>

All the properties here are optional and we cover them later. The important thing for now is that the MaduraRulesPlugin is injected into the validationEngine plugin (ie Madura Objects) like this:

<bean id="validationEngine" class="nz.co.senanque.validationengine.ValidationEngineImpl">
  <property name="plugins">
    <list>
      <ref bean="MaduraRulesPlugin"/>
    </list>
  </property>
  ...
</bean>

Yes, you can wire multiple plugins into Madura Objects. They can do whatever you like, actually. Madura Rules is a rules engine, but you might like to add a pricing engine or something more exotic in there. The only thing to watch out for is that you must not cross map fields to more than one engine because the engines cannot see each other's updates.

That's the job done. We defined some rules in the text file, generated them with XJR and then wired the engine into our Spring file. Those rules are now active, and your application code doesn't have to know anything about them. So, of course, you can change the rules at any time without changing your application code.

In my next post on this I will cover those extra properties and some more about what the rules can do.