<div><span style="font-size:13px;color:rgb(34,34,34);font-family:arial,sans-serif;background-color:rgb(255,255,255)">Drools Flow (aka JBPM5) will look for all the Persons and Dogs you have in your session.</span></div><div>

<span style="font-size:13px;color:rgb(34,34,34);font-family:arial,sans-serif;background-color:rgb(255,255,255)">Since the conditions in an XOR gateway are evaluated in order, the first one being true is going to be selected.</span></div>

<div><span style="font-size:13px;color:rgb(34,34,34);font-family:arial,sans-serif;background-color:rgb(255,255,255)">In your case, after you insert the Persons, both rules are activated, but the gateway is always going to pick the first one.</span></div>

<div><span style="font-size:13px;color:rgb(34,34,34);font-family:arial,sans-serif;background-color:rgb(255,255,255)">I would suggest to use different process instances for different scenarios.</span></div><div><span style="font-size:13px;color:rgb(34,34,34);font-family:arial,sans-serif;background-color:rgb(255,255,255)"><br>

</span></div><div><span style="font-size:13px;color:rgb(34,34,34);font-family:arial,sans-serif;background-color:rgb(255,255,255)">Best Regards,</span></div><div><br>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br><br>Esteban Aliverti<br>

- Blog @ <a href="http://ilesteban.wordpress.com" target="_blank">http://ilesteban.wordpress.com</a><br>
<br><br><div class="gmail_quote">On Tue, Aug 21, 2012 at 11:14 PM, BenjaminWolfe <span dir="ltr">&lt;<a href="mailto:benjamin.e.wolfe@gmail.com" target="_blank">benjamin.e.wolfe@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Thanks Wolfgang.<br>
<br>
My original post was a conceptual analogy.  But this still isn&#39;t working<br>
right for me, so I&#39;ve written out a full-fledged example to see if you or<br>
anyone else can help.  The full example is behaving exactly the way my real<br>
(important) code is -- which is the wrong way for the business application.<br>
:-/  I should add that in real life, the ruleflow groups each have multiple<br>
rules within them.<br>
<br>
So without further ado, here&#39;s my code -- two POJOs, a bpmn file, a rule<br>
resource, and a test class -- along with the expected output and actual<br>
output.<br>
<br>
*User.java*<br>
<br>
package com.examples.ruleflow;<br>
<br>
public class User {<br>
<br>
        private int id;<br>
<br>
        public User() {}<br>
        public User(int id) {<br>
                <a href="http://this.id" target="_blank">this.id</a> = id;<br>
        }<br>
<br>
        public int getId() {<br>
                return id;<br>
        }<br>
<br>
        public void setId(int id) {<br>
                <a href="http://this.id" target="_blank">this.id</a> = id;<br>
        }<br>
}<br>
<br>
*Dog.java*<br>
<br>
package com.examples.ruleflow;<br>
<br>
public class Dog {<br>
<br>
        private int id;<br>
        private int ownerId;<br>
        private boolean hasDogTag;<br>
<br>
        public Dog() {}<br>
        public Dog(int id) {<br>
                <a href="http://this.id" target="_blank">this.id</a> = id;<br>
        }<br>
<br>
        public int getId() {<br>
                return id;<br>
        }<br>
        public int getOwnerId() {<br>
                return ownerId;<br>
        }<br>
        public boolean isHasDogTag() {<br>
                return hasDogTag;<br>
        }<br>
        public void setId(int id) {<br>
                <a href="http://this.id" target="_blank">this.id</a> = id;<br>
        }<br>
        public void setOwnerId(int ownerId) {<br>
                this.ownerId = ownerId;<br>
        }<br>
        public void setHasDogTag(boolean hasDogTag) {<br>
                this.hasDogTag = hasDogTag;<br>
        }<br>
<br>
}<br>
<br>
*dog_owner_flow.bpmn*<br>
<br>
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;<br>
&lt;definitions id=&quot;Definition&quot;<br>
             targetNamespace=&quot;<a href="http://www.jboss.org/drools" target="_blank">http://www.jboss.org/drools</a>&quot;<br>
             typeLanguage=&quot;<a href="http://www.java.com/javaTypes" target="_blank">http://www.java.com/javaTypes</a>&quot;<br>
             expressionLanguage=&quot;<a href="http://www.mvel.org/2.0" target="_blank">http://www.mvel.org/2.0</a>&quot;<br>
             xmlns=&quot;<a href="http://www.omg.org/spec/BPMN/20100524/MODEL" target="_blank">http://www.omg.org/spec/BPMN/20100524/MODEL</a>&quot;<br>
             xmlns:xsi=&quot;<a href="http://www.w3.org/2001/XMLSchema-instance" target="_blank">http://www.w3.org/2001/XMLSchema-instance</a>&quot;<br>
             xsi:schemaLocation=&quot;<a href="http://www.omg.org/spec/BPMN/20100524/MODEL" target="_blank">http://www.omg.org/spec/BPMN/20100524/MODEL</a><br>
