/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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.compiler.oopath;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import org.assertj.core.api.Assertions;
import org.drools.compiler.oopath.model.Adult;
import org.drools.compiler.oopath.model.Child;
import org.drools.compiler.oopath.model.Group;
import org.drools.compiler.oopath.model.Man;
import org.drools.compiler.oopath.model.Person;
import org.drools.compiler.oopath.model.TMDirectory;
import org.drools.compiler.oopath.model.TMFile;
import org.drools.compiler.oopath.model.TMFileSet;
import org.drools.compiler.oopath.model.TMFileWithParentObj;
import org.drools.compiler.oopath.model.Thing;
import org.drools.compiler.oopath.model.Toy;
import org.drools.compiler.oopath.model.Woman;
import org.drools.core.phreak.AbstractReactiveObject;
import org.drools.core.phreak.ReactiveSet;
import org.junit.Test;
import org.kie.api.KieServices;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.Message;
import org.kie.api.builder.Results;
import org.kie.api.event.rule.DefaultRuleRuntimeEventListener;
import org.kie.api.event.rule.ObjectDeletedEvent;
import org.kie.api.event.rule.ObjectInsertedEvent;
import org.kie.api.event.rule.ObjectUpdatedEvent;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.internal.utils.KieHelper;
import static org.drools.compiler.TestUtil.assertDrlHasCompilationError;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class OOPathTest {
@Test
public void testInvalidOOPath() {
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"global java.util.List list\n" +
"\n" +
"rule R when\n" +
" Man( $toy: /wife.children/toys )\n" +
"then\n" +
" list.add( $toy.getName() );\n" +
"end\n";
testInvalid(drl);
}
@Test
public void testInvalidOOPathProperty() {
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"global java.util.List list\n" +
"\n" +
"rule R when\n" +
" Man( $toy: /wife/children/toys/wrongProperty )\n" +
"then\n" +
" list.add( $toy.getName() );\n" +
"end\n";
testInvalid(drl);
}
private void testInvalid(final String drl) {
final KieServices ks = KieServices.Factory.get();
final KieFileSystem kfs = ks.newKieFileSystem().write( "src/main/resources/r1.drl", drl );
final Results results = ks.newKieBuilder( kfs ).buildAll().getResults();
assertTrue( results.hasMessages( Message.Level.ERROR ) );
}
@Test
public void testIndexedAccess() {
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"global java.util.List list\n" +
"\n" +
"rule R when\n" +
" Man( $toy: /wife/children[0]/toys[1] )\n" +
"then\n" +
" list.add( $toy.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final List<String> list = new ArrayList<>();
ksession.setGlobal( "list", list );
final Woman alice = new Woman( "Alice", 38 );
final Man bob = new Man( "Bob", 40 );
bob.setWife( alice );
final Child charlie = new Child( "Charles", 12 );
final Child debbie = new Child( "Debbie", 11 );
alice.addChild( charlie );
alice.addChild( debbie );
charlie.addToy( new Toy( "car" ) );
charlie.addToy( new Toy( "ball" ) );
debbie.addToy( new Toy( "doll" ) );
ksession.insert( bob );
ksession.fireAllRules();
Assertions.assertThat(list).containsExactlyInAnyOrder("ball");
}
@Test
public void testRecursiveOOPathQuery() {
final String drl =
"import org.drools.compiler.oopath.model.Thing;\n" +
"global java.util.List list\n" +
"\n" +
"rule \"Print all things contained in the Office\" when\n" +
" $office : Thing( name == \"office\" )\n" +
" isContainedIn( $office, thing; )\n" +
"then\n" +
" list.add( thing.getName() );\n" +
"end\n" +
"\n" +
"query isContainedIn( Thing $x, Thing $y )\n" +
" $y := /$x/children\n" +
"or\n" +
" ( $z := /$x/children and isContainedIn( $z, $y; ) )\n" +
"end\n";
final Thing house = new Thing( "house" );
final Thing office = new Thing( "office" );
house.addChild( office );
final Thing kitchen = new Thing( "kitchen" );
house.addChild( kitchen );
final Thing knife = new Thing( "knife" );
kitchen.addChild( knife );
final Thing cheese = new Thing( "cheese" );
kitchen.addChild( cheese );
final Thing desk = new Thing( "desk" );
office.addChild( desk );
final Thing chair = new Thing( "chair" );
office.addChild( chair );
final Thing computer = new Thing( "computer" );
desk.addChild( computer );
final Thing draw = new Thing( "draw" );
desk.addChild( draw );
final Thing key = new Thing( "key" );
draw.addChild( key );
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final List<String> list = new ArrayList<>();
ksession.setGlobal( "list", list );
ksession.insert(house);
ksession.insert(office);
ksession.insert(kitchen);
ksession.insert(knife);
ksession.insert(cheese);
ksession.insert(desk);
ksession.insert(chair);
ksession.insert(computer);
ksession.insert(draw);
ksession.insert(key);
ksession.fireAllRules();
Assertions.assertThat(list).containsExactlyInAnyOrder("desk", "chair", "key", "draw", "computer");
}
@Test
public void testBackReferenceConstraint() {
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"global java.util.List list\n" +
"\n" +
"rule R when\n" +
" Man( $toy: /wife/children/toys[ name.length == ../name.length ] )\n" +
"then\n" +
" list.add( $toy.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final List<String> list = new ArrayList<>();
ksession.setGlobal( "list", list );
final Woman alice = new Woman( "Alice", 38 );
final Man bob = new Man( "Bob", 40 );
bob.setWife( alice );
final Child charlie = new Child( "Carl", 12 );
final Child debbie = new Child( "Debbie", 8 );
alice.addChild( charlie );
alice.addChild( debbie );
charlie.addToy( new Toy( "car" ) );
charlie.addToy( new Toy( "ball" ) );
debbie.addToy( new Toy( "doll" ) );
debbie.addToy( new Toy( "guitar" ) );
ksession.insert( bob );
ksession.fireAllRules();
Assertions.assertThat(list).containsExactlyInAnyOrder("ball", "guitar");
}
@Test
public void testPrimitives() {
// DROOLS-1266
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"global java.util.List list\n" +
"\n" +
"rule R when\n" +
" Adult( $x: /children.age )\n" +
"then\n" +
" list.add( $x );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final List<String> list = new ArrayList<>();
ksession.setGlobal( "list", list );
final Man bob = new Man( "Bob", 40 );
bob.addChild( new Child( "Charles", 12 ) );
bob.addChild( new Child( "Debbie", 8 ) );
ksession.insert( bob );
ksession.fireAllRules();
Assertions.assertThat(list).hasSize(2);
}
@Test
public void testDoubleAdd() {
// DROOLS-1376
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"\n" +
"rule R2 when\n" +
" Group( $id: name, $p: /members[age >= 20] )\n" +
"then\n" +
" System.out.println( $id + \".\" + $p.getName() );\n" +
" insertLogical( $id + \".\" + $p.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final Group x = new Group("X");
final Group y = new Group("Y");
ksession.insert( x );
ksession.insert( y );
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.Ada"));
assertFalse (factsCollection(ksession).contains("X.Bea"));
assertFalse (factsCollection(ksession).contains("Y.Ada"));
assertFalse (factsCollection(ksession).contains("Y.Bea"));
final Adult ada = new Adult("Ada", 20);
final Adult bea = new Adult("Bea", 20);
x.addPerson(ada);
x.addPerson(bea);
y.addPerson(ada);
y.addPerson(bea);
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.Ada"));
assertTrue (factsCollection(ksession).contains("X.Bea"));
assertTrue (factsCollection(ksession).contains("Y.Ada"));
assertTrue (factsCollection(ksession).contains("Y.Bea"));
x.removePerson(ada);
x.removePerson(bea);
y.removePerson(ada);
y.removePerson(bea);
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.Ada"));
assertFalse (factsCollection(ksession).contains("X.Bea"));
assertFalse (factsCollection(ksession).contains("Y.Ada"));
assertFalse (factsCollection(ksession).contains("Y.Bea"));
}
@Test
public void testDoubleRemove() {
// DROOLS-1376
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"\n" +
"rule R2 when\n" +
" Group( $id: name, $p: /members[age >= 20] )\n" +
"then\n" +
" System.out.println( $id + \".\" + $p.getName() );\n" +
" insertLogical( $id + \".\" + $p.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final Adult ada = new Adult("Ada", 20);
final Adult bea = new Adult("Bea", 20);
final Group x = new Group("X");
final Group y = new Group("Y");
x.addPerson(ada);
x.addPerson(bea);
y.addPerson(ada);
y.addPerson(bea);
ksession.insert( x );
ksession.insert( y );
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.Ada"));
assertTrue (factsCollection(ksession).contains("X.Bea"));
assertTrue (factsCollection(ksession).contains("Y.Ada"));
assertTrue (factsCollection(ksession).contains("Y.Bea"));
x.removePerson(ada);
x.removePerson(bea);
y.removePerson(ada);
y.removePerson(bea);
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.Ada"));
assertFalse (factsCollection(ksession).contains("X.Bea"));
assertFalse (factsCollection(ksession).contains("Y.Ada"));
assertFalse (factsCollection(ksession).contains("Y.Bea"));
}
@Test
public void testAddAllRemoveIdx() {
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"\n" +
"rule R2 when\n" +
" Group( $id: name, $p: /members[age >= 30] )\n" +
"then\n" +
" System.out.println( $id + \".\" + $p.getName() );\n" +
" insertLogical( $id + \".\" + $p.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final Group x = new Group("X");
final Group y = new Group("Y");
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.Ada"));
assertFalse (factsCollection(ksession).contains("X.Bea"));
assertFalse (factsCollection(ksession).contains("Y.Ada"));
assertFalse (factsCollection(ksession).contains("Y.Bea"));
final Adult ada = new Adult("Ada", 29);
final Adult bea = new Adult("Bea", 29);
final List<Person> bothList = Arrays.asList(new Person[]{ada, bea});
x.getMembers().addAll(bothList);
y.getMembers().addAll(bothList);
ksession.insert( x );
ksession.insert( y );
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.Ada"));
assertFalse (factsCollection(ksession).contains("X.Bea"));
assertFalse (factsCollection(ksession).contains("Y.Ada"));
assertFalse (factsCollection(ksession).contains("Y.Bea"));
ada.setAge( 30 );
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.Ada"));
assertFalse (factsCollection(ksession).contains("X.Bea"));
assertTrue (factsCollection(ksession).contains("Y.Ada"));
assertFalse (factsCollection(ksession).contains("Y.Bea"));
y.getMembers().remove(1); // removing Bea from Y
bea.setAge( 30 );
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.Ada"));
assertTrue (factsCollection(ksession).contains("X.Bea"));
assertTrue (factsCollection(ksession).contains("Y.Ada"));
assertFalse (factsCollection(ksession).contains("Y.Bea"));
}
@Test
public void testMiscListMethods() {
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"\n" +
"rule R2 when\n" +
" TMDirectory( $id: name, $p: /files[size >= 100] )\n" +
"then\n" +
" System.out.println( $id + \".\" + $p.getName() );\n" +
" insertLogical( $id + \".\" + $p.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final TMDirectory x = new TMDirectory("X");
final TMDirectory y = new TMDirectory("Y");
ksession.insert( x );
ksession.insert( y );
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.File0"));
assertFalse (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
final TMFile file0 = new TMFile("File0", 47);
final TMFile file1 = new TMFile("File1", 47);
final TMFile file2 = new TMFile("File2", 47);
x.getFiles().add(file2);
x.getFiles().addAll(0, Arrays.asList(file0, file1));
y.getFiles().add(0, file2);
y.getFiles().add(0, file0);
y.getFiles().add(1, file1);
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.File0"));
assertFalse (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertFalse (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertFalse (factsCollection(ksession).contains("Y.File2"));
file0.setSize( 999 );
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertFalse (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertFalse (factsCollection(ksession).contains("Y.File2"));
y.getFiles().remove(1); // removing File1 from Y
file1.setSize( 999 );
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertTrue (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertFalse (factsCollection(ksession).contains("Y.File2"));
file2.setSize( 999 );
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertTrue (factsCollection(ksession).contains("X.File1"));
assertTrue (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertTrue (factsCollection(ksession).contains("Y.File2"));
final TMFile file0R = new TMFile("File0R", 999);
x.getFiles().set(0, file0R);
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.File0"));
assertTrue (factsCollection(ksession).contains("X.File0R"));
assertTrue (factsCollection(ksession).contains("X.File1"));
assertTrue (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertTrue (factsCollection(ksession).contains("Y.File2"));
}
@Test
public void testCollectionIteratorRemove() {
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"\n" +
"rule R2 when\n" +
" TMDirectory( $id: name, $p: /files[size >= 100] )\n" +
"then\n" +
" System.out.println( $id + \".\" + $p.getName() );\n" +
" insertLogical( $id + \".\" + $p.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final TMDirectory x = new TMDirectory("X");
final TMDirectory y = new TMDirectory("Y");
final TMFile file0 = new TMFile("File0", 999);
final TMFile file1 = new TMFile("File1", 999);
final TMFile file2 = new TMFile("File2", 999);
x.getFiles().addAll(Arrays.asList(file0, file1, file2));
y.getFiles().addAll(Arrays.asList(file0, file1, file2));
ksession.insert( x );
ksession.insert( y );
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertTrue (factsCollection(ksession).contains("X.File1"));
assertTrue (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertTrue (factsCollection(ksession).contains("Y.File1"));
assertTrue (factsCollection(ksession).contains("Y.File2"));
java.util.Iterator<TMFile> iterator = x.getFiles().iterator();
iterator.next();
iterator.remove();
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.File0"));
assertTrue (factsCollection(ksession).contains("X.File1"));
assertTrue (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertTrue (factsCollection(ksession).contains("Y.File1"));
assertTrue (factsCollection(ksession).contains("Y.File2"));
iterator.next();
iterator.remove();
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.File0"));
assertFalse (factsCollection(ksession).contains("X.File1"));
assertTrue (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertTrue (factsCollection(ksession).contains("Y.File1"));
assertTrue (factsCollection(ksession).contains("Y.File2"));
iterator.next();
iterator.remove();
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.File0"));
assertFalse (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertTrue (factsCollection(ksession).contains("Y.File1"));
assertTrue (factsCollection(ksession).contains("Y.File2"));
assertFalse( iterator.hasNext() );
}
@Test
public void testListIteratorRemove() {
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"\n" +
"rule R2 when\n" +
" TMDirectory( $id: name, $p: /files[size >= 100] )\n" +
"then\n" +
" insertLogical( $id + \".\" + $p.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
ksession.addEventListener(new DefaultRuleRuntimeEventListener() {
@Override
public void objectDeleted(ObjectDeletedEvent event) {
System.out.println(event.getOldObject() + " -> " + "_");
}
@Override
public void objectInserted(ObjectInsertedEvent event) {
System.out.println("_" + " -> " + event.getObject());
}
@Override
public void objectUpdated(ObjectUpdatedEvent event) {
System.out.println(event.getOldObject() + " -> " + event.getObject());
}
});
final TMDirectory x = new TMDirectory("X");
final TMDirectory y = new TMDirectory("Y");
final TMFile file0 = new TMFile("File0", 999);
final TMFile file1 = new TMFile("File1", 999);
final TMFile file2 = new TMFile("File2", 999);
x.getFiles().addAll(Arrays.asList(file0, file1, file2));
y.getFiles().addAll(Arrays.asList(file0, file1, file2));
ksession.insert( x );
ksession.insert( y );
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertTrue (factsCollection(ksession).contains("X.File1"));
assertTrue (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertTrue (factsCollection(ksession).contains("Y.File1"));
assertTrue (factsCollection(ksession).contains("Y.File2"));
final ListIterator<TMFile> xIterator = x.getFiles().listIterator(1);
final ListIterator<TMFile> yIterator = y.getFiles().listIterator();
xIterator.next();
xIterator.remove();
yIterator.next();
yIterator.next();
yIterator.next();
yIterator.remove();
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertFalse (factsCollection(ksession).contains("X.File1"));
assertTrue (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertTrue (factsCollection(ksession).contains("Y.File1"));
assertFalse (factsCollection(ksession).contains("Y.File2"));
assertTrue ( xIterator.hasNext() );
assertTrue ( xIterator.hasPrevious() );
assertFalse ( yIterator.hasNext() );
assertTrue ( yIterator.hasPrevious() );
xIterator.next();
xIterator.remove();
yIterator.previous();
yIterator.remove();
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertFalse (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertFalse (factsCollection(ksession).contains("Y.File2"));
assertFalse ( xIterator.hasNext() );
assertTrue ( xIterator.hasPrevious() );
assertFalse ( yIterator.hasNext() );
assertTrue ( yIterator.hasPrevious() );
xIterator.previous();
xIterator.remove();
yIterator.previous();
yIterator.remove();
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.File0"));
assertFalse (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertFalse (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertFalse (factsCollection(ksession).contains("Y.File2"));
assertFalse ( xIterator.hasNext() );
assertFalse ( xIterator.hasPrevious() );
assertFalse ( yIterator.hasNext() );
assertFalse ( yIterator.hasPrevious() );
}
@Test
public void testListIteratorMisc() {
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"\n" +
"rule R2 when\n" +
" TMDirectory( $id: name, $p: /files[size >= 100] )\n" +
"then\n" +
" insertLogical( $id + \".\" + $p.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
ksession.addEventListener(new DefaultRuleRuntimeEventListener() {
@Override
public void objectDeleted(ObjectDeletedEvent event) {
System.out.println(event.getOldObject() + " -> " + "_");
}
@Override
public void objectInserted(ObjectInsertedEvent event) {
System.out.println("_" + " -> " + event.getObject());
}
@Override
public void objectUpdated(ObjectUpdatedEvent event) {
System.out.println(event.getOldObject() + " -> " + event.getObject());
}
});
final TMDirectory x = new TMDirectory("X");
final TMDirectory y = new TMDirectory("Y");
ksession.insert( x );
ksession.insert( y );
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.File0"));
assertFalse (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertFalse (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertFalse (factsCollection(ksession).contains("Y.File2"));
final TMFile file0 = new TMFile("File0", 999);
final TMFile file1 = new TMFile("File1", 999);
final TMFile file2 = new TMFile("File2", 999);
final ListIterator<TMFile> xIterator = x.getFiles().listIterator();
final ListIterator<TMFile> yIterator = y.getFiles().listIterator();
xIterator.add(file0);
yIterator.add(file2);
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertFalse (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertFalse (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertTrue (factsCollection(ksession).contains("Y.File2"));
xIterator.add(file1);
yIterator.previous();
yIterator.add(file1);
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertTrue (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertFalse (factsCollection(ksession).contains("Y.File0"));
assertTrue (factsCollection(ksession).contains("Y.File1"));
assertTrue (factsCollection(ksession).contains("Y.File2"));
xIterator.add(file2);
yIterator.previous();
yIterator.add(file0);
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertTrue (factsCollection(ksession).contains("X.File1"));
assertTrue (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertTrue (factsCollection(ksession).contains("Y.File1"));
assertTrue (factsCollection(ksession).contains("Y.File2"));
System.out.println(x.getFiles());
System.out.println(y.getFiles());
xIterator.previous();
xIterator.set(new TMFile("File2R", 999));
yIterator.previous();
yIterator.set(new TMFile("File0R", 999));
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertTrue (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertFalse (factsCollection(ksession).contains("Y.File0"));
assertTrue (factsCollection(ksession).contains("Y.File1"));
assertTrue (factsCollection(ksession).contains("Y.File2"));
assertTrue (factsCollection(ksession).contains("X.File2R"));
assertTrue (factsCollection(ksession).contains("Y.File0R"));
}
@Test
public void testRemoveIfSupport() {
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"\n" +
"rule R2 when\n" +
" TMDirectory( $id: name, $p: /files[size >= 100] )\n" +
"then\n" +
" insertLogical( $id + \".\" + $p.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
ksession.addEventListener(new DefaultRuleRuntimeEventListener() {
@Override
public void objectDeleted(ObjectDeletedEvent event) {
System.out.println(event.getOldObject() + " -> " + "_");
}
@Override
public void objectInserted(ObjectInsertedEvent event) {
System.out.println("_" + " -> " + event.getObject());
}
@Override
public void objectUpdated(ObjectUpdatedEvent event) {
System.out.println(event.getOldObject() + " -> " + event.getObject());
}
});
final TMDirectory x = new TMDirectory("X");
final TMDirectory y = new TMDirectory("Y");
ksession.insert( x );
ksession.insert( y );
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.File0"));
assertFalse (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertFalse (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertFalse (factsCollection(ksession).contains("Y.File2"));
final TMFile file0 = new TMFile("File0", 1000);
final TMFile file1 = new TMFile("File1", 1001);
final TMFile file2 = new TMFile("File2", 1002);
x.getFiles().addAll(Arrays.asList(file0, file1, file2));
y.getFiles().addAll(Arrays.asList(file0, file1, file2));
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertTrue (factsCollection(ksession).contains("X.File1"));
assertTrue (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertTrue (factsCollection(ksession).contains("Y.File1"));
assertTrue (factsCollection(ksession).contains("Y.File2"));
x.getFiles().removeIf( f -> f.getSize() % 2 == 0 );
y.getFiles().removeIf( f -> f.getSize() % 2 == 1 );
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.File0"));
assertTrue (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertTrue (factsCollection(ksession).contains("Y.File2"));
}
@Test
public void testMiscSetMethods() {
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"\n" +
"rule R2 when\n" +
" TMFileSet( $id: name, $p: /files[size >= 100] )\n" +
"then\n" +
" System.out.println( $id + \".\" + $p.getName() );\n" +
" insertLogical( $id + \".\" + $p.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final TMFileSet x = new TMFileSet("X");
final TMFileSet y = new TMFileSet("Y");
ksession.insert( x );
ksession.insert( y );
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.File0"));
assertFalse (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
final TMFile file0 = new TMFile("File0", 47);
final TMFile file1 = new TMFile("File1", 47);
final TMFile file2 = new TMFile("File2", 47);
x.getFiles().add(file2);
x.getFiles().addAll(Arrays.asList(file0, file1));
y.getFiles().add(file2);
y.getFiles().add(file0);
y.getFiles().add(file1);
ksession.fireAllRules();
assertFalse (factsCollection(ksession).contains("X.File0"));
assertFalse (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertFalse (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertFalse (factsCollection(ksession).contains("Y.File2"));
file0.setSize( 999 );
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertFalse (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertFalse (factsCollection(ksession).contains("Y.File2"));
y.getFiles().remove( file1 ); // removing File1 from Y
file1.setSize( 999 );
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertTrue (factsCollection(ksession).contains("X.File1"));
assertFalse (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertFalse (factsCollection(ksession).contains("Y.File2"));
file2.setSize( 999 );
ksession.fireAllRules();
assertTrue (factsCollection(ksession).contains("X.File0"));
assertTrue (factsCollection(ksession).contains("X.File1"));
assertTrue (factsCollection(ksession).contains("X.File2"));
assertTrue (factsCollection(ksession).contains("Y.File0"));
assertFalse (factsCollection(ksession).contains("Y.File1"));
assertTrue (factsCollection(ksession).contains("Y.File2"));
}
@Test
public void testDeclarationOutsideOOPath() {
// DROOLS-1411
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"global java.util.Set duplicateNames; \n" +
"\n" +
"rule DIFF_FILES_BUT_WITH_SAME_FILENAME when\n" +
" $dir1 : TMFileSet( $ic1 : /files )\n" +
" TMFileSet( this == $dir1, $ic2 : /files[name == $ic1.name], $ic2 != $ic1 )\n" +
"then\n" +
" System.out.println( $dir1 + \".: \" + $ic1 + \" \" + $ic2 );\n" +
" duplicateNames.add( $ic1.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final Set<String> duplicateNames = new HashSet<>();
ksession.setGlobal("duplicateNames", duplicateNames);
final TMFileSet x = new TMFileSet("X");
final TMFile file0 = new TMFile("File0", 47);
final TMFile file1 = new TMFile("File1", 47);
final TMFile file2 = new TMFile("File0", 47);
x.getFiles().addAll(Arrays.asList(file0, file1, file2));
ksession.insert(x);
ksession.fireAllRules();
assertTrue( duplicateNames.contains("File0") );
assertFalse( duplicateNames.contains("File1") );
}
@Test
public void testDereferencedDeclarationOutsideOOPath() {
// DROOLS-1411
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"global java.util.Set duplicateNames; \n" +
"\n" +
"rule DIFF_FILES_BUT_WITH_SAME_FILENAME when\n" +
" $dir1 : TMFileSet( $ic1 : /files )\n" +
" TMFileSet( this == $dir1, $ic2 : /files[this != $ic1], $ic2.name == $ic1.name )\n" +
"then\n" +
" System.out.println( $dir1 + \".: \" + $ic1 + \" \" + $ic2 );\n" +
" duplicateNames.add( $ic1.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final Set<String> duplicateNames = new HashSet<>();
ksession.setGlobal("duplicateNames", duplicateNames);
final TMFileSet x = new TMFileSet("X");
final TMFile file0 = new TMFile("File0", 47);
final TMFile file1 = new TMFile("File1", 47);
final TMFile file2 = new TMFile("File0", 47);
x.getFiles().addAll(Arrays.asList(file0, file1, file2));
ksession.insert(x);
ksession.fireAllRules();
assertTrue( duplicateNames.contains("File0") );
assertFalse( duplicateNames.contains("File1") );
}
@Test
public void testDeclarationInsideOOPath() {
// DROOLS-1411
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"global java.util.Set duplicateNames; \n" +
"\n" +
"rule DIFF_FILES_BUT_WITH_SAME_FILENAME when\n" +
" $dir1 : TMFileSet( $ic1 : /files )\n" +
" TMFileSet( this == $dir1, $ic2 : /files[name == $ic1.name, this != $ic1] )\n" +
"then\n" +
" System.out.println( $dir1 + \".: \" + $ic1 + \" \" + $ic2 );\n" +
" duplicateNames.add( $ic1.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final Set<String> duplicateNames = new HashSet<>();
ksession.setGlobal("duplicateNames", duplicateNames);
final TMFileSet x = new TMFileSet("X");
final TMFile file0 = new TMFile("File0", 47);
final TMFile file1 = new TMFile("File1", 47);
final TMFile file2 = new TMFile("File0", 47);
x.getFiles().addAll(Arrays.asList(file0, file1, file2));
ksession.insert(x);
ksession.fireAllRules();
assertTrue( duplicateNames.contains("File0") );
assertFalse( duplicateNames.contains("File1") );
}
@Test
public void testCompileErrorOnDoubleOOPathInPattern() {
// DROOLS-1411
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"global java.util.Set duplicateNames; \n" +
"\n" +
"rule DIFF_FILES_BUT_WITH_SAME_FILENAME when\n" +
" $dir1 : TMFileSet( $ic1 : /files, /files[name == $ic1.name, this != $ic1] )\n" +
"then\n" +
" duplicateNames.add( $ic1.getName() );\n" +
"end\n";
assertDrlHasCompilationError( drl, 1 );
}
@Test
public void testOOPathWithLocalDeclaration() {
// DROOLS-1411
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"global java.util.Set duplicateNames; \n" +
"\n" +
"rule DIFF_FILES_BUT_WITH_SAME_FILENAME when\n" +
" $ic1 : TMFileWithParentObj( $curName : name,\n" +
" $ic2: /parent#TMFileSet/files[name == $curName, this != $ic1 ] )\n" +
"then\n" +
" System.out.println( $ic1 + \" \" + $ic2 );\n" +
" duplicateNames.add( $ic1.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final Set<String> duplicateNames = new HashSet<>();
ksession.setGlobal("duplicateNames", duplicateNames);
final TMFileSet x = new TMFileSet("X");
final TMFileWithParentObj file0 = new TMFileWithParentObj(0, "File0", 47, x);
final TMFileWithParentObj file1 = new TMFileWithParentObj(1, "File1", 47, x);
final TMFileWithParentObj file2 = new TMFileWithParentObj(2, "File0", 47, x);
x.getFiles().addAll(Arrays.asList(file0, file1, file2));
ksession.insert( x );
ksession.insert( file0 );
ksession.insert( file1 );
ksession.insert( file2 );
ksession.fireAllRules();
assertTrue( duplicateNames.contains("File0") );
assertFalse( duplicateNames.contains("File1") );
}
public static class TMFileSetQuater extends AbstractReactiveObject {
private final String name;
private final Set<TMFileWithParentObj> members = new ReactiveSet<>();
public TMFileSetQuater(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Set<TMFileWithParentObj> getFiles() {
return members;
}
}
@Test
public void testOOPathWithLocalInnerDeclaration() {
// DROOLS-1411
final String drl =
"import org.drools.compiler.oopath.model.*;\n" +
"import "+TMFileSetQuater.class.getCanonicalName()+";\n" +
"global java.util.Set duplicateNames; \n" +
"\n" +
"rule DIFF_FILES_BUT_WITH_SAME_FILENAME when\n" +
" $ic1 : TMFileWithParentObj( $curName : name, $curId : id, \n" +
" $ic2: /parent#TMFileSetQuater/files[name == $curName, id != $curId ] )\n" +
"then\n" +
" System.out.println( $ic1 + \" \" + $ic2 );\n" +
" duplicateNames.add( $ic1.getName() );\n" +
"end\n";
final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
final Set duplicateNames = new HashSet();
ksession.setGlobal("duplicateNames", duplicateNames);
final TMFileSetQuater x = new TMFileSetQuater("X");
final TMFileWithParentObj file0 = new TMFileWithParentObj(0, "File0", 47, x);
final TMFileWithParentObj file1 = new TMFileWithParentObj(1, "File1", 47, x);
final TMFileWithParentObj file2 = new TMFileWithParentObj(2, "File0", 47, x);
x.getFiles().addAll(Arrays.asList(file0, file1, file2));
ksession.insert( x );
ksession.insert( file0 );
ksession.insert( file1 );
ksession.insert( file2 );
ksession.fireAllRules();
assertTrue( duplicateNames.contains("File0") );
assertFalse( duplicateNames.contains("File1") );
}
private List<?> factsCollection(KieSession ksession) {
final List<Object> res = new ArrayList<>();
res.addAll(ksession.getObjects());
return res;
}
}