Author: bagerman Date: 2006-02-17 21:00:04 -0500 (Fri, 17 Feb 2006) New Revision: 2520 Added: trunk/labs/jbossrules/drools-core/src/test/java/org/drools/leaps/SchedulerTest.java Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/leaps/FactTable.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/leaps/WorkingMemoryImpl.java trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/LeapsMannersTest.java trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/MannersTest.java trunk/labs/jbossrules/drools-core/src/test/java/org/drools/leaps/LogicalAssertionTest.java trunk/labs/jbossrules/drools-core/src/test/java/org/drools/leaps/RuleBaseImplTest.java Log: More leaps unit tests Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/leaps/FactTable.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/leaps/FactTable.java 2006-02-17 21:28:06 UTC (rev 2519) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/leaps/FactTable.java 2006-02-18 02:00:04 UTC (rev 2520) @@ -79,7 +79,8 @@ * where added since then. Iterates through all facts asserted (and not * retracted, they are not here duh) and adds them to the stack. * - * @param working memory + * @param working + * memory * */ private void checkAndAddFactsToStack(WorkingMemoryImpl workingMemory) { @@ -103,7 +104,9 @@ /** * set indicator if rule was added already after fire all completed - * @param new value + * + * @param new + * value */ public void setReseededStack(boolean reseeded) { this.reseededStack = reseeded; Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/leaps/WorkingMemoryImpl.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/leaps/WorkingMemoryImpl.java 2006-02-17 21:28:06 UTC (rev 2519) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/leaps/WorkingMemoryImpl.java 2006-02-18 02:00:04 UTC (rev 2520) @@ -30,7 +30,6 @@ import org.drools.FactException; import org.drools.FactHandle; -import org.drools.RuleBase; import org.drools.WorkingMemory; import org.drools.base.ClassObjectType; import org.drools.common.AbstractWorkingMemory; @@ -50,7 +49,7 @@ import org.drools.spi.AgendaGroup; import org.drools.spi.Duration; import org.drools.spi.PropagationContext; -import org.drools.util.IdentityMap; +import org.drools.util.PrimitiveLongMap; /** * Followed RETEOO implementation for interfaces. @@ -64,22 +63,21 @@ * @see java.io.Serializable * */ -class WorkingMemoryImpl extends AbstractWorkingMemory implements WorkingMemory, EventSupport, +class WorkingMemoryImpl extends AbstractWorkingMemory implements EventSupport, PropertyChangeListener { private static final long serialVersionUID = -2524904474925421759L; - /** - * the following member variables are used to handle retraction - * we are not following original leaps approach that involves - * shadow fact tables due to the fact that objects can mutate and - * there is no easy way of puting original object image into shadow/retracted - * fact tables + /** + * the following member variables are used to handle retraction we are not + * following original leaps approach that involves shadow fact tables due to + * the fact that objects can mutate and there is no easy way of puting + * original object image into shadow/retracted fact tables */ // collection of pending activations for each blocking fact handle - private final IdentityMap blockingFactHandles; + private final PrimitiveLongMap blockingFactHandles; // collection of pending activations for each blocking fact handle - private final IdentityMap factHandleActivations; + private final PrimitiveLongMap factHandleActivations; /** * Construct. @@ -88,10 +86,9 @@ * The backing rule-base. */ public WorkingMemoryImpl(RuleBaseImpl ruleBase) { - super((RuleBase)ruleBase, (HandleFactory)((RuleBaseImpl)ruleBase) - .newFactHandleFactory()); - this.blockingFactHandles = new IdentityMap(); - this.factHandleActivations = new IdentityMap(); + super(ruleBase, ruleBase.newFactHandleFactory()); + this.blockingFactHandles = new PrimitiveLongMap(); + this.factHandleActivations = new PrimitiveLongMap(); } /** @@ -100,7 +97,7 @@ * @return The new fact handle. */ FactHandle newFactHandle(Object object) { - return ((HandleFactory)this.handleFactory).newFactHandle(object); + return ((HandleFactory) this.handleFactory).newFactHandle(object); } /** @@ -108,7 +105,8 @@ */ public void setGlobal(String name, Object value) { // Make sure the application data has been declared in the RuleBase - Map applicationDataDefintions = ((RuleBaseImpl)this.ruleBase).getApplicationData(); + Map applicationDataDefintions = ((RuleBaseImpl) this.ruleBase) + .getApplicationData(); Class type = (Class) applicationDataDefintions.get(name); if ((type == null)) { throw new RuntimeException("Unexpected application data [" + name @@ -139,7 +137,6 @@ return ((FactHandleImpl) handle).getObject(); } - public List getObjects(Class objectClass) { List list = new LinkedList(); for (Iterator it = this.getFactTable(objectClass).iterator(); it @@ -198,91 +195,84 @@ */ FactHandle assertObject(Object object, boolean dynamic, boolean logical, Rule rule, Activation activation) throws FactException { - // check if the object already exists in the WM - FactHandleImpl handle = (FactHandleImpl) this.identityMap.get( object ); + // check if the object already exists in the WM + FactHandleImpl handle = (FactHandleImpl) this.identityMap.get(object); - // return if the handle exists and this is a logical assertion - if ( (handle != null) && (logical) ) { - return handle; - } + // return if the handle exists and this is a logical assertion + if ((handle != null) && (logical)) { + return handle; + } - // lets see if the object is already logical asserted - Object logicalState = this.equalsMap.get( object ); + // lets see if the object is already logical asserted + Object logicalState = this.equalsMap.get(object); - // if we have a handle and this STATED fact was previously STATED - if ( (handle != null) && (!logical) && logicalState == AbstractWorkingMemory.STATED ) { - return handle; - } + // if we have a handle and this STATED fact was previously STATED + if ((handle != null) && (!logical) + && logicalState == AbstractWorkingMemory.STATED) { + return handle; + } if (!logical) { - // If this stated assertion already has justifications then we need - // to cancel them - if ( logicalState instanceof FactHandleImpl ) { - handle = (FactHandleImpl) logicalState; - removeLogicalDependencies( handle ); - } else { - handle = (FactHandleImpl) newFactHandle(object); - } + // If this stated assertion already has justifications then we need + // to cancel them + if (logicalState instanceof FactHandleImpl) { + handle = (FactHandleImpl) logicalState; + removeLogicalDependencies(handle); + } else { + handle = (FactHandleImpl) newFactHandle(object); + } - putObject( handle, - object ); + putObject(handle, object); - this.equalsMap.put( object, - AbstractWorkingMemory.STATED ); + this.equalsMap.put(object, AbstractWorkingMemory.STATED); - if ( dynamic ) { - addPropertyChangeListener( object ); - } + if (dynamic) { + addPropertyChangeListener(object); + } } else { - // This object is already STATED, we cannot make it justifieable - if ( logicalState == AbstractWorkingMemory.STATED ) { - return null; - } + // This object is already STATED, we cannot make it justifieable + if (logicalState == AbstractWorkingMemory.STATED) { + return null; + } - handle = (FactHandleImpl) logicalState; - // we create a lookup handle for the first asserted equals object - // all future equals objects will use that handle - if ( handle == null ) { - handle = (FactHandleImpl) newFactHandle(object); + handle = (FactHandleImpl) logicalState; + // we create a lookup handle for the first asserted equals object + // all future equals objects will use that handle + if (handle == null) { + handle = (FactHandleImpl) newFactHandle(object); - putObject( handle, - object ); + putObject(handle, object); - this.equalsMap.put( object, - handle ); - } - addLogicalDependency( handle, activation, activation.getPropagationContext(), rule ); + this.equalsMap.put(object, handle); + } + addLogicalDependency(handle, activation, activation + .getPropagationContext(), rule); } - // leaps handle already has object attached // handle.setObject( object ); - PropagationContext propagationContext = new PropagationContextImpl( ++this.propagationIdCounter, - PropagationContext.ASSERTION, - rule, - activation ); + // this.ruleBase.assertObject( handle, + // object, + // propagationContext, + // this ); - // this.ruleBase.assertObject( handle, - // object, - // propagationContext, - // this ); - - // determine what classes it belongs to put it into the "table" on + // determine what classes it belongs to put it into the "table" on // class name key List tablesList = this.getFactTablesList(object.getClass()); for (Iterator it = tablesList.iterator(); it.hasNext();) { // adding fact to container ((FactTable) it.next()).add(handle); } - Token token = new Token(this, (FactHandleImpl) handle); + Token token = new Token(this, handle); this.pushTokenOnStack(token); - this.workingMemoryEventSupport.fireObjectAsserted( propagationContext, - handle, - object ); - return handle; + this.workingMemoryEventSupport.fireObjectAsserted( + new PropagationContextImpl(++this.propagationIdCounter, + PropagationContext.ASSERTION, rule, activation), + handle, object); + return handle; } /** @@ -294,20 +284,19 @@ * The object. */ Object putObject(FactHandle handle, Object object) { - Object oldValue = this.objects.put(((FactHandleImpl) handle).getId(), - object); this.identityMap.put(object, handle); - return oldValue; + return this.objects.put(((FactHandleImpl) handle).getId(), object); + } Object removeObject(FactHandle handle) { - Object object = this.objects.remove(((FactHandleImpl) handle).getId()); - this.identityMap.remove(object); + this.identityMap.remove(((FactHandleImpl) handle).getObject()); - return object; + return this.objects.remove(((FactHandleImpl) handle).getId()); + } /** @@ -316,21 +305,19 @@ public void retractObject(FactHandle handle, boolean removeLogical, boolean updateEqualsMap, Rule rule, Activation activation) throws FactException { - removePropertyChangeListener( handle ); + removePropertyChangeListener(handle); + PropagationContextImpl context = new PropagationContextImpl( + ++this.propagationIdCounter, PropagationContext.RETRACTION, + rule, activation); + // this.ruleBase.retractObject( handle, + // propagationContext, + // this ); - PropagationContext propagationContext = new PropagationContextImpl( ++this.propagationIdCounter, - PropagationContext.RETRACTION, - rule, - activation ); - - // this.ruleBase.retractObject( handle, - // propagationContext, - // this ); - // // leaps specific actions // - Set pendingActivations = (Set) this.blockingFactHandles.remove(handle); + Set pendingActivations = (Set) this.blockingFactHandles + .remove(((FactHandleImpl) handle).getId()); if (pendingActivations != null) { for (Iterator it = pendingActivations.iterator(); it.hasNext();) { PendingActivation item = (PendingActivation) it.next(); @@ -351,7 +338,7 @@ } } Set postedActivations = (Set) this.factHandleActivations - .remove(handle); + .remove(((FactHandleImpl) handle).getId()); if (postedActivations != null) { for (Iterator it = postedActivations.iterator(); it.hasNext();) { PostedActivation item = (PostedActivation) it.next(); @@ -361,8 +348,14 @@ if (!((LeapsTuple) itemActivation.getTuple()) .isActivationNull() && itemActivation.isActivated()) { + item.getActivation().remove(); + + getAgendaEventSupport().fireActivationCancelled( + item.getActivation()); } + removeLogicalDependencies(item.getActivation(), context, + rule); item.setRemoved(); } } @@ -373,26 +366,25 @@ // // end leaps specific actions // - Object oldObject = removeObject( handle ); + Object oldObject = removeObject(handle); - /* check to see if this was a logical asserted object */ - if ( removeLogical ) { - removeLogicalDependencies( handle ); - this.equalsMap.remove( oldObject ); - } + /* check to see if this was a logical asserted object */ + if (removeLogical) { + removeLogicalDependencies(handle); + this.equalsMap.remove(oldObject); + } - if ( updateEqualsMap ) { - this.equalsMap.remove( oldObject ); - } - - // not applicable to leaps implementation - // this.factHandlePool.push( ((FactHandleImpl) handle).getId() ); + if (updateEqualsMap) { + this.equalsMap.remove(oldObject); + } - this.workingMemoryEventSupport.fireObjectRetracted( propagationContext, - handle, - oldObject ); - // not applicable to leaps fact handle - // ((FactHandleImpl) handle).invalidate(); + // not applicable to leaps implementation + // this.factHandlePool.push( ((FactHandleImpl) handle).getId() ); + + this.workingMemoryEventSupport.fireObjectRetracted(context, handle, + oldObject); + // not applicable to leaps fact handle + // ((FactHandleImpl) handle).invalidate(); } /** @@ -401,10 +393,6 @@ public void modifyObject(FactHandle handle, Object object, Rule rule, Activation activation) throws FactException { - PropagationContext propagationContext = new PropagationContextImpl( - ++this.propagationIdCounter, PropagationContext.MODIFICATION, - rule, activation); - this.retractObject(handle); this.assertObject(object); @@ -412,7 +400,9 @@ /* * this.ruleBase.modifyObject( handle, object, this ); */ - this.workingMemoryEventSupport.fireObjectModified(propagationContext, + this.workingMemoryEventSupport.fireObjectModified( + new PropagationContextImpl(++this.propagationIdCounter, + PropagationContext.MODIFICATION, rule, activation), handle, ((FactHandleImpl) handle).getObject(), object); } @@ -426,8 +416,6 @@ private long idLastFireAllAt = -1; - private boolean addedRulesAfterLastFire = false; - /** * algorithm stack. TreeSet is used to facilitate dynamic rule add/remove */ @@ -464,11 +452,11 @@ this.stack.push(token); } - /** - * get leaps fact table of specific type (class) + * get leaps fact table of specific type (class) * - * @param type of objects + * @param type + * of objects * @return fact table of requested class type */ protected FactTable getFactTable(Class c) { @@ -490,18 +478,19 @@ */ protected void addLeapsRules(List rules) { synchronized (this.lock) { - this.addedRulesAfterLastFire = true; + // this.addedRulesAfterLastFire = true; LeapsRule rule; RuleHandle ruleHandle; for (Iterator it = rules.iterator(); it.hasNext();) { rule = (LeapsRule) it.next(); for (int i = 0; i < rule.getNumberOfColumns(); i++) { - ruleHandle = new RuleHandle(((HandleFactory)this.handleFactory).getNextId(), + ruleHandle = new RuleHandle( + ((HandleFactory) this.handleFactory).getNextId(), rule, i); this.getFactTable( - ((ClassObjectType) ((ColumnConstraints) rule + ((ClassObjectType) (rule .getColumnConstraintsAtPosition(i)) .getColumn().getObjectType()) .getClassType()).addRule(this, ruleHandle); @@ -544,10 +533,12 @@ if (!done) { try { // ok. now we have tuple, dominant fact and - // rules and ready to seek to checks if any activation + // rules and ready to seek to checks if any + // activation // matches on current rule TokenEvaluator.evaluate(token); - // something was found so set marks for resume processing + // something was found so set marks for + // resume processing token.setResume(true); done = true; } catch (NoMatchesFoundException ex) { @@ -568,15 +559,13 @@ } catch (TableOutOfBoundException e) { new RuntimeException(e); } - if (this.addedRulesAfterLastFire) { - this.addedRulesAfterLastFire = false; - // mark when method was called last time - this.idLastFireAllAt = ((HandleFactory)this.handleFactory).getNextId(); - // set all factTables to be reseeded - for (Enumeration e = this.factTables.elements(); e - .hasMoreElements();) { - ((FactTable) e.nextElement()).setReseededStack(true); - } + // mark when method was called last time + this.idLastFireAllAt = ((HandleFactory) this.handleFactory) + .getNextId(); + // set all factTables to be reseeded + for (Enumeration e = this.factTables.elements(); e + .hasMoreElements();) { + ((FactTable) e.nextElement()).setReseededStack(true); } } finally { this.firing = false; @@ -618,44 +607,42 @@ public void assertTuple(LeapsTuple tuple, Set tupleBlockingFactHandles, PropagationContext context, Rule rule) { // if the current Rule is no-loop and the origin rule is the same then - // return - if ( rule.getNoLoop() && rule.equals( context.getRuleOrigin() ) ) { - return; - } - // see if there are blocking facts and put it on pending activations + // return + if (rule.getNoLoop() && rule.equals(context.getRuleOrigin())) { + return; + } + // see if there are blocking facts and put it on pending activations // list if (tupleBlockingFactHandles.size() != 0) { FactHandleImpl factHandle; PendingActivation item = new PendingActivation(tuple, tupleBlockingFactHandles.size(), context, rule); Set pendingActivations; - for (Iterator it = tupleBlockingFactHandles.iterator(); it.hasNext();) { + for (Iterator it = tupleBlockingFactHandles.iterator(); it + .hasNext();) { factHandle = (FactHandleImpl) it.next(); pendingActivations = (Set) this.blockingFactHandles - .get(factHandle); + .get(factHandle.getId()); if (pendingActivations == null) { pendingActivations = new HashSet(); - this.blockingFactHandles - .put(factHandle, pendingActivations); + this.blockingFactHandles.put(factHandle.getId(), + pendingActivations); } pendingActivations.add(item); } return; } - Duration dur = rule.getDuration(); + Duration dur = rule.getDuration(); - if ( dur != null && dur.getDuration( tuple ) > 0 ) { - ScheduledAgendaItem item = new ScheduledAgendaItem( context.getPropagationNumber(), - tuple, - this.agenda, - context, - rule ); - this.agenda.scheduleItem( item ); - tuple.setActivation( item ); - item.setActivated( true ); - this.getAgendaEventSupport().fireActivationCreated( item ); - } else { + if (dur != null && dur.getDuration(tuple) > 0) { + ScheduledAgendaItem item = new ScheduledAgendaItem(context + .getPropagationNumber(), tuple, this.agenda, context, rule); + this.agenda.scheduleItem(item); + tuple.setActivation(item); + item.setActivated(true); + this.getAgendaEventSupport().fireActivationCreated(item); + } else { // ----------------- // Lazy instantiation and addition to the Agenda of AgendGroup // implementations @@ -699,10 +686,11 @@ for (int i = 0; i < factHandles.length; i++) { factHandle = factHandles[i]; postedActivations = (Set) this.factHandleActivations - .get(factHandle); + .get(((FactHandleImpl) factHandle).getId()); if (postedActivations == null) { postedActivations = new HashSet(); - this.factHandleActivations.put(factHandle, + this.factHandleActivations.put( + ((FactHandleImpl) factHandle).getId(), postedActivations); } postedActivations.add(postedActivation); @@ -715,7 +703,7 @@ // returns. agendaGroup.addToAgenda(queue); tuple.setActivation(item); - item.setActivated( true ); + item.setActivated(true); this.getAgendaEventSupport().fireActivationCreated(item); } } @@ -724,69 +712,67 @@ return ++this.propagationIdCounter; } - public void removeLogicalDependencies(Activation activation, - PropagationContext context, - Rule rule) throws FactException { - org.drools.util.LinkedList list = activation.getLogicalDependencies(); - if ( list == null || list.isEmpty() ) { - return; - } - for ( LogicalDependency node = (LogicalDependency) list.getFirst(); node != null; node = (LogicalDependency) node.getNext() ) { - FactHandleImpl handle = (FactHandleImpl) node.getFactHandle(); - Set set = (Set) this.justified.get( handle.getId() ); - set.remove( node ); - if ( set.isEmpty() ) { - this.justified.remove( handle.getId() ); - retractObject( handle, - false, - true, - context.getRuleOrigin(), - context.getActivationOrigin() ); - } - } - } + public void removeLogicalDependencies(Activation activation, + PropagationContext context, Rule rule) throws FactException { + org.drools.util.LinkedList list = activation.getLogicalDependencies(); + if (list == null || list.isEmpty()) { + return; + } + for (LogicalDependency node = (LogicalDependency) list.getFirst(); node != null; node = (LogicalDependency) node + .getNext()) { + FactHandleImpl handle = (FactHandleImpl) node.getFactHandle(); + Set set = (Set) this.justified.get(handle.getId()); + set.remove(node); + if (set.isEmpty()) { + this.justified.remove(handle.getId()); + retractObject(handle, false, true, context.getRuleOrigin(), + context.getActivationOrigin()); + } + } + } - public void removeLogicalDependencies(FactHandle handle) throws FactException { - Set set = (Set) this.justified.remove( ((FactHandleImpl) handle).getId() ); - if (set != null && !set.isEmpty()) { - for( Iterator it = set.iterator(); it.hasNext(); ) { - LogicalDependency node = (LogicalDependency) it.next(); - node.getJustifier().getLogicalDependencies().remove( node ); - } - } - } + public void removeLogicalDependencies(FactHandle handle) + throws FactException { + Set set = (Set) this.justified + .remove(((FactHandleImpl) handle).getId()); + if (set != null && !set.isEmpty()) { + for (Iterator it = set.iterator(); it.hasNext();) { + LogicalDependency node = (LogicalDependency) it.next(); + node.getJustifier().getLogicalDependencies().remove(node); + } + } + } - public void addLogicalDependency(FactHandle handle, - Activation activation, - PropagationContext context, - Rule rule) throws FactException { - LogicalDependency node = new LogicalDependency( activation, - handle ); - activation.addLogicalDependency( node ); - Set set = (Set) this.justified.get( ((FactHandleImpl) handle).getId() ); - if ( set == null ) { - set = new HashSet(); - this.justified.put( ((FactHandleImpl) handle).getId(), - set ); - } - set.add( node ); - } + public void addLogicalDependency(FactHandle handle, Activation activation, + PropagationContext context, Rule rule) throws FactException { + LogicalDependency node = new LogicalDependency(activation, handle); + activation.addLogicalDependency(node); + Set set = (Set) this.justified.get(((FactHandleImpl) handle).getId()); + if (set == null) { + set = new HashSet(); + this.justified.put(((FactHandleImpl) handle).getId(), set); + } + set.add(node); + } public void dispose() { - ((RuleBaseImpl)this.ruleBase).disposeWorkingMemory(this); + ((RuleBaseImpl) this.ruleBase).disposeWorkingMemory(this); } - /** - * Retrieve the rule-firing <code>Agenda</code> for this - * <code>WorkingMemory</code>. - * - * @return The <code>Agenda</code>. - */ - protected Agenda getAgenda() { - return this.agenda; - } - - protected Set getFactHandleActivations(FactHandle factHandle) { - return (Set)this.factHandleActivations.get(factHandle); - } + /** + * Retrieve the rule-firing <code>Agenda</code> for this + * <code>WorkingMemory</code>. + * + * @return The <code>Agenda</code>. + */ + protected Agenda getAgenda() { + return this.agenda; + } + + protected Set getFactHandleActivations(FactHandle factHandle) { + + return (Set) this.factHandleActivations + .get(((FactHandleImpl) factHandle).getId()); + + } } Modified: trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/LeapsMannersTest.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/LeapsMannersTest.java 2006-02-17 21:28:06 UTC (rev 2519) +++ trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/LeapsMannersTest.java 2006-02-18 02:00:04 UTC (rev 2520) @@ -124,7 +124,7 @@ ruleBase.addRuleSet( ruleSet ); WorkingMemory workingMemory = ruleBase.newWorkingMemory(); - InputStream is = getClass().getResourceAsStream( "/manners16.dat" ); + InputStream is = getClass().getResourceAsStream( "/manners64.dat" ); List list = getInputObjects( is ); for ( Iterator it = list.iterator(); it.hasNext(); ) { Object object = it.next(); Modified: trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/MannersTest.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/MannersTest.java 2006-02-17 21:28:06 UTC (rev 2519) +++ trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/MannersTest.java 2006-02-18 02:00:04 UTC (rev 2520) @@ -124,7 +124,7 @@ ruleBase.addRuleSet( ruleSet ); WorkingMemory workingMemory = ruleBase.newWorkingMemory(); - InputStream is = getClass().getResourceAsStream( "/manners5.dat" ); + InputStream is = getClass().getResourceAsStream( "/manners64.dat" ); List list = getInputObjects( is ); for ( Iterator it = list.iterator(); it.hasNext(); ) { Object object = it.next(); Modified: trunk/labs/jbossrules/drools-core/src/test/java/org/drools/leaps/LogicalAssertionTest.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/test/java/org/drools/leaps/LogicalAssertionTest.java 2006-02-17 21:28:06 UTC (rev 2519) +++ trunk/labs/jbossrules/drools-core/src/test/java/org/drools/leaps/LogicalAssertionTest.java 2006-02-18 02:00:04 UTC (rev 2520) @@ -19,15 +19,22 @@ import java.util.HashSet; import org.drools.DroolsTestCase; +import org.drools.FactException; import org.drools.FactHandle; +import org.drools.RuleIntegrationException; +import org.drools.RuleSetIntegrationException; import org.drools.WorkingMemory; import org.drools.common.Agenda; import org.drools.common.PropagationContextImpl; +import org.drools.rule.InvalidPatternException; import org.drools.rule.Rule; import org.drools.spi.Activation; import org.drools.spi.Consequence; import org.drools.spi.PropagationContext; +/** + * @author Alexander Bagerman + */ public class LogicalAssertionTest extends DroolsTestCase { public void testEqualsMap() throws Exception { @@ -93,11 +100,7 @@ * @throws Exception */ public void testStatedOverride() throws Exception { - // create a RuleBase with a single ObjectTypeNode we attach a - // MockObjectSink so we can detect assertions and retractions RuleBaseImpl ruleBase = new RuleBaseImpl(); - // create a RuleBase with a single ObjectTypeNode we attach a - // MockObjectSink so we can detect assertions and retractions final Rule rule1 = new Rule("test-rule1"); WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) ruleBase @@ -140,8 +143,8 @@ // so while new STATED assertion is equal assertEquals(logicalString1, workingMemory.getObject(logicalHandle2)); - // they are not identity same - assertNotSame(logicalString1, workingMemory.getObject(logicalHandle2)); + // they are not - not identity same - leaps can not store two objects if handles are the same + assertSame(logicalString1, workingMemory.getObject(logicalHandle2)); // Test that a logical assertion cannot override a STATED assertion factHandles[0] = (FactHandleImpl) logicalHandle2; @@ -183,175 +186,129 @@ } - // public void testRetract() throws Exception { - // // create a RuleBase with a single ObjectTypeNode we attach a - // // MockObjectSink so we can detect assertions and retractions - // final Rule rule1 = new Rule( "test-rule1" ); - // Rete rete = new Rete(); - // ObjectTypeNode objectTypeNode = new ObjectTypeNode( 0, - // new ClassObjectType( String.class ), - // rete ); - // objectTypeNode.attach(); - // MockObjectSink sink = new MockObjectSink(); - // objectTypeNode.addObjectSink( sink ); - // final TerminalNode node = new TerminalNode(2, new MockTupleSource(2), rule1); - // RuleBase ruleBase = new RuleBaseImpl(); - // WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) ruleBase.newWorkingMemory(); - // - // Consequence consequence = new Consequence() { - // public void invoke(Activation activation, WorkingMemory workingMemory) { - // // do nothing - // } - // }; - // - // // create the first activation which will justify the fact "logical" - // rule1.setConsequence( consequence ); - // - // FactHandleImpl handle1 = new FactHandleImpl( 1 ); - // ReteTuple tuple1 = new ReteTuple( handle1 ); - // - // PropagationContext context = new PropagationContextImpl( 0, - // PropagationContext.ASSERTION, - // null, - // null ); - // - // node.assertTuple( tuple1, context, workingMemory ); - // - // // Assert the logical "logical" fact - // String logicalString1 = new String( "logical" ); - // FactHandle logicalHandle1 = workingMemory.assertObject( logicalString1, - // false, - // true, - // rule1, - // tuple1.getActivation() ); - // - // // create the second activation to justify the "logical" fact - // final Rule rule2 = new Rule( "test-rule2" ); - // final TerminalNode node2 = new TerminalNode(4, new MockTupleSource(3), rule2); - // rule2.setConsequence( consequence ); - // - // FactHandleImpl handle2 = new FactHandleImpl( 2 ); - // ReteTuple tuple2 = new ReteTuple( handle2 ); - // - // node.assertTuple( tuple2, context, workingMemory ); - // - // node2.assertTuple( tuple2, context, workingMemory ); - // - // // Assert the logical "logical" fact - // String logicalString2 = new String( "logical" ); - // FactHandle logicalHandle2 = workingMemory.assertObject( logicalString2, - // false, - // true, - // rule2, - // tuple2.getActivation() ); - // - // // "logical" should only appear once - // assertLength( 1, - // workingMemory.getJustified().values() ); - // - // // retract the logical object - // workingMemory.retractObject( logicalHandle2 ); - // - // // The logical object should never appear - // assertLength( 0, - // workingMemory.getJustified().values() ); - // - // } - // - // public void testMultipleLogicalRelationships() throws FactException { - // final Rule rule1 = new Rule( "test-rule1" ); - // RuleBaseImpl ruleBase = new RuleBaseImpl(); - // Rete rete = ruleBase.getRete(); - // - // // Create a RuleBase with a single ObjectTypeNode we attach a - // // MockObjectSink so we can detect assertions and retractions - // ObjectTypeNode objectTypeNode = new ObjectTypeNode( 1, - // new ClassObjectType( String.class ), - // rete ); - // objectTypeNode.attach(); - // MockObjectSink sink = new MockObjectSink(); - // objectTypeNode.addObjectSink( sink ); - // final TerminalNode node = new TerminalNode(2, new MockTupleSource(2), rule1); - // WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) ruleBase.newWorkingMemory(); - // - // final Agenda agenda = workingMemory.getAgenda(); - // - // Consequence consequence = new Consequence() { - // public void invoke(Activation activation, WorkingMemory workingMemory) { - // // do nothing - // } - // }; - // - // // Create first justifier - // rule1.setConsequence( consequence ); - // - // FactHandleImpl handle1 = new FactHandleImpl( 1 ); - // ReteTuple tuple1 = new ReteTuple( handle1 ); - // - // final PropagationContext context1 = new PropagationContextImpl( 0, - // PropagationContext.ASSERTION, - // null, - // null ); - // // get the activation onto the agenda - // node.assertTuple( tuple1, context1, workingMemory ); - // - // // Create the second justifer - // final Rule rule2 = new Rule( "test-rule2" ); - // final TerminalNode node2 = new TerminalNode(4, new MockTupleSource(3), rule2); - // rule2.setConsequence( consequence ); - // - // FactHandleImpl handle2 = new FactHandleImpl( 2 ); - // ReteTuple tuple2 = new ReteTuple( handle2 ); - // - // final PropagationContext context2 = new PropagationContextImpl( 0, - // PropagationContext.ASSERTION, - // null, - // null ); - // - // // get the activations onto the agenda - // node2.assertTuple( tuple2, context2, workingMemory ); - // - // // Create the first justifieable relationship - // String logicalString1 = new String( "logical" ); - // FactHandle logicalHandle1 = workingMemory.assertObject( logicalString1, - // false, - // true, - // rule1, - // tuple1.getActivation() ); - // - // // Create the second justifieable relationship - // String logicalString2 = new String ( "logical" ); - // FactHandle logicalHandle2 = workingMemory.assertObject( logicalString2, - // false, - // true, - // rule2, - // tuple2.getActivation()); - // - // // "logical" should only appear once - // assertLength( 1, - // workingMemory.getJustified().values() ); - // - // // Now lets cancel the first activation - // node2.retractTuple( tuple2, context2, workingMemory ); - // - // // because this logical fact has two relationships it shouldn't retract yet - // assertLength( 0, - // sink.getRetracted() ); - // - // // check "logical" is still in the system - // assertLength( 1, - // workingMemory.getJustified().values() ); - // - // // now remove that final justification - // node.retractTuple( tuple1, context1, workingMemory ); - // - // // Should cause the logical fact to be retracted - // assertLength( 1, - // sink.getRetracted() ); - // - // // "logical" fact should no longer be in the system - // assertLength( 0, - // workingMemory.getJustified().values() ); - // } - // + public void testRetract() throws Exception { + final Rule rule1 = new Rule("test-rule1"); + + RuleBaseImpl ruleBase = new RuleBaseImpl(); + WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) ruleBase + .newWorkingMemory(); + + Consequence consequence = new Consequence() { + public void invoke(Activation activation, + WorkingMemory workingMemory) { + // do nothing + } + }; + + // create the first activation which will justify the fact "logical" + rule1.setConsequence(consequence); + + FactHandleImpl tuple1FactHandle = (FactHandleImpl) workingMemory + .assertObject("tuple1 object"); + FactHandleImpl tuple2FactHandle = (FactHandleImpl) workingMemory + .assertObject("tuple2 object"); + FactHandleImpl[] factHandlesTuple1 = new FactHandleImpl[1]; + FactHandleImpl[] factHandlesTuple2 = new FactHandleImpl[1]; + factHandlesTuple1[0] = tuple1FactHandle; + factHandlesTuple2[0] = tuple2FactHandle; + PropagationContext context1; + LeapsTuple tuple1 = new LeapsTuple(factHandlesTuple1); + LeapsTuple tuple2 = new LeapsTuple(factHandlesTuple2); + + PropagationContext context = new PropagationContextImpl(0, + PropagationContext.ASSERTION, null, null); + workingMemory.assertTuple(tuple1, new HashSet(), context, rule1); + Activation activation1 = workingMemory.getAgenda().getActivations()[0]; + + // Assert the logical "logical" fact + String logicalString1 = new String("logical"); + FactHandle logicalHandle1 = workingMemory.assertObject(logicalString1, + false, true, rule1, activation1); + + // create the second activation to justify the "logical" fact + final Rule rule2 = new Rule("test-rule2"); + rule2.setConsequence(consequence); + tuple1 = new LeapsTuple(factHandlesTuple2); + workingMemory.assertTuple(tuple1, new HashSet(), context, rule1); + Activation activation2 = workingMemory.getAgenda().getActivations()[1]; + // + String logicalString2 = new String("logical"); + FactHandle logicalHandle2 = workingMemory.assertObject(logicalString2, + false, true, rule1, activation2); + // "logical" should only appear once + assertLength(1, workingMemory.getJustified().values()); + + // retract the logical object + workingMemory.retractObject(logicalHandle2); + + // The logical object should never appear + assertLength(0, workingMemory.getJustified().values()); + + } + + public void testMultipleLogicalRelationships() throws FactException, + RuleSetIntegrationException, InvalidPatternException, + RuleIntegrationException { + final Rule rule1 = new Rule("test-rule1"); + + RuleBaseImpl ruleBase = new RuleBaseImpl(); + + WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) ruleBase + .newWorkingMemory(); + + Consequence consequence = new Consequence() { + public void invoke(Activation activation, + WorkingMemory workingMemory) { + // do nothing + } + }; + + // create the first activation which will justify the fact "logical" + rule1.setConsequence(consequence); + FactHandleImpl tuple1FactHandle = (FactHandleImpl) workingMemory + .assertObject("tuple1 object"); + FactHandleImpl tuple2FactHandle = (FactHandleImpl) workingMemory + .assertObject("tuple2 object"); + FactHandleImpl[] factHandlesTuple1 = new FactHandleImpl[1]; + FactHandleImpl[] factHandlesTuple2 = new FactHandleImpl[1]; + factHandlesTuple1[0] = tuple1FactHandle; + factHandlesTuple2[0] = tuple2FactHandle; + PropagationContext context1; + LeapsTuple tuple1 = new LeapsTuple(factHandlesTuple1); + LeapsTuple tuple2 = new LeapsTuple(factHandlesTuple2); + + PropagationContext context = new PropagationContextImpl(0, + PropagationContext.ASSERTION, null, null); + workingMemory.assertTuple(tuple1, new HashSet(), context, rule1); + Activation activation1 = workingMemory.getAgenda().getActivations()[0]; + + // Assert the logical "logical" fact + String logicalString1 = new String("logical"); + FactHandle logicalHandle1 = workingMemory.assertObject(logicalString1, + false, true, rule1, activation1); + + // create the second activation to justify the "logical" fact + final Rule rule2 = new Rule("test-rule2"); + rule2.setConsequence(consequence); + tuple2 = new LeapsTuple(factHandlesTuple2); + workingMemory.assertTuple(tuple2, new HashSet(), context, rule1); + Activation activation2 = workingMemory.getAgenda().getActivations()[1]; + // + String logicalString2 = new String("logical"); + FactHandle logicalHandle2 = workingMemory.assertObject(logicalString2, + false, true, rule1, activation2); + + // "logical" should only appear once + assertLength(1, workingMemory.getJustified().values()); + // + workingMemory.retractObject(tuple1FactHandle); + // check "logical" is still in the system + assertLength(1, workingMemory.getJustified().values()); + + // now remove that final justification + workingMemory.retractObject(tuple2FactHandle); + // "logical" fact should no longer be in the system + assertLength(0, workingMemory.getJustified().values()); + } + } Modified: trunk/labs/jbossrules/drools-core/src/test/java/org/drools/leaps/RuleBaseImplTest.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/test/java/org/drools/leaps/RuleBaseImplTest.java 2006-02-17 21:28:06 UTC (rev 2519) +++ trunk/labs/jbossrules/drools-core/src/test/java/org/drools/leaps/RuleBaseImplTest.java 2006-02-18 02:00:04 UTC (rev 2520) @@ -16,77 +16,362 @@ * limitations under the License. */ +import java.beans.IntrospectionException; + import org.drools.DroolsTestCase; import org.drools.WorkingMemory; +import org.drools.base.ClassFieldExtractor; +import org.drools.base.ClassObjectType; +import org.drools.base.DefaultKnowledgeHelper; +import org.drools.base.EvaluatorFactory; +import org.drools.examples.manners.Chosen; +import org.drools.examples.manners.Context; +import org.drools.examples.manners.Guest; +import org.drools.rule.Column; +import org.drools.rule.Declaration; +import org.drools.rule.LiteralConstraint; +import org.drools.rule.Rule; +import org.drools.spi.Activation; +import org.drools.spi.Consequence; +import org.drools.spi.ConsequenceException; +import org.drools.spi.Evaluator; +import org.drools.spi.Field; +import org.drools.spi.FieldConstraint; +import org.drools.spi.FieldExtractor; +import org.drools.spi.KnowledgeHelper; +import org.drools.spi.MockField; +import org.drools.spi.Tuple; +import java.util.*; +/** + * + * @author Alexander Bagerman + * + */ public class RuleBaseImplTest extends DroolsTestCase { - RuleBaseImpl ruleBase; + RuleBaseImpl ruleBase; + RuleBaseImpl ruleBaseAddRule; - WorkingMemory wm1; - WorkingMemory wm2; - WorkingMemory wm3; - WorkingMemory wm4; + WorkingMemory wm1; - public void setUp() throws Exception { - this.ruleBase = new RuleBaseImpl(); + WorkingMemory wm2; - this.wm1 = this.ruleBase.newWorkingMemory(); - this.wm2 = this.ruleBase.newWorkingMemory(); - this.wm3 = this.ruleBase.newWorkingMemory(); - this.wm4 = this.ruleBase.newWorkingMemory(); - } + WorkingMemory wm3; - public void testKeepReference() throws Exception { - /* Make sure the RuleBase is referencing all 4 Working Memories */ - assertLength( 4, - this.ruleBase.getWorkingMemories() ); - assertTrue( this.ruleBase.getWorkingMemories().contains( this.wm1 ) ); - assertTrue( this.ruleBase.getWorkingMemories().contains( this.wm2 ) ); - assertTrue( this.ruleBase.getWorkingMemories().contains( this.wm3 ) ); - assertTrue( this.ruleBase.getWorkingMemories().contains( this.wm4 ) ); - } + WorkingMemory wm4; - public void testWeakReference() throws Exception { - /* nulling these two so the keys should get garbage collected */ - this.wm2 = null; - this.wm4 = null; + // leaps add rule objects + final String handle1Rule1 = "11"; - /* Run GC */ - System.gc(); - Thread.sleep( 200 ); // Shouldn't need to sleep, but put it in anyway + final String handle1Rule2 = "12"; - /* Check we now only have two keys */ - assertLength( 2, - this.ruleBase.getWorkingMemories() ); + final String handle2Rule1 = "21"; - /* Make sure the correct keys were removed */ - assertTrue( this.ruleBase.getWorkingMemories().contains( this.wm1 ) ); - assertFalse( this.ruleBase.getWorkingMemories().contains( this.wm2 ) ); - assertTrue( this.ruleBase.getWorkingMemories().contains( this.wm3 ) ); - assertFalse( this.ruleBase.getWorkingMemories().contains( this.wm4 ) ); + final String handle2Rule2 = "22"; - } + final ArrayList handlesForRules = new ArrayList(); - public void testDispose() throws Exception { - /* - * Now lets test the dispose method on the WorkingMemory itself. dispose - * doesn't need GC - */ - this.wm3.dispose(); + WorkingMemory workingMemory; - /* Check only wm3 was removed */ - assertLength( 3, - this.ruleBase.getWorkingMemories() ); - assertFalse( this.ruleBase.getWorkingMemories().contains( this.wm3 ) ); - } + Rule rule1; - public void testNoKeepReference() throws Exception { - WorkingMemory wm5 = this.ruleBase.newWorkingMemory( false ); - WorkingMemory wm6 = this.ruleBase.newWorkingMemory( false ); - assertLength( 4, - this.ruleBase.getWorkingMemories() ); - assertFalse( this.ruleBase.getWorkingMemories().contains( wm5 ) ); - assertFalse( this.ruleBase.getWorkingMemories().contains( wm6 ) ); - } + Rule rule2; + final Context context1 = new Context(1); + + final Context context2 = new Context(1); + + public void setUp() throws Exception { + this.ruleBase = new RuleBaseImpl(); + + this.wm1 = this.ruleBase.newWorkingMemory(); + this.wm2 = this.ruleBase.newWorkingMemory(); + this.wm3 = this.ruleBase.newWorkingMemory(); + this.wm4 = this.ruleBase.newWorkingMemory(); + // add rules section + this.ruleBaseAddRule = new RuleBaseImpl(); + + this.workingMemory = this.ruleBaseAddRule.newWorkingMemory(); + // rules + ClassObjectType contextType = new ClassObjectType(Context.class); + Evaluator integerEqualEvaluator = EvaluatorFactory.getInstance() + .getEvaluator(Evaluator.INTEGER_TYPE, Evaluator.EQUAL); + // rule 1 + // fires on context.state == integer(1) + this.rule1 = new Rule("rule1"); + Column contextColumnRule1 = new Column(0, contextType, "context1"); + contextColumnRule1.addConstraint(getLiteralConstraint( + contextColumnRule1, "state", new Integer(1), + integerEqualEvaluator)); + this.rule1.addPattern(contextColumnRule1); + final Declaration contextRule1Declaration = this.rule1 + .getDeclaration("context1"); + this.rule1.setConsequence(new Consequence() { + public void invoke(Activation activation, + WorkingMemory workingMemory) throws ConsequenceException { + try { + Rule rule = activation.getRule(); + Tuple tuple = activation.getTuple(); + KnowledgeHelper drools = new DefaultKnowledgeHelper(rule, + tuple, workingMemory); + + Context dummy = (Context) drools + .get(contextRule1Declaration); + if (dummy == RuleBaseImplTest.this.context1) { + RuleBaseImplTest.this.handlesForRules + .add(RuleBaseImplTest.this.handle1Rule1); + } else if (dummy == RuleBaseImplTest.this.context2) { + RuleBaseImplTest.this.handlesForRules + .add(RuleBaseImplTest.this.handle2Rule1); + } + + } catch (Exception e) { + throw new ConsequenceException(e); + } + } + + }); + this.rule2 = new Rule("rule2"); + Column contextColumnRule2 = new Column(0, contextType, "context2"); + contextColumnRule2.addConstraint(getLiteralConstraint( + contextColumnRule2, "state", new Integer(1), + integerEqualEvaluator)); + this.rule2.addPattern(contextColumnRule2); + final Declaration contextRule2Declaration = rule2 + .getDeclaration("context2"); + this.rule2.setConsequence(new Consequence() { + public void invoke(Activation activation, + WorkingMemory workingMemory) throws ConsequenceException { + try { + Rule rule = activation.getRule(); + Tuple tuple = activation.getTuple(); + KnowledgeHelper drools = new DefaultKnowledgeHelper(rule, + tuple, workingMemory); + + Context dummy = (Context) drools + .get(contextRule2Declaration); + if (dummy == RuleBaseImplTest.this.context1) { + RuleBaseImplTest.this.handlesForRules + .add(RuleBaseImplTest.this.handle1Rule2); + } else if (dummy == RuleBaseImplTest.this.context2) { + RuleBaseImplTest.this.handlesForRules + .add(RuleBaseImplTest.this.handle2Rule2); + } + + } catch (Exception e) { + throw new ConsequenceException(e); + } + } + + }); + } + + public void testKeepReference() throws Exception { + /* Make sure the RuleBase is referencing all 4 Working Memories */ + assertLength(4, this.ruleBase.getWorkingMemories()); + assertTrue(this.ruleBase.getWorkingMemories().contains(this.wm1)); + assertTrue(this.ruleBase.getWorkingMemories().contains(this.wm2)); + assertTrue(this.ruleBase.getWorkingMemories().contains(this.wm3)); + assertTrue(this.ruleBase.getWorkingMemories().contains(this.wm4)); + } + + public void testWeakReference() throws Exception { + /* nulling these two so the keys should get garbage collected */ + this.wm2 = null; + this.wm4 = null; + + /* Run GC */ + System.gc(); + Thread.sleep(200); // Shouldn't need to sleep, but put it in anyway + + /* Check we now only have two keys */ + assertLength(2, this.ruleBase.getWorkingMemories()); + + /* Make sure the correct keys were removed */ + assertTrue(this.ruleBase.getWorkingMemories().contains(this.wm1)); + assertFalse(this.ruleBase.getWorkingMemories().contains(this.wm2)); + assertTrue(this.ruleBase.getWorkingMemories().contains(this.wm3)); + assertFalse(this.ruleBase.getWorkingMemories().contains(this.wm4)); + + } + + public void testDispose() throws Exception { + /* + * Now lets test the dispose method on the WorkingMemory itself. dispose + * doesn't need GC + */ + this.wm3.dispose(); + + /* Check only wm3 was removed */ + assertLength(3, this.ruleBase.getWorkingMemories()); + assertFalse(this.ruleBase.getWorkingMemories().contains(this.wm3)); + } + + public void testNoKeepReference() throws Exception { + WorkingMemory wm5 = this.ruleBase.newWorkingMemory(false); + WorkingMemory wm6 = this.ruleBase.newWorkingMemory(false); + assertLength(4, this.ruleBase.getWorkingMemories()); + assertFalse(this.ruleBase.getWorkingMemories().contains(wm5)); + assertFalse(this.ruleBase.getWorkingMemories().contains(wm6)); + } + + public void testAddRuleBeforeFacts() throws Exception { + + assertEquals(0, this.handlesForRules.size()); + + this.ruleBaseAddRule.addRule(this.rule1); + this.ruleBaseAddRule.addRule(this.rule2); + this.workingMemory.assertObject(this.context1); + this.workingMemory.assertObject(this.context2); + // firing + this.workingMemory.fireAllRules(); + // finally everything should be filled + assertEquals(4, this.handlesForRules.size()); + assertTrue(this.handlesForRules.contains(this.handle1Rule1)); + assertTrue(this.handlesForRules.contains(this.handle2Rule1)); + assertTrue(this.handlesForRules.contains(this.handle1Rule2)); + assertTrue(this.handlesForRules.contains(this.handle2Rule2)); + } + + public void testAddRuleMixedWithFacts() throws Exception { + + assertEquals(0, this.handlesForRules.size()); + + this.ruleBaseAddRule.addRule(this.rule1); + this.workingMemory.assertObject(this.context1); + this.ruleBaseAddRule.addRule(this.rule2); + this.workingMemory.assertObject(this.context2); + // firing + this.workingMemory.fireAllRules(); + // finally everything should be filled + assertEquals(4, this.handlesForRules.size()); + assertTrue(this.handlesForRules.contains(this.handle1Rule1)); + assertTrue(this.handlesForRules.contains(this.handle2Rule1)); + assertTrue(this.handlesForRules.contains(this.handle1Rule2)); + assertTrue(this.handlesForRules.contains(this.handle2Rule2)); + } + + public void testAddRuleAfterFacts() throws Exception { + + assertEquals(0, this.handlesForRules.size()); + this.workingMemory.assertObject(this.context1); + this.workingMemory.assertObject(this.context2); + this.ruleBaseAddRule.addRule(this.rule1); + this.ruleBaseAddRule.addRule(this.rule2); + // firing + this.workingMemory.fireAllRules(); + // finally everything should be filled + assertEquals(4, this.handlesForRules.size()); + assertTrue(this.handlesForRules.contains(this.handle1Rule1)); + assertTrue(this.handlesForRules.contains(this.handle2Rule1)); + assertTrue(this.handlesForRules.contains(this.handle1Rule2)); + assertTrue(this.handlesForRules.contains(this.handle2Rule2)); + } + + + public void testAddRuleBeforeFactsFiring() throws Exception { + + assertEquals(0, this.handlesForRules.size()); + + this.ruleBaseAddRule.addRule(this.rule1); + // firing + this.workingMemory.fireAllRules(); + this.ruleBaseAddRule.addRule(this.rule2); + // firing + this.workingMemory.fireAllRules(); + this.workingMemory.assertObject(this.context1); + // firing + this.workingMemory.fireAllRules(); + this.workingMemory.assertObject(this.context2); + // firing + this.workingMemory.fireAllRules(); + // finally everything should be filled + assertEquals(4, this.handlesForRules.size()); + assertTrue(this.handlesForRules.contains(this.handle1Rule1)); + assertTrue(this.handlesForRules.contains(this.handle2Rule1)); + assertTrue(this.handlesForRules.contains(this.handle1Rule2)); + assertTrue(this.handlesForRules.contains(this.handle2Rule2)); + } + + public void testAddRuleMixedWithFactsFiring1() throws Exception { + + assertEquals(0, this.handlesForRules.size()); + + this.ruleBaseAddRule.addRule(this.rule1); + // firing + this.workingMemory.fireAllRules(); + this.workingMemory.assertObject(this.context1); + // firing + this.workingMemory.fireAllRules(); + this.ruleBaseAddRule.addRule(this.rule2); + // firing + this.workingMemory.fireAllRules(); + this.workingMemory.assertObject(this.context2); + // firing + this.workingMemory.fireAllRules(); + // finally everything should be filled + assertEquals(4, this.handlesForRules.size()); + assertTrue(this.handlesForRules.contains(this.handle1Rule1)); + assertTrue(this.handlesForRules.contains(this.handle2Rule1)); + assertTrue(this.handlesForRules.contains(this.handle1Rule2)); + assertTrue(this.handlesForRules.contains(this.handle2Rule2)); + } + + public void testAddRuleMixedWithFactsFiring2() throws Exception { + + assertEquals(0, this.handlesForRules.size()); + + this.ruleBaseAddRule.addRule(this.rule2); + // firing + this.workingMemory.fireAllRules(); + this.workingMemory.assertObject(this.context1); + // firing + this.workingMemory.fireAllRules(); + // firing + this.workingMemory.fireAllRules(); + this.workingMemory.assertObject(this.context2); + this.ruleBaseAddRule.addRule(this.rule1); + // firing + this.workingMemory.fireAllRules(); + // finally everything should be filled + assertEquals(4, this.handlesForRules.size()); + assertTrue(this.handlesForRules.contains(this.handle1Rule1)); + assertTrue(this.handlesForRules.contains(this.handle2Rule1)); + assertTrue(this.handlesForRules.contains(this.handle1Rule2)); + assertTrue(this.handlesForRules.contains(this.handle2Rule2)); + } + + public void testAddRuleAfterFactsFiring() throws Exception { + + assertEquals(0, this.handlesForRules.size()); + this.workingMemory.assertObject(this.context1); + // firing + this.workingMemory.fireAllRules(); + this.workingMemory.assertObject(this.context2); + // firing + this.workingMemory.fireAllRules(); + this.ruleBaseAddRule.addRule(this.rule1); + // firing + this.workingMemory.fireAllRules(); + this.ruleBaseAddRule.addRule(this.rule2); + // firing + this.workingMemory.fireAllRules(); + // finally everything should be filled + assertEquals(4, this.handlesForRules.size()); + assertTrue(this.handlesForRules.contains(this.handle1Rule1)); + assertTrue(this.handlesForRules.contains(this.handle2Rule1)); + assertTrue(this.handlesForRules.contains(this.handle1Rule2)); + assertTrue(this.handlesForRules.contains(this.handle2Rule2)); + } + + private FieldConstraint getLiteralConstraint(Column column, + String fieldName, Object fieldValue, Evaluator evaluator) { + Class clazz = ((ClassObjectType) column.getObjectType()).getClassType(); + + FieldExtractor extractor = new ClassFieldExtractor(clazz, f... [truncated message content] |