[jboss-svn-commits] JBL Code SVN: r10895 - in labs/jbossrules/trunk/drools-core/src: main/java/org/drools/reteoo and 3 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Apr 11 12:58:54 EDT 2007


Author: mark.proctor at jboss.com
Date: 2007-04-11 12:58:54 -0400 (Wed, 11 Apr 2007)
New Revision: 10895

Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaGroupImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleFlowGroup.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/AgendaGroup.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AgendaTest.java
Log:
JBRULES-788 lock-on-activate rule attribute
-includes core changes, grammar changes, ide changes, with full unit/integration testing.

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaGroupImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaGroupImpl.java	2007-04-11 16:58:41 UTC (rev 10894)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaGroupImpl.java	2007-04-11 16:58:54 UTC (rev 10895)
@@ -44,6 +44,8 @@
 
     /** Items in the agenda. */
     private final BinaryHeapQueue queue;
+    
+    private boolean active;
 
     /**
      * Construct an <code>AgendaGroup</code> with the given name.
@@ -75,13 +77,24 @@
     }
 
     public void add(final Activation activation) {
+        if ( this.active && activation.getRule().isLockOnActivate() ) {
+            return;
+        }
         this.queue.enqueue( (Queueable) activation );
     }
 
     public Activation getNext() {
         return (Activation) this.queue.dequeue();
+    }        
+
+    public boolean isActivate() {
+        return active;
     }
 
+    public void setActive(boolean activate) {
+        this.active = activate;
+    }
+
     /**
      * Iterates a PriorityQueue removing empty entries until it finds a populated entry and return true,
      * otherwise it returns false;

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java	2007-04-11 16:58:41 UTC (rev 10894)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java	2007-04-11 16:58:54 UTC (rev 10895)
@@ -166,7 +166,9 @@
     public boolean setFocus(final AgendaGroup agendaGroup) {
         // Set the focus to the agendaGroup if it doesn't already have the focus
         if ( this.focusStack.getLast() != agendaGroup ) {
+            ((AgendaGroupImpl)this.focusStack.getLast()).setActive( false );            
             this.focusStack.add( agendaGroup );
+            ((AgendaGroupImpl)agendaGroup).setActive( true );
             final EventSupport eventsupport = (EventSupport) this.workingMemory;
             eventsupport.getAgendaEventSupport().fireAgendaGroupPushed( agendaGroup );            
             return true;
@@ -209,7 +211,8 @@
 
             // No populated queus found so pop the focusStack and repeat            
             if ( empty && (this.focusStack.size() > 1) ) {
-                this.focusStack.removeLast();
+                agendaGroup.setActive( false );
+                this.focusStack.removeLast();                
                 final EventSupport eventsupport = (EventSupport) this.workingMemory;
                 eventsupport.getAgendaEventSupport().fireAgendaGroupPopped( agendaGroup );                
             } else {
@@ -218,6 +221,9 @@
             }
         }
 
+        if ( agendaGroup != null ) {
+            agendaGroup.setActive( true );            
+        }
         return agendaGroup;
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleFlowGroup.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleFlowGroup.java	2007-04-11 16:58:41 UTC (rev 10894)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleFlowGroup.java	2007-04-11 16:58:54 UTC (rev 10895)
@@ -21,5 +21,7 @@
      * its activations are not added to the agenda. 
      */
     void setActive(boolean active);
+    
+    boolean isActive();
 
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupImpl.java	2007-04-11 16:58:41 UTC (rev 10894)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupImpl.java	2007-04-11 16:58:54 UTC (rev 10895)
@@ -114,10 +114,15 @@
     }
 
     public void addActivation(final Activation activation) {
+        if ( this.active && activation.getRule().isLockOnActivate() ) {
+            return;
+        }
+        
         final RuleFlowGroupNode node = new RuleFlowGroupNode(activation, this);
         activation.setRuleFlowGroupNode(node);
     	list.add( node );
-        if (active) {
+        
+        if ( active ) {
         	((AgendaGroupImpl) activation.getAgendaGroup()).add(activation);
         }
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java	2007-04-11 16:58:41 UTC (rev 10894)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java	2007-04-11 16:58:54 UTC (rev 10895)
@@ -148,7 +148,7 @@
             }
         } else if ( this.rule.getNoLoop() && this.rule.equals( context.getRuleOrigin() ) ) {
             return;
-        }
+        }        
 
         //we only have to clone the head fact to make sure the graph is not affected during consequence reads after a modify
         final ReteTuple cloned = new ReteTuple( tuple );

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java	2007-04-11 16:58:41 UTC (rev 10894)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java	2007-04-11 16:58:54 UTC (rev 10895)
@@ -60,7 +60,7 @@
     /** Salience value. */
     private int               salience;
 
