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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Aug 22 15:24:58 EDT 2007


Author: tirelli
Date: 2007-08-22 15:24:58 -0400 (Wed, 22 Aug 2007)
New Revision: 14452

Added:
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AutoVivificationVR.drl
Modified:
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/LiteralRestrictionDescr.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/QualifiedIdentifierRestrictionDescr.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/RestrictionConnectiveDescr.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/ReturnValueRestrictionDescr.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/VariableRestrictionDescr.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Cheese.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
Log:
JBRULES-1065: implementing support for autovivification in variable restrictions

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/LiteralRestrictionDescr.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/LiteralRestrictionDescr.java	2007-08-22 17:49:27 UTC (rev 14451)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/LiteralRestrictionDescr.java	2007-08-22 19:24:58 UTC (rev 14452)
@@ -44,6 +44,7 @@
     }
 
     public String toString() {
-        return this.evaluator + " " + this.text;
+        return "[LiteralRestriction: " + this.evaluator + " " + this.text + "]";
+
     }
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/QualifiedIdentifierRestrictionDescr.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/QualifiedIdentifierRestrictionDescr.java	2007-08-22 17:49:27 UTC (rev 14451)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/QualifiedIdentifierRestrictionDescr.java	2007-08-22 19:24:58 UTC (rev 14452)
@@ -49,6 +49,6 @@
     }
 
     public String toString() {
-        return this.evaluator + " " + this.text;
+        return "[QualifiedIndentifierRestr: " + this.evaluator + " " + this.text + " ]";
     }
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/RestrictionConnectiveDescr.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/RestrictionConnectiveDescr.java	2007-08-22 17:49:27 UTC (rev 14451)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/RestrictionConnectiveDescr.java	2007-08-22 19:24:58 UTC (rev 14452)
@@ -2,6 +2,7 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -51,4 +52,18 @@
     public List getRestrictions() {
         return this.restrictions;
     }
+    
+    public String toString() {
+        final String connectiveStr = this.connective == OR ? " || " : " && ";
+        final StringBuffer buf = new StringBuffer();
+        buf.append( "( " );
+        for( Iterator it = this.restrictions.iterator(); it.hasNext(); ) {
+            buf.append( it.next().toString() );
+            if( it.hasNext() ) {
+                buf.append( connectiveStr );
+            }
+        }
+        buf.append( "  )" );
+        return buf.toString();
+    }
 }

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/ReturnValueRestrictionDescr.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/ReturnValueRestrictionDescr.java	2007-08-22 17:49:27 UTC (rev 14451)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/ReturnValueRestrictionDescr.java	2007-08-22 19:24:58 UTC (rev 14452)
@@ -66,6 +66,6 @@
     }
 
     public String toString() {
-        return "[ReturnValue: evaluator=" + this.evaluator + "; text=" + this.content + "]";
+        return "[ReturnValue: " + this.evaluator + " " + this.content + "]";
     }
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/VariableRestrictionDescr.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/VariableRestrictionDescr.java	2007-08-22 17:49:27 UTC (rev 14451)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/VariableRestrictionDescr.java	2007-08-22 19:24:58 UTC (rev 14452)
@@ -37,4 +37,8 @@
     public String getIdentifier() {
         return this.declarationIdentifier;
     }
