/** * 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.lang.reflect.Field; import java.util.Iterator; import java.util.Map; import junit.framework.Assert; import junit.framework.TestCase; import org.drools.FactHandle; import org.drools.QueryResult; import org.drools.QueryResults; import org.drools.RuleBaseFactory; import org.drools.WorkingMemory; import org.drools.base.ClassFieldAccessorCache; import org.drools.base.ClassFieldAccessorStore; import org.drools.base.ClassFieldReader; import org.drools.base.ClassObjectType; import org.drools.base.DroolsQuery; 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.EmptyBetaConstraints; import org.drools.reteoo.builder.BuildContext; import org.drools.rule.Behavior; import org.drools.rule.LiteralConstraint; import org.drools.rule.Query; import org.drools.spi.Evaluator; import org.drools.spi.FieldValue; public class QueryTerminalNodeTest extends TestCase { private ReteooRuleBase ruleBase; private BuildContext buildContext; private EntryPointNode entryPoint; private EqualityEvaluatorsDefinition equals = new EqualityEvaluatorsDefinition(); ClassFieldAccessorStore store = new ClassFieldAccessorStore(); protected void setUp() throws Exception { store.setClassFieldAccessorCache( new ClassFieldAccessorCache( Thread.currentThread().getContextClassLoader() ) ); store.setEagerWire( true ); 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 testQueryTerminalNode() { final ClassObjectType queryObjectType = new ClassObjectType( DroolsQuery.class ); final ObjectTypeNode queryObjectTypeNode = new ObjectTypeNode( this.buildContext.getNextId(), this.entryPoint, queryObjectType, buildContext ); queryObjectTypeNode.attach(); ClassFieldReader extractor = store.getReader( DroolsQuery.class, "name", DroolsQuery.class.getClassLoader() ); FieldValue field = FieldFactory.getFieldValue( "query-1" ); final Evaluator evaluator = equals.getEvaluator( ValueType.STRING_TYPE, 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(), this.entryPoint, cheeseObjectType, buildContext ); cheeseObjectTypeNode.attach(); extractor = store.getReader( 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(), Behavior.EMPTY_BEHAVIOR_LIST, buildContext ); joinNode.attach(); final Query query = new Query( "query-1" ); final QueryTerminalNode queryNode = new QueryTerminalNode( this.buildContext.getNextId(), joinNode, query, query.getLhs(), buildContext ); 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( stilton1, result.get( 0 ) ); result = results.get( 1 ); assertEquals( 1, result.size() ); assertEquals( stilton2, 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( stilton2, result.get( 0 ) ); } else { assertSame( stilton1, 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 class Cheese { private String type; private int price; public Cheese(final String type, final int price) { super(); this.type = type; this.price = price; } public int getPrice() { return this.price; } public String getType() { return this.type; } public String toString() { return "[Cheese type='" + this.type + "' price='" + this.price + "']"; } } }