-    private boolean           dirty             = false;
+    private boolean           dirty;
     private Map               declarations;
     private Declaration[]     declarationArray;
 
@@ -86,15 +86,17 @@
     private String            activationGroup;
     
     private String		      ruleFlowGroup;
+    
+    private boolean           lockOnActivate;
 
     /** indicates that the rule is semantically correct. */
-    private boolean           semanticallyValid = true;
+    private boolean           semanticallyValid;
     
-    private Calendar          dateEffective = null;
+    private Calendar          dateEffective;
     
-    private Calendar          dateExpires = null;
+    private Calendar          dateExpires;
 
-    private boolean           enabled  = true;
+    private boolean           enabled;
 
     // ------------------------------------------------------------
     // Constructors
@@ -114,6 +116,8 @@
         this.pkg = pkg;
         this.agendaGroup = agendaGroup;
         this.lhsRoot = GroupElementFactory.newAndInstance();
+        this.semanticallyValid = true;
+        this.enabled  = true;
     }
 
     /**
@@ -314,7 +318,17 @@
         }
         return (Declaration) this.declarations.get( identifier );
     }
+    
+    
 
+    public boolean isLockOnActivate() {
+        return lockOnActivate;
+    }
+
+    public void setLockOnActivate(boolean lockOnActive) {
+        this.lockOnActivate = lockOnActive;
+    }
+
     /**
      * Retrieve the set of all <i>root fact object </i> parameter
      * <code>Declarations</code>.

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/AgendaGroup.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/AgendaGroup.java	2007-04-11 16:58:41 UTC (rev 10894)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/AgendaGroup.java	2007-04-11 16:58:54 UTC (rev 10895)
@@ -56,5 +56,7 @@
      *      int value for the total number of activations
      */
     public int size();
+    
+    public boolean isActivate();
 
 }

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AgendaTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AgendaTest.java	2007-04-11 16:58:41 UTC (rev 10894)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AgendaTest.java	2007-04-11 16:58:54 UTC (rev 10895)
@@ -30,6 +30,7 @@
 import org.drools.common.DefaultFactHandle;
 import org.drools.common.InternalAgenda;
 import org.drools.common.PropagationContextImpl;
+import org.drools.common.RuleFlowGroupImpl;
 import org.drools.rule.Rule;
 import org.drools.spi.Activation;
 import org.drools.spi.ActivationGroup;
@@ -426,7 +427,6 @@
         // create the agendaGroup
         final AgendaGroupImpl agendaGroup = new AgendaGroupImpl( "agendaGroup" );
         agenda.addAgendaGroup( agendaGroup );
-        //        ActivationQueue queue = agendaGroup.getActivationQueue( 0 );
 
         // create the consequence
         final Consequence consequence = new Consequence() {
@@ -465,37 +465,90 @@
                           context,
                           workingMemory );
 
