Friday, July 23, 2010

Glazed Lists examples for Drools Live Querries

A while back I talked about the new features with Drools for Live querries:

Where you could open a query in Drools and receive event notifications for added, deleted and upated rows. I mentioned this could be used with Glazed Lists for filtering, sorting and transformation.

I just added a unit test to Drools, which people can use as a template for their own Drools integration with Glazed Lists. The test is based on the one in QueryTest.testOpenQuery():

The EventList implemention itself is very simple. At the moment it backs onto an ArrayList and uses linear searches for the updates and removes. Because Drools is likely to have a high volume of changes it should probably be backed by a HashMap or something for constant levels of performance for those lookups.
public class DroolsEventList extends AbstractEventList implements ViewChangedEventListener {
List data = new ArrayList();

public Row get(int index) {
return index );

public int size() {

public void rowAdded(Row row) {
int index = size();
updates.elementInserted(index, row);
boolean result = data.add(row);

public void rowRemoved(Row row) {
int index = row );
Row removed = data.remove( index );
updates.elementDeleted(index, removed);

public void rowUpdated(Row row) {
int index = row );
updates.elementUpdated(index, row, row);
Creating and using the EventList is also trivial, here is a snippet from the test using the SortedEventList:
        DroolsEventList list = new DroolsEventList();
// Open the LiveQuery
LiveQuery query = ksession.openLiveQuery( "cheeses", new Object[] { "cheddar", "stilton" } , list );

SortedList sorted = new SortedList( list, new Comparator() {

public int compare(Row r1,
Row r2) {
Cheese c1 = ( Cheese ) r1.get( "stilton" );
Cheese c2 = ( Cheese ) r2.get( "stilton" );
return c1.getPrice() - c2.getPrice();

assertEquals( 3, sorted.size() );
assertEquals( 1, ((Cheese)sorted.get( 0 ).get( "stilton" )).getPrice() );
assertEquals( 2, ((Cheese)sorted.get( 1 ).get( "stilton" )).getPrice() );
assertEquals( 3, ((Cheese)sorted.get( 2 ).get( "stilton" )).getPrice() );


1 comment:

  1. Hi Mark Proctor,
    Db-table – tags
    Id value
    1 22
    2 24
    3 25

    public class Asset_Tag implements EntityType {

    private Integer id;
    private Integer value;
    public Integer getId() {
    return id;
    public void setId(Integer id) { = id;
    public Integer getValue() {
    return value;
    public void setValue(Integer value) {
    this.value = value;

    Statement sta = conn.createStatement();
    String sql = "SELECT id,value FROM tags";
    ResultSet rs = sta.executeQuery(sql);

    List list = new ArrayList();
    while ( {
    Asset_Tag assetTag = new Asset_Tag();

    String drl=applyRuleTemplateDynamic(assetTag, condition);
    EvaluateRule evaluateRule = new EvaluateRule();
    AlertDecision alertDecision = evaluateRule.evaluate(drl, list);

    Now my condition ((id==1 && value==22) && (id==2 && value==24)) and I formed drl file using below code.(I am fetching this condition from db)
    private String applyRuleTemplateDynamic(Asset_Tag assetTag, String condition) {
    Map data = new HashMap();
    ObjectDataCompiler objectDataCompiler = new ObjectDataCompiler();

    data.put("CustomeRule", condition);
    data.put("eventType", assetTag.getClass().getName());

    return objectDataCompiler.compile(Arrays.asList(data),

    Drl file:
    package com.iot;
    global com.iot.AlertDecision alertDecision;

    rule "alert_0"
    com.iot.entityType.Asset_Tag(((id==1 && value==22) && (id==2 && value==24)))

    Now I am passing data to execute drl file,
    public AlertDecision evaluate(String drl, List list) {
    KieServices kieServices = KieServices.Factory.get();
    KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
    kieFileSystem.write("src/main/resources/rule.drl", drl);
    //ReleaseId releaseId = kieServices.newReleaseId("org.default", "artifact", "1.0.0-SNAPSHOT");
    KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
    StatelessKieSession statelessKieSession = kieContainer.getKieBase().newStatelessKieSession();

    AlertDecision alertDecision = new AlertDecision();
    statelessKieSession.getGlobals().set("alertDecision", alertDecision);

    return alertDecision;


    Now my question is list contain 3 records, statelessKieSession.execute(list) this line execute only one row from list will consider and condition will get fail there any way I can pass all 3 records and condtion will satisfy

    plz help me out my mail id