001: package org.drools.reteoo;
002:
003: import java.util.ArrayList;
004: import java.util.Collection;
005: import java.util.Iterator;
006: import java.util.List;
007:
008: import junit.framework.TestCase;
009:
010: import org.drools.Cheese;
011: import org.drools.FactHandle;
012: import org.drools.RuleBaseConfiguration;
013: import org.drools.RuleBaseFactory;
014: import org.drools.WorkingMemory;
015: import org.drools.base.ClassFieldExtractor;
016: import org.drools.base.ClassFieldExtractorCache;
017: import org.drools.base.ClassObjectType;
018: import org.drools.base.FieldFactory;
019: import org.drools.base.ValueType;
020: import org.drools.base.evaluators.Operator;
021: import org.drools.common.BetaConstraints;
022: import org.drools.common.DefaultFactHandle;
023: import org.drools.common.InternalFactHandle;
024: import org.drools.common.PropagationContextImpl;
025: import org.drools.common.SingleBetaConstraints;
026: import org.drools.rule.Pattern;
027: import org.drools.rule.Declaration;
028: import org.drools.rule.LiteralConstraint;
029: import org.drools.rule.VariableConstraint;
030: import org.drools.spi.AlphaNodeFieldConstraint;
031: import org.drools.spi.DataProvider;
032: import org.drools.spi.FieldValue;
033: import org.drools.spi.PropagationContext;
034: import org.drools.spi.Tuple;
035: import org.drools.util.LinkedList;
036: import org.drools.util.LinkedListEntry;
037:
038: public class FromNodeTest extends TestCase {
039:
040: public void testAlphaNode() {
041: final PropagationContext context = new PropagationContextImpl(
042: 0, PropagationContext.ASSERTION, null, null);
043: final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory(
044: 1, (ReteooRuleBase) RuleBaseFactory.newRuleBase());
045: final ClassFieldExtractor extractor = ClassFieldExtractorCache
046: .getExtractor(Cheese.class, "type", getClass()
047: .getClassLoader());
048:
049: final FieldValue field = FieldFactory.getFieldValue("stilton");
050: final LiteralConstraint constraint = new LiteralConstraint(
051: extractor, ValueType.STRING_TYPE
052: .getEvaluator(Operator.EQUAL), field);
053:
054: final List list = new ArrayList();
055: final Cheese cheese1 = new Cheese("cheddar", 20);
056: final Cheese cheese2 = new Cheese("brie", 20);
057: list.add(cheese1);
058: list.add(cheese2);
059: final MockDataProvider dataProvider = new MockDataProvider(list);
060:
061: final FromNode from = new FromNode(3, dataProvider, null,
062: new AlphaNodeFieldConstraint[] { constraint }, null);
063: final MockTupleSink sink = new MockTupleSink(5);
064: from.addTupleSink(sink);
065:
066: final Person person1 = new Person("xxx1", 30);
067: final FactHandle person1Handle = workingMemory.insert(person1);
068: final ReteTuple tuple1 = new ReteTuple(
069: (DefaultFactHandle) person1Handle);
070: from.assertTuple(tuple1, context, workingMemory);
071:
072: // nothing should be asserted, as cheese1 is cheddar and we are filtering on stilton
073: assertEquals(0, sink.getAsserted().size());
074:
075: //Set cheese1 to stilton and it should now propagate
076: cheese1.setType("stilton");
077: final Person person2 = new Person("xxx2", 30);
078: final FactHandle person2Handle = workingMemory.insert(person2);
079: final ReteTuple tuple2 = new ReteTuple(
080: (DefaultFactHandle) person2Handle);
081: from.assertTuple(tuple2, context, workingMemory);
082:
083: final List asserted = sink.getAsserted();
084: assertEquals(1, asserted.size());
085: Tuple tuple = (Tuple) ((Object[]) asserted.get(0))[0];
086: assertSame(person2, tuple.getFactHandles()[1].getObject());
087: assertSame(cheese1, tuple.getFactHandles()[0].getObject());
088:
089: cheese2.setType("stilton");
090: final Person person3 = new Person("xxx2", 30);
091: final FactHandle person3Handle = workingMemory.insert(person3);
092: final ReteTuple tuple3 = new ReteTuple(
093: (DefaultFactHandle) person3Handle);
094: from.assertTuple(tuple3, context, workingMemory);
095:
096: assertEquals(3, asserted.size());
097: tuple = (Tuple) ((Object[]) asserted.get(1))[0];
098: assertSame(person3, tuple.getFactHandles()[1].getObject());
099: assertSame(cheese1, tuple.getFactHandles()[0].getObject());
100: tuple = (Tuple) ((Object[]) asserted.get(2))[0];
101: assertSame(person3, tuple.getFactHandles()[1].getObject());
102: assertSame(cheese2, tuple.getFactHandles()[0].getObject());
103:
104: assertNotSame(cheese1, cheese2);
105: }
106:
107: public void testBetaNode() {
108: final PropagationContext context = new PropagationContextImpl(
109: 0, PropagationContext.ASSERTION, null, null);
110:
111: final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory(
112: 1, (ReteooRuleBase) RuleBaseFactory.newRuleBase());
113:
114: final ClassFieldExtractor priceExtractor = ClassFieldExtractorCache
115: .getExtractor(Cheese.class, "price", getClass()
116: .getClassLoader());
117:
118: final ClassFieldExtractor ageExtractor = ClassFieldExtractorCache
119: .getExtractor(Person.class, "age", getClass()
120: .getClassLoader());
121:
122: final Pattern pattern = new Pattern(0, new ClassObjectType(
123: Person.class));
124:
125: final Declaration declaration = new Declaration("age",
126: ageExtractor, pattern);
127:
128: final VariableConstraint variableConstraint = new VariableConstraint(
129: priceExtractor, declaration, ValueType.PINTEGER_TYPE
130: .getEvaluator(Operator.EQUAL));
131: final RuleBaseConfiguration configuration = new RuleBaseConfiguration();
132: configuration.setIndexRightBetaMemory(false);
133: configuration.setIndexLeftBetaMemory(false);
134: final BetaConstraints betaConstraints = new SingleBetaConstraints(
135: variableConstraint, configuration);
136:
137: final List list = new ArrayList();
138: final Cheese cheese1 = new Cheese("cheddar", 18);
139: final Cheese cheese2 = new Cheese("brie", 12);
140: list.add(cheese1);
141: list.add(cheese2);
142: final MockDataProvider dataProvider = new MockDataProvider(list);
143:
144: final FromNode from = new FromNode(3, dataProvider, null, null,
145: betaConstraints);
146: final MockTupleSink sink = new MockTupleSink(5);
147: from.addTupleSink(sink);
148:
149: final Person person1 = new Person("xxx1", 30);
150: final FactHandle person1Handle = workingMemory.insert(person1);
151: final ReteTuple tuple1 = new ReteTuple(
152: (DefaultFactHandle) person1Handle);
153: from.assertTuple(tuple1, context, workingMemory);
154:
155: // nothing should be asserted, as cheese1 is cheddar and we are filtering on stilton
156: assertEquals(0, sink.getAsserted().size());
157:
158: //Set cheese1 to stilton and it should now propagate
159: cheese1.setPrice(30);
160: final Person person2 = new Person("xxx2", 30);
161: final FactHandle person2Handle = workingMemory.insert(person2);
162: final ReteTuple tuple2 = new ReteTuple(
163: (DefaultFactHandle) person2Handle);
164: from.assertTuple(tuple2, context, workingMemory);
165:
166: final List asserted = sink.getAsserted();
167: assertEquals(1, asserted.size());
168: Tuple tuple = (Tuple) ((Object[]) asserted.get(0))[0];
169: assertSame(person2, tuple.getFactHandles()[1].getObject());
170: assertSame(cheese1, tuple.getFactHandles()[0].getObject());
171:
172: cheese2.setPrice(30);
173: final Person person3 = new Person("xxx2", 30);
174: final FactHandle person3Handle = workingMemory.insert(person3);
175: final ReteTuple tuple3 = new ReteTuple(
176: (DefaultFactHandle) person3Handle);
177: from.assertTuple(tuple3, context, workingMemory);
178:
179: assertEquals(3, asserted.size());
180: tuple = (Tuple) ((Object[]) asserted.get(1))[0];
181: assertSame(person3, tuple.getFactHandles()[1].getObject());
182: assertSame(cheese1, tuple.getFactHandles()[0].getObject());
183: tuple = (Tuple) ((Object[]) asserted.get(2))[0];
184: assertSame(person3, tuple.getFactHandles()[1].getObject());
185: assertSame(cheese2, tuple.getFactHandles()[0].getObject());
186:
187: assertNotSame(cheese1, cheese2);
188: }
189:
190: public void testRestract() {
191: final PropagationContext context = new PropagationContextImpl(
192: 0, PropagationContext.ASSERTION, null, null);
193: final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory(
194: 1, (ReteooRuleBase) RuleBaseFactory.newRuleBase());
195: final ClassFieldExtractor extractor = ClassFieldExtractorCache
196: .getExtractor(Cheese.class, "type", getClass()
197: .getClassLoader());
198:
199: final FieldValue field = FieldFactory.getFieldValue("stilton");
200: final LiteralConstraint constraint = new LiteralConstraint(
201: extractor, ValueType.STRING_TYPE
202: .getEvaluator(Operator.EQUAL), field);
203:
204: final List list = new ArrayList();
205: final Cheese cheese1 = new Cheese("stilton", 5);
206: final Cheese cheese2 = new Cheese("stilton", 15);
207: list.add(cheese1);
208: list.add(cheese2);
209: final MockDataProvider dataProvider = new MockDataProvider(list);
210:
211: final FromNode from = new FromNode(3, dataProvider, null,
212: new AlphaNodeFieldConstraint[] { constraint }, null);
213: final MockTupleSink sink = new MockTupleSink(5);
214: from.addTupleSink(sink);
215:
216: final List asserted = sink.getAsserted();
217:
218: final Person person1 = new Person("xxx2", 30);
219: final FactHandle person1Handle = workingMemory.insert(person1);
220: final ReteTuple tuple = new ReteTuple(
221: (DefaultFactHandle) person1Handle);
222: from.assertTuple(tuple, context, workingMemory);
223:
224: assertEquals(2, asserted.size());
225:
226: final BetaMemory memory = (BetaMemory) workingMemory
227: .getNodeMemory(from);
228: assertEquals(1, memory.getTupleMemory().size());
229: assertNull(memory.getFactHandleMemory());
230: assertEquals(2, ((LinkedList) memory.getCreatedHandles().get(
231: tuple)).size());
232:
233: final InternalFactHandle handle1 = (InternalFactHandle) ((LinkedListEntry) ((LinkedList) memory
234: .getCreatedHandles().get(tuple)).getFirst())
235: .getObject();
236: final InternalFactHandle handle2 = (InternalFactHandle) ((LinkedListEntry) ((LinkedList) memory
237: .getCreatedHandles().get(tuple)).getLast()).getObject();
238: assertEquals(handle1.getObject(), cheese1);
239: assertEquals(handle2.getObject(), cheese2);
240:
241: from.retractTuple(tuple, context, workingMemory);
242: assertEquals(0, memory.getTupleMemory().size());
243: assertNull(memory.getFactHandleMemory());
244: }
245:
246: public static class MockDataProvider implements DataProvider {
247:
248: private Collection collection;
249:
250: public Declaration[] getRequiredDeclarations() {
251: return null;
252: }
253:
254: public MockDataProvider(final Collection collection) {
255: this .collection = collection;
256: }
257:
258: public Iterator getResults(final Tuple tuple,
259: final WorkingMemory wm, final PropagationContext ctx) {
260: return this .collection.iterator();
261: }
262: }
263:
264: public static class Person {
265: private String name;
266: private int age;
267:
268: public Person(final String name, final int age) {
269: super ();
270: this .name = name;
271: this .age = age;
272: }
273:
274: public int getAge() {
275: return this .age;
276: }
277:
278: public String getName() {
279: return this.name;
280: }
281: }
282: }
|