BPMN20.xsd&quot;<br>
             xmlns:g=&quot;<a href="http://www.jboss.org/drools/flow/gpd" target="_blank">http://www.jboss.org/drools/flow/gpd</a>&quot;<br>
             xmlns:bpmndi=&quot;<a href="http://www.omg.org/spec/BPMN/20100524/DI" target="_blank">http://www.omg.org/spec/BPMN/20100524/DI</a>&quot;<br>
             xmlns:dc=&quot;<a href="http://www.omg.org/spec/DD/20100524/DC" target="_blank">http://www.omg.org/spec/DD/20100524/DC</a>&quot;<br>
             xmlns:di=&quot;<a href="http://www.omg.org/spec/DD/20100524/DI" target="_blank">http://www.omg.org/spec/DD/20100524/DI</a>&quot;<br>
             xmlns:tns=&quot;<a href="http://www.jboss.org/drools" target="_blank">http://www.jboss.org/drools</a>&quot;&gt;<br>
<br>
  &lt;process processType=&quot;Private&quot; isExecutable=&quot;true&quot;<br>
id=&quot;com.examples.ruleflow.dogProcess&quot; name=&quot;Dog Owner Process&quot;<br>
tns:packageName=&quot;com.examples.ruleflow&quot; tns:version=&quot;1&quot; &gt;<br>
<br>
<br>
    &lt;startEvent id=&quot;_1&quot; name=&quot;StartProcess&quot; /&gt;<br>
    &lt;exclusiveGateway id=&quot;_2&quot; name=&quot;Gateway&quot; gatewayDirection=&quot;Diverging&quot; /&gt;<br>
    &lt;businessRuleTask id=&quot;_3&quot; name=&quot;Branch A&quot; g:ruleFlowGroup=&quot;flowA&quot;<br>
&gt;&lt;/businessRuleTask&gt;<br>
    &lt;businessRuleTask id=&quot;_4&quot; name=&quot;Branch B&quot; g:ruleFlowGroup=&quot;flowB&quot;<br>
&gt;&lt;/businessRuleTask&gt;<br>
    &lt;exclusiveGateway id=&quot;_5&quot; name=&quot;Gateway&quot; gatewayDirection=&quot;Converging&quot;<br>
/&gt;<br>
    &lt;endEvent id=&quot;_6&quot; name=&quot;End&quot; &gt;&lt;terminateEventDefinition/&gt;&lt;/endEvent&gt;<br>
<br>
<br>
    &lt;sequenceFlow id=&quot;_1-_2&quot; sourceRef=&quot;_1&quot; targetRef=&quot;_2&quot; /&gt;<br>
    &lt;sequenceFlow id=&quot;_2-_3&quot; sourceRef=&quot;_2&quot; targetRef=&quot;_3&quot; name=&quot;dog tags<br>
OK&quot; tns:priority=&quot;1&quot; &gt;<br>
      &lt;conditionExpression xsi:type=&quot;tFormalExpression&quot;<br>
