Author: mar...@jb... Date: 2006-01-06 21:17:23 -0500 (Fri, 06 Jan 2006) New Revision: 2010 Removed: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/ExtractorBinding.java Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/reteoo/ReteTuple.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/Binding.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/ColumnBinding.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/Declaration.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/EvaluatorFactory.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/Rule.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/ClassObjectType.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/DefaultKnowledgeHelper.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/Evaluator.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/Extractor.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/KnowledgeHelper.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/ObjectType.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/Tuple.java trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/Context.java trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/Guest.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/examples/manners/Seat.java trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/Seating.java trunk/labs/jbossrules/drools-core/src/test/java/org/drools/rule/ConstraintTest.java trunk/labs/jbossrules/drools-core/src/test/java/org/drools/rule/DeclarationTest.java trunk/labs/jbossrules/drools-core/src/test/java/org/drools/spi/ClassFieldExtractor.java trunk/labs/jbossrules/drools-core/src/test/java/org/drools/spi/MockObjectType.java Log: -Fist commit for the native manners example -Refactoring due to issues uncovered implementing manners Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/reteoo/ReteTuple.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/reteoo/ReteTuple.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/reteoo/ReteTuple.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -158,6 +158,10 @@ return null; } } + + public FactHandle getFactHandleForDeclaration(Declaration declaration) { + return this.key.get( declaration.getColumn() ); + } public WorkingMemory getWorkingMemory() { return this.workingMemory; Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/Binding.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/Binding.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/Binding.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -1,16 +1,21 @@ package org.drools.rule; +import org.drools.spi.Extractor; import org.drools.spi.ObjectType; public abstract class Binding { private final String identifier; - private final ObjectType objectType; + private final ObjectType objectType; + + private final Extractor extractor; public Binding(String identifier, - ObjectType objectType) { + ObjectType objectType, + Extractor extractor) { this.identifier = identifier; this.objectType = objectType; + this.extractor = extractor; } /** @@ -26,5 +31,11 @@ public ObjectType getObjectType() { return this.objectType; } + + public Extractor getExtractor() { + return this.extractor; + } + + } Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/ColumnBinding.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/ColumnBinding.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/ColumnBinding.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -1,5 +1,6 @@ package org.drools.rule; +import org.drools.spi.ColumnExtractor; import org.drools.spi.ObjectType; public class ColumnBinding extends Binding { @@ -9,7 +10,8 @@ ObjectType objectType, Column column) { super( identifier, - objectType ); + objectType, + new ColumnExtractor(objectType)); this.column = column; } Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/Declaration.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/Declaration.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/Declaration.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -114,8 +114,8 @@ * * @return The object-type. */ - public Class getDeclarationType() { - return this.extractor.getValueType(); + public ObjectType getObjectType() { + return this.extractor.getObjectType(); } /** @@ -176,7 +176,7 @@ Declaration other = (Declaration) object; - return this.index == other.index && this.identifier.equals( other.identifier ) && this.extractor.getValueType().equals( other.extractor.getValueType() ); + return this.index == other.index && this.identifier.equals( other.identifier ) && this.extractor.getObjectType().equals( other.extractor.getObjectType() ); } } Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/EvaluatorFactory.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/EvaluatorFactory.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/EvaluatorFactory.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -23,6 +23,8 @@ return getShortEvaluator( operator ); case Evaluator.INTEGER_TYPE : return getIntegerEvaluator( operator ); + case Evaluator.BOOLEAN_TYPE : + return getBooleanEvaluator( operator ); default : throw new RuntimeException( "Type '" + type + "' does not exist for BaseEvaluatorFactory" ); } @@ -80,7 +82,60 @@ return !object1.equals( object2 ); } } + + static class BooleanEqualEvaluator extends BaseEvaluator { + private static Evaluator INSTANCE; + public static Evaluator getInstance() { + if ( INSTANCE == null ) { + INSTANCE = new BooleanEqualEvaluator(); + } + return INSTANCE; + } + + private BooleanEqualEvaluator() { + super( Evaluator.BOOLEAN_TYPE, + Evaluator.EQUAL ); + } + + public boolean evaluate(Object object1, + Object object2) { + return ((Boolean)object1).booleanValue() == ((Boolean)object2).booleanValue(); + } + } + + Evaluator getBooleanEvaluator(int operator) { + switch ( operator ) { + case Evaluator.EQUAL : + return ObjectEqualEvaluator.getInstance(); + case Evaluator.NOT_EQUAL : + return ObjectNotEqualEvaluator.getInstance(); + default : + throw new RuntimeException( "Operator '" + operator + "' does not exist for BooleanEvaluator" ); + } + } + + static class BooleanNotEqualEvaluator extends BaseEvaluator { + private static Evaluator INSTANCE; + + public static Evaluator getInstance() { + if ( INSTANCE == null ) { + INSTANCE = new BooleanNotEqualEvaluator(); + } + return INSTANCE; + } + + private BooleanNotEqualEvaluator() { + super( Evaluator.BOOLEAN_TYPE, + Evaluator.NOT_EQUAL ); + } + + public boolean evaluate(Object object1, + Object object2) { + return ((Boolean)object1).booleanValue() != ((Boolean)object2).booleanValue(); + } + } + Evaluator getShortEvaluator(int operator) { switch ( operator ) { case Evaluator.EQUAL : Deleted: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/ExtractorBinding.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/ExtractorBinding.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/ExtractorBinding.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -1,24 +0,0 @@ -package org.drools.rule; - -import org.drools.spi.Extractor; -import org.drools.spi.ObjectType; - -public class ExtractorBinding extends Binding { - private final Extractor extractor; - - public ExtractorBinding(String identifier, - ObjectType objectType, - Extractor extractor) { - super( identifier, - objectType ); - this.extractor = extractor; - } - - /** - * @return Returns the extractor. - */ - public Extractor getExtractor() { - return this.extractor; - } - -} Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/Rule.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/Rule.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/rule/Rule.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -49,9 +49,13 @@ import java.util.List; import java.util.Map; +import org.drools.spi.ClassObjectType; +import org.drools.spi.ColumnExtractor; import org.drools.spi.Condition; import org.drools.spi.Consequence; +import org.drools.spi.Constraint; import org.drools.spi.Duration; +import org.drools.spi.Evaluator; import org.drools.spi.Extractor; import org.drools.spi.Importer; import org.drools.spi.Module; @@ -363,7 +367,7 @@ * the <code>identifier</code>. */ public Declaration getDeclaration(String identifier) { - return (Declaration) this.declarations; + return (Declaration) this.declarations.get( identifier ); } /** @@ -378,14 +382,50 @@ } /** - * Add a <code>Test</code> to this rule. + * Add a pattern to the rule. All patterns are searched for bindings which are then added to the rule + * as declarations * * @param condition * The <code>Test</code> to add. + * @throws InvalidRuleException */ - public void addPattern(ConditionalElement ce) { + public void addPattern(ConditionalElement ce) throws InvalidRuleException { + addDeclarations( ce ); this.headPattern.addChild( ce ); } + + public void addPattern(Column column) throws InvalidRuleException { + addDeclarations( column ); + this.headPattern.addChild( column ); + } + + private void addDeclarations(Column column) throws InvalidRuleException { + // Check if the column is bound and if so add it as a declaration + if ( column.getBinding() != null ) { + ColumnBinding binding = (ColumnBinding ) column.getBinding(); + addDeclaration( binding.getIdentifier(), column.getIndex(), new ColumnExtractor( new ClassObjectType( Object.class ) ) ); + } + + // Check if there are any bound fields and if so add it as a declaration + for ( Iterator constraintIter = column.getConstraints().iterator(); constraintIter.hasNext(); ) { + Constraint constraint = ( Constraint ) constraintIter.next(); + if ( constraint instanceof FieldBinding ) { + FieldBinding fieldBinding = ( FieldBinding ) constraint; + addDeclaration(fieldBinding.getIdentifier(), fieldBinding.getColumn(), fieldBinding.getExtractor() ); + } + } + } + + private void addDeclarations(ConditionalElement ce) throws InvalidRuleException { + for ( Iterator it = ce.getChildren().iterator(); it.hasNext(); ) { + Object object = it.next(); + if ( object instanceof Column ) { + addDeclarations( (Column) object ); + } else if ( object instanceof ConditionalElement ) { + addDeclarations( (ConditionalElement) object ); + } + } + } /** * Retrieve the <code>List</code> of <code>Conditions</code> for this Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/ClassObjectType.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/ClassObjectType.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/ClassObjectType.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -41,6 +41,8 @@ * */ +import java.util.Arrays; + /** * Java class semantics <code>ObjectType</code>. * @@ -57,6 +59,8 @@ /** Java object class. */ protected Class objectTypeClass; + + protected int valueType; // ------------------------------------------------------------ // Constructors @@ -81,7 +85,7 @@ * * @return The Java object class. */ - public Class getType() { + public Class getClassType() { return this.objectTypeClass; } @@ -100,8 +104,12 @@ * object type, else <code>false</code>. */ public boolean matches(Object object) { - return getType().isInstance( object ); + return getClassType().isInstance( object ); } + + public int getValueType() { + return this.valueType; + } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // java.lang.Object @@ -113,8 +121,32 @@ * @return The hash. */ public int hashCode() { - return getType().hashCode(); + return getClassType().hashCode(); } + + protected void setValueType(Class clazz) { + if ( clazz == Character.class ) { + this.valueType = Evaluator.CHAR_TYPE; + } else if ( clazz == Byte.class ) { + this.valueType = Evaluator.BYTE_TYPE; + } else if (clazz == Short.class ) { + this.valueType = Evaluator.SHORT_TYPE; + } else if (clazz == Integer.class ) { + this.valueType = Evaluator.INTEGER_TYPE; + } else if (clazz == Long.class) { + this.valueType = Evaluator.LONG_TYPE; + } else if (clazz == Float.class) { + this.valueType = Evaluator.FLOAT_TYPE; + } else if (clazz == Double.class) { + this.valueType = Evaluator.DOUBLE_TYPE; + } else if (clazz == java.sql.Date.class) { + this.valueType = Evaluator.DATE_TYPE; + } else if (clazz.isAssignableFrom( Object[].class )) { + this.valueType = Evaluator.ARRAY_TYPE; + } else if (clazz instanceof Object) { + this.valueType = Evaluator.OBJECT_TYPE; + } + } /** * Determine if another object is equal to this. @@ -138,6 +170,6 @@ } public String toString() { - return getType().getName(); + return getClassType().getName(); } } Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/DefaultKnowledgeHelper.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/DefaultKnowledgeHelper.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/DefaultKnowledgeHelper.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -78,10 +78,14 @@ public void modifyObject(Object oldObject, Object newObject) throws FactException { FactHandle handle = this.tuple.getFactHandleForObject( oldObject ); - - this.tuple.getWorkingMemory().modifyObject( handle, - newObject ); + + modifyObject(handle, newObject); } + + public void modifyObject(FactHandle handle, + Object newObject) throws FactException { + this.tuple.getWorkingMemory().modifyObject( handle, newObject ); + } public void retractObject(Object object) throws FactException { FactHandle handle = this.tuple.getFactHandleForObject( object ); Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/Evaluator.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/Evaluator.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/Evaluator.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -14,14 +14,15 @@ // Types public static final int CHAR_TYPE = 100; public static final int BYTE_TYPE = 110; - public static final int SHORT_TYPE = 130; - public static final int INTEGER_TYPE = 140; - public static final int LONG_TYPE = 150; - public static final int FLOAT_TYPE = 160; - public static final int DOUBLE_TYPE = 170; + public static final int SHORT_TYPE = 120; + public static final int INTEGER_TYPE = 130; + public static final int LONG_TYPE = 140; + public static final int FLOAT_TYPE = 150; + public static final int DOUBLE_TYPE = 160; + public static final int BOOLEAN_TYPE = 170; public static final int DATE_TYPE = 180; public static final int ARRAY_TYPE = 190; - public static final int OBJECT_TYPE = 195; + public static final int OBJECT_TYPE = 200; public int getType(); Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/Extractor.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/Extractor.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/Extractor.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -7,5 +7,5 @@ Serializable { Object getValue(Object object); - Class getValueType(); + ObjectType getObjectType(); } Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/KnowledgeHelper.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/KnowledgeHelper.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/KnowledgeHelper.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -44,6 +44,7 @@ import java.util.List; import org.drools.FactException; +import org.drools.FactHandle; /** * KnowledgeHelper implementation types are injected into consequenses @@ -111,6 +112,9 @@ void modifyObject(Object oldObject, Object newObject) throws FactException; + void modifyObject(FactHandle handle, + Object newObject) throws FactException; + /** * Retracts an object from the WorkingMemory. All Activations on the Agenda * that are cancelled should emit ActivationCancelled events. Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/ObjectType.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/ObjectType.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/ObjectType.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -61,4 +61,6 @@ * object type, else <code>false</code>. */ boolean matches(Object object); + + int getValueType(); } Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/Tuple.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/Tuple.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/spi/Tuple.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -83,6 +83,8 @@ * not a root fact object. */ FactHandle getFactHandleForObject(Object object); + + FactHandle getFactHandleForDeclaration(Declaration declaration); /** * Returns a reference to the <code>WorkingMemory</code> associated with Modified: trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/Context.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/Context.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/Context.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -47,9 +47,15 @@ implements Serializable { - public static final int START_UP = 0; + public static final int START_UP = 0; + public static final int ASSIGN_SEATS = 1; + public static final int MAKE_PATH = 2; + public static final int CHECK_DONE = 3; + public static final int PRINT_RESULTS = 4; private int state; + + //private Path path; public Context(int state) { this.state = state; @@ -63,6 +69,10 @@ return this.state == state; } + public int getState() { + return this.state; + } + public String toString() { return "{state=" + this.state + "}"; } Modified: trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/Guest.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/Guest.java 2006-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/Guest.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -48,45 +48,33 @@ public class Guest implements Serializable { - private String name; + private final String name; - private char sex; + private final Sex sex; - private List hobbies; + private final Hobby hobby; public Guest(String name, - char sex) { + Sex sex, + Hobby hobby) { this.name = name; this.sex = sex; - this.hobbies = new ArrayList(); + this.hobby = hobby; } public String getName() { return this.name; } - public void addHobby(String hobby) { - this.hobbies.add( hobby ); + public Hobby getHobby() { + return this.hobby; } + + public Sex getSex() { + return this.sex; + } - public List getHobbies() { - return this.hobbies; - } - - public boolean hasOppositeSex(Guest guest) { - return this.sex != guest.sex; - } - - public boolean hasSameHobby(Guest guest) { - boolean hobbyFound = false; - for ( int i = 0; !hobbyFound && i < this.hobbies.size(); i++ ) { - String hobby = (String) this.hobbies.get( i ); - hobbyFound = guest.hobbies.contains( hobby ); - } - return hobbyFound; - } - public String toString() { - return "{name=" + this.name + ",sex=" + this.sex + ",hobbies=" + this.hobbies + "}"; + return "{name=" + this.name + ",sex=" + this.sex + ",hobbies=" + this.hobby + "}"; } } \ No newline at end of file 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-01-06 22:44:34 UTC (rev 2009) +++ trunk/labs/jbossrules/drools-core/src/test/java/org/drools/examples/manners/MannersTest.java 2006-01-07 02:17:23 UTC (rev 2010) @@ -1,5 +1,8 @@ package org.drools.examples.manners; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.StringWriter; @@ -7,14 +10,36 @@ import java.util.List; import java.util.Random; +import org.drools.Cheese; +import org.drools.FactException; +import org.drools.WorkingMemory; +import org.drools.rule.And; +import org.drools.rule.BoundVariableConstraint; import org.drools.rule.Column; import org.drools.rule.ColumnBinding; +import org.drools.rule.Declaration; +import org.drools.rule.EvaluatorFactory; +import org.drools.rule.FieldBinding; +import org.drools.rule.InvalidRuleException; import org.drools.rule.LiteralConstraint; +import org.drools.rule.Not; import org.drools.rule.Rule; import org.drools.rule.RuleSet; +import org.drools.spi.Activation; +import org.drools.spi.ClassFieldExtractor; import org.drools.spi.ClassObjectType; import org.drools.spi.BaseEvaluator; +import org.drools.spi.Consequence; +import org.drools.spi.ConsequenceException; +import org.drools.spi.Constraint; +import org.drools.spi.DefaultKnowledgeHelper; +import org.drools.spi.Evaluator; +import org.drools.spi.Field; +import org.drools.spi.FieldExtractor; +import org.drools.spi.KnowledgeHelper; import org.drools.spi.LiteralExpressionConstraint; +import org.drools.spi.MockField; +import org.drools.spi.Tuple; public class MannersTest { /** Number of guests at the dinner (default: 16). */ @@ -33,47 +58,852 @@ private ClassObjectType guestType; private ClassObjectType seatingType; private ClassObjectType lastSeatType; + private ClassObjectType countType; + private ClassObjectType pathType; + private ClassObjectType chosenType; + private Evaluator objectEqualEvaluator; + private Evaluator objectNotEqualEvaluator; + private Evaluator integerEqualEvaluator; + private Evaluator integerNotEqualEvaluator; + private Evaluator booleanEqualEvaluator; + private Evaluator booleanNotEqualEvaluator; protected void setUp() throws Exception { - contextType = new ClassObjectType( Context.class ); - guestType = new ClassObjectType( Guest.class ); - seatingType = new ClassObjectType( Seating.class ); - lastSeatType = new ClassObjectType( LastSeat.class ); + this.contextType = new ClassObjectType( Context.class ); + this.guestType = new ClassObjectType( Guest.class ); + this.seatingType = new ClassObjectType( Seating.class ); + this.lastSeatType = new ClassObjectType( LastSeat.class ); + this.countType = new ClassObjectType( Count.class ); + this.pathType = new ClassObjectType( Path.class ); + this.chosenType = new ClassObjectType( Chosen.class ); + this.integerEqualEvaluator = EvaluatorFactory.getInstance().getEvaluator( Evaluator.INTEGER_TYPE, + Evaluator.EQUAL ); + this.integerNotEqualEvaluator = EvaluatorFactory.getInstance().getEvaluator( Evaluator.INTEGER_TYPE, + Evaluator.NOT_EQUAL ); + + this.objectEqualEvaluator = EvaluatorFactory.getInstance().getEvaluator( Evaluator.OBJECT_TYPE, + Evaluator.EQUAL ); + this.objectNotEqualEvaluator = EvaluatorFactory.getInstance().getEvaluator( Evaluator.OBJECT_TYPE, + Evaluator.NOT_EQUAL ); + + this.booleanEqualEvaluator = EvaluatorFactory.getInstance().getEvaluator( Evaluator.BOOLEAN_TYPE, + Evaluator.EQUAL ); + this.booleanNotEqualEvaluator = EvaluatorFactory.getInstance().getEvaluator( Evaluator.BOOLEAN_TYPE, + Evaluator.NOT_EQUAL ); + RuleSet ruleSet = new RuleSet( "Miss Manners" ); Rule assignFirstSeat = getAssignFirstSeatRule(); } - private Rule getAssignFirstSeatRule() { - Rule rule = new Rule( "assignFirstSeat" ); + /** + * <pre> + * rule assignFirstSeat() { + * Context context; + * Guest guest; + * Count count; + * when { + * context : Context( state == Context.START_UP ) + * guest : Guest() + * count : Count() + * } then { + * String guestName = guest.getName(); + * drools.assert( new Seating( count.getValue(), 1, true, 1, guestName, 1, guestName) ); + * drools.assert( new Path( count.getValue(), 1, guestName ) ); + * count.setCount( count.getValue() + 1 ); + * + * System.out.println( "seat 1 " + guest.getName() + " ); + * + * context.setPath( Context.ASSIGN_SEATS ); + * } + * } + * </pre> + * + * + * @return + * @throws IntrospectionException + * @throws InvalidRuleException + */ + private Rule getAssignFirstSeatRule() throws IntrospectionException, + InvalidRuleException { + final Rule rule = new Rule( "assignFirstSeat" ); - Column context = new Column( 0, - contextType, - "context" ); + // ----------- + // context : Context( state == Context.START_UP ) + // ----------- + Column contextColumn = new Column( 0, + contextType, + "context" ); -// LiteralExpressionConstraint isCheddar = new LiteralExpressionConstraint() { -// -// public boolean isAllowed(Object object, -// BaseEvaluator comparator) { -// Context context = (Context) object; -// return comparator.compare( context, -// Context.START_UP ); -// } -// -// }; + contextColumn.addConstraint( getLiteralConstraint( contextColumn, + "state", + new Integer( Context.START_UP ), + this.integerEqualEvaluator ) ); - /* - * Creates a constraint with the given expression - */ -// LiteralConstraint constraint0 = new LiteralConstraint( isCheddar, -// new ObjectConstraintComparator( BaseEvaluator.EQUAL ) ); + rule.addPattern( contextColumn ); - // context. + final Declaration contextDeclaration = rule.getDeclaration( "context" ); + // ----------- + // guest: Guest() + // ----------- + Column guestColumn = new Column( 1, + guestType, + "guest" ); + + rule.addPattern( guestColumn ); + + final Declaration guestDeclaration = rule.getDeclaration( "guest" ); + + // ------------ + // count : Count() + // ------------ + Column countColumn = new Column( 2, + countType, + "count" ); + + rule.addPattern( countColumn ); + + final Declaration countDeclaration = rule.getDeclaration( "count" ); + + Consequence consequence = new Consequence() { + + public void invoke(Activation activation) throws ConsequenceException { + try { + Rule rule = activation.getRule(); + Tuple tuple = activation.getTuple(); + KnowledgeHelper drools = new DefaultKnowledgeHelper( rule, + tuple ); + + Guest guest = (Guest) tuple.get( guestDeclaration ); + Context context = (Context) tuple.get( contextDeclaration ); + Count count = (Count) tuple.get( countDeclaration ); + + String guestName = guest.getName(); + + drools.assertObject( new Seating( count.getValue(), + 0, + true, + 1, + guestName, + 1, + guestName ) ); + drools.assertObject( new Path( count.getValue(), + 1, + guestName ) ); + + count.setValue( count.getValue() + 1 ); + drools.modifyObject( tuple.getFactHandleForDeclaration( countDeclaration ), + count ); + + context.setState( Context.ASSIGN_SEATS ); + drools.modifyObject( tuple.getFactHandleForDeclaration( contextDeclaration ), + context ); + System.out.println( "leftSeat " + guestName ); + + } catch ( Exception e ) { + throw new ConsequenceException( e ); + } + } + + }; + + rule.setConsequence( consequence ); + return rule; } + /** + * <pre> + * rule makePath() { + * Context context; + * int seatingId, seatingPid, pathSeat; + * String pathGuestName; + * + * when { + * context : Context( state == Context.MAKE_PATH ) + * Seating( seatingId:id, seatingPid:pid, pathDone == false ) + * Path( id == seatingPid, pathGuestName:guest, pathSeat:seat ) + * (not Path( id == seatingId, guestName == pathGuestName ) + * } else { + * drools.assert( new Path( seatingId, pathSeat, pathGuestName ) ); + * + * } + * } + * </pre> + * + * @return + * @throws IntrospectionException + * @throws InvalidRuleException + */ + private Rule makePath() throws IntrospectionException, + InvalidRuleException { + final Rule rule = new Rule( "makePath" ); + + // ----------- + // context : Context( state == Context.MAKE_PATH ) + // ----------- + Column contextColumn = new Column( 0, + contextType ); + + contextColumn.addConstraint( getLiteralConstraint( contextColumn, + "state", + new Integer( Context.MAKE_PATH ), + this.integerEqualEvaluator ) ); + + rule.addPattern( contextColumn ); + + // --------------- + // Seating( seatingId:id, seatingPid:pid, pathDone == false ) + // --------------- + Column seatingColumn = new Column( 1, + seatingType ); + + seatingColumn.addConstraint( getFieldBinding( seatingColumn, + "id", + "seatingId" ) ); + seatingColumn.addConstraint( getFieldBinding( seatingColumn, + "pid", + "seatingPid" ) ); + seatingColumn.addConstraint( getLiteralConstraint( seatingColumn, + "pathDone", + new Boolean( false ), + booleanEqualEvaluator ) ); + + rule.addPattern( seatingColumn ); + + final Declaration seatingIdDeclaration = rule.getDeclaration( "seatingId" ); + final Declaration seatingPidDeclaration = rule.getDeclaration( "seatingPid" ); + + // ----------- + // Path( id == seatingPid, pathGuestName:guestName, pathSeat:seat ) + // ----------- + Column pathColumn = new Column( 2, + pathType ); + + pathColumn.addConstraint( getBoundVariableConstraint( pathColumn, + "id", + seatingPidDeclaration, + integerEqualEvaluator ) ); + pathColumn.addConstraint( getFieldBinding( pathColumn, + "guestName", + "pathGuestName" ) ); + pathColumn.addConstraint( getFieldBinding( pathColumn, + "seat", + "pathSeat" ) ); + + rule.addPattern( pathColumn ); + + final Declaration pathGuestNameDeclaration = rule.getDeclaration( "pathGuestName" ); + final Declaration pathSeatDeclaration = rule.getDeclaration( "pathSeat" ); + // ------------- + // (not Path( id == seatingId, guestName == pathGuestName ) + // ------------- + Column notPathColumn = new Column( 3, + pathType ); + + notPathColumn.addConstraint( getBoundVariableConstraint( notPathColumn, + "id", + seatingIdDeclaration, + integerEqualEvaluator ) ); + notPathColumn.addConstraint( getBoundVariableConstraint( notPathColumn, + "guestName", + pathGuestNameDeclaration, + objectEqualEvaluator ) ); + + Not not = new Not(); + + not.addChild( notPathColumn ); + notPathColumn.addConstraint( not ); + + rule.addPattern( notPathColumn ); + + // ------------ + // drools.assert( new Path( id, pathName, pathSeat ) ); + // ------------ + Consequence consequence = new Consequence() { + + public void invoke(Activation activation) throws ConsequenceException { + try { + Rule rule = activation.getRule(); + Tuple tuple = activation.getTuple(); + KnowledgeHelper drools = new DefaultKnowledgeHelper( rule, + tuple ); + + int id = ((Integer) tuple.get( seatingIdDeclaration )).intValue(); + String guestName = (String) tuple.get( pathGuestNameDeclaration ); + int seat = ((Integer) tuple.get( pathSeatDeclaration )).intValue(); + + drools.assertObject( new Path( id, + seat, + guestName ) ); + } catch ( Exception e ) { + throw new ConsequenceException( e ); + } + } + + }; + + rule.setConsequence( consequence ); + + return rule; + } + + /** + * <pre> + * rule findSeating() { + * Context context; + * int seatingId, seatingPid; + * String seatingRightGuestName, leftGuestName; + * Sex rightGuestSex; + * Hobby rightGuestHobby; + * Count count; + * + * when { + * context : Context( state == Context.ASSIGN_SEATS ) + * Seating( seatingId:id, seatingPid:pid, pathDone == true + * seatingRightGuestName:rightGuestName ) + * Guest( name == seatingRightGuestName, rightGuestSex:sex, rightGuestHobby:hobby ) + * Guest( leftGuestName:name , sex != rightGuestSex, hobby == rightGuestHobby ) + * + * count : Count() + * + * not ( Path( id == seatingId, guestName == leftGuestName) ) + * not ( Chosen( id == seatingId, guestName == leftGuestName, hobby == rightGuestHobby) ) + * } then { + * int newSeat = rightSeat + 1; + * drools.assert( new Seating( coung.getValue(), rightSeat, rightSeatName, leftGuestName, newSeat, countValue, id, false ); + * drools.assert( new Path( countValue, leftGuestName, newSeat ); + * drools.assert( new Chosen( id, leftGuestName, rightGuestHobby ) ); + * + * System.out.println( "seat " + rightSeat + " " + rightSeatName + " " + leftGuestName ); + * + * count.setCount( countValue + 1 ); + * context.setPath( Context.MAKE_PATH ); + * } + * } + * </pre> + * + * @return + * @throws IntrospectionException + * @throws InvalidRuleException + */ + private Rule findSeating() throws IntrospectionException, + InvalidRuleException { + final Rule rule = new Rule( "makePath" ); + + // --------------- + // context : Context( state == Context.ASSIGN_SEATS ) + // --------------- + Column contextColumn = new Column( 0, + contextType, + "context" ); + + contextColumn.addConstraint( getLiteralConstraint( contextColumn, + "state", + new Integer( Context.ASSIGN_SEATS ), + this.integerEqualEvaluator ) ); + + rule.addPattern( contextColumn ); + + final Declaration contextDeclaration = rule.getDeclaration( "context" ); + + // ------------------------------- + // Seating( seatingId:id, seatingPid:pid, pathDone == true + // seatingRightSeat:rightSeat + // seatingRightGuestName:rightGuestName ) + // ------------------------------- + Column seatingColumn = new Column( 1, + seatingType ); + + seatingColumn.addConstraint( getFieldBinding( seatingColumn, + "id", + "seatingId" ) ); + seatingColumn.addConstraint( getFieldBinding( seatingColumn, + "pid", + "seatingPid" ) ); + seatingColumn.addConstraint( getLiteralConstraint( seatingColumn, + "pathDone", + new Boolean( true ), + this.booleanEqualEvaluator ) ); + seatingColumn.addConstraint( getFieldBinding( seatingColumn, + "rightSeat", + "seatingRightSeat" ) ); + seatingColumn.addConstraint( getFieldBinding( seatingColumn, + "rightGuestName", + "seatingRightGuestName" ) ); + + rule.addPattern( seatingColumn ); + + final Declaration seatingIdDeclaration = rule.getDeclaration( "seatingId" ); + final Declaration seatingPidDeclaration = rule.getDeclaration( "seatingPid" ); + final Declaration seatingRightGuestNameDeclaration = rule.getDeclaration( "seatingRightGuestName" ); + final Declaration seatingRightSeatDeclaration = rule.getDeclaration( "seatingRightSeat" ); + // -------------- + // Guest( name == seatingRightGuestName, rightGuestSex:sex, + // rightGuestHobby:hobby ) + // --------------- + Column rightGuestColumn = new Column( 2, + guestType ); + + rightGuestColumn.addConstraint( getBoundVariableConstraint( rightGuestColumn, + "name", + seatingRightGuestNameDeclaration, + objectEqualEvaluator ) ); + + rightGuestColumn.addConstraint( getFieldBinding( rightGuestColumn, + "sex", + "rightGuestSex" ) ); + + rightGuestColumn.addConstraint( getFieldBinding( rightGuestColumn, + "hobby", + "rightGuestHobby" ) ); + + rule.addPattern( rightGuestColumn ); + + final Declaration rightGuestSexDeclaration = rule.getDeclaration( "rightGuestSex" ); + final Declaration rightGuestHobbyDeclaration = rule.getDeclaration( "rightGuestHobby" ); + + // ---------------- + // Guest( leftGuestName:name , sex != rightGuestSex, hobby == rightGuestHobby ) + // ---------------- + Column leftGuestColumn = new Column( 3, + guestType ); + + leftGuestColumn.addConstraint( getFieldBinding( leftGuestColumn, + "name", + "leftGuestHobby" ) ); + + leftGuestColumn.addConstraint( getBoundVariableConstraint( leftGuestColumn, + "sex", + rightGuestSexDeclaration, + objectEqualEvaluator ) ); + + leftGuestColumn.addConstraint( getBoundVariableConstraint( rightGuestColumn, + "hobby", + rightGuestHobbyDeclaration, + objectEqualEvaluator ) ); + rule.addPattern( leftGuestColumn ); + final Declaration leftGuestNameDeclaration = rule.getDeclaration( "lefttGuestName" ); + + // --------------- + // count : Count() + // --------------- + Column count = new Column( 2, + countType, + "count" ); + + rule.addPattern( count ); + + final Declaration countDeclaration = rule.getDeclaration( "count" ); + + // -------------- + // not ( Path( id == seatingId, guestName == leftGuestName) ) + // not ( Chosen( id == seatingId, guestName == leftGuestName, hobby == rightGuestHobby) ) + // -------------- + Column notPathColumn = new Column( 3, + pathType ); + + notPathColumn.addConstraint( getBoundVariableConstraint( notPathColumn, + "id", + seatingIdDeclaration, + integerEqualEvaluator ) ); + + notPathColumn.addConstraint( getBoundVariableConstraint( notPathColumn, + "guestName", + leftGuestNameDeclaration, + objectEqualEvaluator ) ); + Not not = new Not(); + not.addChild( notPathColumn ); + notPathColumn.addConstraint( not ); + // ------------ + // not ( Chosen( id == seatingId, guestName == leftGuestName, hobby == rightGuestHobby ) ) + // ------------ + Column notChosenColumn = new Column( 4, + chosenType ); + + notChosenColumn.addConstraint( getBoundVariableConstraint( notChosenColumn, + "id", + seatingIdDeclaration, + integerEqualEvaluator ) ); + + notChosenColumn.addConstraint( getBoundVariableConstraint( notChosenColumn, + "guestName", + leftGuestNameDeclaration, + objectEqualEvaluator ) ); + + notChosenColumn.addConstraint( getBoundVariableConstraint( notChosenColumn, + "hobby", + rightGuestHobbyDeclaration, + objectEqualEvaluator ) ); + + notChosenColumn.addConstraint( notChosenColumn ); + + rule.addPattern( notChosenColumn ); + + // ------------ + // int newSeat = rightSeat + 1; + // drools.assert( new Seating( coung.getValue(), rightSeat, + // rightSeatName, leftGuestName, newSeat, countValue, id, false ); + // drools.assert( new Path( countValue, leftGuestName, newSeat ); + // drools.assert( new Chosen( id, leftGuestName, rightGuestHobby ) ); + // + // System.out.println( "seat " + rightSeat + " " + rightSeatName + " " + + // leftGuestName ); + // + // count.setCount( countValue + 1 ); + // context.setPath( Context.MAKE_PATH ); + // ------------ + Consequence consequence = new Consequence() { + + public void invoke(Activation activation) throws ConsequenceException { + try { + Rule rule = activation.getRule(); + Tuple tuple = activation.getTuple(); + KnowledgeHelper drools = new DefaultKnowledgeHelper( rule, + tuple ); + + Context context = (Context) tuple.get( contextDeclaration ); + Count count = (Count) tuple.get( countDeclaration ); + int seatId = ((Integer) tuple.get( seatingIdDeclaration )).intValue(); + int seatingRightSeat = ((Integer) tuple.get( seatingRightSeatDeclaration )).intValue(); + String leftGuestName = (String) tuple.get( leftGuestNameDeclaration ); + String rightGuestName = (String) tuple.get( seatingRightGuestNameDeclaration ); + Hobby rightGuestHobby = (Hobby) tuple.get( rightGuestHobbyDeclaration ); + + drools.assertObject( new Seating( count.getValue(), + seatId, + false, + seatingRightSeat, + leftGuestName, + seatingRightSeat + 1, + rightGuestName ) ); + + drools.assertObject( new Path( count.getValue(), + seatingRightSeat + 1, + leftGuestName ) ); + + drools.assertObject( new Chosen( seatId, + leftGuestName, + rightGuestHobby ) ); + + count.setValue( count.getValue() + 1 ); + drools.modifyObject( tuple.getFactHandleForDeclaration( countDeclaration ), + count ); + + context.setState( Context.MAKE_PATH ); + drools.modifyObject( tuple.getFactHandleForDeclaration( contextDeclaration ), + context ); + + } catch ( Exception e ) { + throw new ConsequenceException( e ); + } + } + + }; + + rule.setConsequence( consequence ); + + return rule; + } + + /** + * + * rule pathDone() { + * Context context; + * Seating seating; + * when { + * context : Context( state == Context.MAKE_PATH ) + * seating : Seating( pathDone == false ) + * } then { + * seating.setPathDone( true ); + * context.setName( Context.CHECK_DONE ); + * } + * } + * + * + * @return + * @throws IntrospectionException + * @throws InvalidRuleException + */ + private Rule pathDone() throws IntrospectionException, + InvalidRuleException { + final Rule rule = new Rule( "makePath" ); + + // ----------- + // context : Context( state == Context.MAKE_PATH ) + // ----------- + Column contextColumn = new Column( 0, + contextType ); + + contextColumn.addConstraint( getLiteralConstraint( contextColumn, + "state", + new Integer( Context.MAKE_PATH ), + this.integerEqualEvaluator ) ); + + rule.addPattern( contextColumn ); + final Declaration contextDeclaration = rule.getDeclaration( "context" ); + + // --------------- + // seating : Seating( pathDone == false ) + // --------------- + Column seatingColumn = new Column( 1, + seatingType, + "seating" ); + + seatingColumn.addConstraint( getLiteralConstraint( seatingColumn, + "pathDone", + new Boolean( false ), + booleanEqualEvaluator ) ); + + rule.addPattern( seatingColumn ); + + final Declaration seatingDeclaration = rule.getDeclaration( "seating" ); + + // ------------ + // context.setName( Context.CHECK_DONE ); + // seating.setPathDone( true ); + // ------------ + Consequence consequence = new Consequence() { + + public void invoke(Activation activation) throws ConsequenceException { + try { + Rule rule = activation.getRule(); + Tuple tuple = activation.getTuple(); + KnowledgeHelper drools = new DefaultKnowledgeHelper( rule, + tuple ); + + Context context = (Context) tuple.get( contextDeclaration ); + Seating seating = (Seating) tuple.get( seatingDeclaration ); + + seating.setPathDone( true ); + drools.modifyObject( tuple.getFactHandleForDeclaration( seatingDeclaration ), + seating ); + + context.setState( Context.CHECK_DONE ); + drools.modifyObject( tuple.getFactHandleForDeclaration( contextDeclaration ), + context ); + } catch ( Exception e ) { + throw new ConsequenceException( e ); + } + } + + }; + + rule.setConsequence( consequence ); + + return rule; + } + + /** + * + * rule areWeDone() { + * Context context; + * LastSeat lastSear; + * when { + * context : Context( state == Context.CHECK_DONE ) + * LastSeat( lastSeat: seat ) + * Seating( seat == lastSeat ) + * } then { + * context.setState( Context.PRINT_RESULTS ); + * } + * } + * + * + * @return + * @throws IntrospectionException + * @throws InvalidRuleException + */ + private Rule areWeDone() throws IntrospectionException, + InvalidRuleException { + final Rule rule = new Rule( "areWeDone" ); + + // ----------- + // context : Context( state == Context.CHECK_DONE ) + // ----------- + Column contextColumn = new Column( 0, + contextType ); + + contextColumn.addConstraint( getLiteralConstraint( contextColumn, + "state", + new Integer( Context.CHECK_DONE ), + this.integerEqualEvaluator ) ); + + rule.addPattern( contextColumn ); + final Declaration contextDeclaration = rule.getDeclaration( "context" ); + + // --------------- + // LastSeat( lastSeat: seat ) + // --------------- + Column lastSeatColumn = new Column( 1, + lastSeatType, + null ); + + lastSeatColumn.addConstraint( getFieldBinding( lastSeatColumn, + "seat", + "lastSeat" ) ); + rule.addPattern( lastSeatColumn ); + final Declaration lastSeatDeclaration = rule.getDeclaration( "lastSeat" ); + // ------------- + // Seating( seat == lastSeat ) + // ------------- + Column seatingColumn = new Column( 2, + seatingType, + null ); + + seatingColumn.addConstraint( getBoundVariableConstraint( seatingColumn, + "seat", + lastSeatDeclaration, + integerEqualEvaluator ) ); + + rule.addPattern( seatingColumn ); + + // ------------ + // context.setName(... [truncated message content] |