[jboss-svn-commits] JBL Code SVN: r34114 - in labs/jbossrules/trunk/drools-compiler/src: main/java/org/drools/rule/builder/dialect/java and 3 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Jul 22 12:47:00 EDT 2010


Author: tirelli
Date: 2010-07-22 12:46:59 -0400 (Thu, 22 Jul 2010)
New Revision: 34114

Added:
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_NonExistingAccumulateFunction.drl
Modified:
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/DescrBuildError.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/RuleBuildError.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/java/JavaAccumulateBuilder.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/mvel/MVELAccumulateBuilder.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/AccumulateTest.java
Log:
JBRULES-2419: Raising proper error message when trying to compile a source file that uses an unknown accumulate function

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/DescrBuildError.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/DescrBuildError.java	2010-07-22 15:52:25 UTC (rev 34113)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/DescrBuildError.java	2010-07-22 16:46:59 UTC (rev 34114)
@@ -20,16 +20,16 @@
 import org.drools.lang.descr.BaseDescr;
 
 public class DescrBuildError extends DroolsError {
-    private BaseDescr      parentDescr;
+    private BaseDescr parentDescr;
     private BaseDescr descr;
     private Object    object;
     private String    message;
     private int[]     errorLines = new int[0];
 
     public DescrBuildError(final BaseDescr parentDescr,
-                     final BaseDescr descr,
-                     final Object object,
-                     final String message) {
+                           final BaseDescr descr,
+                           final Object object,
+                           final String message) {
         super();
         this.parentDescr = parentDescr;
         this.descr = descr;
@@ -48,7 +48,7 @@
     public Object getObject() {
         return this.object;
     }
-    
+
     public int[] getErrorLines() {
         return this.errorLines;
     }
@@ -66,7 +66,7 @@
         if ( this.object instanceof CompilationProblem[] ) {
             final CompilationProblem[] problem = (CompilationProblem[]) this.object;
             for ( int i = 0; i < problem.length; i++ ) {
-                if (i != 0) {
+                if ( i != 0 ) {
                     summary = summary + "\n" + problem[i].getMessage();
                 } else {
                     summary = summary + " " + problem[i].getMessage();
@@ -96,29 +96,28 @@
         return buf.toString();
     }
 
-//    private String createMessage( String message ) {
-//        StringBuilder detail = new StringBuilder();
-//        detail.append( this.message );
-//        detail.append( " : " );
-//        detail.append( this.rule );
-//        detail.append( "\n" );
-//        if( object instanceof CompilationProblem[] ) {
-//            CompilationProblem[] cp = (CompilationProblem[]) object;
-//            this.errorLines = new int[cp.length];
-//            for( int i = 0; i < cp.length ; i ++ ) {
-//               this.errorLines[i] = cp[i].getStartLine() - this.descr.getOffset() + this.descr.getLine() - 1; 
-//               detail.append( this.rule.getName() );
-//               detail.append( " (line:" );
-//               detail.append( this.errorLines[i] );
-//               detail.append( "): " );
-//               detail.append( cp[i].getMessage() );
-//               detail.append( "\n" );
-//            }
-//        } else {
-//            this.errorLines = new int[0];
-//        }
-//        return "[ "+this.rule.getName()+" : "+message + "\n"+detail.toString()+" ]";
-//    }
-    
-    
+    //    private String createMessage( String message ) {
+    //        StringBuilder detail = new StringBuilder();
+    //        detail.append( this.message );
+    //        detail.append( " : " );
+    //        detail.append( this.rule );
+    //        detail.append( "\n" );
+    //        if( object instanceof CompilationProblem[] ) {
+    //            CompilationProblem[] cp = (CompilationProblem[]) object;
+    //            this.errorLines = new int[cp.length];
+    //            for( int i = 0; i < cp.length ; i ++ ) {
+    //               this.errorLines[i] = cp[i].getStartLine() - this.descr.getOffset() + this.descr.getLine() - 1; 
+    //               detail.append( this.rule.getName() );
+    //               detail.append( " (line:" );
+    //               detail.append( this.errorLines[i] );
+    //               detail.append( "): " );
+    //               detail.append( cp[i].getMessage() );
+    //               detail.append( "\n" );
+    //            }
+    //        } else {
+    //            this.errorLines = new int[0];
+    //        }
+    //        return "[ "+this.rule.getName()+" : "+message + "\n"+detail.toString()+" ]";
+    //    }
+
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/RuleBuildError.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/RuleBuildError.java	2010-07-22 15:52:25 UTC (rev 34113)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/RuleBuildError.java	2010-07-22 16:46:59 UTC (rev 34114)
@@ -1,21 +1,22 @@
 package org.drools.compiler;
 
-import java.io.Serializable;
-
 import org.drools.lang.descr.BaseDescr;
 import org.drools.rule.Rule;
 
-public class RuleBuildError extends DescrBuildError  {
+public class RuleBuildError extends DescrBuildError {
     private final Rule rule;
-    
+
     public RuleBuildError(final Rule rule,
-                           final BaseDescr descr,
-                           final Object object,
-                           final String message) {
-              super(descr, descr, object, message);
-              this.rule = rule;
-          }
-    
+                          final BaseDescr descr,
+                          final Object object,
+                          final String message) {
+        super( descr,
+               descr,
+               object,
+               message );
+        this.rule = rule;
+    }
+
     public Rule getRule() {
         return this.rule;
     }

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/java/JavaAccumulateBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/java/JavaAccumulateBuilder.java	2010-07-22 15:52:25 UTC (rev 34113)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/java/JavaAccumulateBuilder.java	2010-07-22 16:46:59 UTC (rev 34114)
@@ -26,6 +26,7 @@
 import java.util.TreeSet;
 
 import org.drools.base.accumulators.JavaAccumulatorFunctionExecutor;
+import org.drools.compiler.DescrBuildError;
 import org.drools.compiler.Dialect;
 import org.drools.lang.descr.AccumulateDescr;
 import org.drools.lang.descr.BaseDescr;
@@ -55,6 +56,7 @@
                       null );
     }
 
+    @SuppressWarnings("unchecked")
     public RuleConditionElement build(final RuleBuildContext context,
                                       final BaseDescr descr,
                                       final Pattern prefixPattern) {
@@ -78,7 +80,16 @@
 
         if ( accumDescr.isExternalFunction() ) {
             // if it is an external function, build a method for it
+            AccumulateFunction function = context.getConfiguration().getAccumulateFunction( accumDescr.getFunctionIdentifier() );
 
+            if( function == null ) {
+                context.getErrors().add( new DescrBuildError( accumDescr,
+                                                              context.getRuleDescr(),
+                                                              null,
+                                                              "Unknown accumulate function: '"+accumDescr.getFunctionIdentifier()+"' on rule '"+context.getRuleDescr().getName()+"'. All accumulate functions must be registered before building a resource." ) );
+                return null;
+            }
+
             final JavaAnalysisResult analysis = (JavaAnalysisResult) context.getDialect().analyzeBlock( context,
                                                                                                         accumDescr,
                                                                                                         accumDescr.getExpression(),
@@ -107,10 +118,8 @@
             map.put( "readLocalsFromTuple",
                      accumDescr.isMultiPattern() ? Boolean.TRUE : Boolean.FALSE );
 
-            AccumulateFunction function = context.getConfiguration().getAccumulateFunction( accumDescr.getFunctionIdentifier() );
-
             JavaAccumulatorFunctionExecutor accumulator = new JavaAccumulatorFunctionExecutor( function );
-
+            
             accumulate = new Accumulate( source,
                                          previousDeclarations,
                                          sourceDeclArr,
@@ -239,19 +248,18 @@
         return accumulate;
     }
 
+    @SuppressWarnings("unchecked")
     protected String fixInitCode(JavaAnalysisResult analysis,
                                  final String originalCode) {
-        TreeSet locals = new TreeSet( new Comparator() {
-            public int compare(Object o1,
-                               Object o2) {
-                JavaLocalDeclarationDescr d1 = (JavaLocalDeclarationDescr) o1;
-                JavaLocalDeclarationDescr d2 = (JavaLocalDeclarationDescr) o2;
-                return d1.getStart() - d2.getStart();
+        TreeSet<JavaLocalDeclarationDescr> locals = new TreeSet<JavaLocalDeclarationDescr>( new Comparator<JavaLocalDeclarationDescr>() {
+            public int compare(JavaLocalDeclarationDescr o1,
+                               JavaLocalDeclarationDescr o2) {
+                return o1.getStart() - o2.getStart();
             }
         } );
 
         for ( Iterator it = analysis.getLocalVariablesMap().values().iterator(); it.hasNext(); ) {
-            locals.add( it.next() );
+            locals.add( (JavaLocalDeclarationDescr) it.next() );
         }
 
         StringBuilder initCode = new StringBuilder();

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/mvel/MVELAccumulateBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/mvel/MVELAccumulateBuilder.java	2010-07-22 15:52:25 UTC (rev 34113)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/mvel/MVELAccumulateBuilder.java	2010-07-22 16:46:59 UTC (rev 34114)
@@ -16,7 +16,6 @@
 
 package org.drools.rule.builder.dialect.mvel;
 
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
@@ -56,6 +55,7 @@
                       null );
     }
 
+    @SuppressWarnings("unchecked")
     public RuleConditionElement build(final RuleBuildContext context,
                                       final BaseDescr descr,
                                       final Pattern prefixPattern) {
@@ -87,6 +87,16 @@
 
             if ( accumDescr.isExternalFunction() ) {
                 // build an external function executor
+                AccumulateFunction function = context.getConfiguration().getAccumulateFunction( accumDescr.getFunctionIdentifier() );
+
+                if( function == null ) {
+                    context.getErrors().add( new DescrBuildError( accumDescr,
+                                                                  context.getRuleDescr(),
+                                                                  null,
+                                                                  "Unknown accumulate function: '"+accumDescr.getFunctionIdentifier()+"' on rule '"+context.getRuleDescr().getName()+"'. All accumulate functions must be registered before building a resource." ) );
+                    return null;
+                }
+
                 Map<String, Class< ? >> declarationsMap = context.getDeclarationResolver().getDeclarationClasses( context.getRule() );
                 final Dialect.AnalysisResult analysis = dialect.analyzeExpression( context,
                                                                                    accumDescr,
@@ -100,8 +110,6 @@
                                                                            null,
                                                                            context );
 
-                AccumulateFunction function = context.getConfiguration().getAccumulateFunction( accumDescr.getFunctionIdentifier() );
-
                 accumulator = new MVELAccumulatorFunctionExecutor( unit,
                                                                    function );
             } else {

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/AccumulateTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/AccumulateTest.java	2010-07-22 15:52:25 UTC (rev 34113)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/AccumulateTest.java	2010-07-22 16:46:59 UTC (rev 34114)
@@ -14,6 +14,8 @@
 import org.drools.Cheese;
 import org.drools.Cheesery;
 import org.drools.FactHandle;
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseFactory;
 import org.drools.Order;
 import org.drools.OrderItem;
 import org.drools.OuterClass;
@@ -24,10 +26,15 @@
 import org.drools.RuntimeDroolsException;
 import org.drools.StatefulSession;
 import org.drools.WorkingMemory;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderConfiguration;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.builder.ResourceType;
 import org.drools.compiler.DrlParser;
 import org.drools.compiler.DroolsParserException;
 import org.drools.compiler.PackageBuilder;
 import org.drools.compiler.PackageBuilderConfiguration;
+import org.drools.io.ResourceFactory;
 import org.drools.lang.descr.PackageDescr;
 import org.drools.rule.Package;
 import org.drools.rule.builder.dialect.java.JavaDialectConfiguration;
@@ -80,6 +87,23 @@
         return ruleBase;
     }
 
+    public KnowledgeBase loadKnowledgeBase(final String resource,
+                                           final KnowledgeBuilderConfiguration kbconf) {
+        final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder( kbconf );
+        kbuilder.add( ResourceFactory.newClassPathResource( resource,
+                                                            getClass() ),
+                      ResourceType.DRL );
+        if ( kbuilder.hasErrors() ) {
+            fail( kbuilder.getErrors().toString() );
+        }
+
+        final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+
+        return kbase;
+
+    }
+
     public void testAccumulateModify() throws Exception {
         // read in the source
         final Reader reader = new InputStreamReader( getClass().getResourceAsStream( "test_AccumulateModify.drl" ) );
@@ -616,7 +640,7 @@
         wm.update( cheeseryHandle,
                    cheesery );
         wm.fireAllRules();
-        
+
         // no fire
         Assert.assertEquals( 1,
                              results.size() );
@@ -1518,6 +1542,20 @@
                       results.get( 0 ) );
     }
 
+    public void testAccumulateNonExistingFunction() throws Exception {
+        final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+
+        kbuilder.add( ResourceFactory.newClassPathResource( "test_NonExistingAccumulateFunction.drl",
+                                                            getClass() ),
+                      ResourceType.DRL );
+
+        // should report a proper error, not raise an exception
+        assertTrue( "It must report a proper error when trying to use a non-registered funcion",
+                    kbuilder.hasErrors() );
+        assertEquals( 2,
+                      kbuilder.getErrors().size() );
+    }
+
     public static class DataSet {
         public Cheese[]     cheese;
         public FactHandle[] cheeseHandles;

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_NonExistingAccumulateFunction.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_NonExistingAccumulateFunction.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_NonExistingAccumulateFunction.drl	2010-07-22 16:46:59 UTC (rev 34114)
@@ -0,0 +1,19 @@
+package org.drools;
+
+rule "Accumulate non existing function - Java"
+    dialect "java"
+    when
+    	$val : Number() from accumulate( $st : StockTick(),
+                                         nonExistingFunction( 1 ) );
+    then
+        // no-op
+end  
+
+rule "Accumulate non existing function - MVEL"
+    dialect "mvel"
+    when
+    	$val : Number() from accumulate( $st : StockTick(),
+                                         nonExistingFunction( 1 ) );
+    then
+        // no-op
+end  



More information about the jboss-svn-commits mailing list