language=&quot;<a href="http://www.jboss.org/drools/rule" target="_blank">http://www.jboss.org/drools/rule</a>&quot; &gt;<br>
        /$u : User()<br>
        not ( Dog( ownerId == $<a href="http://u.id" target="_blank">u.id</a>, hasDogTag == false ) )/<br>
      &lt;/conditionExpression&gt;<br>
    &lt;/sequenceFlow&gt;<br>
    &lt;sequenceFlow id=&quot;_2-_4&quot; sourceRef=&quot;_2&quot; targetRef=&quot;_4&quot; name=&quot;dog tag<br>
issue&quot; tns:priority=&quot;1&quot; &gt;<br>
      &lt;conditionExpression xsi:type=&quot;tFormalExpression&quot;<br>
language=&quot;<a href="http://www.jboss.org/drools/rule" target="_blank">http://www.jboss.org/drools/rule</a>&quot; &gt;<br>
        /$u : User()<br>
        exists ( Dog( ownerId == $<a href="http://u.id" target="_blank">u.id</a>, hasDogTag == false ) )/<br>
      &lt;/conditionExpression&gt;<br>
    &lt;/sequenceFlow&gt;<br>
    &lt;sequenceFlow id=&quot;_3-_5&quot; sourceRef=&quot;_3&quot; targetRef=&quot;_5&quot; /&gt;<br>
    &lt;sequenceFlow id=&quot;_4-_5&quot; sourceRef=&quot;_4&quot; targetRef=&quot;_5&quot; /&gt;<br>
    &lt;sequenceFlow id=&quot;_5-_6&quot; sourceRef=&quot;_5&quot; targetRef=&quot;_6&quot; /&gt;<br>
  &lt;/process&gt;<br>
