/**
* Copyright 2010 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.
*/
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.util.List;
import java.util.Map;
import org.drools.Cheese;
import org.drools.DroolsTestCase;
import org.drools.FactException;
import org.drools.Person;
import org.drools.RuleBase;
import org.drools.RuleBaseConfiguration;
import org.drools.RuleBaseFactory;
import org.drools.base.ClassObjectType;
import org.drools.common.DefaultFactHandle;
import org.drools.common.InternalFactHandle;
import org.drools.common.InternalRuleBase;
import org.drools.common.PropagationContextImpl;
import org.drools.core.util.ObjectHashSet;
import org.drools.reteoo.ReteooBuilder.IdGenerator;
import org.drools.reteoo.builder.BuildContext;
import org.drools.rule.EntryPoint;
import org.drools.spi.ObjectType;
import org.drools.spi.PropagationContext;
public class ObjectTypeNodeTest extends DroolsTestCase {
private ReteooRuleBase ruleBase;
private BuildContext buildContext;
private EntryPointNode entryPoint;
protected void setUp() throws Exception {
this.ruleBase = ( ReteooRuleBase ) RuleBaseFactory.newRuleBase();
this.buildContext = new BuildContext( ruleBase, ((ReteooRuleBase)ruleBase).getReteooBuilder().getIdGenerator() );
this.entryPoint = new EntryPointNode( 0,
this.ruleBase.getRete(),
buildContext );
this.entryPoint.attach();
}
public void testAttach() throws Exception {
IdGenerator idGenerator = ruleBase.getReteooBuilder().getIdGenerator();
final Rete source = this.ruleBase.getRete();
final ObjectType objectType = new ClassObjectType( String.class );
int id = idGenerator.getNextId();
final ObjectTypeNode objectTypeNode = new ObjectTypeNode( id,
this.entryPoint,
objectType,
buildContext );
assertEquals( id,
objectTypeNode.getId() );
Map<ObjectType, ObjectTypeNode> map = source.getObjectTypeNodes( EntryPoint.DEFAULT );
assertEquals( 0,
map.size() );
objectTypeNode.attach();
assertEquals( 1,
map.size() );
assertSame( objectTypeNode,
map.get( objectType ) );
}
public void testAssertObject() throws Exception {
final PropagationContext context = new PropagationContextImpl( 0,
PropagationContext.ASSERTION,
null,
null,
null );
ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase();
IdGenerator idGenerator = ruleBase.getReteooBuilder().getIdGenerator();
final ReteooWorkingMemory workingMemory = ( ReteooWorkingMemory ) ruleBase.newStatefulSession();
final Rete source = ruleBase.getRete();
final EntryPointNode entryPoint = new EntryPointNode( 0,
source,
buildContext );
entryPoint.attach();
final ObjectTypeNode objectTypeNode = new ObjectTypeNode( idGenerator.getNextId(),
entryPoint,
new ClassObjectType( String.class ),
buildContext );
final MockObjectSink sink = new MockObjectSink();
objectTypeNode.addObjectSink( sink );
final Object string1 = "cheese";
final InternalFactHandle handle1 = (InternalFactHandle) workingMemory.insert( string1 );
// should assert as ObjectType matches
objectTypeNode.assertObject( handle1,
context,
workingMemory );
// make sure just string1 was asserted
final List asserted = sink.getAsserted();
assertLength( 1,
asserted );
assertSame( string1,
workingMemory.getObject( (DefaultFactHandle) ((Object[]) asserted.get( 0 ))[0] ) );
// check asserted object was added to memory
final ObjectHashSet memory = (ObjectHashSet) workingMemory.getNodeMemory( objectTypeNode );
assertEquals( 1,
memory.size() );
assertTrue( memory.contains( handle1 ) );
}
public void testAssertObjectSequentialMode() {
final PropagationContext context = new PropagationContextImpl( 0,
PropagationContext.ASSERTION,
null,
null,
null );
RuleBaseConfiguration conf = new RuleBaseConfiguration();
conf.setSequential( true );
final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase( conf );
buildContext = new BuildContext( ruleBase, ((ReteooRuleBase)ruleBase).getReteooBuilder().getIdGenerator() );
buildContext.setObjectTypeNodeMemoryEnabled( false );
final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory( 1,
ruleBase );
final Rete source = ruleBase.getRete();
final EntryPointNode entryPoint = new EntryPointNode( 0,
source,
buildContext );
entryPoint.attach();
final ObjectTypeNode objectTypeNode = new ObjectTypeNode( 1,
entryPoint,
new ClassObjectType( String.class ),
buildContext );
final MockObjectSink sink = new MockObjectSink();
objectTypeNode.addObjectSink( sink );
final Object string1 = "cheese";
final InternalFactHandle handle1 = (InternalFactHandle) workingMemory.insert( string1 );
// should assert as ObjectType matches
objectTypeNode.assertObject( handle1,
context,
workingMemory );
// make sure just string1 was asserted
final List asserted = sink.getAsserted();
assertLength( 1,
asserted );
assertSame( string1,
workingMemory.getObject( (DefaultFactHandle) ((Object[]) asserted.get( 0 ))[0] ) );
// it's sequential, so check the asserted object was not added to the node memory
final ObjectHashSet memory = (ObjectHashSet) workingMemory.getNodeMemory( objectTypeNode );
assertEquals( 0,
memory.size() );
}
public void testMemory() {
ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase();
IdGenerator idGenerator = ruleBase.getReteooBuilder().getIdGenerator();
final ReteooWorkingMemory workingMemory = ( ReteooWorkingMemory ) ruleBase.newStatefulSession();
final ObjectTypeNode objectTypeNode = new ObjectTypeNode( idGenerator.getNextId(),
this.entryPoint,
new ClassObjectType( String.class ),
buildContext );
final ObjectHashSet memory = (ObjectHashSet) workingMemory.getNodeMemory( objectTypeNode );
assertNotNull( memory );
}
public void testIsAssignableFrom() {
ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase();
IdGenerator idGenerator = ruleBase.getReteooBuilder().getIdGenerator();
final Rete source = new Rete((InternalRuleBase) ruleBase);
ObjectTypeNode objectTypeNode = new ObjectTypeNode( idGenerator.getNextId(),
this.entryPoint,
new ClassObjectType( String.class ),
buildContext );
assertFalse( objectTypeNode.isAssignableFrom( new ClassObjectType( new Object().getClass() ) ) );
assertFalse( objectTypeNode.isAssignableFrom( new ClassObjectType( new Integer( 5 ).getClass() ) ) );
assertTrue( objectTypeNode.isAssignableFrom( new ClassObjectType( "string".getClass() ) ) );
objectTypeNode = new ObjectTypeNode( idGenerator.getNextId(),
this.entryPoint,
new ClassObjectType( Object.class ),
buildContext );
assertTrue( objectTypeNode.isAssignableFrom( new ClassObjectType( new Object().getClass() ) ) );
assertTrue( objectTypeNode.isAssignableFrom( new ClassObjectType( new Integer( 5 ).getClass() ) ) );
assertTrue( objectTypeNode.isAssignableFrom( new ClassObjectType( "string".getClass() ) ) );
}
public void testRetractObject() throws Exception {
ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase();
IdGenerator idGenerator = ruleBase.getReteooBuilder().getIdGenerator();
final PropagationContext context = new PropagationContextImpl( 0,
PropagationContext.ASSERTION,
null,
null,
null );
final ReteooWorkingMemory workingMemory = (ReteooWorkingMemory)ruleBase.newStatefulSession();
final Rete source = new Rete((InternalRuleBase) ruleBase);
final ObjectTypeNode objectTypeNode = new ObjectTypeNode( idGenerator.getNextId(),
this.entryPoint,
new ClassObjectType( String.class ),
buildContext );
final MockObjectSink sink = new MockObjectSink();
objectTypeNode.addObjectSink( sink );
final Object string1 = "cheese";
final DefaultFactHandle handle1 = new DefaultFactHandle( 1,
string1 );
// should assert as ObjectType matches
objectTypeNode.assertObject( handle1,
context,
workingMemory );
// check asserted object was added to memory
final ObjectHashSet memory = (ObjectHashSet) workingMemory.getNodeMemory( objectTypeNode );
assertEquals( 1,
memory.size() );
// should retract as ObjectType matches
objectTypeNode.retractObject( handle1,
context,
workingMemory );
// check asserted object was removed from memory
assertEquals( 0,
memory.size() );
// make sure its just the handle1 for string1 that was propagated
final List retracted = sink.getRetracted();
assertLength( 1,
retracted );
assertSame( handle1,
((Object[]) retracted.get( 0 ))[0] );
}
public void testUpdateSink() throws FactException {
// Tests that when new child is added only the last added child is
// updated
// When the attachingNewNode flag is set
final PropagationContext context = new PropagationContextImpl( 0,
PropagationContext.ASSERTION,
null,
null,
null );
final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory( 1,
(ReteooRuleBase) ruleBase );
final Rete source = new Rete( (InternalRuleBase)ruleBase);
final ObjectTypeNode objectTypeNode = new ObjectTypeNode( 1,
this.entryPoint,
new ClassObjectType( String.class ),
buildContext );
final MockObjectSink sink1 = new MockObjectSink();
objectTypeNode.addObjectSink( sink1 );
final Object string1 = "cheese";
final Object string2 = "bread";
final DefaultFactHandle handle1 = new DefaultFactHandle( 1,
string1 );
final DefaultFactHandle handle2 = new DefaultFactHandle( 2,
string2 );
objectTypeNode.assertObject( handle1,
context,
workingMemory );
objectTypeNode.assertObject( handle2,
context,
workingMemory );
assertEquals( 2,
sink1.getAsserted().size() );
final MockObjectSink sink2 = new MockObjectSink();
objectTypeNode.addObjectSink( sink2 );
assertEquals( 0,
sink2.getAsserted().size() );
objectTypeNode.updateSink( sink2,
null,
workingMemory );
assertEquals( 2,
sink2.getAsserted().size() );
final Object string3 = "water";
final DefaultFactHandle handle3 = new DefaultFactHandle( 3,
string3 );
objectTypeNode.assertObject( handle3,
context,
workingMemory );
assertEquals( 3,
sink1.getAsserted().size() );
assertEquals( 3,
sink2.getAsserted().size() );
}
public void testAssertObjectWithShadowEnabled() throws Exception {
final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase();
final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory( 1,
ruleBase );
final Rete source = ruleBase.getRete();
final EntryPointNode entryPoint = new EntryPointNode( 0,
source,
buildContext );
entryPoint.attach();
final ObjectTypeNode objectTypeNode = new ObjectTypeNode( 1,
this.entryPoint,
new ClassObjectType( Cheese.class ),
buildContext );
final MockObjectSink sink = new MockObjectSink();
objectTypeNode.addObjectSink( sink );
entryPoint.addObjectSink( objectTypeNode );
final Object cheese = new Cheese( "muzzarela",
5 );
final InternalFactHandle handle1 = (InternalFactHandle) workingMemory.insert( cheese );
// make sure just string1 was asserted
final List asserted = sink.getAsserted();
assertLength( 1,
asserted );
assertEquals( cheese,
((InternalFactHandle) ((Object[]) asserted.get( 0 ))[0]).getObject() );
// check asserted object was added to memory
final ObjectHashSet memory = (ObjectHashSet) workingMemory.getNodeMemory( objectTypeNode );
assertEquals( 1,
memory.size() );
assertTrue( memory.contains( handle1 ) );
}
public void testAssertObjectWithShadowEnabledNoDefaultConstr() throws Exception {
final PropagationContext context = new PropagationContextImpl( 0,
PropagationContext.ASSERTION,
null,
null,
null );
ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase();
IdGenerator idGenerator = ruleBase.getReteooBuilder().getIdGenerator();
final ReteooWorkingMemory workingMemory = ( ReteooWorkingMemory ) ruleBase.newStatefulSession();
final Rete source = ruleBase.getRete();
final EntryPointNode entryPoint = new EntryPointNode( 0,
source,
buildContext );
entryPoint.attach();
final ObjectTypeNode objectTypeNode = new ObjectTypeNode( idGenerator.getNextId(),
entryPoint,
new ClassObjectType( Person.class ),
buildContext );
final MockObjectSink sink = new MockObjectSink();
objectTypeNode.addObjectSink( sink );
final Object person = new Person( "bob",
25 );
final InternalFactHandle handle1 = (InternalFactHandle) workingMemory.insert( person );
// should assert as ObjectType matches
objectTypeNode.assertObject( handle1,
context,
workingMemory );
// make sure just string1 was asserted
final List asserted = sink.getAsserted();
assertLength( 1,
asserted );
assertEquals( ((InternalFactHandle) ((Object[]) asserted.get( 0 ))[0]).getObject(),
person );
// check asserted object was added to memory
final ObjectHashSet memory = (ObjectHashSet) workingMemory.getNodeMemory( objectTypeNode );
assertEquals( 1,
memory.size() );
assertTrue( memory.contains( handle1 ) );
}
}