+    
+    public String toString() {
+        return "[VariableRestriction: " + evaluator + " " + declarationIdentifier + " ]";
+    }
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java	2007-08-22 17:49:27 UTC (rev 14451)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java	2007-08-22 19:24:58 UTC (rev 14452)
@@ -78,7 +78,7 @@
 public class PatternBuilder
     implements
     RuleConditionBuilder {
-    
+
     public PatternBuilder() {
     }
 
@@ -247,7 +247,7 @@
         if ( fieldName.indexOf( '.' ) > -1 ) {
             // we have a composite field name
             String[] identifiers = fieldName.split( "\\." );
-            if ( identifiers.length == 2 && pattern.getDeclaration() != null && identifiers[0].equals( pattern.getDeclaration().getIdentifier() ) ) {
+            if ( identifiers.length == 2 && ((pattern.getDeclaration() != null && identifiers[0].equals( pattern.getDeclaration().getIdentifier() )) || ("this".equals( identifiers[0] ))) ) {
                 // we have a self reference, so, it is fine to do direct access
                 fieldName = identifiers[1];
             } else {
@@ -266,10 +266,24 @@
                                                             fieldConstraintDescr,
                                                             pattern.getObjectType(),
                                                             fieldName,
-                                                            true );
+                                                            false );
         if ( extractor == null ) {
-            // @todo log error
-            return;
+            if( fieldConstraintDescr.getFieldName().startsWith( "this." ) ) {
+                // it may still be MVEL special syntax, like map key syntax, so try eval
+                rewriteToEval( context,
+                               pattern,
+                               fieldConstraintDescr,
+                               container );
+
+                // after building the predicate, we are done, so return
+                return;
+            } else {
+                context.getErrors().add( new RuleError( context.getRule(),
+                                                        fieldConstraintDescr,
+                                                        null,
+                                                        "Unable to create Field Extractor for '" + fieldName + "' of '"+pattern.getObjectType().toString()+"' in rule '"+context.getRule().getName()+"'" ) );
+                return;
+            }
         }
 
         Restriction restriction = createRestriction( context,
@@ -279,7 +293,7 @@
                                                      extractor );
 
         if ( restriction == null ) {
-            // @todo log error
+            // error was already logged during restriction creation failure
             return;
         }
 
@@ -315,10 +329,10 @@
         // it is a complex expression, so we need to turn it into an MVEL predicate
         Dialect dialect = context.getDialect();
         // switch to MVEL dialect
-        MVELDialect mvelDialect = ( MVELDialect ) context.getDialect( "mvel" );
+        MVELDialect mvelDialect = (MVELDialect) context.getDialect( "mvel" );
         boolean strictMode = mvelDialect.isStrictMode();
         mvelDialect.setStrictMode( false );
-        
+
         context.setDialect( mvelDialect );
 
         PredicateDescr predicateDescr = new PredicateDescr();
@@ -354,11 +368,18 @@
                                                                 extractor );
 
             } else {
-                restrictions[index++] = buildRestriction( context,
+                restrictions[index] = buildRestriction( context,
                                                           pattern,
                                                           extractor,
                                                           fieldConstraintDescr,
                                                           restrictionDescr );
+                if( restrictions[index] == null ) {
+                    context.getErrors().add( new RuleError( context.getRule(),
+                                                            fieldConstraintDescr,
+                                                            null,
+                                                            "Unable to create restriction '" + restrictionDescr.toString() + "' for field '"+ fieldConstraintDescr.getFieldName() +"' in the rule '" + context.getRule().getName() + "'" ) );
+                }
+                index++;
             }
         }
 
@@ -566,19 +587,23 @@
             return null;
         }
 
-        final Declaration declaration = context.getDeclarationResolver().getDeclaration( variableRestrictionDescr.getIdentifier() );
+        Declaration declaration = context.getDeclarationResolver().getDeclaration( variableRestrictionDescr.getIdentifier() );
 