<br>
  &lt;bpmndi:BPMNDiagram&gt;<br>
    &lt;bpmndi:BPMNPlane bpmnElement=&quot;com.examples.ruleflow.dogProcess&quot; &gt;<br>
      &lt;bpmndi:BPMNShape bpmnElement=&quot;_1&quot; &gt;<br>
        &lt;dc:Bounds x=&quot;16&quot; y=&quot;16&quot; width=&quot;48&quot; height=&quot;48&quot; /&gt;<br>
      &lt;/bpmndi:BPMNShape&gt;<br>
      &lt;bpmndi:BPMNShape bpmnElement=&quot;_2&quot; &gt;<br>
        &lt;dc:Bounds x=&quot;180&quot; y=&quot;15&quot; width=&quot;48&quot; height=&quot;48&quot; /&gt;<br>
      &lt;/bpmndi:BPMNShape&gt;<br>
      &lt;bpmndi:BPMNShape bpmnElement=&quot;_3&quot; &gt;<br>
        &lt;dc:Bounds x=&quot;42&quot; y=&quot;162&quot; width=&quot;80&quot; height=&quot;48&quot; /&gt;<br>
      &lt;/bpmndi:BPMNShape&gt;<br>
      &lt;bpmndi:BPMNShape bpmnElement=&quot;_4&quot; &gt;<br>
        &lt;dc:Bounds x=&quot;296&quot; y=&quot;162&quot; width=&quot;80&quot; height=&quot;48&quot; /&gt;<br>
      &lt;/bpmndi:BPMNShape&gt;<br>
      &lt;bpmndi:BPMNShape bpmnElement=&quot;_5&quot; &gt;<br>
        &lt;dc:Bounds x=&quot;180&quot; y=&quot;306&quot; width=&quot;48&quot; height=&quot;48&quot; /&gt;<br>
      &lt;/bpmndi:BPMNShape&gt;<br>
      &lt;bpmndi:BPMNShape bpmnElement=&quot;_6&quot; &gt;<br>
        &lt;dc:Bounds x=&quot;188&quot; y=&quot;384&quot; width=&quot;48&quot; height=&quot;48&quot; /&gt;<br>
      &lt;/bpmndi:BPMNShape&gt;<br>
      &lt;bpmndi:BPMNEdge bpmnElement=&quot;_1-_2&quot; &gt;<br>
        &lt;di:waypoint x=&quot;40&quot; y=&quot;40&quot; /&gt;<br>
        &lt;di:waypoint x=&quot;204&quot; y=&quot;39&quot; /&gt;<br>
      &lt;/bpmndi:BPMNEdge&gt;<br>
      &lt;bpmndi:BPMNEdge bpmnElement=&quot;_2-_3&quot; &gt;<br>
        &lt;di:waypoint x=&quot;204&quot; y=&quot;39&quot; /&gt;<br>
        &lt;di:waypoint x=&quot;82&quot; y=&quot;186&quot; /&gt;<br>
      &lt;/bpmndi:BPMNEdge&gt;<br>
      &lt;bpmndi:BPMNEdge bpmnElement=&quot;_2-_4&quot; &gt;<br>
        &lt;di:waypoint x=&quot;204&quot; y=&quot;39&quot; /&gt;<br>
        &lt;di:waypoint x=&quot;336&quot; y=&quot;186&quot; /&gt;<br>
      &lt;/bpmndi:BPMNEdge&gt;<br>
      &lt;bpmndi:BPMNEdge bpmnElement=&quot;_3-_5&quot; &gt;<br>
        &lt;di:waypoint x=&quot;82&quot; y=&quot;186&quot; /&gt;<br>
        &lt;di:waypoint x=&quot;204&quot; y=&quot;330&quot; /&gt;<br>
      &lt;/bpmndi:BPMNEdge&gt;<br>
      &lt;bpmndi:BPMNEdge bpmnElement=&quot;_4-_5&quot; &gt;<br>
        &lt;di:waypoint x=&quot;336&quot; y=&quot;186&quot; /&gt;<br>
        &lt;di:waypoint x=&quot;204&quot; y=&quot;330&quot; /&gt;<br>
      &lt;/bpmndi:BPMNEdge&gt;<br>
      &lt;bpmndi:BPMNEdge bpmnElement=&quot;_5-_6&quot; &gt;<br>
        &lt;di:waypoint x=&quot;204&quot; y=&quot;330&quot; /&gt;<br>
        &lt;di:waypoint x=&quot;212&quot; y=&quot;408&quot; /&gt;<br>
      &lt;/bpmndi:BPMNEdge&gt;<br>
    &lt;/bpmndi:BPMNPlane&gt;<br>
  &lt;/bpmndi:BPMNDiagram&gt;<br>
&lt;/definitions&gt;<br>
<br>
*dog_owners.drl*<br>
<br>
package com.examples.ruleflow<br>
<br>
rule &quot;sample A&quot;<br>
        ruleflow-group &quot;flowA&quot;<br>
        no-loop true<br>
        dialect &quot;mvel&quot;<br>
        when<br>
                $u : User()<br>
        then<br>
                System.out.println(&quot;User &quot; + $<a href="http://u.id" target="_blank">u.id</a> + &quot; took branch A.&quot;);<br>
end<br>
<br>
rule &quot;sample B&quot;<br>
        ruleflow-group &quot;flowB&quot;<br>
        no-loop true<br>
        dialect &quot;mvel&quot;<br>
        when<br>
                $u : User()<br>
        then<br>
                System.out.println(&quot;User &quot; + $<a href="http://u.id" target="_blank">u.id</a> + &quot; took branch B.&quot;);<br>
