[jboss-svn-commits] JBL Code SVN: r9676 - in labs/jbossrules/trunk: drools-compiler/src/main/java/org/drools/semantics/java/builder and 6 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed Feb 21 10:08:42 EST 2007
Author: tirelli
Date: 2007-02-21 10:08:42 -0500 (Wed, 21 Feb 2007)
New Revision: 9676
Added:
labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_duplicateVariableBinding.drl
labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_duplicateVariableBindingError.drl
Removed:
labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/lang/multiple_bindings.drl
labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/lang/multiple_bindings_more.drl
Modified:
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/AndDescr.java
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/builder/ColumnBuilder.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/RuleParserTest.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/descr/AndDescrTest.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/DeclarationScopeResolver.java
Log:
JBRULES-554: fixing variable scope resolution in the rule parser/builder
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/AndDescr.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/AndDescr.java 2007-02-21 13:31:26 UTC (rev 9675)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/AndDescr.java 2007-02-21 15:08:42 UTC (rev 9676)
@@ -18,10 +18,7 @@
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
-import java.util.Map;
public class AndDescr extends BaseDescr
implements
@@ -31,7 +28,6 @@
*/
private static final long serialVersionUID = 8225023304408452585L;
private List descrs = Collections.EMPTY_LIST;
- private final Map boundColumns = new HashMap();
public AndDescr() {
}
@@ -41,50 +37,9 @@
this.descrs = new ArrayList( 1 );
}
- if ( baseDescr instanceof ColumnDescr ) {
- addColumn( (ColumnDescr) baseDescr );
- } else {
- this.descrs.add( baseDescr );
- }
+ this.descrs.add( baseDescr );
}
- /**
- * NOTE: to be used possibly in a future version... wire in above...
- * This will check the column binding, and add the patterns
- * to a previously bound column
- * if one exists.
- * If its not a bound column, or it is a unique bound variable column,
- * it will just add it to the list of children descrs.
- */
- private void addColumn(final ColumnDescr col) {
- final String identifier = col.getIdentifier();
- if ( identifier == null || "".equals( identifier ) ) {
- this.descrs.add( col );
- } else {
- if ( this.boundColumns.containsKey( identifier ) ) {
- final ColumnDescr existingCol = (ColumnDescr) this.boundColumns.get( identifier );
- if ( existingCol.getObjectType().equals( col.getObjectType() ) ) {
- combinePatterns( existingCol,
- col.getDescrs() );
- } else {
- this.descrs.add( col );
- }
- } else {
- this.boundColumns.put( identifier,
- col );
- this.descrs.add( col );
- }
- }
- }
-
- private void combinePatterns(final ColumnDescr existingCol,
- final List newColPatterns) {
- for ( final Iterator iter = newColPatterns.iterator(); iter.hasNext(); ) {
- existingCol.addDescr( (BaseDescr) iter.next() );
- }
-
- }
-
public List getDescrs() {
return this.descrs;
}
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/builder/ColumnBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/builder/ColumnBuilder.java 2007-02-21 13:31:26 UTC (rev 9675)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/builder/ColumnBuilder.java 2007-02-21 15:08:42 UTC (rev 9676)
@@ -124,6 +124,15 @@
Column column;
if ( columnDescr.getIdentifier() != null && !columnDescr.getIdentifier().equals( "" ) ) {
+
+ if ( context.getDeclarationResolver().isDuplicated( columnDescr.getIdentifier() ) ) {
+ // This declaration already exists, so throw an Exception
+ context.getErrors().add( new RuleError( context.getRule(),
+ columnDescr,
+ null,
+ "Duplicate declaration for variable '" + columnDescr.getIdentifier() + "' in the rule '" + context.getRule().getName() + "'" ) );
+ }
+
column = new Column( context.getNextColumnId(),
0, // offset is 0 by default
objectType,
@@ -319,8 +328,7 @@
final Column column,
final FieldBindingDescr fieldBindingDescr) {
- Declaration declaration = (Declaration) context.getDeclarationResolver().getDeclaration( fieldBindingDescr.getIdentifier() );
- if ( declaration != null ) {
+ if ( context.getDeclarationResolver().isDuplicated( fieldBindingDescr.getIdentifier() ) ) {
// This declaration already exists, so throw an Exception
context.getErrors().add( new RuleError( context.getRule(),
fieldBindingDescr,
@@ -338,8 +346,8 @@
return;
}
- declaration = column.addDeclaration( fieldBindingDescr.getIdentifier(),
- extractor );
+ column.addDeclaration( fieldBindingDescr.getIdentifier(),
+ extractor );
}
private void build(final BuildContext context,
@@ -381,7 +389,7 @@
final String[] localDeclarationTypes = new String[localDeclarations.length];
for ( int i = 0, size = localDeclarations.length; i < size; i++ ) {
- localDeclarationTypes[i] = utils.getTypeFixer().fix( localDeclarations[i] );
+ localDeclarationTypes[i] = utils.getTypeFixer().fix( localDeclarations[i] );
}
st.setAttribute( "localDeclarations",
@@ -598,7 +606,7 @@
final String[] localDeclarationTypes = new String[localDeclarations.length];
for ( int i = 0, size = localDeclarations.length; i < size; i++ ) {
- localDeclarationTypes[i] = utils.getTypeFixer().fix( localDeclarations[i] );
+ localDeclarationTypes[i] = utils.getTypeFixer().fix( localDeclarations[i] );
}
st.setAttribute( "localDeclarations",
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java 2007-02-21 13:31:26 UTC (rev 9675)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java 2007-02-21 15:08:42 UTC (rev 9676)
@@ -29,6 +29,7 @@
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -3961,4 +3962,64 @@
}
+ public void testDuplicateVariableBinding() throws Exception {
+ try {
+ final PackageBuilder builder = new PackageBuilder();
+ builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_duplicateVariableBinding.drl" ) ) );
+ final Package pkg = builder.getPackage();
+
+ final RuleBase ruleBase = getRuleBase();
+ ruleBase.addPackage( pkg );
+ final WorkingMemory workingMemory = ruleBase.newWorkingMemory();
+ final Map result = new HashMap();
+ workingMemory.setGlobal( "results",
+ result );
+
+ final Cheese stilton = new Cheese("stilton", 20);
+ final Cheese brie = new Cheese("brie", 10);
+
+ workingMemory.assertObject( stilton );
+ workingMemory.assertObject( brie );
+
+ workingMemory.fireAllRules();
+ assertEquals( 5,
+ result.size() );
+ assertEquals( stilton.getPrice(), ((Integer)result.get( stilton.getType() )).intValue());
+ assertEquals( brie.getPrice(), ((Integer)result.get( brie.getType() )).intValue());
+
+ assertEquals( stilton.getPrice(), ((Integer)result.get( stilton )).intValue());
+ assertEquals( brie.getPrice(), ((Integer)result.get( brie )).intValue());
+
+ assertEquals( stilton.getPrice(), ((Integer)result.get( "test3"+stilton.getType() )).intValue());
+
+ workingMemory.assertObject( new Person("bob", brie.getType()) );
+ workingMemory.fireAllRules();
+
+ assertEquals( 6,
+ result.size() );
+ assertEquals( brie.getPrice(), ((Integer)result.get( "test3"+brie.getType() )).intValue());
+
+ } catch ( Exception e ) {
+ e.printStackTrace();
+ fail("Should not raise any exception");
+ }
+ }
+
+ public void testDuplicateVariableBindingError() throws Exception {
+ try {
+ final PackageBuilder builder = new PackageBuilder();
+ builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_duplicateVariableBindingError.drl" ) ) );
+ final Package pkg = builder.getPackage();
+
+ assertFalse( pkg.isValid() );
+ assertEquals( 6, pkg.getErrorSummary().split( "\n" ).length);
+
+ } catch ( Exception e ) {
+ e.printStackTrace();
+ fail("Should not raise any exception");
+ }
+ }
+
+
+
}
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/RuleParserTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/RuleParserTest.java 2007-02-21 13:31:26 UTC (rev 9675)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/RuleParserTest.java 2007-02-21 15:08:42 UTC (rev 9676)
@@ -61,7 +61,6 @@
import org.drools.lang.descr.RuleDescr;
import org.drools.lang.descr.VariableRestrictionDescr;
import org.drools.lang.dsl.DefaultExpander;
-import org.drools.lang.dsl.DefaultExpanderResolver;
public class RuleParserTest extends TestCase {
@@ -924,38 +923,6 @@
rhs );
}
- public void testMultiBindings() throws Exception {
- final RuleDescr rule = parseResource( "multiple_bindings.drl" ).rule();
- assertNotNull( rule );
- assertEquals( "simple_rule",
- rule.getName() );
-
- assertEquals( 2,
- rule.getLhs().getDescrs().size() );
- assertEquals( "foo",
- ((ColumnDescr) rule.getLhs().getDescrs().get( 0 )).getIdentifier() );
- assertEquals( "baz",
- ((ColumnDescr) rule.getLhs().getDescrs().get( 1 )).getIdentifier() );
-
- }
-
- public void testMultiBindingsMore() throws Exception {
- final RuleDescr rule = parseResource( "multiple_bindings_more.drl" ).rule();
- assertNotNull( rule );
- assertEquals( "simple_rule",
- rule.getName() );
-
- assertEquals( 3,
- rule.getLhs().getDescrs().size() );
- assertEquals( "foo",
- ((ColumnDescr) rule.getLhs().getDescrs().get( 0 )).getIdentifier() );
- assertEquals( "something foo",
- ((EvalDescr) rule.getLhs().getDescrs().get( 1 )).getText() );
- assertEquals( "another foo",
- ((EvalDescr) rule.getLhs().getDescrs().get( 2 )).getText() );
-
- }
-
public void testLhsSemicolonDelim() throws Exception {
final RuleDescr rule = parseResource( "lhs_semicolon_delim.drl" ).rule();
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/descr/AndDescrTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/descr/AndDescrTest.java 2007-02-21 13:31:26 UTC (rev 9675)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/descr/AndDescrTest.java 2007-02-21 15:08:42 UTC (rev 9676)
@@ -14,48 +14,4 @@
and.getDescrs().size() );
}
- /** This is for combining bound columns with the same name patterns together */
- public void testAddBoundCols() {
- final AndDescr and = new AndDescr();
- final ColumnDescr col1 = new ColumnDescr( "Foo" );
- col1.setIdentifier( "foo" );
- FieldConstraintDescr fieldConstraint1 = new FieldConstraintDescr("foo" );
- fieldConstraint1.addRestriction( new VariableRestrictionDescr("==", "bar") );
- col1.addDescr( fieldConstraint1 );
- and.addDescr( col1 );
-
- final ColumnDescr col2 = new ColumnDescr( "Foo" );
- col2.setIdentifier( "foo" );
- FieldConstraintDescr fieldConstraint2 = new FieldConstraintDescr("bar" );
- fieldConstraint2.addRestriction( new VariableRestrictionDescr("==", "baz") );
- col2.addDescr( fieldConstraint2 );
- and.addDescr( col2 );
-
- and.addDescr( new NotDescr() );
-
- final ColumnDescr col3 = new ColumnDescr( "Foo" );
- and.addDescr( col3 ); //will not be combined, as not bound
-
- final ColumnDescr col4 = new ColumnDescr( "Bar" );
- col4.setIdentifier( "foo" );
- and.addDescr( col4 ); //even though has a name, should be left alone
-
- assertEquals( 4,
- and.getDescrs().size() );
- assertEquals( col1,
- and.getDescrs().get( 0 ) );
- assertTrue( and.getDescrs().get( 1 ) instanceof NotDescr );
- assertEquals( col3,
- and.getDescrs().get( 2 ) );
- assertEquals( col4,
- and.getDescrs().get( 3 ) );
-
- assertEquals( 2,
- col1.getDescrs().size() );
- assertEquals( "bar",
- ( (VariableRestrictionDescr)( (FieldConstraintDescr) col1.getDescrs().get( 0 )).getRestrictions().get( 0 )).getIdentifier() );
- assertEquals( "baz",
- ( (VariableRestrictionDescr)( (FieldConstraintDescr) col1.getDescrs().get( 1 )).getRestrictions().get( 0 )).getIdentifier() );
- }
-
}
Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_duplicateVariableBinding.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_duplicateVariableBinding.drl (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_duplicateVariableBinding.drl 2007-02-21 15:08:42 UTC (rev 9676)
@@ -0,0 +1,33 @@
+package org.drools;
+
+global java.util.Map results;
+
+rule "Duplicate Variable testing"
+ when
+ // there should be no problem since each variable
+ // is in a different logical branch
+ Cheese( $type : type == "stilton", $price : price ) or
+ Cheese( $type : type == "brie", $price : price )
+ then
+ results.put( $type, new Integer( $price ) );
+end
+
+rule "Duplicate Variable testing 2"
+ when
+ // there should be no problem since each variable
+ // is in a different logical branch
+ $cheese : Cheese( type == "stilton", $price : price ) or
+ $cheese : Cheese( type == "brie", $price : price )
+ then
+ results.put( $cheese, new Integer( $price ) );
+end
+
+rule "Duplicate Variable testing 3"
+ when
+ // there should be no problem since each variable
+ // is in a different logical branch
+ Cheese( $type : type == "stilton", $price : price ) or
+ ( Cheese( $type : type == "brie", $price : price ) and Person( name == "bob", likes == $type ) )
+ then
+ results.put( "test3"+$type, new Integer( $price ) );
+end
Property changes on: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_duplicateVariableBinding.drl
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_duplicateVariableBindingError.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_duplicateVariableBindingError.drl (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_duplicateVariableBindingError.drl 2007-02-21 15:08:42 UTC (rev 9676)
@@ -0,0 +1,30 @@
+package org.drools;
+
+global java.util.Map results;
+
+rule "Duplicate Variable testing"
+ when
+ // this must raise an error as the variables are in the same branch
+ Cheese( $type : type == "stilton", $price : price )
+ Cheese( $type : type == "brie", $price : price )
+ then
+ results.put( $type, new Integer( $price ) );
+end
+
+rule "Duplicate Variable testing 2"
+ when
+ // this must raise an error as the variables are in the same branch
+ $cheese : Cheese( type == "stilton", $price : price )
+ $cheese : Cheese( type == "brie", $price : price )
+ then
+ results.put( $cheese, new Integer( $price ) );
+end
+
+rule "Duplicate Variable testing 3"
+ when
+ // this must raise an error as the variables are in the same branch
+ Cheese( $type : type == "stilton", $price : price )
+ Cheese( $type : type == "brie", $price : price ) and Person( name == "bob", likes == $type )
+ then
+ results.put( "test3"+$type, new Integer( $price ) );
+end
Property changes on: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_duplicateVariableBindingError.drl
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:eol-style
+ native
Deleted: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/lang/multiple_bindings.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/lang/multiple_bindings.drl 2007-02-21 13:31:26 UTC (rev 9675)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/lang/multiple_bindings.drl 2007-02-21 15:08:42 UTC (rev 9676)
@@ -1,9 +0,0 @@
-#trying to show how it will normalise biondings
-rule simple_rule
- when
- foo : Bar(a==3)
- foo : Bar(a!=4)
- baz : Bar(a==3)
- then
- Baz();
-end
\ No newline at end of file
Deleted: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/lang/multiple_bindings_more.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/lang/multiple_bindings_more.drl 2007-02-21 13:31:26 UTC (rev 9675)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/lang/multiple_bindings_more.drl 2007-02-21 15:08:42 UTC (rev 9676)
@@ -1,12 +0,0 @@
-#trying to show how it will normalise biondings
-rule simple_rule
- when
- foo : Bar()
- eval(something foo)
-
- foo : Bar()
- eval(another foo)
-
- then
- Baz();
-end
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/DeclarationScopeResolver.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/DeclarationScopeResolver.java 2007-02-21 13:31:26 UTC (rev 9675)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/DeclarationScopeResolver.java 2007-02-21 15:08:42 UTC (rev 9676)
@@ -5,8 +5,14 @@
import java.util.Stack;
import org.drools.rule.Declaration;
+import org.drools.rule.GroupElement;
import org.drools.rule.RuleConditionElement;
+/**
+ * A class capable of resolving a declaration in the current build context
+ *
+ * @author etirelli
+ */
public class DeclarationScopeResolver {
private static final Stack EMPTY_STACK = new Stack( );
private Map[] maps;
@@ -70,6 +76,27 @@
return false;
}
+ public boolean isDuplicated( final String name ) {
+ for ( int i = 0, length = this.maps.length; i < length; i++ ) {
+ if ( this.maps[i].containsKey( (name) ) ) {
+ return true;
+ }
+ }
+ for( int i = this.buildStack.size()-1; i >= 0; i-- ) {
+ RuleConditionElement rce = ( RuleConditionElement ) this.buildStack.get( i );
+ Declaration declaration = ( Declaration ) rce.getInnerDeclarations().get( name );
+ if( declaration != null ) {
+ if( ( rce instanceof GroupElement ) && ( (GroupElement)rce).isOr() ) {
+ // if it is an OR and it is duplicated, we can stop looking for duplication now
+ // as it is a separate logical branch
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Return all declarations scoped to the current
* RuleConditionElement in the build stack
More information about the jboss-svn-commits
mailing list