[rules-users] collection question

Wolfgang Laun wolfgang.laun at gmail.com
Wed Jul 21 02:59:40 EDT 2010


Things would be smpler if you could avoid re-creating Product objects
because adding an identical Object does not change the Set. (This
could be implemented with the help of a global Map<String,Product>,)

Second, overriding equals (and hashCode) in Product would also avoid adding
an "evil twin" in your rule code - as it is!

Even simpler is a solution where the relevant Product objects are inserted
as facts, so that
   $cd1 : Product( name == "cd1" )
   $bonus_cd : Product( name == "bonus_cd" )
   $order : ShippingOrder( products contains $cd1, products not
contains $bonus_cd )
is true (again, with equals and hashCode being overridden).

Given your solution with collect, an additional eval testing for
"bonus_cd" not being the
name of the single Product in List $productList might be more
efficient than iterating
all products a second time.

-W

On 21 July 2010 00:41, javaj <jmilliro at ameritech.net> wrote:
>
> I'm trying to write a rule to add an object to a collection if the collection
> already contained a certain object with a specific attribute.
>
> I developed a small example so maybe that will make more sense:
>
> Use Case: In a product shipping applicaiton, anytime a product with the name
> "cd1" is in the shipping order, a bonus product named "bonus_cd" needs to be
> added to the shipping order.  The bonus cd should not be added if it's
> already in the shipping order.
>
> Shipping Order:
>
> public class ShippingOrder {
>
>        private Set<Product> products;
>
>        public ShippingOrder() {}
>
>        public Set<Product> getProducts() {
>                return products;
>        }
>
>        public void setProducts(Set<Product> products) {
>                this.products = products;
>        }
>
> }
>
> Product:
>
> public class Product {
>
>        private String name;
>
>        public Product(){}
>
>        public String getName() {
>                return name;
>        }
>
>        public void setName(String name) {
>                this.name = name;
>        }
>
> }
>
>
> Rule:
>
> rule "AddBonusCd"
>
>        when
>                $so : ShippingOrder()
>                $productList : ArrayList(size == 1) from collect( Product(name matches
> "cd1|bonus_cd") from $so.products)
>        then
>                System.out.println("Adding Bonus Cd");
>
>                Set<Product> productSet = new HashSet<Product>($so.getProducts());
>
>                Product bonusCd = new Product();
>                bonusCd.setName("bonus_cd");
>                productSet.add(bonusCd);
>
>                modify($so) {
>                        setProducts(productSet);
>                }
> end
>
> The Shipping Order object is inserted as the fact.
>
> The rule is valid if only cd1 or cd_bonus is in the shipping order.  I only
> want the rule to run when cd1 is in the product set but cd_bonus is not.
> Makes sense?
>
> Thanks,
> J
> --
> View this message in context: http://drools-java-rules-engine.46999.n3.nabble.com/collection-question-tp982769p982769.html
> Sent from the Drools - User mailing list archive at Nabble.com.
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>




More information about the rules-users mailing list