end<br>
<br>
*DogTest.java*<br>
<br>
package com.examples.ruleflow;<br>
<br>
import org.drools.KnowledgeBase;<br>
import org.drools.builder.KnowledgeBuilder;<br>
import org.drools.builder.KnowledgeBuilderFactory;<br>
import org.drools.builder.ResourceType;<br>
import org.drools.io.ResourceFactory;<br>
import org.drools.logger.KnowledgeRuntimeLogger;<br>
import org.drools.logger.KnowledgeRuntimeLoggerFactory;<br>
import org.drools.runtime.StatefulKnowledgeSession;<br>
/import java.util.List;<br>
import java.util.ArrayList;/<br>
<br>
public class DogTest {<br>
<br>
    public static final void main(String[] args) {<br>
        try {<br>
            // load up the knowledge base<br>
            KnowledgeBase kbase = readKnowledgeBase();<br>
            StatefulKnowledgeSession ksession =<br>
kbase.newStatefulKnowledgeSession();<br>
            KnowledgeRuntimeLogger logger =<br>
KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, &quot;test&quot;);<br>
            /// create and insert facts<br>
            List&lt;User&gt; users = new ArrayList&lt;User&gt;();<br>
            List&lt;Dog&gt; dogs = new ArrayList&lt;Dog&gt;();<br>
<br>
            users.add(new User(0));<br>
            dogs.add(new Dog(0));<br>
            dogs.get(0).setOwnerId(1);<br>
            dogs.get(0).setHasDogTag(true);<br>
            dogs.add(new Dog(1));<br>
            dogs.get(1).setOwnerId(0);<br>
            dogs.get(1).setHasDogTag(true);<br>
<br>
            users.add(new User(1));<br>
            dogs.add(new Dog(2));<br>
            dogs.get(2).setOwnerId(1);<br>
            dogs.get(2).setHasDogTag(true);<br>
            dogs.add(new Dog(3));<br>
            dogs.get(3).setOwnerId(1);<br>
            dogs.get(3).setHasDogTag(true);<br>
            dogs.add(new Dog(4));<br>
            dogs.get(4).setOwnerId(1);<br>
            dogs.get(4).setHasDogTag(false);<br>
<br>
            for (User u:users) {<br>
                ksession.insert(u);<br>
            }<br>
            for (Dog d:dogs) {<br>
                ksession.insert(d);<br>
            }/<br>
<br>
            // start a new process instance<br>
            /ksession.startProcess(&quot;com.examples.ruleflow.dogProcess&quot;);<br>
            ksession.fireAllRules();/<br>
            logger.close();<br>
        } catch (Throwable t) {<br>
            t.printStackTrace();<br>
        }<br>
    }<br>