-        //        // check activation as added to the agendaGroup
-        //        assertEquals( 1,
-        //                      queue.size() );
-        //
-        //        // fire next item, agendaGroup should not fire as its not on the focus
-        //        // stack
-        //        // and thus should retain its sinle activation
-        //        agenda.fireNextItem( null );
-        //        assertEquals( 1,
-        //                      queue.size() );
-        //
-        //        // Clear the agenda we we can test again
-        //        agenda.clearAgenda();
-        //        assertEquals( 0,
-        //                      queue.size() );
-        //
-        //        // Now test that autoFocus=true works. Here the rule should fire as its
-        //        // agendaGroup gets the focus when the activation is created.
-        //        rule.setAutoFocus( true );
-        //
-        //        node.assertTuple( tuple,
-        //                          context,
-        //                          workingMemory );
-        //
-        //        assertEquals( 1,
-        //                      queue.size() );
-        //        agenda.fireNextItem( null );
-        //        assertEquals( 0,
-        //                      queue.size() );
+        // check activation as added to the agendaGroup
+        assertEquals( 1,
+                      agendaGroup.size() );
+
+        // fire next item, agendaGroup should not fire as its not on the focus stack
+        // and thus should retain its sinle activation
+        agenda.fireNextItem( null );
+        assertEquals( 1,
+                      agendaGroup.size() );
+
+        // Clear the agenda we we can test again
+        agenda.clearAgenda();
+        assertEquals( 0,
+                      agendaGroup.size() );
+
+        // Now test that autoFocus=true works. Here the rule should fire as its
+        // agendaGroup gets the focus when the activation is created.
+        rule.setAutoFocus( true );
+
+        node.assertTuple( tuple,
+                          context,
+                          workingMemory );
+
+        assertEquals( 1,
+                      agendaGroup.size() );
+        agenda.fireNextItem( null );
+        assertEquals( 0,
+                      agendaGroup.size() );
     }
 
+    public void testAgendaGroupLockOnActive() {
+        final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+
+        final ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newWorkingMemory();
+        final InternalAgenda agenda = (InternalAgenda) workingMemory.getAgenda();
+
+        // create the agendaGroup
+        final AgendaGroupImpl agendaGroup = new AgendaGroupImpl( "agendaGroup" );
+        agenda.addAgendaGroup( agendaGroup );
+
+        final ReteTuple tuple = new ReteTuple( new DefaultFactHandle( 1,
+                                                                      "cheese" ) );
+
+        // create a rule for the agendaGroup
+        final Rule rule = new Rule( "test-rule",
+                                    "agendaGroup" );
+        final RuleTerminalNode node = new RuleTerminalNode( 2,
+                                                            new MockTupleSource( 2 ),
+                                                            rule,
+                                                            rule.getLhs() );
+
+        final PropagationContext context = new PropagationContextImpl( 0,
+                                                                       PropagationContext.ASSERTION,
+                                                                       rule,
+                                                                       null );
+
+        // When both the rule is lock-on-active and the agenda group is active, activations should be ignored
+        rule.setLockOnActivate( true );
+        agendaGroup.setActive( true );        
+        node.assertTuple( tuple,
+                          context,
+                          workingMemory );
+        // activation should be ignored
+        assertEquals( 0,
+                      agendaGroup.size() );
+
+        // lock-on-active is now false so activation should propagate
+        rule.setLockOnActivate( false );        
+        node.assertTuple( tuple,
+                          context,
+                          workingMemory );        
+        assertEquals( 1,
+                      agendaGroup.size() );
+        
+        // even if lock-on-active is true, unless the agenda group is active the activation will still propagate
+        rule.setLockOnActivate( true );        
+        agendaGroup.setActive( false );        
+        node.assertTuple( tuple,
+                          context,
+                          workingMemory );        
+        assertEquals( 2,
+                      agendaGroup.size() );
+    }
+
     public void testActivationGroup() {
         final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
 
@@ -681,7 +734,7 @@
      * RuleFlowGroup.  First only rule-flow-group-0 is activated and rule0 is
      * executed.  When the two remaining groups are activated, the rule with the
      * highest priority is executed first.
-     */ 
+     */
     public void testRuleFlowGroup() {
         final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
 
@@ -772,12 +825,12 @@
         assertEquals( 1,
                       ruleFlowGroup1.size() );
         assertEquals( 1,
-                      ruleFlowGroup2.size() );        
+                      ruleFlowGroup2.size() );
         assertEquals( 0,
                       agenda.agendaSize() );
 
         // Activate the RuleFlowGroup, the nodes stay in the group, but should now also be in the Agenda
-        agenda.activateRuleFlowGroup("rule-flow-group-0");
+        agenda.activateRuleFlowGroup( "rule-flow-group-0" );
         assertEquals( 2,
                       ruleFlowGroup0.size() );
         assertEquals( 2,
@@ -799,36 +852,36 @@
 
         // Now we activate two RuleFlowGroups together
         // All their activations should be added to the agenda.
-        agenda.activateRuleFlowGroup("rule-flow-group-1");
-        agenda.activateRuleFlowGroup("rule-flow-group-2");
+        agenda.activateRuleFlowGroup( "rule-flow-group-1" );
+        agenda.activateRuleFlowGroup( "rule-flow-group-2" );
         assertEquals( 1,
-                	  ruleFlowGroup1.size() );
+                      ruleFlowGroup1.size() );
         assertEquals( 1,
-                 	  ruleFlowGroup2.size() );        
+                      ruleFlowGroup2.size() );
         assertEquals( 2,
-                	  agenda.agendaSize() );        
+                      agenda.agendaSize() );
 
         // we set the salience higher on rule2, so it sould fire first and empty ruleFlowGroup2
         agenda.fireNextItem( null );
         assertEquals( 1,
                       ruleFlowGroup1.size() );
         assertEquals( 0,
-                      ruleFlowGroup2.size() );        
+                      ruleFlowGroup2.size() );
         assertEquals( 1,
                       agenda.agendaSize() );
