/** * * * <pre> * * * type == "cheddar" && price > 10 * * * </pre> * * Test the use of the composite AND constraint. Composite AND constraints are only used when * nested inside other field constraints, as the top level AND is implicit * * @throws IntrospectionException */ public void testCompositeAndConstraint() { final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(); final InternalWorkingMemory workingMemory = (InternalWorkingMemory) ruleBase.newStatefulSession(); final ClassFieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.STRING_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint1 = new LiteralConstraint(extractor, evaluator, field); final ClassFieldExtractor priceExtractor = cache.getExtractor(Cheese.class, "price", getClass().getClassLoader()); final FieldValue priceField = FieldFactory.getFieldValue(10); final Evaluator priceEvaluator = ValueType.INTEGER_TYPE.getEvaluator(Operator.GREATER); final LiteralConstraint constraint2 = new LiteralConstraint(priceExtractor, priceEvaluator, priceField); final Cheese cheddar = new Cheese("cheddar", 15); final AndConstraint constraint = new AndConstraint(); constraint.addAlphaConstraint(constraint1); constraint.addAlphaConstraint(constraint2); final ContextEntry context = constraint.createContextEntry(); final InternalFactHandle cheddarHandle = (InternalFactHandle) workingMemory.insert(cheddar); // check constraint assertTrue(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setPrice(5); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertFalse(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setType("stilton"); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertFalse(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setPrice(15); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertFalse(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); }
public void testLiteralConstraintAssertSequentialMode() throws Exception { RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setSequential(true); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = new ReteooWorkingMemory(buildContext.getNextId(), ruleBase); final Rule rule = new Rule("test-rule"); final PropagationContext context = new PropagationContextImpl(0, PropagationContext.ASSERTION, null, null); final MockObjectSource source = new MockObjectSource(buildContext.getNextId()); final ClassFieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); // With Memory final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, source, buildContext); // has memory final MockObjectSink sink = new MockObjectSink(); alphaNode.addObjectSink(sink); final Cheese cheddar = new Cheese("cheddar", 5); final DefaultFactHandle f0 = (DefaultFactHandle) workingMemory.insert(cheddar); // check sink is empty assertLength(0, sink.getAsserted()); // check alpha memory is empty final AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory(alphaNode); assertNull(memory.facts); // object should assert as it passes text alphaNode.assertObject(f0, context, workingMemory); assertEquals(1, sink.getAsserted().size()); assertNull(memory.facts); Object[] list = (Object[]) sink.getAsserted().get(0); assertSame(cheddar, workingMemory.getObject((DefaultFactHandle) list[0])); final Cheese stilton = new Cheese("stilton", 6); final DefaultFactHandle f1 = new DefaultFactHandle(1, stilton); // object should NOT assert as it does not pass test alphaNode.assertObject(f1, context, workingMemory); assertLength(1, sink.getAsserted()); assertNull(memory.facts); list = (Object[]) sink.getAsserted().get(0); assertSame(cheddar, workingMemory.getObject((DefaultFactHandle) list[0])); }
/** * * * <pre> * * * ( Cheese (type "cheddar") ) * * * </pre> * * This is currently the same as using a ReturnValueConstraint just that it doesn't need any * requiredDeclarations * * @throws IntrospectionException */ public void testLiteralConstraint() throws IntrospectionException { final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(); final InternalWorkingMemory workingMemory = (InternalWorkingMemory) ruleBase.newStatefulSession(); final ClassFieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.STRING_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); final ContextEntry context = constraint.createContextEntry(); final Cheese cheddar = new Cheese("cheddar", 5); final InternalFactHandle cheddarHandle = (InternalFactHandle) workingMemory.insert(cheddar); // check constraint assertTrue(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); final Cheese stilton = new Cheese("stilton", 5); final InternalFactHandle stiltonHandle = (InternalFactHandle) workingMemory.insert(stilton); // check constraint assertFalse(constraint.isAllowed(stiltonHandle.getObject(), workingMemory, context)); }
public void testRetractObjectWithMemory() throws Exception { RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setAlphaMemory(true); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession(); final Rule rule = new Rule("test-rule"); final PropagationContext context = new PropagationContextImpl(0, PropagationContext.ASSERTION, null, null); final MockObjectSource source = new MockObjectSource(buildContext.getNextId()); final FieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); buildContext.setAlphaNodeMemoryAllowed(true); final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, source, buildContext); // has memory final MockObjectSink sink = new MockObjectSink(); alphaNode.addObjectSink(sink); final Cheese cheddar = new Cheese("cheddar", 5); final DefaultFactHandle f0 = new DefaultFactHandle(0, cheddar); // check alpha memory is empty final AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory(alphaNode); assertEquals(0, memory.facts.size()); // object should assert as it passes text alphaNode.assertObject(f0, context, workingMemory); assertEquals(1, memory.facts.size()); final DefaultFactHandle f1 = new DefaultFactHandle(1, "cheese"); // object should NOT retract as it doesn't exist alphaNode.retractObject(f1, context, workingMemory); assertLength(0, sink.getRetracted()); assertEquals(1, memory.facts.size()); assertTrue("Should contain 'cheddar handle'", memory.facts.contains(f0)); // object should retract as it does exist alphaNode.retractObject(f0, context, workingMemory); assertLength(1, sink.getRetracted()); assertEquals(0, memory.facts.size()); final Object[] list = (Object[]) sink.getRetracted().get(0); assertSame(f0, list[0]); }
/* * dont need to test with and without memory on this, as it was already done * on the previous two tests. This just test AlphaNode With a different * Constraint type. */ public void testReturnValueConstraintAssertObject() throws Exception { RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setAlphaMemory(false); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession(); final Rule rule = new Rule("test-rule"); final PropagationContext context = new PropagationContextImpl(0, PropagationContext.ASSERTION, null, null); final MockObjectSource source = new MockObjectSource(buildContext.getNextId()); final FieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, source, buildContext); final MockObjectSink sink = new MockObjectSink(); alphaNode.addObjectSink(sink); final Cheese cheddar = new Cheese("cheddar", 5); final DefaultFactHandle f0 = (DefaultFactHandle) workingMemory.insert(cheddar); assertLength(0, sink.getAsserted()); // object should assert as it passes text alphaNode.assertObject(f0, context, workingMemory); assertLength(1, sink.getAsserted()); final Object[] list = (Object[]) sink.getAsserted().get(0); assertSame(cheddar, workingMemory.getObject((DefaultFactHandle) list[0])); final Cheese stilton = new Cheese("stilton", 6); f0.setObject(stilton); sink.getAsserted().clear(); // object should not assert as it does not pass text alphaNode.assertObject(f0, context, workingMemory); assertLength(0, sink.getAsserted()); }
public class DeclarationTest extends TestCase { ClassFieldExtractorCache cache = ClassFieldExtractorCache.getInstance(); public void testDeclaration() throws IntrospectionException { final FieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final Pattern pattern = new Pattern(5, new ClassObjectType(Cheese.class)); // Bind the extractor to a decleration // Declarations know the pattern they derive their value from final Declaration declaration = new Declaration("typeOfCheese", extractor, pattern); assertEquals("typeOfCheese", declaration.getIdentifier()); assertSame(String.class, declaration.getExtractor().getExtractToClass()); assertSame(extractor, declaration.getExtractor()); assertEquals(5, declaration.getPattern().getOffset()); } public void testGetFieldValue() throws IntrospectionException { final FieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final Pattern pattern = new Pattern(5, new ClassObjectType(Cheese.class)); // Bind the extractor to a decleration // Declarations know the pattern they derive their value from final Declaration declaration = new Declaration("typeOfCheese", extractor, pattern); // Create some facts final Cheese cheddar = new Cheese("cheddar", 5); // Check we can extract Declarations correctly assertEquals("cheddar", declaration.getValue(null, cheddar)); } public static int getIndex(final Class clazz, final String name) throws IntrospectionException { final PropertyDescriptor[] descriptors = Introspector.getBeanInfo(clazz).getPropertyDescriptors(); for (int i = 0; i < descriptors.length; i++) { if (descriptors[i].getName().equals(name)) { return i; } } return -1; } }
public void testIsMemoryAllowedOverride() throws Exception { RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setAlphaMemory(true); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession(); final Rule rule = new Rule("test-rule"); final PropagationContext context = new PropagationContextImpl(0, PropagationContext.ASSERTION, null, null); final MockObjectSource source = new MockObjectSource(buildContext.getNextId()); final ClassFieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); // With Memory buildContext.setAlphaNodeMemoryAllowed(false); final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, source, buildContext); // has memory final MockObjectSink sink = new MockObjectSink(); alphaNode.addObjectSink(sink); final Cheese cheddar = new Cheese("cheddar", 5); final DefaultFactHandle f0 = (DefaultFactHandle) workingMemory.insert(cheddar); // check sink is empty assertLength(0, sink.getAsserted()); // check alpha memory is empty final AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory(alphaNode); assertNull(memory.facts); // object should assert as it passes text alphaNode.assertObject(f0, context, workingMemory); assertEquals(1, sink.getAsserted().size()); // memory should be one, as even though isAlphaMemory is on for the configuration, the build // never allows memory assertNull(memory.facts); }
public void testGetFieldValue() throws IntrospectionException { final FieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final Pattern pattern = new Pattern(5, new ClassObjectType(Cheese.class)); // Bind the extractor to a decleration // Declarations know the pattern they derive their value from final Declaration declaration = new Declaration("typeOfCheese", extractor, pattern); // Create some facts final Cheese cheddar = new Cheese("cheddar", 5); // Check we can extract Declarations correctly assertEquals("cheddar", declaration.getValue(null, cheddar)); }
public void testSimpleExpression() { final Package pkg = new Package("pkg1"); final RuleDescr ruleDescr = new RuleDescr("rule 1"); PackageBuilder pkgBuilder = new PackageBuilder(pkg); final PackageBuilderConfiguration conf = pkgBuilder.getPackageBuilderConfiguration(); MVELDialect mvelDialect = (MVELDialect) pkgBuilder.getDialectRegistry().getDialect("mvel"); final InstrumentedBuildContent context = new InstrumentedBuildContent( conf, pkg, ruleDescr, pkgBuilder.getDialectRegistry(), mvelDialect); final InstrumentedDeclarationScopeResolver declarationResolver = new InstrumentedDeclarationScopeResolver(); final FieldExtractor extractor = cache.getExtractor(Cheese.class, "price", getClass().getClassLoader()); final Pattern pattern = new Pattern(0, new ClassObjectType(int.class)); final Declaration declaration = new Declaration("a", extractor, pattern); final Map map = new HashMap(); map.put("a", declaration); declarationResolver.setDeclarations(map); context.setDeclarationResolver(declarationResolver); final EvalDescr evalDescr = new EvalDescr(); evalDescr.setContent("a == 10"); final MVELEvalBuilder builder = new MVELEvalBuilder(); final EvalCondition eval = (EvalCondition) builder.build(context, evalDescr); final RuleBase ruleBase = RuleBaseFactory.newRuleBase(); final WorkingMemory wm = ruleBase.newStatefulSession(); final Cheese cheddar = new Cheese("cheddar", 10); final InternalFactHandle f0 = (InternalFactHandle) wm.insert(cheddar); final ReteTuple tuple = new ReteTuple(f0); Object evalContext = eval.createContext(); assertTrue(eval.isAllowed(tuple, wm, evalContext)); cheddar.setPrice(9); wm.update(f0, cheddar); assertFalse(eval.isAllowed(tuple, wm, evalContext)); }
public void testDeclaration() throws IntrospectionException { final FieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final Pattern pattern = new Pattern(5, new ClassObjectType(Cheese.class)); // Bind the extractor to a decleration // Declarations know the pattern they derive their value from final Declaration declaration = new Declaration("typeOfCheese", extractor, pattern); assertEquals("typeOfCheese", declaration.getIdentifier()); assertSame(String.class, declaration.getExtractor().getExtractToClass()); assertSame(extractor, declaration.getExtractor()); assertEquals(5, declaration.getPattern().getOffset()); }
public void testMemory() { RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setAlphaMemory(false); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession(); final ClassFieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, null, buildContext); final AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory(alphaNode); assertNotNull(memory); }
public void setUp() { cache = ClassFieldExtractorCache.getInstance(); }
public class AlphaNodeTest extends DroolsTestCase { ClassFieldExtractorCache cache = ClassFieldExtractorCache.getInstance(); public void testMemory() { RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setAlphaMemory(false); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession(); final ClassFieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, null, buildContext); final AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory(alphaNode); assertNotNull(memory); } public void testLiteralConstraintAssertObjectWithMemory() throws Exception { RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setAlphaMemory(true); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession(); final Rule rule = new Rule("test-rule"); final PropagationContext context = new PropagationContextImpl(0, PropagationContext.ASSERTION, null, null); final MockObjectSource source = new MockObjectSource(buildContext.getNextId()); final ClassFieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); // With Memory buildContext.setAlphaNodeMemoryAllowed(true); final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, source, buildContext); // has memory final MockObjectSink sink = new MockObjectSink(); alphaNode.addObjectSink(sink); final Cheese cheddar = new Cheese("cheddar", 5); final DefaultFactHandle f0 = (DefaultFactHandle) workingMemory.insert(cheddar); // check sink is empty assertLength(0, sink.getAsserted()); // check alpha memory is empty final AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory(alphaNode); assertEquals(0, memory.facts.size()); // object should assert as it passes text alphaNode.assertObject(f0, context, workingMemory); assertEquals(1, sink.getAsserted().size()); assertEquals(1, memory.facts.size()); Object[] list = (Object[]) sink.getAsserted().get(0); assertSame(cheddar, workingMemory.getObject((DefaultFactHandle) list[0])); assertTrue("Should contain 'cheddar handle'", memory.facts.contains(f0)); final Cheese stilton = new Cheese("stilton", 6); final DefaultFactHandle f1 = new DefaultFactHandle(1, stilton); // object should NOT assert as it does not pass test alphaNode.assertObject(f1, context, workingMemory); assertLength(1, sink.getAsserted()); assertEquals(1, memory.facts.size()); list = (Object[]) sink.getAsserted().get(0); assertSame(cheddar, workingMemory.getObject((DefaultFactHandle) list[0])); assertTrue("Should contain 'cheddar handle'", memory.facts.contains(f0)); } public void testIsMemoryAllowedOverride() throws Exception { RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setAlphaMemory(true); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession(); final Rule rule = new Rule("test-rule"); final PropagationContext context = new PropagationContextImpl(0, PropagationContext.ASSERTION, null, null); final MockObjectSource source = new MockObjectSource(buildContext.getNextId()); final ClassFieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); // With Memory buildContext.setAlphaNodeMemoryAllowed(false); final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, source, buildContext); // has memory final MockObjectSink sink = new MockObjectSink(); alphaNode.addObjectSink(sink); final Cheese cheddar = new Cheese("cheddar", 5); final DefaultFactHandle f0 = (DefaultFactHandle) workingMemory.insert(cheddar); // check sink is empty assertLength(0, sink.getAsserted()); // check alpha memory is empty final AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory(alphaNode); assertNull(memory.facts); // object should assert as it passes text alphaNode.assertObject(f0, context, workingMemory); assertEquals(1, sink.getAsserted().size()); // memory should be one, as even though isAlphaMemory is on for the configuration, the build // never allows memory assertNull(memory.facts); } public void testLiteralConstraintAssertObjectWithoutMemory() throws Exception { RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setAlphaMemory(false); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession(); final Rule rule = new Rule("test-rule"); final PropagationContext context = new PropagationContextImpl(0, PropagationContext.ASSERTION, null, null); final MockObjectSource source = new MockObjectSource(buildContext.getNextId()); final ClassFieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); // With Memory final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, source, buildContext); // no memory final MockObjectSink sink = new MockObjectSink(); alphaNode.addObjectSink(sink); final Cheese cheddar = new Cheese("cheddar", 5); final DefaultFactHandle f0 = (DefaultFactHandle) workingMemory.insert(cheddar); // check sink is empty assertLength(0, sink.getAsserted()); // check alpha memory is empty final AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory(alphaNode); assertNull(memory.facts); // object should assert as it passes text alphaNode.assertObject(f0, context, workingMemory); assertEquals(1, sink.getAsserted().size()); assertNull(memory.facts); Object[] list = (Object[]) sink.getAsserted().get(0); assertSame(cheddar, workingMemory.getObject((DefaultFactHandle) list[0])); final Cheese stilton = new Cheese("stilton", 6); final DefaultFactHandle f1 = new DefaultFactHandle(1, stilton); // object should NOT assert as it does not pass test alphaNode.assertObject(f1, context, workingMemory); assertLength(1, sink.getAsserted()); assertNull(memory.facts); list = (Object[]) sink.getAsserted().get(0); assertSame(cheddar, workingMemory.getObject((DefaultFactHandle) list[0])); } public void testLiteralConstraintAssertSequentialMode() throws Exception { RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setSequential(true); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = new ReteooWorkingMemory(buildContext.getNextId(), ruleBase); final Rule rule = new Rule("test-rule"); final PropagationContext context = new PropagationContextImpl(0, PropagationContext.ASSERTION, null, null); final MockObjectSource source = new MockObjectSource(buildContext.getNextId()); final ClassFieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); // With Memory final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, source, buildContext); // has memory final MockObjectSink sink = new MockObjectSink(); alphaNode.addObjectSink(sink); final Cheese cheddar = new Cheese("cheddar", 5); final DefaultFactHandle f0 = (DefaultFactHandle) workingMemory.insert(cheddar); // check sink is empty assertLength(0, sink.getAsserted()); // check alpha memory is empty final AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory(alphaNode); assertNull(memory.facts); // object should assert as it passes text alphaNode.assertObject(f0, context, workingMemory); assertEquals(1, sink.getAsserted().size()); assertNull(memory.facts); Object[] list = (Object[]) sink.getAsserted().get(0); assertSame(cheddar, workingMemory.getObject((DefaultFactHandle) list[0])); final Cheese stilton = new Cheese("stilton", 6); final DefaultFactHandle f1 = new DefaultFactHandle(1, stilton); // object should NOT assert as it does not pass test alphaNode.assertObject(f1, context, workingMemory); assertLength(1, sink.getAsserted()); assertNull(memory.facts); list = (Object[]) sink.getAsserted().get(0); assertSame(cheddar, workingMemory.getObject((DefaultFactHandle) list[0])); } /* * dont need to test with and without memory on this, as it was already done * on the previous two tests. This just test AlphaNode With a different * Constraint type. */ public void testReturnValueConstraintAssertObject() throws Exception { RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setAlphaMemory(false); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession(); final Rule rule = new Rule("test-rule"); final PropagationContext context = new PropagationContextImpl(0, PropagationContext.ASSERTION, null, null); final MockObjectSource source = new MockObjectSource(buildContext.getNextId()); final FieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, source, buildContext); final MockObjectSink sink = new MockObjectSink(); alphaNode.addObjectSink(sink); final Cheese cheddar = new Cheese("cheddar", 5); final DefaultFactHandle f0 = (DefaultFactHandle) workingMemory.insert(cheddar); assertLength(0, sink.getAsserted()); // object should assert as it passes text alphaNode.assertObject(f0, context, workingMemory); assertLength(1, sink.getAsserted()); final Object[] list = (Object[]) sink.getAsserted().get(0); assertSame(cheddar, workingMemory.getObject((DefaultFactHandle) list[0])); final Cheese stilton = new Cheese("stilton", 6); f0.setObject(stilton); sink.getAsserted().clear(); // object should not assert as it does not pass text alphaNode.assertObject(f0, context, workingMemory); assertLength(0, sink.getAsserted()); } public void testRetractObjectWithMemory() throws Exception { RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setAlphaMemory(true); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession(); final Rule rule = new Rule("test-rule"); final PropagationContext context = new PropagationContextImpl(0, PropagationContext.ASSERTION, null, null); final MockObjectSource source = new MockObjectSource(buildContext.getNextId()); final FieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); buildContext.setAlphaNodeMemoryAllowed(true); final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, source, buildContext); // has memory final MockObjectSink sink = new MockObjectSink(); alphaNode.addObjectSink(sink); final Cheese cheddar = new Cheese("cheddar", 5); final DefaultFactHandle f0 = new DefaultFactHandle(0, cheddar); // check alpha memory is empty final AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory(alphaNode); assertEquals(0, memory.facts.size()); // object should assert as it passes text alphaNode.assertObject(f0, context, workingMemory); assertEquals(1, memory.facts.size()); final DefaultFactHandle f1 = new DefaultFactHandle(1, "cheese"); // object should NOT retract as it doesn't exist alphaNode.retractObject(f1, context, workingMemory); assertLength(0, sink.getRetracted()); assertEquals(1, memory.facts.size()); assertTrue("Should contain 'cheddar handle'", memory.facts.contains(f0)); // object should retract as it does exist alphaNode.retractObject(f0, context, workingMemory); assertLength(1, sink.getRetracted()); assertEquals(0, memory.facts.size()); final Object[] list = (Object[]) sink.getRetracted().get(0); assertSame(f0, list[0]); } public void testRetractObjectWithoutMemory() throws Exception { RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setAlphaMemory(false); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession(); final Rule rule = new Rule("test-rule"); final PropagationContext context = new PropagationContextImpl(0, PropagationContext.ASSERTION, null, null); final MockObjectSource source = new MockObjectSource(buildContext.getNextId()); final FieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, source, buildContext); // no memory final MockObjectSink sink = new MockObjectSink(); alphaNode.addObjectSink(sink); final Cheese cheddar = new Cheese("cheddar", 5); final DefaultFactHandle f0 = new DefaultFactHandle(0, cheddar); // check alpha memory is empty final AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory(alphaNode); assertNull(memory.facts); // object should assert as it passes text alphaNode.assertObject(f0, context, workingMemory); assertNull(memory.facts); final DefaultFactHandle f1 = new DefaultFactHandle(1, new Cheese("brie", 10)); // object should NOT retract as it doesn't exist alphaNode.retractObject(f1, context, workingMemory); // without memory, it will always propagate a retract assertLength(0, sink.getRetracted()); assertNull(memory.facts); // object should retract as it does exist alphaNode.retractObject(f0, context, workingMemory); assertLength(1, sink.getRetracted()); assertNull(memory.facts); final Object[] list = (Object[]) sink.getRetracted().get(0); assertSame(f0, list[0]); } public void testUpdateSinkWithMemory() throws FactException, IntrospectionException { // An AlphaNode with memory should not try and repropagate from its source // Also it should only update the latest tuple sinky RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setAlphaMemory(true); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession(); final Rule rule = new Rule("test-rule"); final PropagationContext context = new PropagationContextImpl(0, PropagationContext.ASSERTION, null, null); final MockObjectSource source = new MockObjectSource(buildContext.getNextId()); final FieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); buildContext.setAlphaNodeMemoryAllowed(true); final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, source, buildContext); // has memory alphaNode.attach(); final MockObjectSink sink1 = new MockObjectSink(); alphaNode.addObjectSink(sink1); // Assert a single fact which should be in the AlphaNode memory and also // propagated to the // the tuple sink final Cheese cheese = new Cheese("cheddar", 0); final DefaultFactHandle handle1 = new DefaultFactHandle(1, cheese); alphaNode.assertObject(handle1, context, workingMemory); // Create a fact that should not be propagated, since the alpha node restriction will filter it // out final Cheese stilton = new Cheese("stilton", 10); final DefaultFactHandle handle2 = new DefaultFactHandle(2, stilton); // adding handle to the mock source source.addFact(handle2); alphaNode.assertObject(handle2, context, workingMemory); assertLength(1, sink1.getAsserted()); // Attach a new tuple sink final MockObjectSink sink2 = new MockObjectSink(); // Tell the alphanode to update the new node. Make sure the first sink1 // is not updated // likewise the source should not do anything alphaNode.updateSink(sink2, context, workingMemory); assertLength(1, sink1.getAsserted()); assertLength(1, sink2.getAsserted()); assertEquals(0, source.getUdated()); } public void testUpdateSinkWithoutMemory() throws FactException, IntrospectionException { // An AlphaNode without memory should try and repropagate from its source RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setAlphaMemory(false); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession(); final Rule rule = new Rule("test-rule"); final PropagationContext context = new PropagationContextImpl(0, PropagationContext.ASSERTION, null, null); final MockObjectSource source = new MockObjectSource(buildContext.getNextId()); final FieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, source, buildContext); // no memory alphaNode.attach(); final MockObjectSink sink1 = new MockObjectSink(); alphaNode.addObjectSink(sink1); // Assert a single fact which should be in the AlphaNode memory and also // propagated to the // the tuple sink final Cheese cheese = new Cheese("cheddar", 0); final DefaultFactHandle handle1 = new DefaultFactHandle(1, cheese); // adding handle to the mock source source.addFact(handle1); alphaNode.assertObject(handle1, context, workingMemory); // Create a fact that should not be propagated, since the alpha node restriction will filter it // out final Cheese stilton = new Cheese("stilton", 10); final DefaultFactHandle handle2 = new DefaultFactHandle(2, stilton); // adding handle to the mock source source.addFact(handle2); alphaNode.assertObject(handle2, context, workingMemory); assertLength(1, sink1.getAsserted()); // Attach a new tuple sink final MockObjectSink sink2 = new MockObjectSink(); // Tell the alphanode to update the new node. Make sure the first sink1 // is not updated // likewise the source should not do anything alphaNode.updateSink(sink2, context, workingMemory); assertLength(1, sink1.getAsserted()); assertLength(1, sink2.getAsserted()); assertEquals(1, source.getUdated()); } }
/** * * * <pre> * * * Cheese( ( type == "cheddar" && price > 10) || ( type == "e;stilton"e; && price < 10 ) ) * * * </pre> * * Test the use of the composite OR constraint. * * @throws IntrospectionException */ public void testNestedCompositeConstraints() { final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(); final InternalWorkingMemory workingMemory = (InternalWorkingMemory) ruleBase.newStatefulSession(); final ClassFieldExtractor typeExtractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue cheddarField = FieldFactory.getFieldValue("cheddar"); final Evaluator stringEqual = ValueType.STRING_TYPE.getEvaluator(Operator.EQUAL); // type == 'cheddar' final LiteralConstraint constraint1 = new LiteralConstraint(typeExtractor, stringEqual, cheddarField); final ClassFieldExtractor priceExtractor = cache.getExtractor(Cheese.class, "price", getClass().getClassLoader()); final FieldValue field10 = FieldFactory.getFieldValue(10); final Evaluator integerGreater = ValueType.INTEGER_TYPE.getEvaluator(Operator.GREATER); // price > 10 final LiteralConstraint constraint2 = new LiteralConstraint(priceExtractor, integerGreater, field10); // type == 'cheddar' && price > 10 final AndConstraint and1 = new AndConstraint(); and1.addAlphaConstraint(constraint1); and1.addAlphaConstraint(constraint2); final FieldValue stiltonField = FieldFactory.getFieldValue("stilton"); // type == 'stilton' final LiteralConstraint constraint3 = new LiteralConstraint(typeExtractor, stringEqual, stiltonField); final Evaluator integerLess = ValueType.INTEGER_TYPE.getEvaluator(Operator.LESS); // price < 10 final LiteralConstraint constraint4 = new LiteralConstraint(priceExtractor, integerLess, field10); // type == 'stilton' && price < 10 final AndConstraint and2 = new AndConstraint(); and2.addAlphaConstraint(constraint3); and2.addAlphaConstraint(constraint4); // ( type == 'cheddar' && price > 10 ) || ( type == 'stilton' && price < 10 ) final OrConstraint constraint = new OrConstraint(); constraint.addAlphaConstraint(and1); constraint.addAlphaConstraint(and2); final ContextEntry context = constraint.createContextEntry(); final Cheese cheddar = new Cheese("cheddar", 15); final InternalFactHandle cheddarHandle = (InternalFactHandle) workingMemory.insert(cheddar); // check constraint assertTrue(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setPrice(5); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertFalse(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setType("stilton"); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertTrue(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setPrice(15); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertFalse(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); }
public class FieldConstraintTest extends TestCase { ClassFieldExtractorCache cache = ClassFieldExtractorCache.getInstance(); public FieldConstraintTest() { super(); } /** * * * <pre> * * * ( Cheese (type "cheddar") ) * * * </pre> * * This is currently the same as using a ReturnValueConstraint just that it doesn't need any * requiredDeclarations * * @throws IntrospectionException */ public void testLiteralConstraint() throws IntrospectionException { final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(); final InternalWorkingMemory workingMemory = (InternalWorkingMemory) ruleBase.newStatefulSession(); final ClassFieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.STRING_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); final ContextEntry context = constraint.createContextEntry(); final Cheese cheddar = new Cheese("cheddar", 5); final InternalFactHandle cheddarHandle = (InternalFactHandle) workingMemory.insert(cheddar); // check constraint assertTrue(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); final Cheese stilton = new Cheese("stilton", 5); final InternalFactHandle stiltonHandle = (InternalFactHandle) workingMemory.insert(stilton); // check constraint assertFalse(constraint.isAllowed(stiltonHandle.getObject(), workingMemory, context)); } /** * * * <pre> * * * Cheese( price == 5 ) * * * </pre> * * @throws IntrospectionException */ public void testPrimitiveLiteralConstraint() throws IntrospectionException { final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(); final InternalWorkingMemory workingMemory = (InternalWorkingMemory) ruleBase.newStatefulSession(); final ClassFieldExtractor extractor = cache.getExtractor(Cheese.class, "price", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue(5); final Evaluator evaluator = ValueType.PINTEGER_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); final ContextEntry context = constraint.createContextEntry(); final Cheese cheddar = new Cheese("cheddar", 5); final InternalFactHandle cheddarHandle = (InternalFactHandle) workingMemory.insert(cheddar); // check constraint assertTrue(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); final Cheese stilton = new Cheese("stilton", 10); final InternalFactHandle stiltonHandle = (InternalFactHandle) workingMemory.insert(stilton); // check constraint assertFalse(constraint.isAllowed(stiltonHandle.getObject(), workingMemory, context)); } /** * * * <pre> * * * (Cheese (price ?price1 ) * (Cheese (price ?price2&:(= ?price2 (* 2 ?price1) ) * * * </pre> * * @throws IntrospectionException */ public void testPredicateConstraint() throws IntrospectionException { final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(); final InternalWorkingMemory workingMemory = (InternalWorkingMemory) ruleBase.newStatefulSession(); final FieldExtractor priceExtractor = cache.getExtractor(Cheese.class, "price", getClass().getClassLoader()); Pattern pattern = new Pattern(0, new ClassObjectType(Cheese.class)); // Bind the extractor to a decleration // Declarations know the pattern they derive their value form final Declaration price1Declaration = new Declaration("price1", priceExtractor, pattern); pattern = new Pattern(1, new ClassObjectType(Cheese.class)); // Bind the extractor to a decleration // Declarations know the pattern they derive their value form final Declaration price2Declaration = new Declaration("price2", priceExtractor, pattern); final PredicateExpression evaluator = new PredicateExpression() { /** */ private static final long serialVersionUID = 400L; public boolean evaluate( Object object, Tuple tuple, Declaration[] previousDeclarations, Declaration[] localDeclarations, WorkingMemory workingMemory, Object context) { int price1 = previousDeclarations[0].getIntValue( (InternalWorkingMemory) workingMemory, workingMemory.getObject(tuple.get(previousDeclarations[0]))); int price2 = localDeclarations[0].getIntValue((InternalWorkingMemory) workingMemory, object); return (price2 == (price1 * 2)); } public Object createContext() { return null; } }; final PredicateConstraint constraint1 = new PredicateConstraint( evaluator, new Declaration[] {price1Declaration}, new Declaration[] {price2Declaration}, new String[] {}); final Cheese cheddar0 = new Cheese("cheddar", 5); final FactHandle f0 = workingMemory.insert(cheddar0); InstrumentedReteTuple tuple = new InstrumentedReteTuple(f0); final Cheese cheddar1 = new Cheese("cheddar", 10); final InternalFactHandle f1 = (InternalFactHandle) workingMemory.insert(cheddar1); tuple = new InstrumentedReteTuple(tuple, f1); final PredicateContextEntry context = (PredicateContextEntry) constraint1.createContextEntry(); context.updateFromTuple(workingMemory, tuple); assertTrue(constraint1.isAllowedCachedLeft(context, f1.getObject())); } /** * * * <pre> * * * (Cheese (price ?price ) * (Cheese (price =(* 2 ?price) ) * (Cheese (price >(* 2 ?price) ) * * * </pre> * * @throws IntrospectionException */ public void testReturnValueConstraint() throws IntrospectionException { final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(); final InternalWorkingMemory workingMemory = (InternalWorkingMemory) ruleBase.newStatefulSession(); final FieldExtractor priceExtractor = cache.getExtractor(Cheese.class, "price", getClass().getClassLoader()); final Pattern pattern = new Pattern(0, new ClassObjectType(Cheese.class)); // Bind the extractor to a decleration // Declarations know the pattern they derive their value form final Declaration priceDeclaration = new Declaration("price1", priceExtractor, pattern); final ReturnValueExpression isDoubleThePrice = new ReturnValueExpression() { /** */ private static final long serialVersionUID = 400L; public FieldValue evaluate( Object object, Tuple tuple, // ?price Declaration[] previousDeclarations, Declaration[] localDeclarations, WorkingMemory workingMemory, Object context) { int price = ((Number) previousDeclarations[0].getValue( (InternalWorkingMemory) workingMemory, workingMemory.getObject(tuple.get(previousDeclarations[0])))) .intValue(); return FieldFactory.getFieldValue(2 * price); } public Object createContext() { return null; } }; final ReturnValueRestriction restriction1 = new ReturnValueRestriction( priceExtractor, isDoubleThePrice, new Declaration[] {priceDeclaration}, new Declaration[0], new String[0], ValueType.INTEGER_TYPE.getEvaluator(Operator.EQUAL)); final ReturnValueConstraint constraint1 = new ReturnValueConstraint(priceExtractor, restriction1); final ReturnValueRestriction restriction2 = new ReturnValueRestriction( priceExtractor, isDoubleThePrice, new Declaration[] {priceDeclaration}, new Declaration[0], new String[0], ValueType.INTEGER_TYPE.getEvaluator(Operator.GREATER)); final ReturnValueConstraint constraint2 = new ReturnValueConstraint(priceExtractor, restriction2); final Cheese cheddar0 = new Cheese("cheddar", 5); final FactHandle f0 = workingMemory.insert(cheddar0); InstrumentedReteTuple tuple = new InstrumentedReteTuple(f0); final Cheese cheddar1 = new Cheese("cheddar", 10); final InternalFactHandle f1 = (InternalFactHandle) workingMemory.insert(cheddar1); tuple = new InstrumentedReteTuple(tuple, f1); final ReturnValueContextEntry context1 = (ReturnValueContextEntry) constraint1.createContextEntry(); context1.updateFromTuple(workingMemory, tuple); assertTrue(constraint1.isAllowedCachedLeft(context1, f1.getObject())); final ReturnValueContextEntry context2 = (ReturnValueContextEntry) constraint2.createContextEntry(); context2.updateFromTuple(workingMemory, tuple); assertFalse(constraint2.isAllowedCachedLeft(context2, f1.getObject())); final Cheese cheddar2 = new Cheese("cheddar", 11); final InternalFactHandle f2 = (InternalFactHandle) workingMemory.insert(cheddar2); assertTrue(constraint2.isAllowedCachedLeft(context2, f2.getObject())); } /** * * * <pre> * * * type == "cheddar" && price > 10 * * * </pre> * * Test the use of the composite AND constraint. Composite AND constraints are only used when * nested inside other field constraints, as the top level AND is implicit * * @throws IntrospectionException */ public void testCompositeAndConstraint() { final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(); final InternalWorkingMemory workingMemory = (InternalWorkingMemory) ruleBase.newStatefulSession(); final ClassFieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.STRING_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint1 = new LiteralConstraint(extractor, evaluator, field); final ClassFieldExtractor priceExtractor = cache.getExtractor(Cheese.class, "price", getClass().getClassLoader()); final FieldValue priceField = FieldFactory.getFieldValue(10); final Evaluator priceEvaluator = ValueType.INTEGER_TYPE.getEvaluator(Operator.GREATER); final LiteralConstraint constraint2 = new LiteralConstraint(priceExtractor, priceEvaluator, priceField); final Cheese cheddar = new Cheese("cheddar", 15); final AndConstraint constraint = new AndConstraint(); constraint.addAlphaConstraint(constraint1); constraint.addAlphaConstraint(constraint2); final ContextEntry context = constraint.createContextEntry(); final InternalFactHandle cheddarHandle = (InternalFactHandle) workingMemory.insert(cheddar); // check constraint assertTrue(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setPrice(5); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertFalse(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setType("stilton"); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertFalse(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setPrice(15); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertFalse(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); } /** * * * <pre> * * * Cheese( type == "cheddar" || price > 10 ) * * * </pre> * * Test the use of the composite OR constraint. * * @throws IntrospectionException */ public void testCompositeOrConstraint() { final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(); final InternalWorkingMemory workingMemory = (InternalWorkingMemory) ruleBase.newStatefulSession(); final ClassFieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.STRING_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint1 = new LiteralConstraint(extractor, evaluator, field); final ClassFieldExtractor priceExtractor = cache.getExtractor(Cheese.class, "price", getClass().getClassLoader()); final FieldValue priceField = FieldFactory.getFieldValue(10); final Evaluator priceEvaluator = ValueType.INTEGER_TYPE.getEvaluator(Operator.GREATER); final LiteralConstraint constraint2 = new LiteralConstraint(priceExtractor, priceEvaluator, priceField); final Cheese cheddar = new Cheese("cheddar", 15); final OrConstraint constraint = new OrConstraint(); constraint.addAlphaConstraint(constraint1); constraint.addAlphaConstraint(constraint2); final ContextEntry context = constraint.createContextEntry(); final InternalFactHandle cheddarHandle = (InternalFactHandle) workingMemory.insert(cheddar); // check constraint assertTrue(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setPrice(5); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertTrue(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setType("stilton"); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertFalse(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setPrice(15); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertTrue(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); } /** * * * <pre> * * * Cheese( ( type == "cheddar" && price > 10) || ( type == "e;stilton"e; && price < 10 ) ) * * * </pre> * * Test the use of the composite OR constraint. * * @throws IntrospectionException */ public void testNestedCompositeConstraints() { final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(); final InternalWorkingMemory workingMemory = (InternalWorkingMemory) ruleBase.newStatefulSession(); final ClassFieldExtractor typeExtractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue cheddarField = FieldFactory.getFieldValue("cheddar"); final Evaluator stringEqual = ValueType.STRING_TYPE.getEvaluator(Operator.EQUAL); // type == 'cheddar' final LiteralConstraint constraint1 = new LiteralConstraint(typeExtractor, stringEqual, cheddarField); final ClassFieldExtractor priceExtractor = cache.getExtractor(Cheese.class, "price", getClass().getClassLoader()); final FieldValue field10 = FieldFactory.getFieldValue(10); final Evaluator integerGreater = ValueType.INTEGER_TYPE.getEvaluator(Operator.GREATER); // price > 10 final LiteralConstraint constraint2 = new LiteralConstraint(priceExtractor, integerGreater, field10); // type == 'cheddar' && price > 10 final AndConstraint and1 = new AndConstraint(); and1.addAlphaConstraint(constraint1); and1.addAlphaConstraint(constraint2); final FieldValue stiltonField = FieldFactory.getFieldValue("stilton"); // type == 'stilton' final LiteralConstraint constraint3 = new LiteralConstraint(typeExtractor, stringEqual, stiltonField); final Evaluator integerLess = ValueType.INTEGER_TYPE.getEvaluator(Operator.LESS); // price < 10 final LiteralConstraint constraint4 = new LiteralConstraint(priceExtractor, integerLess, field10); // type == 'stilton' && price < 10 final AndConstraint and2 = new AndConstraint(); and2.addAlphaConstraint(constraint3); and2.addAlphaConstraint(constraint4); // ( type == 'cheddar' && price > 10 ) || ( type == 'stilton' && price < 10 ) final OrConstraint constraint = new OrConstraint(); constraint.addAlphaConstraint(and1); constraint.addAlphaConstraint(and2); final ContextEntry context = constraint.createContextEntry(); final Cheese cheddar = new Cheese("cheddar", 15); final InternalFactHandle cheddarHandle = (InternalFactHandle) workingMemory.insert(cheddar); // check constraint assertTrue(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setPrice(5); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertFalse(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setType("stilton"); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertTrue(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); cheddar.setPrice(15); ((ShadowProxy) cheddarHandle.getObject()).updateProxy(); assertFalse(constraint.isAllowed(cheddarHandle.getObject(), workingMemory, context)); } }
/** * * * <pre> * * * (Cheese (price ?price ) * (Cheese (price =(* 2 ?price) ) * (Cheese (price >(* 2 ?price) ) * * * </pre> * * @throws IntrospectionException */ public void testReturnValueConstraint() throws IntrospectionException { final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(); final InternalWorkingMemory workingMemory = (InternalWorkingMemory) ruleBase.newStatefulSession(); final FieldExtractor priceExtractor = cache.getExtractor(Cheese.class, "price", getClass().getClassLoader()); final Pattern pattern = new Pattern(0, new ClassObjectType(Cheese.class)); // Bind the extractor to a decleration // Declarations know the pattern they derive their value form final Declaration priceDeclaration = new Declaration("price1", priceExtractor, pattern); final ReturnValueExpression isDoubleThePrice = new ReturnValueExpression() { /** */ private static final long serialVersionUID = 400L; public FieldValue evaluate( Object object, Tuple tuple, // ?price Declaration[] previousDeclarations, Declaration[] localDeclarations, WorkingMemory workingMemory, Object context) { int price = ((Number) previousDeclarations[0].getValue( (InternalWorkingMemory) workingMemory, workingMemory.getObject(tuple.get(previousDeclarations[0])))) .intValue(); return FieldFactory.getFieldValue(2 * price); } public Object createContext() { return null; } }; final ReturnValueRestriction restriction1 = new ReturnValueRestriction( priceExtractor, isDoubleThePrice, new Declaration[] {priceDeclaration}, new Declaration[0], new String[0], ValueType.INTEGER_TYPE.getEvaluator(Operator.EQUAL)); final ReturnValueConstraint constraint1 = new ReturnValueConstraint(priceExtractor, restriction1); final ReturnValueRestriction restriction2 = new ReturnValueRestriction( priceExtractor, isDoubleThePrice, new Declaration[] {priceDeclaration}, new Declaration[0], new String[0], ValueType.INTEGER_TYPE.getEvaluator(Operator.GREATER)); final ReturnValueConstraint constraint2 = new ReturnValueConstraint(priceExtractor, restriction2); final Cheese cheddar0 = new Cheese("cheddar", 5); final FactHandle f0 = workingMemory.insert(cheddar0); InstrumentedReteTuple tuple = new InstrumentedReteTuple(f0); final Cheese cheddar1 = new Cheese("cheddar", 10); final InternalFactHandle f1 = (InternalFactHandle) workingMemory.insert(cheddar1); tuple = new InstrumentedReteTuple(tuple, f1); final ReturnValueContextEntry context1 = (ReturnValueContextEntry) constraint1.createContextEntry(); context1.updateFromTuple(workingMemory, tuple); assertTrue(constraint1.isAllowedCachedLeft(context1, f1.getObject())); final ReturnValueContextEntry context2 = (ReturnValueContextEntry) constraint2.createContextEntry(); context2.updateFromTuple(workingMemory, tuple); assertFalse(constraint2.isAllowedCachedLeft(context2, f1.getObject())); final Cheese cheddar2 = new Cheese("cheddar", 11); final InternalFactHandle f2 = (InternalFactHandle) workingMemory.insert(cheddar2); assertTrue(constraint2.isAllowedCachedLeft(context2, f2.getObject())); }
/** * * * <pre> * * * (Cheese (price ?price1 ) * (Cheese (price ?price2&:(= ?price2 (* 2 ?price1) ) * * * </pre> * * @throws IntrospectionException */ public void testPredicateConstraint() throws IntrospectionException { final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(); final InternalWorkingMemory workingMemory = (InternalWorkingMemory) ruleBase.newStatefulSession(); final FieldExtractor priceExtractor = cache.getExtractor(Cheese.class, "price", getClass().getClassLoader()); Pattern pattern = new Pattern(0, new ClassObjectType(Cheese.class)); // Bind the extractor to a decleration // Declarations know the pattern they derive their value form final Declaration price1Declaration = new Declaration("price1", priceExtractor, pattern); pattern = new Pattern(1, new ClassObjectType(Cheese.class)); // Bind the extractor to a decleration // Declarations know the pattern they derive their value form final Declaration price2Declaration = new Declaration("price2", priceExtractor, pattern); final PredicateExpression evaluator = new PredicateExpression() { /** */ private static final long serialVersionUID = 400L; public boolean evaluate( Object object, Tuple tuple, Declaration[] previousDeclarations, Declaration[] localDeclarations, WorkingMemory workingMemory, Object context) { int price1 = previousDeclarations[0].getIntValue( (InternalWorkingMemory) workingMemory, workingMemory.getObject(tuple.get(previousDeclarations[0]))); int price2 = localDeclarations[0].getIntValue((InternalWorkingMemory) workingMemory, object); return (price2 == (price1 * 2)); } public Object createContext() { return null; } }; final PredicateConstraint constraint1 = new PredicateConstraint( evaluator, new Declaration[] {price1Declaration}, new Declaration[] {price2Declaration}, new String[] {}); final Cheese cheddar0 = new Cheese("cheddar", 5); final FactHandle f0 = workingMemory.insert(cheddar0); InstrumentedReteTuple tuple = new InstrumentedReteTuple(f0); final Cheese cheddar1 = new Cheese("cheddar", 10); final InternalFactHandle f1 = (InternalFactHandle) workingMemory.insert(cheddar1); tuple = new InstrumentedReteTuple(tuple, f1); final PredicateContextEntry context = (PredicateContextEntry) constraint1.createContextEntry(); context.updateFromTuple(workingMemory, tuple); assertTrue(constraint1.isAllowedCachedLeft(context, f1.getObject())); }
public void testQueryTerminalNode() { final ClassObjectType queryObjectType = new ClassObjectType(DroolsQuery.class); final ObjectTypeNode queryObjectTypeNode = new ObjectTypeNode(this.buildContext.getNextId(), queryObjectType, buildContext); queryObjectTypeNode.attach(); ClassFieldExtractor extractor = cache.getExtractor(DroolsQuery.class, "name", DroolsQuery.class.getClassLoader()); FieldValue field = FieldFactory.getFieldValue("query-1"); final Evaluator evaluator = ValueType.STRING_TYPE.getEvaluator(Operator.EQUAL); LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); AlphaNode alphaNode = new AlphaNode(this.buildContext.getNextId(), constraint, queryObjectTypeNode, buildContext); alphaNode.attach(); final LeftInputAdapterNode liaNode = new LeftInputAdapterNode(this.buildContext.getNextId(), alphaNode, this.buildContext); liaNode.attach(); final ClassObjectType cheeseObjectType = new ClassObjectType(Cheese.class); final ObjectTypeNode cheeseObjectTypeNode = new ObjectTypeNode(this.buildContext.getNextId(), cheeseObjectType, buildContext); cheeseObjectTypeNode.attach(); extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); field = FieldFactory.getFieldValue("stilton"); constraint = new LiteralConstraint(extractor, evaluator, field); alphaNode = new AlphaNode( this.buildContext.getNextId(), constraint, cheeseObjectTypeNode, buildContext); alphaNode.attach(); BuildContext buildContext = new BuildContext(ruleBase, ruleBase.getReteooBuilder().getIdGenerator()); buildContext.setTupleMemoryEnabled(false); final JoinNode joinNode = new JoinNode( this.buildContext.getNextId(), liaNode, alphaNode, EmptyBetaConstraints.getInstance(), buildContext); joinNode.attach(); final Query query = new Query("query-1"); final QueryTerminalNode queryNode = new QueryTerminalNode(this.buildContext.getNextId(), joinNode, query, query.getLhs()); queryNode.attach(); final org.drools.rule.Package pkg = new org.drools.rule.Package("com.drools.test"); pkg.addRule(query); try { final Field pkgField = ruleBase.getClass().getSuperclass().getDeclaredField("pkgs"); pkgField.setAccessible(true); final Map pkgs = (Map) pkgField.get(ruleBase); pkgs.put(pkg.getName(), pkg); } catch (final Exception e) { Assert.fail("Should not throw any exception: " + e.getMessage()); } final WorkingMemory workingMemory = ruleBase.newStatefulSession(); QueryResults results = workingMemory.getQueryResults("query-1"); assertEquals(0, results.size()); final Cheese stilton1 = new Cheese("stilton", 100); final FactHandle handle1 = workingMemory.insert(stilton1); results = workingMemory.getQueryResults("query-1"); assertEquals(1, results.size()); final Cheese cheddar = new Cheese("cheddar", 55); workingMemory.insert(cheddar); results = workingMemory.getQueryResults("query-1"); assertEquals(1, results.size()); final Cheese stilton2 = new Cheese("stilton", 5); final FactHandle handle2 = workingMemory.insert(stilton2); results = workingMemory.getQueryResults("query-1"); assertEquals(2, results.size()); QueryResult result = results.get(0); assertEquals(1, result.size()); assertEquals(stilton2, result.get(0)); result = results.get(1); assertEquals(1, result.size()); assertEquals(stilton1, result.get(0)); int i = 0; for (final Iterator it = results.iterator(); it.hasNext(); ) { result = (QueryResult) it.next(); assertEquals(1, result.size()); if (i == 1) { assertSame(stilton1, result.get(0)); } else { assertSame(stilton2, result.get(0)); } i++; } workingMemory.retract(handle1); results = workingMemory.getQueryResults("query-1"); assertEquals(1, results.size()); workingMemory.retract(handle2); results = workingMemory.getQueryResults("query-1"); assertEquals(0, results.size()); }
public void testUpdateSinkWithoutMemory() throws FactException, IntrospectionException { // An AlphaNode without memory should try and repropagate from its source RuleBaseConfiguration config = new RuleBaseConfiguration(); config.setAlphaMemory(false); ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase(config); BuildContext buildContext = new BuildContext(ruleBase, ((ReteooRuleBase) ruleBase).getReteooBuilder().getIdGenerator()); ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession(); final Rule rule = new Rule("test-rule"); final PropagationContext context = new PropagationContextImpl(0, PropagationContext.ASSERTION, null, null); final MockObjectSource source = new MockObjectSource(buildContext.getNextId()); final FieldExtractor extractor = cache.getExtractor(Cheese.class, "type", getClass().getClassLoader()); final FieldValue field = FieldFactory.getFieldValue("cheddar"); final Evaluator evaluator = ValueType.OBJECT_TYPE.getEvaluator(Operator.EQUAL); final LiteralConstraint constraint = new LiteralConstraint(extractor, evaluator, field); final AlphaNode alphaNode = new AlphaNode(buildContext.getNextId(), constraint, source, buildContext); // no memory alphaNode.attach(); final MockObjectSink sink1 = new MockObjectSink(); alphaNode.addObjectSink(sink1); // Assert a single fact which should be in the AlphaNode memory and also // propagated to the // the tuple sink final Cheese cheese = new Cheese("cheddar", 0); final DefaultFactHandle handle1 = new DefaultFactHandle(1, cheese); // adding handle to the mock source source.addFact(handle1); alphaNode.assertObject(handle1, context, workingMemory); // Create a fact that should not be propagated, since the alpha node restriction will filter it // out final Cheese stilton = new Cheese("stilton", 10); final DefaultFactHandle handle2 = new DefaultFactHandle(2, stilton); // adding handle to the mock source source.addFact(handle2); alphaNode.assertObject(handle2, context, workingMemory); assertLength(1, sink1.getAsserted()); // Attach a new tuple sink final MockObjectSink sink2 = new MockObjectSink(); // Tell the alphanode to update the new node. Make sure the first sink1 // is not updated // likewise the source should not do anything alphaNode.updateSink(sink2, context, workingMemory); assertLength(1, sink1.getAsserted()); assertLength(1, sink2.getAsserted()); assertEquals(1, source.getUdated()); }