Re: [rules-users] collection question
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 MapString,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 jmill...@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 SetProduct products; public ShippingOrder() {} public SetProduct getProducts() { return products; } public void setProducts(SetProduct 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); SetProduct productSet = new HashSetProduct($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@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] collection question
Hi J, In your example I don't think that the collect is necessary. I believe the following will work: rule AddBonusCd when $so : ShippingOrder() Product(name == cd1) from $so.products not (Product(name == bonus_cd) from $so.products) then System.out.println(Adding Bonus Cd); SetProduct productSet = new HashSetProduct($so.getProducts()); Product bonusCd = new Product(); bonusCd.setName(bonus_cd); productSet.add(bonusCd); modify($so) { setProducts(productSet); } end You don't need the collects because you are just checking for existence/non-existence of facts within the products collection. Good luck! Steve rules-users-boun...@lists.jboss.org wrote on 07/21/2010 01:59:40 AM: From: Wolfgang Laun wolfgang.l...@gmail.com To: Rules Users List rules-users@lists.jboss.org Date: 07/21/2010 02:02 AM Subject: Re: [rules-users] collection question Sent by: rules-users-boun...@lists.jboss.org 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 MapString,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 jmill...@ameritech.net wrote: I'm trying to write a rule to add an object to a collection if thecollection 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 SetProduct products; public ShippingOrder() {} public SetProduct getProducts() { return products; } public void setProducts(SetProduct 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); SetProduct productSet = new HashSetProduct ($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@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] collection question
Very clean. Earnie! From: Steve Ronderos steve.ronde...@ni.com To: Rules Users List rules-users@lists.jboss.org Sent: Wed, July 21, 2010 9:56:56 AM Subject: Re: [rules-users] collection question Hi J, In your example I don't think that the collect is necessary. I believe the following will work: rule AddBonusCd when $so : ShippingOrder() Product(name == cd1) from $so.products not (Product(name == bonus_cd) from $so.products) then System.out.println(Adding Bonus Cd); SetProduct productSet = new HashSetProduct($so.getProducts()); Product bonusCd = new Product(); bonusCd.setName(bonus_cd); productSet.add(bonusCd); modify($so) { setProducts(productSet); } end You don't need the collects because you are just checking for existence/non-existence of facts within the products collection. Good luck! Steve rules-users-boun...@lists.jboss.org wrote on 07/21/2010 01:59:40 AM: From: Wolfgang Laun wolfgang.l...@gmail.com To: Rules Users List rules-users@lists.jboss.org Date: 07/21/2010 02:02 AM Subject: Re: [rules-users] collection question Sent by: rules-users-boun...@lists.jboss.org 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 MapString,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 jmill...@ameritech.net wrote: I'm trying to write a rule to add an object to a collection if thecollection 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 SetProduct products; public ShippingOrder() {} public SetProduct getProducts() { return products; } public void setProducts(SetProduct 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); SetProduct productSet = new HashSetProduct ($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@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] collection question
Thanks everyone for your suggestions. I agree with Earnie that Steve's example is very clean and works like a charm. J -- View this message in context: http://drools-java-rules-engine.46999.n3.nabble.com/collection-question-tp982769p984439.html Sent from the Drools - User mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
[rules-users] collection question
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 SetProduct products; public ShippingOrder() {} public SetProduct getProducts() { return products; } public void setProducts(SetProduct 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); SetProduct productSet = new HashSetProduct($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@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] collection question
Would the following accomplish your goal? Earnie! import java.util.*; import com.sample.Product; import com.sample.ShippingOrder; rule AddBonusCd when $so : ShippingOrder() ArrayList(size == 1) from collect( Product(name matches cd1) from $so.products) ArrayList(size == 0) from collect( Product(name matches bonus_cd) from $so.products) then System.out.println(Adding Bonus Cd ); SetProduct productSet = new HashSetProduct($so.getProducts()); Product bonusCd = new Product(); bonusCd.setName(bonus_cd); productSet.add(bonusCd); modify($so) { setProducts(productSet); } end From: javaj jmill...@ameritech.net To: rules-users@lists.jboss.org Sent: Tue, July 20, 2010 6:41:25 PM Subject: [rules-users] collection question 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 SetProduct products; public ShippingOrder() {} public SetProduct getProducts() { return products; } public void setProducts(SetProduct 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); SetProduct productSet = new HashSetProduct($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@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users