-        //        if ( declaration == null ) {
-        //            build( context, th)
-        //            // lazily create teh declaration
-        //        }        
-
         if ( declaration == null ) {
-            context.getErrors().add( new RuleError( context.getRule(),
-                                                    variableRestrictionDescr,
-                                                    null,
-                                                    "Unable to return Declaration for identifier '" + variableRestrictionDescr.getIdentifier() + "'" ) );
-            return null;
+            // trying to create implicit declaration
+            final Pattern thisPattern = (Pattern) context.getBuildStack().peek();
+            final Declaration implicit = this.createDeclarationObject( context,
+                                                                       variableRestrictionDescr.getIdentifier(),
+                                                                       thisPattern );
+            if ( implicit != null ) {
+                declaration = implicit;
+            } else {
+                context.getErrors().add( new RuleError( context.getRule(),
+                                                        variableRestrictionDescr,
+                                                        null,
+                                                        "Unable to return Declaration for identifier '" + variableRestrictionDescr.getIdentifier() + "'" ) );
+                return null;
+            }
         }
 
         final Evaluator evaluator = getEvaluator( context,
@@ -635,32 +660,42 @@
 
         // if only 2 parts, it may be a composed direct property access
         if ( parts.length == 2 ) {
-            final Declaration decl = context.getDeclarationResolver().getDeclaration( parts[0] );
-            // if a declaration exists, then it is a variable direct property access, not an enum
-            if ( decl != null ) {
-                if ( decl.isPatternDeclaration() ) {
-                    final Declaration implicit = this.createDeclarationObject( context,
-                                                                               parts[1],
-                                                                               decl.getPattern() );
+            Declaration implicit = null;
+            if ( "this".equals( parts[0] ) ) {
+                implicit = this.createDeclarationObject( context,
+                                                         parts[1],
+                                                         (Pattern) context.getBuildStack().peek() );
+            } else {
+                final Declaration decl = context.getDeclarationResolver().getDeclaration( parts[0] );
+                // if a declaration exists, then it may be a variable direct property access, not an enum
+                if ( decl != null ) {
+                    if ( decl.isPatternDeclaration() ) {
+                        implicit = this.createDeclarationObject( context,
+                                                                 parts[1],
+                                                                 decl.getPattern() );
 
-                    final Evaluator evaluator = getEvaluator( context,
-                                                              qiRestrictionDescr,
-                                                              extractor.getValueType(),
-                                                              qiRestrictionDescr.getEvaluator() );
-                    if ( evaluator == null ) {
+                    } else {
+                        context.getErrors().add( new RuleError( context.getRule(),
+                                                                qiRestrictionDescr,
+                                                                "",
+                                                                "Not possible to directly access the property '" + parts[1] + "' of declaration '" + parts[0] + "' since it is not a pattern" ) );
                         return null;
                     }
-
-                    return new VariableRestriction( extractor,
-                                                    implicit,
-                                                    evaluator );
-                } else {
-                    context.getErrors().add( new RuleError( context.getRule(),
-                                                            qiRestrictionDescr,
-                                                            "",
-                                                            "Not possible to directly access the property '" + parts[1] + "' of declaration '" + parts[0] + "' since it is not a pattern" ) );
+                }
+            }
+            
+            if( implicit != null ) {
+                final Evaluator evaluator = getEvaluator( context,
+                                                          qiRestrictionDescr,
+                                                          extractor.getValueType(),
+                                                          qiRestrictionDescr.getEvaluator() );
+                if ( evaluator == null ) {
                     return null;
                 }
+
+                return new VariableRestriction( extractor,
+                                                implicit,
+                                                evaluator );
             }
         }
 
@@ -673,10 +708,7 @@
             field = FieldFactory.getFieldValue( staticClass.getField( fieldName ).get( null ),
                                                 extractor.getValueType() );
         } catch ( final ClassNotFoundException e ) {
-            context.getErrors().add( new RuleError( context.getRule(),
-                                                    qiRestrictionDescr,
-                                                    e,
-                                                    e.getMessage() ) );
+            // nothing to do, as it is not a class name with static field
         } catch ( final Exception e ) {
             context.getErrors().add( new RuleError( context.getRule(),
                                                     qiRestrictionDescr,
@@ -803,5 +835,5 @@
 
         return evaluator;
     }
-    
+
 }

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Cheese.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Cheese.java	2007-08-22 17:49:27 UTC (rev 14451)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Cheese.java	2007-08-22 19:24:58 UTC (rev 14452)
@@ -30,6 +30,7 @@
     private static final long serialVersionUID = 400L;
     private String            type;
     private int               price;
+    private int               oldPrice;
 
     public Cheese() {
 
@@ -42,6 +43,15 @@
         this.price = price;
     }
 
+    public Cheese(final String type,
+                  final int price,
+                  final int oldPrice ) {
+        super();
+        this.type = type;
+        this.price = price;
+        this.oldPrice = oldPrice;
+    }
+
     public int getPrice() {
         return this.price;
     }
@@ -81,6 +91,14 @@
         } else if ( !type.equals( other.type ) ) return false;
         return true;
     }
+
+    public int getOldPrice() {
+        return oldPrice;
+    }
+
+    public void setOldPrice(int oldPrice) {
+        this.oldPrice = oldPrice;
+    }
     
     
 

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java	2007-08-22 17:49:27 UTC (rev 14451)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java	2007-08-22 19:24:58 UTC (rev 14452)
@@ -3836,4 +3836,27 @@
         workingMemory.fireAllRules();
     }
 
+    public void testAutovivificationOfVariableRestrictions() throws Exception {
+        final PackageBuilder builder = new PackageBuilder();
+        builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_AutoVivificationVR.drl" ) ) );
+        final Package pkg = builder.getPackage();
+
+        final RuleBase ruleBase = getRuleBase();
+        ruleBase.addPackage( pkg );
+        final WorkingMemory workingMemory = ruleBase.newStatefulSession();
+
+        final List results = new ArrayList();
+        workingMemory.setGlobal( "results",
+                                 results );
+
+        workingMemory.insert( new Cheese( "stilton",
+                                          10,
+                                          8 ) );
+
+        workingMemory.fireAllRules();
+
+        assertEquals( 1,
+                      results.size() );
+    }
+
 }
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AutoVivificationVR.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AutoVivificationVR.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AutoVivificationVR.drl	2007-08-22 19:24:58 UTC (rev 14452)
@@ -0,0 +1,10 @@
+package org.drools;
+
+global java.util.List results;
+
+rule "autovivification"
+when
+     Cheese( price > oldPrice, price > this.oldPrice )
+then
+     results.add( "OK" );
+end
\ No newline at end of file




More information about the jboss-svn-commits mailing list