[jboss-jira] [JBoss JIRA] Created: (JBRULES-941) Add support to pluggable accumulate functions

Edson Tirelli (JIRA) jira-events at lists.jboss.org
Thu Jun 21 21:17:00 EDT 2007


Add support to pluggable accumulate functions
---------------------------------------------

                 Key: JBRULES-941
                 URL: http://jira.jboss.com/jira/browse/JBRULES-941
             Project: JBoss Rules
          Issue Type: Feature Request
      Security Level: Public (Everyone can see)
            Reporter: Edson Tirelli
         Assigned To: Edson Tirelli


   All,

   Today I used a few hours to develop something I think it is quite useful: the ability to have externally coded functions for accumulate. Basically, the idea is that common functions should have a predefined template and not be coded in every accumulate of every rule in your rule base.
   Example: "average"

   The idea is that instead of writing something like bellow in every rule:

$avg : Number() from accumulate( Cheese( $price : price ),
                                                   init( double total = 0; int count = 0 ),
                                                   action( total += $price; count++; ),
                                                   reverse( total -= $price; count--; ),
                                                   result( new Double( total / count ) ) )

     The user could simply use a predefined function like:

$avg : Number() from accumulate( Cheese( $price : price ),
                                                   average( $price ) );

      Or if he wants to know how much will cost him to give 10% raise to all employees of a given department:

$sum : Number() from accumulate( Employee( dept == "X", $salary : salary )
                                                    sum( $salary * 0.1 ) )

     And whatever the user wants to do.
     So, instead of hardcoding a few functions, I thought it was better to let it pluggable. So I defined a simple interface (AccumulateFunction) and anyone willing to create an external function simply implement this interface and wires it using either the PackageBuilderConfiguration API or the configuration files mark created. Example:

drools.accumulate.function.average = org.drools.base.accumulators.AverageAccumulator

     Where "drools.accumulate.function." is a constant prefix and "average" is the function identifier the user will use in the rule file (DRL, XML, etc).

     Also, we will provide common functions like "average", "sum", "count", "min", "max", etc, out of the box, since it is really easy to implement any function. Example: to implement the average function, all one needs to do is:

package org.drools.base.accumulators;


/**
 * An implementation of an accumulator capable of calculating average values
 *
 * @author etirelli
 *
 */
public class AverageAccumulator implements AccumulateFunction {

    protected static class AverageData {
        public int    count = 0;
        public double total = 0;
    }

    /* (non-Javadoc)
     * @see org.drools.base.accumulators.AccumulateFunction#createContext ()
     */
    public Object createContext() {
        return new AverageData();
    }

    /* (non-Javadoc)
     * @see org.drools.base.accumulators.AccumulateFunction#init(java.lang.Object)
     */
    public void init(Object context) throws Exception {
        AverageData data = (AverageData) context;
        data.count = 0;
        data.total = 0;
    }

    /* (non-Javadoc)
     * @see org.drools.base.accumulators.AccumulateFunction#accumulate (java.lang.Object, java.lang.Object)
     */
    public void accumulate(Object context,
                           Object value) {
        AverageData data = (AverageData) context;
        data.count++;
        data.total += ((Number) value).doubleValue();
    }

    /* (non-Javadoc)
     * @see org.drools.base.accumulators.AccumulateFunction#reverse(java.lang.Object, java.lang.Object)
     */
    public void reverse(Object context,
                        Object value) throws Exception {
        AverageData data = (AverageData) context;
        data.count--;
        data.total -= ((Number) value).doubleValue();
    }

    /* (non-Javadoc)
     * @see org.drools.base.accumulators.AccumulateFunction#getResult(java.lang.Object)
     */
    public Object getResult(Object context) throws Exception {
        AverageData data = (AverageData) context;
        return new Double( data.count == 0 ? 0 : data.total / data.count );
    }

    /* (non-Javadoc)
     * @see org.drools.base.accumulators.AccumulateFunction#supportsReverse()
     */
    public boolean supportsReverse() {
        return true;
    }
}

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

        



More information about the jboss-jira mailing list