package org.drools.rule.builder.dialect.java; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import junit.framework.TestCase; import org.antlr.runtime.RecognitionException; import org.drools.Cheese; import org.drools.base.ClassObjectType; import org.drools.compiler.DialectCompiletimeRegistry; import org.drools.compiler.PackageBuilder; import org.drools.compiler.PackageBuilderConfiguration; import org.drools.compiler.PackageRegistry; import org.drools.lang.descr.RuleDescr; import org.drools.rule.ImportDeclaration; import org.drools.rule.Package; import org.drools.rule.Pattern; import org.drools.rule.Rule; import org.drools.rule.builder.RuleBuildContext; import org.drools.spi.CompiledInvoker; import org.drools.spi.Consequence; public class JavaConsequenceBuilderTest extends TestCase { private JavaConsequenceBuilder builder; private RuleBuildContext context; private RuleDescr ruleDescr; protected void setUp() throws Exception { super.setUp(); } protected void tearDown() throws Exception { super.tearDown(); } private void setupTest(String consequence, Map<String, Object> namedConsequences) { builder = new JavaConsequenceBuilder(); Package pkg = new Package( "org.drools" ); pkg.addImport( new ImportDeclaration( "org.drools.Cheese" ) ); PackageBuilderConfiguration conf = new PackageBuilderConfiguration(); PackageBuilder pkgBuilder = new PackageBuilder( pkg, conf ); ruleDescr = new RuleDescr( "test consequence builder" ); ruleDescr.setConsequence( consequence ); for ( Entry<String, Object> entry : namedConsequences.entrySet() ) { ruleDescr.getNamedConsequences().put( entry.getKey(), entry.getValue() ); } Rule rule = new Rule( ruleDescr.getName() ); rule.addPattern( new Pattern( 0, new ClassObjectType( Cheese.class ), "$cheese" ) ); PackageRegistry pkgRegistry = pkgBuilder.getPackageRegistry( pkg.getName() ); DialectCompiletimeRegistry reg = pkgBuilder.getPackageRegistry( pkg.getName() ).getDialectCompiletimeRegistry(); context = new RuleBuildContext( pkgBuilder, ruleDescr, reg, pkg, reg.getDialect( pkgRegistry.getDialect() ) ); context.getBuildStack().push( rule.getLhs() ); context.getDialect().getConsequenceBuilder().build( context, "default" ); for ( String name : namedConsequences.keySet() ) { context.getDialect().getConsequenceBuilder().build( context, name ); } context.getDialect().addRule( context ); pkgRegistry.getPackage().addRule( context.getRule() ); pkgBuilder.compileAll(); pkgBuilder.reloadAll(); } public void testFixExitPointsReferences() { String consequence = " System.out.println(\"this is a test\");\n " + " exitPoints[\"foo\"].insert( new Cheese() );\n " + " System.out.println(\"we are done with exitPoints\");\n "; setupTest( consequence, new HashMap<String, Object>() ); try { JavaExprAnalyzer analyzer = new JavaExprAnalyzer(); JavaAnalysisResult analysis = (JavaAnalysisResult) analyzer.analyzeBlock( (String) ruleDescr.getConsequence(), new Map[]{} ); String fixed = builder.fixBlockDescr( context, analysis, (String) ruleDescr.getConsequence() ); String expected = " System.out.println(\"this is a test\");\n " + " drools.getExitPoint(\"foo\").insert( new Cheese() );\n " + " System.out.println(\"we are done with exitPoints\");\n "; // System.out.println( "=============================" ); // System.out.println( ruleDescr.getConsequence() ); // System.out.println( "=============================" ); // System.out.println( fixed ); assertNotNull( context.getErrors().toString(), fixed ); assertEqualsIgnoreSpaces( expected, fixed ); } catch ( RecognitionException e ) { e.printStackTrace(); } } public void testFixEntryPointsReferences() { String consequence = " System.out.println(\"this is a test\");\n " + " entryPoints[\"foo\"].insert( new Cheese() );\n " + " System.out.println(\"we are done with entryPoints\");\n "; setupTest( consequence, new HashMap<String, Object>() ); try { JavaExprAnalyzer analyzer = new JavaExprAnalyzer(); JavaAnalysisResult analysis = (JavaAnalysisResult) analyzer.analyzeBlock( (String) ruleDescr.getConsequence(), new Map[]{} ); String fixed = builder.fixBlockDescr( context, analysis, (String) ruleDescr.getConsequence() ); String expected = " System.out.println(\"this is a test\");\n " + " drools.getEntryPoint(\"foo\").insert( new Cheese() );\n " + " System.out.println(\"we are done with entryPoints\");\n "; // System.out.println( "=============================" ); // System.out.println( ruleDescr.getConsequence() ); // System.out.println( "=============================" ); // System.out.println( fixed ); assertNotNull( context.getErrors().toString(), fixed ); assertEqualsIgnoreSpaces( expected, fixed ); } catch ( RecognitionException e ) { e.printStackTrace(); } } public void testFixModifyBlocks() { String consequence = " System.out.println(\"this is a test\");\n " + " modify( $cheese ) { setPrice( 10 ), setAge( age ) }\n " + " System.out.println(\"we are done\");\n "; setupTest( consequence, new HashMap<String, Object>() ); try { JavaExprAnalyzer analyzer = new JavaExprAnalyzer(); JavaAnalysisResult analysis = (JavaAnalysisResult) analyzer.analyzeBlock( (String) ruleDescr.getConsequence(), new Map[]{} ); String fixed = builder.fixBlockDescr( context, analysis, (String) ruleDescr.getConsequence() ); String expected = " System.out.println(\"this is a test\");\n" + "{ org.drools.Cheese __obj__ = (org.drools.Cheese) ( $cheese );\n" + "__obj__.setPrice( 10 );\n" + "__obj__.setAge( age );\n" + "update( __obj__ );}\n" + "System.out.println(\"we are done\");\n"; assertNotNull( context.getErrors().toString(), fixed ); assertEqualsIgnoreSpaces( expected, fixed ); // System.out.println( "=============================" ); // System.out.println( ruleDescr.getConsequence() ); // System.out.println( "=============================" ); // System.out.println( fixed ); } catch ( RecognitionException e ) { e.printStackTrace(); } } public void testFixInsertCalls() { String consequence = " System.out.println(\"this is a test\");\n " + " insert( $cheese );\n " + " if( true ) { \n " + " insert($another); \n" + " } else { \n"+ " retract($oneMore); \n" + " } \n" + " // just in case, one more call: \n" + " insert( $abc );\n" ; setupTest( consequence, new HashMap<String, Object>() ); try { JavaExprAnalyzer analyzer = new JavaExprAnalyzer(); JavaAnalysisResult analysis = (JavaAnalysisResult) analyzer.analyzeBlock( (String) ruleDescr.getConsequence(), new Map[]{} ); String fixed = builder.fixBlockDescr( context, analysis, (String) ruleDescr.getConsequence() ); fixed = new KnowledgeHelperFixer().fix( fixed ); String expected = " System.out.println(\"this is a test\");\n " + " drools.insert( $cheese );\n " + " if( true ) { \n " + " drools.insert($another); \n" + " } else { \n"+ " drools.retract($oneMore); \n" + " } \n" + " // just in case, one more call: \n" + " drools.insert( $abc );\n" ; // System.out.println( "=============================" ); // System.out.println( ruleDescr.getConsequence() ); // System.out.println( "=============================" ); // System.out.println( fixed ); assertNotNull( context.getErrors().toString(), fixed ); assertEqualsIgnoreSpaces( expected, fixed ); } catch ( RecognitionException e ) { e.printStackTrace(); } } public void testDefaultConsequenceCompilation() { String consequence = " System.out.println(\"this is a test\");\n "; setupTest( consequence, new HashMap<String, Object>() ); assertNotNull( context.getRule().getConsequence() ); assertTrue( context.getRule().getNamedConsequences().isEmpty() ); assertTrue( context.getRule().getConsequence() instanceof CompiledInvoker ); assertTrue( context.getRule().getConsequence() instanceof Consequence ); } public void testDefaultConsequenceWithSingleNamedConsequenceCompilation() { String defaultCon = " System.out.println(\"this is a test\");\n "; Map<String, Object> namedConsequences = new HashMap<String, Object>(); String name1 = " System.out.println(\"this is a test name1\");\n "; namedConsequences.put( "name1", name1 ); setupTest( defaultCon, namedConsequences); assertEquals( 1, context.getRule().getNamedConsequences().size() ); assertTrue( context.getRule().getConsequence() instanceof CompiledInvoker ); assertTrue( context.getRule().getConsequence() instanceof Consequence ); assertTrue( context.getRule().getNamedConsequences().get( "name1" ) instanceof CompiledInvoker ); assertTrue( context.getRule().getNamedConsequences().get( "name1" ) instanceof Consequence ); assertNotSame( context.getRule().getConsequence(), context.getRule().getNamedConsequences().get( "name1" ) ); } public void testDefaultConsequenceWithMultipleNamedConsequenceCompilation() { String defaultCon = " System.out.println(\"this is a test\");\n "; Map<String, Object> namedConsequences = new HashMap<String, Object>(); String name1 = " System.out.println(\"this is a test name1\");\n "; namedConsequences.put( "name1", name1 ); String name2 = " System.out.println(\"this is a test name2\");\n "; namedConsequences.put( "name2", name2 ); setupTest( defaultCon, namedConsequences); assertEquals( 2, context.getRule().getNamedConsequences().size() ); assertTrue( context.getRule().getConsequence() instanceof CompiledInvoker ); assertTrue( context.getRule().getConsequence() instanceof Consequence ); assertTrue( context.getRule().getNamedConsequences().get( "name1" ) instanceof CompiledInvoker ); assertTrue( context.getRule().getNamedConsequences().get( "name1" ) instanceof Consequence ); assertTrue( context.getRule().getNamedConsequences().get( "name2" ) instanceof CompiledInvoker ); assertTrue( context.getRule().getNamedConsequences().get( "name2" ) instanceof Consequence ); assertNotSame( context.getRule().getConsequence(), context.getRule().getNamedConsequences().get( "name1" ) ); assertNotSame( context.getRule().getConsequence(), context.getRule().getNamedConsequences().get( "name2" ) ); assertNotSame( context.getRule().getNamedConsequences().get( "name1"), context.getRule().getNamedConsequences().get( "name2" ) ); } private void assertEqualsIgnoreSpaces(String expected, String fixed) { assertEquals( expected.replaceAll( "\\s+", "" ), fixed.replaceAll( "\\s+", "" ) ); } }