package org.drools.reteoo;
/*
* Copyright 2005 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.beans.IntrospectionException;
import org.drools.Cheese;
import org.drools.DroolsTestCase;
import org.drools.FactException;
import org.drools.RuleBaseFactory;
import org.drools.base.ClassFieldAccessorCache;
import org.drools.base.ClassFieldAccessorStore;
import org.drools.base.ClassFieldReader;
import org.drools.base.FieldFactory;
import org.drools.base.ValueType;
import org.drools.base.evaluators.EqualityEvaluatorsDefinition;
import org.drools.base.evaluators.Operator;
import org.drools.common.DefaultFactHandle;
import org.drools.common.PropagationContextImpl;
import org.drools.reteoo.AlphaNode.AlphaMemory;
import org.drools.reteoo.builder.BuildContext;
import org.drools.rule.LiteralConstraint;
import org.drools.rule.Rule;
import org.drools.spi.Evaluator;
import org.drools.spi.FieldValue;
import org.drools.spi.InternalReadAccessor;
import org.drools.spi.PropagationContext;
public class AlphaNodeTest extends DroolsTestCase {
EqualityEvaluatorsDefinition equals = new EqualityEvaluatorsDefinition();
ClassFieldAccessorStore store = new ClassFieldAccessorStore();
protected void setUp() throws Exception {
store.setClassFieldAccessorCache( new ClassFieldAccessorCache( Thread.currentThread().getContextClassLoader() ) );
store.setEagerWire( true );
}
public void testLiteralConstraintAssertObjectWithoutMemory() throws Exception {
ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase();
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,
null );
final MockObjectSource source = new MockObjectSource( buildContext.getNextId() );
final ClassFieldReader extractor = store.getReader( Cheese.class,
"type",
getClass().getClassLoader() );
final FieldValue field = FieldFactory.getFieldValue( "cheddar" );
final Evaluator evaluator = equals.getEvaluator( ValueType.OBJECT_TYPE,
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 );
// object should assert as it passes text
alphaNode.assertObject( f0,
context,
workingMemory );
assertEquals( 1,
sink.getAsserted().size() );
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() );
list = (Object[]) sink.getAsserted().get( 0 );
assertSame( cheddar,
workingMemory.getObject( (DefaultFactHandle) list[0] ) );
}
/*
* This just test AlphaNode With a different Constraint type.
*/
public void testReturnValueConstraintAssertObject() throws Exception {
ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase();
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,
null );
final MockObjectSource source = new MockObjectSource( buildContext.getNextId() );
final InternalReadAccessor extractor = store.getReader( Cheese.class,
"type",
getClass().getClassLoader() );
final FieldValue field = FieldFactory.getFieldValue( "cheddar" );
final Evaluator evaluator = equals.getEvaluator( ValueType.OBJECT_TYPE,
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 testUpdateSinkWithoutMemory() throws FactException,
IntrospectionException {
// An AlphaNode should try and repropagate from its source
ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase();
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,
null );
final MockObjectSource source = new MockObjectSource( buildContext.getNextId() );
final InternalReadAccessor extractor = store.getReader( Cheese.class,
"type",
getClass().getClassLoader() );
final FieldValue field = FieldFactory.getFieldValue( "cheddar" );
final Evaluator evaluator = equals.getEvaluator( ValueType.OBJECT_TYPE,
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() );
}
}