Search code examples
collectionstypesdroolsrulesdeclare

Drools 6.2 How to use ArrayList in declared types?


Here is what I have in my DLR file:

package mytypes;

declare Person
    firstName : String
    lastName : String    
    address : java.util.ArrayList
end

declare Address
    city : String
    state : String
end

rule "city"
when 
 p : Person()
 Address(city == "Dallas") from p.address
then
System.out.println("city rule fired");
end

I use gson to convert my json to ojbect of type Person using FactType. see below:

    FactType ft  = base.getFactType( "mytypes","Person" );
    Object oPerson = ft.newInstance();      
    Gson gConverter = new Gson();
    Object input = gConverter.fromJson(fact, oPerson.getClass());

Here is my json:

{"firstName":"John","lastName":"Smith","address":[{"city":"Dallas","state":"TX"}]}

I get the object back. This is how it looks in memory:

Person( firstName=John, lastName=Smith, address=[{city=Irving, state=TX}] )

My rule is not getting fired because as you can see there is no Address type inside address collection. Does anyone know how to make it work?

Alternatively, if i don't use json to get the Person object and I build it manually using "getFactType" and set properties using "set" then I am able to get my rule fired. Here is how I build it manually

    FactType ftPerson  = base.getFactType( "mytypes","Person" );
    Object oPerson = ft.newInstance();
    ArrayList al = new ArrayList();
    FactType ftAddress  = base.getFactType( "mytypes","Address" );
    Object add = ftAddress.newInstance();
    ftAddress.set(add, "city", "Dallas");
    ftAddress.set(add, "state", "TX");
    al.add(add);
    ftPerson.set(oPerson, "address", al);

This is how Person object looks in memory and notice how Address type is specified in address collection:

Person( firstName=null, lastName=null, address=[Address( city=Irving, state=TX )] )

I hope i have explained the complete scenario. How can i still use json and still make it work?


Solution

  • Since ArrayList is a generic collection, Gson is not able to correctly identify the type of the address object when processing the JSON string. The easiest way to accomplish what you are trying to do would be to use an array instead of a ArrayList:

    declare Person
      firstName : String
      lastName : String    
      address : Address[]
    end
    

    In that case, Gson should correctly pick up the type and the rule will fire.