Re: [rules-users] when condition on multiple facts of the same type
by Greg Barton
Doesn't seem to be a problem. See attached project.
--- On Mon, 8/17/09, Justin King <justin.matthew.king(a)gmail.com> wrote:
> From: Justin King <justin.matthew.king(a)gmail.com>
> Subject: [rules-users] when condition on multiple facts of the same type
> To: "Rules Users List" <rules-users(a)lists.jboss.org>
> Date: Monday, August 17, 2009, 8:24 PM
> I'm trying to have a rule execute based
> on the following condition:
>
> ObligationComplianceEvent(term == "term
> 1", obligation == "obligation 1", level ==
> 1)
> ObligationComplianceEvent(term == "term
> 2", obligation == "obligation 1", level ==
> 1)
>
>
> I pass in two facts of type ObligationComplianceEvent with
> the values shown above but the rule does not execute. It
> only executes if I put an 'or' like so
>
> ObligationComplianceEvent(term == "term
> 1", obligation == "obligation 1", level == 1)
> or
>
>
> ObligationComplianceEvent(term == "term
> 2", obligation == "obligation 1", level ==
> 1)
>
> Any help on what the correct way to do this is? I'm
> guessing its because it does not distinguish the two lines
> as two different facts, so because neither of the facts has
> the value 'term 1' and 'term 2' it never
> executes.
>
>
> Thanks for any help.
>
> Justin
>
>
> -----Inline Attachment Follows-----
>
> _______________________________________________
> rules-users mailing list
> rules-users(a)lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>
15 years, 4 months
Here is a ResultSetCompiler for drools-templates
by Bill Tarr
I’ve been trying out the DROOLS-TEMPLATES project, really impressed so far, surprised there isn’t more buzz about this project.
I wrote a new version of the DataProviderCompiler that takes a SQL ResultSet instead of a org.drools.template.DataProvider.
I don’t think it will be useful to that many people, so I’m not going to try and add it to the code base, but I’ll provide it here. I used it for testing out templates, but for our actual production code, I will naturally be using Hibernate to retrieve the rules from the DB (so I can take advantage of Hibernate cache.) It is much quicker to set up a template test with this compiler though.
It also allows you to put the data in whatever types you like in the database, as long as you add a String converter for that type in processData(), like:
<pre>
case java.sql.Types.DOUBLE:
cell = String.valueOf(rs.getInt(cellNum));
break;
</pre>
Calling Code (based on drools-examples\drools-examples-drl\src\main\java\org\drools\examples\DataDrivenTemplateExample.java)
<pre>
ResultSet rs;
try {
Statement sta = conn.createStatement();
rs = sta.executeQuery("SELECT * FROM RulePricingPolicy");
// TODO: you need to catch or handle
} catch (SQLException e) {
}
final ResultSetCompiler converter = new ResultSetCompiler();
final String drl = converter.compile(rs, getTemplate());
</pre>
Here is the ResultSet Compiler:
<pre>
import org.drools.template.parser.TemplateContainer;
import org.drools.template.parser.DefaultTemplateContainer;
import org.drools.template.parser.TemplateDataListener;
import org.drools.template.parser.DataListener;
import java.io.InputStream;
import java.util.List;
import java.util.ArrayList;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
/**
* <p> A Drools template compiler which takes a ResultSet and compiles it into
* a template using DefaultTemplateContainer.
* </p>
*
* @author bxt, Aug 19, 2009 1:53:38 PM
* <br>
* Copyright © 2008 Customized Services Administrators, Inc.
* All Rights Reserved.
*/
public class ResultSetCompiler {
/**
* Generates DRL from a data provider for the spreadsheet data and templates.
*
* @param rs the resultset for the table data
* @param template the string containing the template resource name
* @return the generated DRL text as a String
*/
public String compile(final ResultSet rs,
final String template) {
final InputStream templateStream = this.getClass().getResourceAsStream(template);
return compile(rs,
templateStream);
}
/**
* Generates DRL from a data provider for the spreadsheet data and templates.
*
* @param rs the resultset for the table data
* @param templateStream the InputStream for reading the templates
* @return the generated DRL text as a String
*/
public String compile(final ResultSet rs,
final InputStream templateStream) {
TemplateContainer tc = new DefaultTemplateContainer(templateStream);
closeStream(templateStream);
return compile(rs,
new TemplateDataListener(tc));
}
/**
* Generates DRL from a data provider for the spreadsheet data and templates.
*
* @param rs the resultset for the table data
* @param listener a template data listener
* @return the generated DRL text as a String
*/
public String compile(final ResultSet rs,
final TemplateDataListener listener) {
List<DataListener> listeners = new ArrayList<DataListener>();
listeners.add(listener);
processData(rs,
listeners);
return listener.renderDRL();
}
/**
* Iterate through the resultset.
* @param rs the resultset for the table data
* @param listeners list of template data listener
*/
private void processData(final ResultSet rs,
List<DataListener> listeners) {
try {
ResultSetMetaData rsmd = rs.getMetaData();
int colCount = rsmd.getColumnCount();
int i = 0;
while (rs.next()) {
newRow(listeners, i, colCount);
for (int cellNum = 1; cellNum < colCount + 1; cellNum++) {
String cell;
int sqlType = rsmd.getColumnType(cellNum);
switch (sqlType) {
case java.sql.Types.DATE:
cell = rs.getDate(cellNum).toString();
break;
case java.sql.Types.INTEGER:
case java.sql.Types.DOUBLE:
cell = String.valueOf(rs.getInt(cellNum));
break;
default:
cell = rs.getString(cellNum);
}
newCell(listeners,
i,
cellNum -1,
cell,
DataListener.NON_MERGED);
}
i++;
}
//TODO: you need to throw or handle
} catch (SQLException e) {
}
finishData(listeners);
}
private void finishData(List<DataListener> listeners) {
for (DataListener listener : listeners) {
listener.finishSheet();
}
}
private void newRow(List<DataListener> listeners,
int row,
int cols) {
for (DataListener listener : listeners) {
listener.newRow(row,
cols);
}
}
public void newCell(List<DataListener> listeners,
int row,
int column,
String value,
int mergedColStart) {
for (DataListener listener : listeners) {
listener.newCell(row,
column,
value,
mergedColStart);
}
}
protected void closeStream(final InputStream stream) {
try {
stream.close();
} catch (final Exception e) {
System.err.print("WARNING: Wasn't able to correctly close stream for rule template. " + e.getMessage());
}
}
}
</pre>
15 years, 4 months
Drools and Clojure (maps as facts)
by André Thieme
Hello group!
I am a Clojure user and would like to look into using Drools with it.
From Clojure I can use all Java classes and call all methods. So,
instantiating a KnowledgeBase, KnowledgePackages or a KBFactory is no
problem, and calling the respective methods, to get the system started,
or insert facts into a session, dispose it and fireAllRules is also
fine.
It is just that in Clojure one typically does not use POJOs.
The most typical data structures used are: hashmaps, vectors, structs,
lists, structuremaps and sets (in no particular order).
Those are persistent and "concurrency ready" Clojure DSs, and btw, also
usable from Java directly.
Now the basic Drools examples I saw all work with POJOs.
They were mostly comparisons of native typed fields in a class.
I however would be interested to compare different qualities of key/
value pairs in a hashmap, or compare structs with each other.
Comparing structuremaps is maybe what comes closest to the POJO examples.
For example, we may have a struct (defstruct person :name :age :type)
and store it's instances in a vector. And we would also insert it into
our Drools session object:
(doseq [p all-persons] (.insert session p))
which would correspond roughly to
for (Person p : allPersons) { session.insert(p); }
Only that "person" is a map, not a class.
Well, of course it is also an object and under the hood a class, a
java.util.Map even - but I mean that unlike POJOs the key/value pairs
are stored differently (fields in classes are also just key/value pairs).
So, is there a way to insert maps (let it be java.util.HashMaps for
example) and also to reason about them? I won't care if the syntax
for that is complicated. As Clojure is a Lisp I would just write a
little macro and have a very nice and readable syntax (probably a bit
similar to the one of Jess or Lisa).
Instead of looking at all instances of the type Person AND then have
their age compared, I would look at all maps/structs which have a key
:type with the value :person AND then compare the value of their :age
key with a number, such as:
(rule "example person rule, matching non-adults"
:when (= :type :person)
(< :age 18)
:then
(println "No service for minors."))
In Java terms it would mean that we insert several instances of
java.util.HashMap, all having the k/v pairs for name, age and type.
HashMap<String, Object> hm = new HashMap<String, Object>();
hm.put("name", someName);
hm.put("age", someAge);
hm.put("type", "person");
session.insert(hm);
Is that in principle possible with Drools 5?
Sunny greetings,
André
--
Lisp is not dead. It’s just the URL that has changed:
http://clojure.org/
15 years, 4 months
Drools library - updating Drools jar
by KDR
Thanks to Edson and André for the very interesting discussion on maps in
Drools. :) I suspect my follow up question got a bit buried in that thread
and probably is a separate topic anyway, so I hope you don't mind my asking
this newbie question in a new thread.
All Drools projects created in Eclipse with the Drools plugin have a Drools
library associated with them, which shows up as a Drools Library entry on
the left in both project/package explorer, and in the project properties for
the project - in the Libraries tab for the project properties' Java Build
Path.
My question is, how do you get Eclipse to recognise an updated jar in the
Drools library please? Or perhaps it should be, how do you get Drools to
recognise an update to a jar which it uses?
Edson said in the other thread that I need to update my mvel jar to 2.0.12.
I can only find 2.0.13 but no doubt that's also got the maps bugfix.
However where I'm stuck is how get the Drools projects to use the updated
jar. I've copied the 2.0.13 jar to the Drools runtime folder on my computer
(both top level and subfolder). I've tried to add the 2.0.13 jar to the Java
build path for the project as an external jar. I've tried to create a fresh
Drools project in Eclipse. I've restarted Eclipse with -clean. The map issue
is still there, and the Drools library for the Drools projects still don't
even show 2.0.13 in the list of jars - just 2.0.10. I'm sure the crux of it
is that somewhere Drools has been told to use 2.0.10, and I don't know how
to tell it otherwise.
I'm sure it's a really easy thing to do if you know how, but I've tried
everything I can think of and am totally at a loss as to what to try next.
(Probably try to rename 2.0.13 to 2.0.10, delete or rename the old 2.0.10
and restart Eclipse?).
Would some kind person be able to point me in the right direction please?
I'm trying to think of a workaround for my project that doesn't use maps,
but ideally maps would be the best way. I'm willing to offer a box of
chocolates or a bottle of wine or beer whatever your poison of choice, if
blatant bribes will help! :D
Many thanks. Any suggestions at all would be most appreciated.
--
View this message in context: http://www.nabble.com/Drools-library---updating-Drools-jar-tp25057905p250...
Sent from the drools - user mailing list archive at Nabble.com.
15 years, 4 months
Using "in" in Guvnor's Guided Rule Editor
by Steve Ronderos
Hello Rules Users,
I think I've seen a message about this before, but I can not find it.
We make heavy use of the "in" keyword in our current DRL rules files. We
are trying to start using Guvnor and its Guided Rule Editor. Is there a
way to use "in" in the Guided Rule Editor, other than by adding free form
DRL? If there is not a way, can anyone propose another way to accomplish
the same goal?
Also if you can't use "in" in the Guided Rule Editor, is there an open
feature request?
Thanks,
Steve Ronderos
15 years, 4 months
how to use xml file instead of java object ?
by tv.raghavan
I remember seeing a sample in jboss-esb sample where they were able to use
xpath to query a xml file
[sample extract]
package com.jboss.soa.esb.routing.cbr
#list any import classes here.
import org.jboss.soa.esb.message.Message;
import org.jboss.soa.esb.message.format.MessageType;
expander XPathLanguage.dsl
#declare any global variables here
global java.util.List destinations;
rule "Blue Routing Rule using XPATH"
when
xpathEquals "/Order/@statusCode", "0"
then
Log : "Blue Team";
Destination : "blue";
end
Is it possible to use this approach to use a xml as input to drool vs java
object ?
Thanks,
-Raghav
--
View this message in context: http://www.nabble.com/how-to-use-xml-file-instead-of-java-object---tp2502...
Sent from the drools - user mailing list archive at Nabble.com.
15 years, 4 months
Decision table problem
by Alex Esmann
Hey
I am using drools with a decision table (XLS). One of the conditions in
the table is a call to a java method, c.checkFoo($1,$2)), where c is of
type Foo. When I first created this method it took 2 integers and that
worked fine, now I need to update it to take to strings instead. I have
updated the method but when trying to it I get some errors.
Some examples of values in the cells for this condition are
[ 901, 910 ]
[ 90AAA, 90ABC]
For the first value I get this error:
The method checkFoo(String, String) in the type Foo is not applicable
for the arguments (int, int)
For the second value I get this error:
The method checkFoo(String, String) in the type Foo is not applicable
for the arguments (int, int)
Syntax error on token "AAA", delete this token
Syntax error on token "AAC", delete this token
How do I convince drools that the values in the cells should be read as
strings and not integers?
Kind Regards
Alex
15 years, 4 months
Collecting / sorting by the number of matches
by KDR
Hi, ta very much everyone for the help so far.
Another question - how to sort by number of matches please?
Say I have objects A, B, C and D and rules 1 to 5. Each object can match
each rule independently e.g. A can match rule 1 and 2, B might match all
rules 1 to 5, C might match none, D rules 3 and 4 etc.
I need to rank them and then print out info about them in order of number of
matches, with an indication of which rules matched, i.e. print info on B
before A but nothing at all on C, etc.
In Java I'd probably do it by having, as a global variable, a map where the
key is the name or ID field of the object and the value is an arraylist
which gets added to in the consequence (with a string about what kind of
match it was i.e. which rule was matched) whenever there's a match on a rule
for that object. Then sort it by descending length of the arraylists.
There has to be a better and more elegant way of doing it in Drools,
probably involving collecting info on the matches and then sorting them, but
I can't think what or how.
Does anyone have any thoughts or suggestions please?
Many thanks in advance.
--
View this message in context: http://www.nabble.com/Collecting---sorting-by-the-number-of-matches-tp250...
Sent from the drools - user mailing list archive at Nabble.com.
15 years, 4 months
(no subject)
by Nilima R
Hi,
I am new to Drools. Can anyone help me with an example of Drools in
jsp/servlets.
Thanks,
Nilima Rajendra Raichandani
Tata Consultancy Services
Mailto: nilima.r(a)tcs.com
Website: http://www.tcs.com
____________________________________________
Experience certainty. IT Services
Business Solutions
Outsourcing
____________________________________________
=====-----=====-----=====
Notice: The information contained in this e-mail
message and/or attachments to it may contain
confidential or privileged information. If you are
not the intended recipient, any dissemination, use,
review, distribution, printing or copying of the
information contained in this e-mail message
and/or attachments to it are strictly prohibited. If
you have received this communication in error,
please notify us by reply e-mail or telephone and
immediately and permanently delete the message
and any attachments. Thank you
15 years, 4 months