-        
+
         // this is the last activation, so everything should be empty after this
         agenda.fireNextItem( null );
         assertEquals( 0,
-                      ruleFlowGroup0.size() );        
+                      ruleFlowGroup0.size() );
         assertEquals( 0,
                       ruleFlowGroup1.size() );
         assertEquals( 0,
-                      ruleFlowGroup2.size() );        
+                      ruleFlowGroup2.size() );
         assertEquals( 0,
-                      agenda.agendaSize() );        
+                      agenda.agendaSize() );
     }
-    
+
     /**
      * RuleFlowGroup test that makes sure that, if new activations are created
      * for an active RuleFlowGroup, those activations get added to the agenda
@@ -844,9 +897,10 @@
         // create rule1
         final Consequence consequence1 = new Consequence() {
             private static final long serialVersionUID = -2596133893109870505L;
+
             public void evaluate(KnowledgeHelper knowledgeHelper,
                                  WorkingMemory workingMemory) {
-            	// do nothing
+                // do nothing
             }
         };
 
@@ -858,20 +912,22 @@
                                                              new MockTupleSource( 2 ),
                                                              rule1,
                                                              rule1.getLhs() );
-        
+
         // create context
         final PropagationContext context0 = new PropagationContextImpl( 0,
-														                PropagationContext.ASSERTION,
-														                rule1,
-														                null );
+                                                                        PropagationContext.ASSERTION,
+                                                                        rule1,
+                                                                        null );
 
         // create rule0
         final Consequence consequence0 = new Consequence() {
             private static final long serialVersionUID = -2596133893109870505L;
+
             public void evaluate(KnowledgeHelper knowledgeHelper,
                                  WorkingMemory w) {
-            	// activate rule1
-                final ReteTuple tuple1 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+                // activate rule1
+                final ReteTuple tuple1 = new ReteTuple( new DefaultFactHandle( 1,
+                                                                               "cheese" ) );
                 node1.assertTuple( tuple1,
                                    context0,
                                    workingMemory );
@@ -890,7 +946,8 @@
         final RuleFlowGroup ruleFlowGroup0 = agenda.getRuleFlowGroup( "rule-flow-group-0" );
 
         // Create one activation for rule0 only
-        final ReteTuple tuple0 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+        final ReteTuple tuple0 = new ReteTuple( new DefaultFactHandle( 1,
+                                                                       "cheese" ) );
         node0.assertTuple( tuple0,
                            context0,
                            workingMemory );
@@ -902,7 +959,7 @@
                       agenda.agendaSize() );
 
         // Activate the RuleFlowGroup, the activation stays in the group, but should now also be in the Agenda
-        agenda.activateRuleFlowGroup("rule-flow-group-0");
+        agenda.activateRuleFlowGroup( "rule-flow-group-0" );
         assertEquals( 1,
                       ruleFlowGroup0.size() );
         assertEquals( 1,
@@ -920,9 +977,9 @@
         assertEquals( 0,
                       ruleFlowGroup0.size() );
         assertEquals( 0,
-                      agenda.agendaSize() );   
+                      agenda.agendaSize() );
     }
-    
+
     /**
      * RuleFlowGroup test that makes sure that, if an activation in an active
      * RuleFlowGroup gets deactivated, the activation is no longer executed.
@@ -937,9 +994,10 @@
         // create rule1
         final Consequence consequence1 = new Consequence() {
             private static final long serialVersionUID = -2596133893109870505L;
+
             public void evaluate(KnowledgeHelper knowledgeHelper,
                                  WorkingMemory workingMemory) {
-            	// do nothing
+                // do nothing
             }
         };
 
@@ -951,21 +1009,23 @@
                                                              new MockTupleSource( 2 ),
                                                              rule1,
                                                              rule1.getLhs() );
-        
+
         // create context
         final PropagationContext context0 = new PropagationContextImpl( 0,
-														                PropagationContext.ASSERTION,
-														                rule1,
-														                null );
+                                                                        PropagationContext.ASSERTION,
+                                                                        rule1,
+                                                                        null );
 
-        final ReteTuple tuple1 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+        final ReteTuple tuple1 = new ReteTuple( new DefaultFactHandle( 1,
+                                                                       "cheese" ) );
 
         // create rule0
         final Consequence consequence0 = new Consequence() {
             private static final long serialVersionUID = -2596133893109870505L;
+
             public void evaluate(KnowledgeHelper knowledgeHelper,
                                  WorkingMemory w) {
-            	// deactivate rule1
+                // deactivate rule1
                 node1.retractTuple( tuple1,
                                     context0,
                                     workingMemory );
@@ -975,7 +1035,7 @@
         final Rule rule0 = new Rule( "test-rule0" );
         rule0.setRuleFlowGroup( "rule-flow-group-0" );
         rule0.setConsequence( consequence0 );
-        rule0.setSalience(10);
+        rule0.setSalience( 10 );
 
         final RuleTerminalNode node0 = new RuleTerminalNode( 3,
                                                              new MockTupleSource( 2 ),
@@ -985,7 +1045,8 @@
         final RuleFlowGroup ruleFlowGroup0 = agenda.getRuleFlowGroup( "rule-flow-group-0" );
 
         // Create an activation for both rules
-        final ReteTuple tuple0 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+        final ReteTuple tuple0 = new ReteTuple( new DefaultFactHandle( 1,
+                                                                       "cheese" ) );
         node0.assertTuple( tuple0,
                            context0,
                            workingMemory );
@@ -1001,7 +1062,7 @@
                       agenda.agendaSize() );
 
         // Activate the RuleFlowGroup, the activations stay in the group, but should now also be in the Agenda
-        agenda.activateRuleFlowGroup("rule-flow-group-0");
+        agenda.activateRuleFlowGroup( "rule-flow-group-0" );
         assertEquals( 2,
                       ruleFlowGroup0.size() );
         assertEquals( 2,
@@ -1016,7 +1077,7 @@
                       agenda.agendaSize() );
 
     }
-    
+
     /**
      * RuleFlowGroup test that makes sure that, when deactivating a RuleFlowGroup,
      * all activations for that group are no longer on the agenda.  When
@@ -1032,9 +1093,10 @@
         // create rule0
         final Consequence consequence0 = new Consequence() {
             private static final long serialVersionUID = -2596133893109870505L;
+
             public void evaluate(KnowledgeHelper knowledgeHelper,
                                  WorkingMemory w) {
-            	// do nothing
+                // do nothing
             }
         };
 
@@ -1051,16 +1113,18 @@
 
         // create context
         final PropagationContext context0 = new PropagationContextImpl( 0,
-														                PropagationContext.ASSERTION,
-														                rule0,
-														                null );
+                                                                        PropagationContext.ASSERTION,
+                                                                        rule0,
+                                                                        null );
 
         // Create two activation for this rule
-        final ReteTuple tuple0 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+        final ReteTuple tuple0 = new ReteTuple( new DefaultFactHandle( 1,
+                                                                       "cheese" ) );
         node0.assertTuple( tuple0,
                            context0,
                            workingMemory );
-        final ReteTuple tuple1 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+        final ReteTuple tuple1 = new ReteTuple( new DefaultFactHandle( 1,
+                                                                       "cheese" ) );
         node0.assertTuple( tuple1,
                            context0,
                            workingMemory );
@@ -1073,14 +1137,14 @@
 
         // Activate the RuleFlowGroup, the activations stay in the group, but 
         // should now also be in the Agenda
-        agenda.activateRuleFlowGroup("rule-flow-group-0");
+        agenda.activateRuleFlowGroup( "rule-flow-group-0" );
         assertEquals( 2,
                       ruleFlowGroup0.size() );
         assertEquals( 2,
                       agenda.agendaSize() );
 
         // Reactivate an already active RuleFlowGroup should not have any effect
-        agenda.activateRuleFlowGroup("rule-flow-group-0");
+        agenda.activateRuleFlowGroup( "rule-flow-group-0" );
         assertEquals( 2,
                       ruleFlowGroup0.size() );
         assertEquals( 2,
@@ -1088,7 +1152,7 @@
 
         // Deactivate the RuleFlowGroup, the activations should be removed from
         // the agenda but still in the RuleFlowGroup
-        agenda.deactivateRuleFlowGroup("rule-flow-group-0");
+        agenda.deactivateRuleFlowGroup( "rule-flow-group-0" );
         assertEquals( 2,
                       ruleFlowGroup0.size() );
         assertEquals( 0,
@@ -1096,7 +1160,7 @@
 
         // Reactivate the RuleFlowGroup, the activations stay in the group, but 
         // should now also be in the Agenda again
-        agenda.activateRuleFlowGroup("rule-flow-group-0");
+        agenda.activateRuleFlowGroup( "rule-flow-group-0" );
         assertEquals( 2,
                       ruleFlowGroup0.size() );
         assertEquals( 2,
@@ -1117,9 +1181,10 @@
         // create rule0
         final Consequence consequence0 = new Consequence() {
             private static final long serialVersionUID = -2596133893109870505L;
+
             public void evaluate(KnowledgeHelper knowledgeHelper,
                                  WorkingMemory w) {
-            	// do nothing
+                // do nothing
             }
         };
 
@@ -1134,21 +1199,22 @@
 
         final RuleFlowGroup ruleFlowGroup0 = agenda.getRuleFlowGroup( "rule-flow-group-0" );
         assertTrue( ruleFlowGroup0.isAutoDeactivate() );
-        ruleFlowGroup0.setAutoDeactivate(false);
+        ruleFlowGroup0.setAutoDeactivate( false );
         assertFalse( ruleFlowGroup0.isAutoDeactivate() );
 
         // create context
         final PropagationContext context0 = new PropagationContextImpl( 0,
-														                PropagationContext.ASSERTION,
-														                rule0,
-														                null );
+                                                                        PropagationContext.ASSERTION,
+                                                                        rule0,
+                                                                        null );
 
         // Create an activation for this rule
-        final ReteTuple tuple0 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+        final ReteTuple tuple0 = new ReteTuple( new DefaultFactHandle( 1,
+                                                                       "cheese" ) );
         node0.assertTuple( tuple0,
                            context0,
                            workingMemory );
-        
+
         // RuleFlowGroup should be populated, but the agenda shouldn't be
         assertEquals( 1,
                       ruleFlowGroup0.size() );
@@ -1157,7 +1223,7 @@
 
         // Activate the RuleFlowGroup, the activations stay in the group, but 
         // should now also be in the Agenda
-        agenda.activateRuleFlowGroup("rule-flow-group-0");
+        agenda.activateRuleFlowGroup( "rule-flow-group-0" );
         assertEquals( 1,
                       ruleFlowGroup0.size() );
         assertEquals( 1,
@@ -1169,24 +1235,25 @@
                       ruleFlowGroup0.size() );
         assertEquals( 0,
                       agenda.agendaSize() );
-        assertTrue(   ruleFlowGroup0.isActive() );
-        
+        assertTrue( ruleFlowGroup0.isActive() );
+
         // Set auto-deactivation status to true
-        ruleFlowGroup0.setAutoDeactivate(true);
+        ruleFlowGroup0.setAutoDeactivate( true );
         assertTrue( ruleFlowGroup0.isAutoDeactivate() );
         assertFalse( ruleFlowGroup0.isActive() );
 
         // Add another activation and activate RuleFlowGroup again
-        final ReteTuple tuple1 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+        final ReteTuple tuple1 = new ReteTuple( new DefaultFactHandle( 1,
+                                                                       "cheese" ) );
         node0.assertTuple( tuple1,
                            context0,
                            workingMemory );
-        agenda.activateRuleFlowGroup("rule-flow-group-0");
+        agenda.activateRuleFlowGroup( "rule-flow-group-0" );
         assertEquals( 1,
                       ruleFlowGroup0.size() );
         assertEquals( 1,
                       agenda.agendaSize() );
-        assertTrue(   ruleFlowGroup0.isActive() );
+        assertTrue( ruleFlowGroup0.isActive() );
 
         // Execute the activation, the RuleFlowGroup should automatically deactivate
         agenda.fireNextItem( null );
@@ -1197,7 +1264,8 @@
         assertFalse( ruleFlowGroup0.isActive() );
 
         // A new activation should now be added to the RuleFlowGroup but not to the agenda 
-        final ReteTuple tuple2 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+        final ReteTuple tuple2 = new ReteTuple( new DefaultFactHandle( 1,
+                                                                       "cheese" ) );
         node0.assertTuple( tuple2,
                            context0,
                            workingMemory );
@@ -1206,5 +1274,62 @@
         assertEquals( 0,
                       agenda.agendaSize() );
     }
+    
+    public void testRuleFlowGroupLockOnActive() {
+        final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
 
+        final ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newWorkingMemory();
+        final InternalAgenda agenda = (InternalAgenda) workingMemory.getAgenda();
+
+        // create the agendaGroup
+        //final AgendaGroupImpl agendaGroup = new AgendaGroupImpl( "agendaGroup" );
+        //agenda.addAgendaGroup( agendaGroup );
+        
+        final RuleFlowGroupImpl ruleFlowGroup = ( RuleFlowGroupImpl ) agenda.getRuleFlowGroup( "rule-flow-group-0" );
+
+        final ReteTuple tuple = new ReteTuple( new DefaultFactHandle( 1,
+                                                                      "cheese" ) );
+
+        // create a rule for the agendaGroup
+        final Rule rule = new Rule( "test-rule" );        
+        rule.setRuleFlowGroup( "rule-flow-group-0" );        
+        final RuleTerminalNode node = new RuleTerminalNode( 2,
+                                                            new MockTupleSource( 2 ),
+                                                            rule,
+                                                            rule.getLhs() );
+
+        final PropagationContext context = new PropagationContextImpl( 0,
+                                                                       PropagationContext.ASSERTION,
+                                                                       rule,
+                                                                       null );
+
+        // When both the rule is lock-on-active and the agenda group is active, activations should be ignored
+        rule.setLockOnActivate( true );
+        ruleFlowGroup.setActive( true );        
+        node.assertTuple( tuple,
+                          context,
+                          workingMemory );
+        // activation should be ignored
+        assertEquals( 0,
+                      ruleFlowGroup.size() );
+
+        // lock-on-active is now false so activation should propagate
+        rule.setLockOnActivate( false );        
+        node.assertTuple( tuple,
+                          context,
+                          workingMemory );        
+        assertEquals( 1,
+                      ruleFlowGroup.size() );
+        
+        // even if lock-on-active is true, unless the agenda group is active the activation will still propagate
+        rule.setLockOnActivate( true );        
+        ruleFlowGroup.setActive( false );        
+        node.assertTuple( tuple,
+                          context,
+                          workingMemory );        
+        assertEquals( 2,
+                      ruleFlowGroup.size() );
+    }
+    
+
 }




More information about the jboss-svn-commits mailing list