[jboss-jira] [JBoss JIRA] Commented: (JBRULES-1817) FactTemplateFieldExtractor must implement equals() method

Charles Daniels (JIRA) jira-events at lists.jboss.org
Fri Feb 6 20:16:44 EST 2009


    [ https://jira.jboss.org/jira/browse/JBRULES-1817?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12451621#action_12451621 ] 

Charles Daniels commented on JBRULES-1817:
------------------------------------------

In the previous posting, I failed to include the unit test changes in the patch. Here is a patch that includes changes to the class and its unit test. This patch must be applied to the root of the drools-core project:

Index: src/main/java/org/drools/facttemplates/FactTemplateFieldExtractor.java
===================================================================
--- src/main/java/org/drools/facttemplates/FactTemplateFieldExtractor.java	(revision 25144)
+++ src/main/java/org/drools/facttemplates/FactTemplateFieldExtractor.java	(working copy)
@@ -96,4 +96,30 @@
                                Object object) {
         return ((Fact) object).getFieldValue( this.fieldIndex ) == null;
     }
+ 
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((factTemplate == null) ? 0 : factTemplate.hashCode());
+        result = prime * result + fieldIndex;
+        return result;
+    }
+     
+    public boolean equals(Object obj) { 
+        if ( this == obj ) return true;
+        if ( obj == null ) return false;
+        if ( getClass() != obj.getClass() ) return false;
+        FactTemplateFieldExtractor other = (FactTemplateFieldExtractor) obj;
+     
+        if ( factTemplate == null ) {
+            if ( other.factTemplate != null ) return false;
+        } else if ( !factTemplate.equals( other.factTemplate ) ) {
+            return false;
+        }
+     
+        if ( fieldIndex != other.fieldIndex ) {
+            return false;
+        }
+        return true;
+    }
 }
Index: src/test/java/org/drools/facttemplates/FactTemplateFieldExtractorTest.java
===================================================================
--- src/test/java/org/drools/facttemplates/FactTemplateFieldExtractorTest.java	(revision 25144)
+++ src/test/java/org/drools/facttemplates/FactTemplateFieldExtractorTest.java	(working copy)
@@ -8,25 +8,45 @@
 import org.drools.spi.Extractor;
 
 public class FactTemplateFieldExtractorTest extends TestCase {
+    Package pkg;
+    FieldTemplate cheeseName;
+    FieldTemplate cheesePrice;
+    FieldTemplate[] fields;
+    FactTemplate cheese;
+    Extractor extractName;
+    Extractor extractPrice;
+    Extractor extractPriceDup;
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        
+        pkg = new Package( "org.store" );
+        cheeseName = new FieldTemplateImpl( "name", 0, String.class );
+        cheesePrice = new FieldTemplateImpl( "price", 1, Integer.class );
+        fields = new FieldTemplate[]{cheeseName, cheesePrice};
+        cheese = new FactTemplateImpl( pkg, "Cheese", fields );
+        extractName = new FactTemplateFieldExtractor( cheese, 0 );
+        extractPrice = new FactTemplateFieldExtractor( cheese, 1 );
+        extractPriceDup = new FactTemplateFieldExtractor( cheese, 1 );
+    }
+    
+    public void testEquals() {
+        assertEquals( extractPrice, extractPriceDup );
+    }
+    
+    public void testNotEquals() {
+        assertFalse( extractName.equals( extractPrice ) );
+    }
+    
+    public void testNotEqualsNull() {
+        assertFalse( extractName.equals( null ) );
+    }
+    
+    public void testHashCode() {
+        assertEquals( extractPrice.hashCode(), extractPriceDup.hashCode() );
+    }
+    
     public void testExtractor() {
-        final Package pkg = new Package( "org.store" );
-
-        final FieldTemplate cheeseName = new FieldTemplateImpl( "name",
-                                                                0,
-                                                                String.class );
-        final FieldTemplate cheesePrice = new FieldTemplateImpl( "price",
-                                                                 1,
-                                                                 Integer.class );
-        final FieldTemplate[] fields = new FieldTemplate[]{cheeseName, cheesePrice};
-        final FactTemplate cheese = new FactTemplateImpl( pkg,
-                                                          "Cheese",
-                                                          fields );
-
-        final Extractor extractName = new FactTemplateFieldExtractor( cheese,
-                                                                      0 );
-        final Extractor extractPrice = new FactTemplateFieldExtractor( cheese,
-                                                                       1 );
-
         final Fact stilton = cheese.createFact( 10 );
         stilton.setFieldValue( "name",
                                "stilton" );
@@ -69,22 +89,6 @@
     }
 
     public void testDeclaration() {
-        final Package pkg = new Package( "org.store" );
-
-        final FieldTemplate cheeseName = new FieldTemplateImpl( "name",
-                                                                0,
-                                                                String.class );
-        final FieldTemplate cheesePrice = new FieldTemplateImpl( "price",
-                                                                 1,
-                                                                 Integer.class );
-        final FieldTemplate[] fields = new FieldTemplate[]{cheeseName, cheesePrice};
-        final FactTemplate cheese = new FactTemplateImpl( pkg,
-                                                          "Cheese",
-                                                          fields );
-
-        final Extractor extractName = new FactTemplateFieldExtractor( cheese,
-                                                                      0 );
-
         final Pattern pattern = new Pattern( 0,
                                           new FactTemplateObjectType( cheese ) );
 



> FactTemplateFieldExtractor must implement equals() method
> ---------------------------------------------------------
>
>                 Key: JBRULES-1817
>                 URL: https://jira.jboss.org/jira/browse/JBRULES-1817
>             Project: JBoss Drools
>          Issue Type: Bug
>      Security Level: Public(Everyone can see) 
>          Components: drools-core
>    Affects Versions: 4.0.7
>         Environment: Sun JDK1.5.0_12 on Windows XP
>            Reporter: Stephanie Kroll
>            Assignee: Mark Proctor
>             Fix For: 5.0.0.M5
>
>
> FactTemplateFieldExtractor does not implement equals().  This causes rules not to fire when the number of literal string equality constraints equals or exceeds the alpha node hashing threshold.
> To reproduce for the trivial case, I created the following rule package:
> package TestFactTemplate
> template MyFact
> 	String stringVal;
> end
> rule "Rule1"
> 	when
> 	    MyFact (stringVal == "AA")
> 	then
> 		System.out.println("Rule1 fired");
> end
> rule "Rule2"
> 	when
> 	    MyFact (stringVal == "AA")
> 	then
> 		System.out.println("Rule2 fired");
> end
> I implemented the Fact interface and returned "AA" from the two getFieldValue() methods.  I also set the alphaNodeHashingThreshold to 2.  When executing the rules, only Rule2 fires.
> If FactTemplateFieldExtractor implements equals() like so:
>     public boolean equals(final Object object) {
>         if ( this == object ) {
>             return true;
>         }
>         if ( !(object instanceof FactTemplateFieldExtractor) ) {
>             return false;
>         }
>         final FactTemplateFieldExtractor other = (FactTemplateFieldExtractor) object;
>         return this.factTemplate.equals(other.factTemplate) && 
>         	this.fieldIndex == other.fieldIndex;
>     }
> then both rules fire.
> The problem arises because without the equals() method for the field extractor, the LiteralConstraints do not report as equal, and the network does not reuse the nodes in BuildUtils.attachNode.  When CompositeObjectSinkAdapter hashes the sinks because the threshold is met, only the last one is preserved in the hashedSinkMap since the HashKeys are the same.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the jboss-jira mailing list