<br>
    private static KnowledgeBase readKnowledgeBase() throws Exception {<br>
        KnowledgeBuilder kbuilder =<br>
KnowledgeBuilderFactory.newKnowledgeBuilder();<br>
<br>
/kbuilder.add(ResourceFactory.newClassPathResource(&quot;dog_owners.drl&quot;),<br>
ResourceType.DRL);<br>
<br>
kbuilder.add(ResourceFactory.newClassPathResource(&quot;dog_owner_flow.bpmn&quot;),<br>
ResourceType.BPMN2);/<br>
        return kbuilder.newKnowledgeBase();<br>
    }<br>
}<br>
<br>
*/Expected/ Console Output...*<br>
<br>
User /0/ took branch /A/.<br>
User /1/ took branch /B/.<br>
<br>
*/Actual/ Console Output...*<br>
<br>
User /1/ took branch /A/.<br>
User /0/ took branch /A/.<br>
<br>
<br>
laune wrote<br>
<div><div class="h5">&gt;<br>
&gt; On 21/08/2012, BenjaminWolfe &amp;lt;benjamin.e.wolfe@&amp;gt; wrote:<br>
&gt;&gt; I&#39;m trying to wrap my mind around the nature of ruleflows -- and I think<br>
&gt;&gt; this<br>
&gt;&gt; question sums up a bit of my confusion.<br>
&gt;&gt;<br>
&gt;&gt; I have a stateful knowledge session.  The stateful knowledge session has<br>
&gt;&gt; a<br>
&gt;&gt; ruleflow associated with it.  That ruleflow diverges into two branches --<br>
&gt;&gt; branch A and branch B -- based on a rule constraint.  It&#39;s an XOR, and<br>
&gt;&gt; the<br>
&gt;&gt; mvel rule constraints are something like this:<br>
&gt;&gt;<br>
&gt;&gt; to branch A<br>
&gt;&gt; $u : User( $i : userId )<br>
&gt;&gt; exists ( Dog( owner == $i, hasDogTag == false) )<br>
&gt;&gt;<br>
&gt;&gt; to branch B<br>
&gt;&gt; $u : User( $i : userId )<br>
&gt;&gt; not ( Dog( owner == $i, hasDogTag == false) )<br>
&gt;&gt;<br>
&gt;&gt; Then the two branches converge again.  I insert two facts: user 1, whose<br>
&gt;&gt; dogs all have dog tags, and user 2 whose third dog is missing a tag.<br>
&gt;&gt; Then,<br>
&gt;&gt; after I insert both facts, I fire all rules.<br>
&gt;<br>
&gt; If you don&#39;t insert any Dogs, only the condition for branch B is true,<br>
&gt; since there no Dogs at all, tag or no tag.<br>
&gt;<br>
&gt; If you insert Dogs according to your statement, both conditions are<br>
&gt; true, A for user 2 and B for user 1 (which is not what you describe<br>
&gt; below, but I think this is an oversight).<br>
&gt;<br>
&gt; Anyway, a &quot;flow&quot; will not cycle automatically if there are several<br>
&gt; fact groups, with some of them requiring this or that processing. To<br>
&gt; notify Users with untagged dogs, a simple rule with the conditions<br>
&gt; you&#39;ve posted and with a consequence notifying the user would be<br>
&gt; sufficient.<br>
&gt;<br>
&gt; For an overall decision between &quot;there are tagless dogs&quot; and &quot;all dogs<br>
&gt; are tagged&quot; you&#39;d need conditions like these:<br>
&gt;<br>
&gt; exists( Dog( hasDogTag == false) )<br>
&gt;<br>
&gt; not( Dog( hasDogTag == false) )<br>
&gt;<br>
&gt; -W<br>
&gt;<br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt; Should the flow be like this?<br>
&gt;&gt;<br>
&gt;&gt; user 1: start --&gt; diverge --&gt; branch A (tell him to buy dog tags) --&gt;<br>
&gt;&gt; converge --&gt; end<br>
&gt;&gt; user 2: start --&gt; diverge --&gt; branch B (leave him alone) --&gt; converge --&gt;<br>
&gt;&gt; end<br>
&gt;&gt;<br>
&gt;&gt; Or does a ruleflow look at the whole session rather than each fact -- in<br>
&gt;&gt; which case either both users would pass through branch A, or both would<br>
&gt;&gt; pass<br>
&gt;&gt; through branch B?<br>
&gt;&gt;<br>
&gt;&gt; If I want the first case to happen, is there something I&#39;m missing in the<br>
&gt;&gt; implementation?  And are there any more details I can add to make my post<br>
&gt;&gt; more specific?  Thank you for your help.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; --<br>
&gt;&gt; View this message in context:<br>
&gt;&gt; <a href="http://drools.46999.n3.nabble.com/Question-about-the-Nature-of-Ruleflows-tp4019292.html" target="_blank">http://drools.46999.n3.nabble.com/Question-about-the-Nature-of-Ruleflows-tp4019292.html</a><br>
&gt;&gt; Sent from the Drools: User forum mailing list archive at Nabble.com.<br>
&gt;&gt; _______________________________________________<br>
&gt;&gt; rules-users mailing list<br>
</div></div>&gt;&gt; rules-users@.jboss<br>
<div class="im">&gt;&gt; <a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
&gt;&gt;<br>
&gt; _______________________________________________<br>
&gt; rules-users mailing list<br>
</div>&gt; rules-users@.jboss<br>
&gt; <a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
&gt;<br>
<br>
<br>
<br>
--<br>
View this message in context: <a href="http://drools.46999.n3.nabble.com/Question-about-the-Nature-of-Ruleflows-tp4019292p4019325.html" target="_blank">http://drools.46999.n3.nabble.com/Question-about-the-Nature-of-Ruleflows-tp4019292p4019325.html</a><br>


<div class="HOEnZb"><div class="h5">Sent from the Drools: User forum mailing list archive at Nabble.com.<br>
_______________________________________________<br>
rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
</div></div></blockquote></div><br></div>