[jboss-svn-commits] JBL Code SVN: r24191 - in labs/jbossrules/trunk/drools-core/src: main/java/org/drools/base/evaluators and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Dec 1 22:10:07 EST 2008


Author: tirelli
Date: 2008-12-01 22:10:07 -0500 (Mon, 01 Dec 2008)
New Revision: 24191

Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/DuringEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/EvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MeetsEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MetByEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlappedByEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlapsEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/base/TemporalEvaluatorFactoryTest.java
Log:
JBRULES-1873: fixing and documenting operators

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java	2008-12-02 02:36:47 UTC (rev 24190)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java	2008-12-02 03:10:07 UTC (rev 24191)
@@ -47,7 +47,6 @@
 import org.drools.process.instance.impl.ContextInstanceFactoryRegistry;
 import org.drools.runtime.process.WorkItemHandler;
 import org.drools.spi.ConflictResolver;
-import org.drools.spi.ConsequenceExceptionHandler;
 import org.drools.util.ChainedProperties;
 import org.drools.util.ConfFileUtils;
 import org.drools.util.StringUtils;
@@ -1302,9 +1301,8 @@
      */
     public static enum EventProcessingMode {
 
-        CLOUD(
-                "cloud"), STREAM(
-                "stream");
+        CLOUD("cloud"), 
+        STREAM("stream");
 
         private String string;
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/DuringEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/DuringEvaluatorDefinition.java	2008-12-02 02:36:47 UTC (rev 24190)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/DuringEvaluatorDefinition.java	2008-12-02 03:10:07 UTC (rev 24191)
@@ -304,7 +304,7 @@
         }
 
         public String toString() {
-            return "during[" + paramText + "]";
+            return "during[" + ( ( paramText != null ) ? paramText : "" ) + "]";
         }
 
         /* (non-Javadoc)

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/EvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/EvaluatorDefinition.java	2008-12-02 02:36:47 UTC (rev 24190)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/EvaluatorDefinition.java	2008-12-02 03:10:07 UTC (rev 24191)
@@ -43,7 +43,7 @@
 
     /**
      * My apologies to English speakers if the word "negatable" does not
-     * exists. :)
+     * exist. :)
      *
      * This method returns true if this evaluator supports negation. Example:
      *

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MeetsEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MeetsEvaluatorDefinition.java	2008-12-02 02:36:47 UTC (rev 24190)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MeetsEvaluatorDefinition.java	2008-12-02 03:10:07 UTC (rev 24191)
@@ -38,29 +38,62 @@
 import org.drools.time.Interval;
 
 /**
- * The implementation of the 'meets' evaluator definition
+ * <p>The implementation of the <code>meets</code> evaluator definition.</p>
+ * 
+ * <p>The <b><code>meets</code></b> evaluator correlates two events and matches when the current event's 
+ * end timestamp happens at the same time as the correlated event's start timestamp.</p> 
+ * 
+ * <p>Lets look at an example:</p>
+ * 
+ * <pre>$eventA : EventA( this meets $eventB )</pre>
  *
+ * <p>The previous pattern will match if and only if the $eventA finishes at the same time $eventB starts. 
+ * In other words:</p>
+ * 
+ * <pre> 
+ * abs( $eventB.startTimestamp - $eventA.endTimestamp ) == 0
+ * </pre>
+ * 
+ * <p>The <b><code>meets</code></b> evaluator accepts one optional parameter. If it is defined, it determines
+ * the maximum distance between the end timestamp of current event and the start timestamp of the correlated
+ * event in order for the operator to match. Example:</p>
+ * 
+ * <pre>$eventA : EventA( this meets[ 5s ] $eventB )</pre>
+ * 
+ * Will match if and only if:
+ * 
+ * <pre> 
+ * abs( $eventB.startTimestamp - $eventA.endTimestamp) <= 5s 
+ * </pre>
+ * 
+ * <p><b>NOTE:</b> it makes no sense to use a negative interval value for the parameter and the 
+ * engine will raise an exception if that happens.</p>
+ * 
+ * @author etirelli
  * @author mgroch
  */
 public class MeetsEvaluatorDefinition
     implements
     EvaluatorDefinition {
 
-    public static final Operator  MEETS       = Operator.addOperatorToRegistry( "meets",
-                                                                                  false );
-    public static final Operator  MEETS_NOT   = Operator.addOperatorToRegistry( "meets",
-                                                                                  true );
+    public static final Operator        MEETS         = Operator.addOperatorToRegistry( "meets",
+                                                                                        false );
+    public static final Operator        MEETS_NOT     = Operator.addOperatorToRegistry( "meets",
+                                                                                        true );
 
-    private static final String[] SUPPORTED_IDS = { MEETS.getOperatorString() };
+    private static final String[]       SUPPORTED_IDS = {MEETS.getOperatorString()};
 
-    private Map<String, MeetsEvaluator> cache        = Collections.emptyMap();
+    private Map<String, MeetsEvaluator> cache         = Collections.emptyMap();
+    private volatile TimeIntervalParser parser        = new TimeIntervalParser();
 
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        cache  = (Map<String, MeetsEvaluator>)in.readObject();
+    @SuppressWarnings("unchecked")
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        cache = (Map<String, MeetsEvaluator>) in.readObject();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(cache);
+        out.writeObject( cache );
     }
 
     /**
@@ -99,8 +132,10 @@
         String key = isNegated + ":" + parameterText;
         MeetsEvaluator eval = this.cache.get( key );
         if ( eval == null ) {
+            Long[] params = parser.parse( parameterText );
             eval = new MeetsEvaluator( type,
                                        isNegated,
+                                       params,
                                        parameterText );
             this.cache.put( key,
                             eval );
@@ -142,29 +177,35 @@
      * Implements the 'meets' evaluator itself
      */
     public static class MeetsEvaluator extends BaseEvaluator {
-		private static final long serialVersionUID = 9091548399308812447L;
+        private static final long serialVersionUID = 9091548399308812447L;
 
-		private long                  finalRange;
+        private long              finalRange;
+        private String            paramText;
 
-        public MeetsEvaluator(){
+        public MeetsEvaluator() {
         }
 
         public MeetsEvaluator(final ValueType type,
                               final boolean isNegated,
-                              final String parameters) {
+                              final Long[] parameters,
+                              final String paramText) {
             super( type,
                    isNegated ? MEETS_NOT : MEETS );
-            this.parseParameters( parameters );
+            this.paramText = paramText;
+            this.setParameters( parameters );
         }
 
-        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-            super.readExternal(in);
-            finalRange   = in.readLong();
+        public void readExternal(ObjectInput in) throws IOException,
+                                                ClassNotFoundException {
+            super.readExternal( in );
+            finalRange = in.readLong();
+            paramText = (String) in.readObject();
         }
 
         public void writeExternal(ObjectOutput out) throws IOException {
-            super.writeExternal(out);
-            out.writeLong(finalRange);
+            super.writeExternal( out );
+            out.writeLong( finalRange );
+            out.writeObject( paramText );
         }
 
         @Override
@@ -176,15 +217,17 @@
         public boolean isTemporal() {
             return true;
         }
-        
+
         @Override
         public Interval getInterval() {
-            if( this.getOperator().isNegated() ) {
-                return new Interval( Interval.MIN, Interval.MAX );
+            if ( this.getOperator().isNegated() ) {
+                return new Interval( Interval.MIN,
+                                     Interval.MAX );
             }
-            return new Interval( 0, Interval.MAX );
+            return new Interval( 0,
+                                 Interval.MAX );
         }
-        
+
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,
@@ -193,46 +236,44 @@
         }
 
         public boolean evaluateCachedRight(InternalWorkingMemory workingMemory,
-                final VariableContextEntry context,
-                final Object left) {
-			if ( context.rightNull ) {
-			return false;
-			}
-			long leftStartTS = ((EventFactHandle) left ).getStartTimestamp();
-			long dist = Math.abs(leftStartTS -
-						((EventFactHandle)((ObjectVariableContextEntry) context).right).getEndTimestamp());
-			return this.getOperator().isNegated() ^ ( ((EventFactHandle)((ObjectVariableContextEntry) context).right).getStartTimestamp() <= leftStartTS
-					&& dist <= this.finalRange );
-		}
+                                           final VariableContextEntry context,
+                                           final Object left) {
+            if ( context.rightNull ) {
+                return false;
+            }
+            long leftStartTS = ((EventFactHandle) left).getStartTimestamp();
+            long dist = Math.abs( leftStartTS - ((EventFactHandle) ((ObjectVariableContextEntry) context).right).getEndTimestamp() );
+            return this.getOperator().isNegated() ^ (dist <= this.finalRange);
+        }
 
-		public boolean evaluateCachedLeft(InternalWorkingMemory workingMemory,
-			               final VariableContextEntry context,
-			               final Object right) {
-			if ( context.extractor.isNullValue( workingMemory,
-			                     right ) ) {
-			return false;
-			}
-			long leftStartTS = ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getStartTimestamp();
-			long dist = Math.abs(leftStartTS - ((EventFactHandle) right ).getEndTimestamp());
-			return this.getOperator().isNegated() ^ ( ((EventFactHandle) right ).getStartTimestamp() <= leftStartTS && dist <= this.finalRange);
-		}
+        public boolean evaluateCachedLeft(InternalWorkingMemory workingMemory,
+                                          final VariableContextEntry context,
+                                          final Object right) {
+            if ( context.extractor.isNullValue( workingMemory,
+                                                right ) ) {
+                return false;
+            }
+            long leftStartTS = ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getStartTimestamp();
+            long dist = Math.abs( leftStartTS - ((EventFactHandle) right).getEndTimestamp() );
+            return this.getOperator().isNegated() ^ (dist <= this.finalRange);
+        }
 
-		public boolean evaluate(InternalWorkingMemory workingMemory,
-			     final InternalReadAccessor extractor1,
-			     final Object object1,
-			     final InternalReadAccessor extractor2,
-			     final Object object2) {
-			if ( extractor1.isNullValue( workingMemory,
-			              object1 ) ) {
-			return false;
-			}
-			long obj2StartTS = ((EventFactHandle) object2 ).getStartTimestamp();
-			long dist = Math.abs(obj2StartTS - ((EventFactHandle) object1 ).getEndTimestamp());
-			return this.getOperator().isNegated() ^ ( ((EventFactHandle) object1 ).getStartTimestamp() <= obj2StartTS && dist <= this.finalRange);
-		}
+        public boolean evaluate(InternalWorkingMemory workingMemory,
+                                final InternalReadAccessor extractor1,
+                                final Object object1,
+                                final InternalReadAccessor extractor2,
+                                final Object object2) {
+            if ( extractor1.isNullValue( workingMemory,
+                                         object1 ) ) {
+                return false;
+            }
+            long obj2StartTS = ((EventFactHandle) object2).getStartTimestamp();
+            long dist = Math.abs( obj2StartTS - ((EventFactHandle) object1).getEndTimestamp() );
+            return this.getOperator().isNegated() ^ (dist <= this.finalRange);
+        }
 
         public String toString() {
-            return "meets[" + finalRange + "]";
+            return "meets[" + ((paramText != null) ? paramText : "") + "]";
         }
 
         /* (non-Javadoc)
@@ -259,32 +300,23 @@
         }
 
         /**
-         * This methods tries to parse the string of parameters to customize
-         * the evaluator.
+         * This methods sets the parameters appropriately.
          *
          * @param parameters
          */
-        private void parseParameters(String parameters) {
-            if ( parameters == null || parameters.trim().length() == 0 ) {
-                // exact meet
+        private void setParameters(Long[] parameters) {
+            if ( parameters == null || parameters.length == 0 ) {
                 this.finalRange = 0;
-                return;
-            }
-
-            try {
-                String[] ranges = parameters.split( "," );
-                if ( ranges.length == 1 ) {
-                	// limit of tolerance for overlap or gap, respectively
-                    this.finalRange = Long.parseLong( ranges[0] );
+            } else if ( parameters.length == 1 ) {
+                if ( parameters[0].longValue() >= 0 ) {
+                    // defined max distance
+                    this.finalRange = parameters[0].longValue();
                 } else {
-                    throw new RuntimeDroolsException( "[Meets Evaluator]: Not possible to parse parameters: '" + parameters + "'" );
+                    throw new RuntimeDroolsException( "[Meets Evaluator]: Not possible to use negative parameter: '" + paramText + "'" );
                 }
-            } catch ( NumberFormatException e ) {
-                throw new RuntimeDroolsException( "[Meets Evaluator]: Not possible to parse parameters: '" + parameters + "'",
-                                                  e );
+            } else {
+                throw new RuntimeDroolsException( "[Meets Evaluator]: Not possible to use " + parameters.length + " parameters: '" + paramText + "'" );
             }
         }
-
     }
-
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MetByEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MetByEvaluatorDefinition.java	2008-12-02 02:36:47 UTC (rev 24190)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MetByEvaluatorDefinition.java	2008-12-02 03:10:07 UTC (rev 24191)
@@ -38,29 +38,62 @@
 import org.drools.time.Interval;
 
 /**
- * The implementation of the 'metby' evaluator definition
+ * <p>The implementation of the <code>metby</code> evaluator definition.</p>
+ * 
+ * <p>The <b><code>metby</code></b> evaluator correlates two events and matches when the current event's 
+ * start timestamp happens at the same time as the correlated event's end timestamp.</p> 
+ * 
+ * <p>Lets look at an example:</p>
+ * 
+ * <pre>$eventA : EventA( this metby $eventB )</pre>
  *
+ * <p>The previous pattern will match if and only if the $eventA starts at the same time $eventB finishes. 
+ * In other words:</p>
+ * 
+ * <pre> 
+ * abs( $eventA.startTimestamp - $eventB.endTimestamp ) == 0
+ * </pre>
+ * 
+ * <p>The <b><code>metby</code></b> evaluator accepts one optional parameter. If it is defined, it determines
+ * the maximum distance between the end timestamp of the correlated event and the start timestamp of the current
+ * event in order for the operator to match. Example:</p>
+ * 
+ * <pre>$eventA : EventA( this metby[ 5s ] $eventB )</pre>
+ * 
+ * Will match if and only if:
+ * 
+ * <pre> 
+ * abs( $eventA.startTimestamp - $eventB.endTimestamp) <= 5s 
+ * </pre>
+ * 
+ * <p><b>NOTE:</b> it makes no sense to use a negative interval value for the parameter and the 
+ * engine will raise an exception if that happens.</p>
+ * 
+ * @author etirelli
  * @author mgroch
  */
 public class MetByEvaluatorDefinition
     implements
     EvaluatorDefinition {
 
-    public static final Operator  MET_BY       = Operator.addOperatorToRegistry( "metby",
-                                                                                  false );
-    public static final Operator  NOT_MET_BY   = Operator.addOperatorToRegistry( "metby",
-                                                                                  true );
+    public static final Operator        MET_BY        = Operator.addOperatorToRegistry( "metby",
+                                                                                        false );
+    public static final Operator        NOT_MET_BY    = Operator.addOperatorToRegistry( "metby",
+                                                                                        true );
 
-    private static final String[] SUPPORTED_IDS = { MET_BY.getOperatorString() };
+    private static final String[]       SUPPORTED_IDS = {MET_BY.getOperatorString()};
 
-    private Map<String, MetByEvaluator> cache        = Collections.emptyMap();
+    private Map<String, MetByEvaluator> cache         = Collections.emptyMap();
+    private volatile TimeIntervalParser parser        = new TimeIntervalParser();
 
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        cache  = (Map<String, MetByEvaluator>)in.readObject();
+    @SuppressWarnings("unchecked")
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        cache = (Map<String, MetByEvaluator>) in.readObject();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(cache);
+        out.writeObject( cache );
     }
 
     /**
@@ -99,8 +132,10 @@
         String key = isNegated + ":" + parameterText;
         MetByEvaluator eval = this.cache.get( key );
         if ( eval == null ) {
+            Long[] params = parser.parse( parameterText );
             eval = new MetByEvaluator( type,
                                        isNegated,
+                                       params,
                                        parameterText );
             this.cache.put( key,
                             eval );
@@ -142,29 +177,35 @@
      * Implements the 'metby' evaluator itself
      */
     public static class MetByEvaluator extends BaseEvaluator {
-		private static final long serialVersionUID = 7907908401657594347L;
+        private static final long serialVersionUID = 7907908401657594347L;
 
-		private long                  finalRange;
+        private long              finalRange;
+        private String            paramText;
 
         public MetByEvaluator() {
         }
 
         public MetByEvaluator(final ValueType type,
                               final boolean isNegated,
-                              final String parameters) {
+                              final Long[] parameters,
+                              final String paramText) {
             super( type,
                    isNegated ? NOT_MET_BY : MET_BY );
-            this.parseParameters( parameters );
+            this.paramText = paramText;
+            this.setParameters( parameters );
         }
 
-        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-            super.readExternal(in);
+        public void readExternal(ObjectInput in) throws IOException,
+                                                ClassNotFoundException {
+            super.readExternal( in );
             finalRange = in.readLong();
+            paramText = (String) in.readObject();
         }
 
         public void writeExternal(ObjectOutput out) throws IOException {
-            super.writeExternal(out);
-            out.writeLong(finalRange);
+            super.writeExternal( out );
+            out.writeLong( finalRange );
+            out.writeObject( paramText );
         }
 
         @Override
@@ -176,15 +217,17 @@
         public boolean isTemporal() {
             return true;
         }
-        
+
         @Override
         public Interval getInterval() {
-            if( this.getOperator().isNegated() ) {
-                return new Interval( Interval.MIN, Interval.MAX );
+            if ( this.getOperator().isNegated() ) {
+                return new Interval( Interval.MIN,
+                                     Interval.MAX );
             }
-            return new Interval( Interval.MIN, 0 );
+            return new Interval( Interval.MIN,
+                                 0 );
         }
-        
+
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,
@@ -198,9 +241,9 @@
             if ( context.rightNull ) {
                 return false;
             }
-            long rightStartTS = ((EventFactHandle)((ObjectVariableContextEntry) context).right).getStartTimestamp();
-            long dist = Math.abs(rightStartTS - ((EventFactHandle) left ).getEndTimestamp());
-            return this.getOperator().isNegated() ^ ( ((EventFactHandle) left ).getStartTimestamp() < rightStartTS && dist <= this.finalRange );
+            long rightStartTS = ((EventFactHandle) ((ObjectVariableContextEntry) context).right).getStartTimestamp();
+            long dist = Math.abs( rightStartTS - ((EventFactHandle) left).getEndTimestamp() );
+            return this.getOperator().isNegated() ^ ( dist <= this.finalRange );
         }
 
         public boolean evaluateCachedLeft(InternalWorkingMemory workingMemory,
@@ -210,11 +253,10 @@
                                                 right ) ) {
                 return false;
             }
-            long rightStartTS = ((EventFactHandle) right ).getStartTimestamp();
-            long dist = Math.abs(rightStartTS - ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getEndTimestamp());
+            long rightStartTS = ((EventFactHandle) right).getStartTimestamp();
+            long dist = Math.abs( rightStartTS - ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getEndTimestamp() );
 
-            return this.getOperator().isNegated() ^ ( ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getStartTimestamp() <= rightStartTS &&
-            	    dist <= this.finalRange );
+            return this.getOperator().isNegated() ^ ( dist <= this.finalRange );
         }
 
         public boolean evaluate(InternalWorkingMemory workingMemory,
@@ -226,13 +268,13 @@
                                          object1 ) ) {
                 return false;
             }
-            long obj1StartTS = ((EventFactHandle) object1 ).getStartTimestamp();
-            long dist = Math.abs(obj1StartTS - ((EventFactHandle) object2 ).getEndTimestamp());
-            return this.getOperator().isNegated() ^ ( ((EventFactHandle) object2 ).getStartTimestamp() <= obj1StartTS && dist <= this.finalRange );
+            long obj1StartTS = ((EventFactHandle) object1).getStartTimestamp();
+            long dist = Math.abs( obj1StartTS - ((EventFactHandle) object2).getEndTimestamp() );
+            return this.getOperator().isNegated() ^ ( dist <= this.finalRange );
         }
 
         public String toString() {
-            return "metby[" + finalRange + "]";
+            return "metby[" + ((paramText != null) ? paramText : "") + "]";
         }
 
         /* (non-Javadoc)
@@ -259,29 +301,22 @@
         }
 
         /**
-         * This methods tries to parse the string of parameters to customize
-         * the evaluator.
+         * This methods sets the parameters appropriately.
          *
          * @param parameters
          */
-        private void parseParameters(String parameters) {
-            if ( parameters == null || parameters.trim().length() == 0 ) {
-                // exact metby
+        private void setParameters(Long[] parameters) {
+            if ( parameters == null || parameters.length == 0 ) {
                 this.finalRange = 0;
-                return;
-            }
-
-            try {
-                String[] ranges = parameters.split( "," );
-                if ( ranges.length == 1 ) {
-                    // limit of tolerance for overlap or gap, respectively
-                    this.finalRange = Long.parseLong( ranges[0] );
+            } else if ( parameters.length == 1 ) {
+                if ( parameters[0].longValue() >= 0 ) {
+                    // defined max distance
+                    this.finalRange = parameters[0].longValue();
                 } else {
-                    throw new RuntimeDroolsException( "[Metby Evaluator]: Not possible to parse parameters: '" + parameters + "'" );
+                    throw new RuntimeDroolsException( "[MetBy Evaluator]: Not possible to use negative parameter: '" + paramText + "'" );
                 }
-            } catch ( NumberFormatException e ) {
-                throw new RuntimeDroolsException( "[Metby Evaluator]: Not possible to parse parameters: '" + parameters + "'",
-                                                  e );
+            } else {
+                throw new RuntimeDroolsException( "[MetBy Evaluator]: Not possible to use " + parameters.length + " parameters: '" + paramText + "'" );
             }
         }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlappedByEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlappedByEvaluatorDefinition.java	2008-12-02 02:36:47 UTC (rev 24190)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlappedByEvaluatorDefinition.java	2008-12-02 03:10:07 UTC (rev 24191)
@@ -38,8 +38,48 @@
 import org.drools.time.Interval;
 
 /**
- * The implementation of the 'overlappedby' evaluator definition
+ * <p>The implementation of the <code>overlappedby</code> evaluator definition.</p>
+ * 
+ * <p>The <b><code>overlappedby</code></b> evaluator correlates two events and matches when the correlated event 
+ * starts before the current event starts and finishes after the current event starts, but before
+ * the current event finishes. In other words, both events have an overlapping period.</p> 
+ * 
+ * <p>Lets look at an example:</p>
+ * 
+ * <pre>$eventA : EventA( this overlappedby $eventB )</pre>
  *
+ * <p>The previous pattern will match if and only if:</p>
+ * 
+ * <pre> $eventB.startTimestamp < $eventA.startTimestamp < $eventB.endTimestamp < $eventA.endTimestamp </pre>
+ * 
+ * <p>The <b><code>overlappedby</code></b> operator accepts 1 or 2 optional parameters as follow:</p>
+ * 
+ * <ul><li>If one parameter is defined, this will be the maximum distance between the start timestamp of the
+ * current event and the end timestamp of the correlated event. Example:</li></lu>
+ * 
+ * <pre>$eventA : EventA( this overlappedby[ 5s ] $eventB )</pre>
+ * 
+ * Will match if and only if:
+ * 
+ * <pre> 
+ * $eventB.startTimestamp < $eventA.startTimestamp < $eventB.endTimestamp < $eventA.endTimestamp &&
+ * 0 <= $eventB.endTimestamp - $eventA.startTimestamp <= 5s 
+ * </pre>
+ * 
+ * <ul><li>If two values are defined, the first value will be the minimum distance and the second value will be 
+ * the maximum distance between the start timestamp of the current event and the end timestamp of the correlated 
+ * event. Example:</li></lu>
+ * 
+ * <pre>$eventA : EventA( this overlappedby[ 5s, 10s ] $eventB )</pre>
+ * 
+ * Will match if and only if:
+ * 
+ * <pre> 
+ * $eventB.startTimestamp < $eventA.startTimestamp < $eventB.endTimestamp < $eventA.endTimestamp &&
+ * 5s <= $eventB.endTimestamp - $eventA.startTimestamp <= 10s 
+ * </pre>
+ * 
+ * @author etirelli
  * @author mgroch
  */
 public class OverlappedByEvaluatorDefinition
@@ -54,7 +94,9 @@
     private static final String[] SUPPORTED_IDS = { OVERLAPPED_BY.getOperatorString() };
 
     private Map<String, OverlappedByEvaluator> cache        = Collections.emptyMap();
+    private volatile TimeIntervalParser    parser        = new TimeIntervalParser();
 
+    @SuppressWarnings("unchecked")
     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
         cache  = (Map<String, OverlappedByEvaluator>)in.readObject();
     }
@@ -99,8 +141,10 @@
         String key = isNegated + ":" + parameterText;
         OverlappedByEvaluator eval = this.cache.get( key );
         if ( eval == null ) {
+            Long[] params = parser.parse( parameterText );
             eval = new OverlappedByEvaluator( type,
                                        isNegated,
+                                       params,
                                        parameterText );
             this.cache.put( key,
                             eval );
@@ -144,34 +188,34 @@
     public static class OverlappedByEvaluator extends BaseEvaluator {
 		private static final long serialVersionUID = -2768899194494247889L;
 
-		private long                  startMinDev, startMaxDev;
-        private long                  endMinDev, endMaxDev;
+		private long                  minDev, maxDev;
+        private String                paramText;
 
         public OverlappedByEvaluator() {
         }
 
         public OverlappedByEvaluator(final ValueType type,
                               final boolean isNegated,
-                              final String parameters) {
+                              final Long[] parameters,
+                              final String paramText) {
             super( type,
                    isNegated ? NOT_OVERLAPPED_BY : OVERLAPPED_BY );
-            this.parseParameters( parameters );
+            this.paramText = paramText;
+            this.setParameters( parameters );
         }
 
         public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
             super.readExternal(in);
-            startMinDev = in.readLong();
-            startMaxDev = in.readLong();
-            endMinDev   = in.readLong();
-            endMaxDev   = in.readLong();
+            minDev = in.readLong();
+            maxDev = in.readLong();
+            paramText = (String) in.readObject();
         }
 
         public void writeExternal(ObjectOutput out) throws IOException {
             super.writeExternal(out);
-            out.writeLong(startMinDev);
-            out.writeLong(startMaxDev);
-            out.writeLong(endMinDev);
-            out.writeLong(endMaxDev);
+            out.writeLong(minDev);
+            out.writeLong(maxDev);
+            out.writeObject( paramText );
         }
 
         @Override
@@ -207,10 +251,11 @@
             }
             long rightStartTS = ((EventFactHandle)((ObjectVariableContextEntry) context).right).getStartTimestamp();
 			long leftEndTS = ((EventFactHandle) left ).getEndTimestamp();
-            long distStart = rightStartTS - ((EventFactHandle) left ).getStartTimestamp();
-            long distEnd = ((EventFactHandle)((ObjectVariableContextEntry) context).right).getEndTimestamp() - leftEndTS;
-            return this.getOperator().isNegated() ^ ( distStart >= this.startMinDev && distStart <= this.startMaxDev
-            		&& distEnd >= this.endMinDev && distEnd <= this.endMaxDev && rightStartTS < leftEndTS );
+            long dist = leftEndTS - rightStartTS;
+            return this.getOperator().isNegated() ^ ( 
+                    ((EventFactHandle) left ).getStartTimestamp() < rightStartTS &&
+                    leftEndTS < ((EventFactHandle)((ObjectVariableContextEntry) context).right).getEndTimestamp() &&
+                    dist >= this.minDev && dist <= maxDev );
         }
 
         public boolean evaluateCachedLeft(InternalWorkingMemory workingMemory,
@@ -222,10 +267,11 @@
             }
             long leftEndTS = ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getEndTimestamp();
 			long rightStartTS = ((EventFactHandle) right ).getStartTimestamp();
-            long distStart = rightStartTS - ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getStartTimestamp();
-            long distEnd = ((EventFactHandle) right ).getEndTimestamp() - leftEndTS;
-            return this.getOperator().isNegated() ^ ( distStart >= this.startMinDev && distStart <= this.startMaxDev
-            		&& distEnd >= this.endMinDev && distEnd <= this.endMaxDev && rightStartTS < leftEndTS );
+            long dist = leftEndTS - rightStartTS;
+            return this.getOperator().isNegated() ^ ( 
+                    ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getStartTimestamp() < rightStartTS &&
+                    leftEndTS < ((EventFactHandle) right).getEndTimestamp() &&
+                    dist >= this.minDev && dist <= maxDev );
         }
 
         public boolean evaluate(InternalWorkingMemory workingMemory,
@@ -237,16 +283,16 @@
                                          object1 ) ) {
                 return false;
             }
-            long o1startTS = ((EventFactHandle) object1 ).getStartTimestamp();
-            long o2endTS = ((EventFactHandle) object2 ).getEndTimestamp();
-            long distStart = o1startTS - ((EventFactHandle) object2 ).getStartTimestamp();
-            long distEnd = ((EventFactHandle) object1 ).getEndTimestamp() - o2endTS;
-            return this.getOperator().isNegated() ^ ( distStart >= this.startMinDev && distStart <= this.startMaxDev
-            		&& distEnd >= this.endMinDev && distEnd <= this.endMaxDev && o1startTS < o2endTS );
+            long startTS = ((EventFactHandle) object1).getStartTimestamp();
+            long endTS = ((EventFactHandle) object2).getEndTimestamp();
+            long dist = endTS - startTS;
+            return this.getOperator().isNegated() ^ ( ((EventFactHandle) object2).getStartTimestamp() < startTS &&
+                    endTS < ((EventFactHandle) object1).getEndTimestamp() &&
+                    dist >= this.minDev && dist <= this.maxDev );
         }
 
         public String toString() {
-            return "overlappedby[" + startMinDev + ", " + startMaxDev + ", " + endMinDev + ", " + endMaxDev + "]";
+            return "overlappedby[" + ( ( paramText != null ) ? paramText : "" ) + "]";
         }
 
         /* (non-Javadoc)
@@ -256,10 +302,8 @@
         public int hashCode() {
             final int PRIME = 31;
             int result = super.hashCode();
-            result = PRIME * result + (int) (endMaxDev ^ (endMaxDev >>> 32));
-            result = PRIME * result + (int) (endMinDev ^ (endMinDev >>> 32));
-            result = PRIME * result + (int) (startMaxDev ^ (startMaxDev >>> 32));
-            result = PRIME * result + (int) (startMinDev ^ (startMinDev >>> 32));
+            result = PRIME * result + (int) (maxDev ^ (maxDev >>> 32));
+            result = PRIME * result + (int) (minDev ^ (minDev >>> 32));
             return result;
         }
 
@@ -272,53 +316,30 @@
             if ( !super.equals( obj ) ) return false;
             if ( getClass() != obj.getClass() ) return false;
             final OverlappedByEvaluator other = (OverlappedByEvaluator) obj;
-            return endMaxDev == other.endMaxDev && endMinDev == other.endMinDev
-            	&& startMaxDev == other.startMaxDev && startMinDev == other.startMinDev;
+            return maxDev == other.maxDev && minDev == other.minDev;
         }
 
         /**
-         * This methods tries to parse the string of parameters to customize
-         * the evaluator.
+         * This methods sets the parameters appropriately.
          *
          * @param parameters
          */
-        private void parseParameters(String parameters) {
-            if ( parameters == null || parameters.trim().length() == 0 ) {
-            	// open bounded ranges
-                this.startMinDev = 1;
-                this.startMaxDev = Long.MAX_VALUE;
-                this.endMinDev = 1;
-                this.endMaxDev = Long.MAX_VALUE;
-                return;
+        private void setParameters(Long[] parameters) {
+            if ( parameters == null || parameters.length == 0 ) {
+                // open bounded range
+                this.minDev = 1;
+                this.maxDev = Long.MAX_VALUE;
+            } else if ( parameters.length == 1 ) {
+                // open bounded ranges
+                this.minDev = 1;
+                this.maxDev = parameters[0].longValue();
+            } else if ( parameters.length == 2 ) {
+                // open bounded ranges
+                this.minDev = parameters[0].longValue();
+                this.maxDev = parameters[1].longValue();
+            } else {
+                throw new RuntimeDroolsException( "[Overlaps Evaluator]: Not possible to use " + parameters.length + " parameters: '" + paramText + "'" );
             }
-
-            try {
-                String[] ranges = parameters.split( "," );
-                if ( ranges.length == 1 ) {
-                    // deterministic point in time for deviation of the starts of the intervals
-                	this.startMinDev = Long.parseLong( ranges[0] );
-                    this.startMaxDev = this.startMinDev;
-                    this.endMinDev = this.startMinDev;
-                    this.endMaxDev = this.startMinDev;
-                } else if ( ranges.length == 2 ) {
-                    // deterministic points in time for deviations of the starts and the ends of the intervals
-                    this.startMinDev = Long.parseLong( ranges[0] );
-                    this.startMaxDev = this.startMinDev;
-                    this.endMinDev = Long.parseLong( ranges[1] );
-                    this.endMaxDev = this.endMinDev;
-                } else if ( ranges.length == 4 ) {
-                    // ranges for deviations of the starts and the ends of the intervals
-                	this.startMinDev = Long.parseLong( ranges[0] );
-                    this.startMaxDev = Long.parseLong( ranges[1] );
-                    this.endMinDev = Long.parseLong( ranges[2] );
-                    this.endMaxDev = Long.parseLong( ranges[3] );
-                } else {
-                    throw new RuntimeDroolsException( "[Overlappedby Evaluator]: Not possible to parse parameters: '" + parameters + "'" );
-                }
-            } catch ( NumberFormatException e ) {
-                throw new RuntimeDroolsException( "[Overlappedby Evaluator]: Not possible to parse parameters: '" + parameters + "'",
-                                                  e );
-            }
         }
 
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlapsEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlapsEvaluatorDefinition.java	2008-12-02 02:36:47 UTC (rev 24190)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlapsEvaluatorDefinition.java	2008-12-02 03:10:07 UTC (rev 24191)
@@ -38,29 +38,72 @@
 import org.drools.time.Interval;
 
 /**
- * The implementation of the 'overlaps' evaluator definition
+ * <p>The implementation of the <code>overlaps</code> evaluator definition.</p>
+ * 
+ * <p>The <b><code>overlaps</code></b> evaluator correlates two events and matches when the current event 
+ * starts before the correlated event starts and finishes after the correlated event starts, but before
+ * the correlated event finishes. In other words, both events have an overlapping period.</p> 
+ * 
+ * <p>Lets look at an example:</p>
+ * 
+ * <pre>$eventA : EventA( this overlaps $eventB )</pre>
  *
+ * <p>The previous pattern will match if and only if:</p>
+ * 
+ * <pre> $eventA.startTimestamp < $eventB.startTimestamp < $eventA.endTimestamp < $eventB.endTimestamp </pre>
+ * 
+ * <p>The <b><code>overlaps</code></b> operator accepts 1 or 2 optional parameters as follow:</p>
+ * 
+ * <ul><li>If one parameter is defined, this will be the maximum distance between the start timestamp of the
+ * correlated event and the end timestamp of the current event. Example:</li></lu>
+ * 
+ * <pre>$eventA : EventA( this overlaps[ 5s ] $eventB )</pre>
+ * 
+ * Will match if and only if:
+ * 
+ * <pre> 
+ * $eventA.startTimestamp < $eventB.startTimestamp < $eventA.endTimestamp < $eventB.endTimestamp &&
+ * 0 <= $eventA.endTimestamp - $eventB.startTimestamp <= 5s 
+ * </pre>
+ * 
+ * <ul><li>If two values are defined, the first value will be the minimum distance and the second value will be 
+ * the maximum distance between the start timestamp of the correlated event and the end timestamp of the current 
+ * event. Example:</li></lu>
+ * 
+ * <pre>$eventA : EventA( this overlaps[ 5s, 10s ] $eventB )</pre>
+ * 
+ * Will match if and only if:
+ * 
+ * <pre> 
+ * $eventA.startTimestamp < $eventB.startTimestamp < $eventA.endTimestamp < $eventB.endTimestamp &&
+ * 5s <= $eventA.endTimestamp - $eventB.startTimestamp <= 10s 
+ * </pre>
+ * 
+ * @author etirelli
  * @author mgroch
  */
 public class OverlapsEvaluatorDefinition
     implements
     EvaluatorDefinition {
 
-    public static final Operator  OVERLAPS       = Operator.addOperatorToRegistry( "overlaps",
-                                                                                  false );
-    public static final Operator  OVERLAPS_NOT   = Operator.addOperatorToRegistry( "overlaps",
-                                                                                  true );
+    public static final Operator           OVERLAPS      = Operator.addOperatorToRegistry( "overlaps",
+                                                                                           false );
+    public static final Operator           OVERLAPS_NOT  = Operator.addOperatorToRegistry( "overlaps",
+                                                                                           true );
 
-    private static final String[] SUPPORTED_IDS = { OVERLAPS.getOperatorString() };
+    private static final String[]          SUPPORTED_IDS = {OVERLAPS.getOperatorString()};
 
-    private Map<String, OverlapsEvaluator> cache        = Collections.emptyMap();
+    private Map<String, OverlapsEvaluator> cache         = Collections.emptyMap();
+    private volatile TimeIntervalParser    parser        = new TimeIntervalParser();
 
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        cache  = (Map<String, OverlapsEvaluator>)in.readObject();
+    @SuppressWarnings("unchecked")
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        cache = (Map<String, OverlapsEvaluator>) in.readObject();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(cache);
+        out.writeObject( cache );
     }
 
     /**
@@ -99,9 +142,11 @@
         String key = isNegated + ":" + parameterText;
         OverlapsEvaluator eval = this.cache.get( key );
         if ( eval == null ) {
+            Long[] params = parser.parse( parameterText );
             eval = new OverlapsEvaluator( type,
-                                       isNegated,
-                                       parameterText );
+                                          isNegated,
+                                          params,
+                                          parameterText );
             this.cache.put( key,
                             eval );
         }
@@ -142,36 +187,37 @@
      * Implements the 'overlaps' evaluator itself
      */
     public static class OverlapsEvaluator extends BaseEvaluator {
-		private static final long serialVersionUID = -5108524288774833244L;
+        private static final long serialVersionUID = -5108524288774833244L;
 
-		private long                  startMinDev, startMaxDev;
-        private long                  endMinDev, endMaxDev;
+        private long              minDev, maxDev;
+        private String            paramText;
 
         public OverlapsEvaluator() {
         }
 
         public OverlapsEvaluator(final ValueType type,
-                              final boolean isNegated,
-                              final String parameters) {
+                                 final boolean isNegated,
+                                 final Long[] parameters, 
+                                 final String paramText) {
             super( type,
                    isNegated ? OVERLAPS_NOT : OVERLAPS );
-            this.parseParameters( parameters );
+            this.paramText = paramText;
+            this.setParameters( parameters );
         }
 
-        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-            super.readExternal(in);
-            startMinDev    = in.readLong();
-            startMaxDev   = in.readLong();
-            endMinDev   = in.readLong();
-            endMaxDev   = in.readLong();
+        public void readExternal(ObjectInput in) throws IOException,
+                                                ClassNotFoundException {
+            super.readExternal( in );
+            minDev = in.readLong();
+            maxDev = in.readLong();
+            paramText = (String) in.readObject();
         }
 
         public void writeExternal(ObjectOutput out) throws IOException {
-            super.writeExternal(out);
-            out.writeLong(startMinDev);
-            out.writeLong(startMaxDev);
-            out.writeLong(endMinDev);
-            out.writeLong(endMaxDev);
+            super.writeExternal( out );
+            out.writeLong( minDev );
+            out.writeLong( maxDev );
+            out.writeObject( paramText );
         }
 
         @Override
@@ -183,15 +229,17 @@
         public boolean isTemporal() {
             return true;
         }
-        
+
         @Override
         public Interval getInterval() {
-            if( this.getOperator().isNegated() ) {
-                return new Interval( Interval.MIN, Interval.MAX );
+            if ( this.getOperator().isNegated() ) {
+                return new Interval( Interval.MIN,
+                                     Interval.MAX );
             }
-            return new Interval( Interval.MIN, 0 );
+            return new Interval( Interval.MIN,
+                                 0 );
         }
-        
+
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,
@@ -200,54 +248,54 @@
         }
 
         public boolean evaluateCachedRight(InternalWorkingMemory workingMemory,
-                final VariableContextEntry context,
-                final Object left) {
+                                           final VariableContextEntry context,
+                                           final Object left) {
 
-        	if ( context.rightNull ) {
-        		return false;
-				}
-        	long leftStartTS = ((EventFactHandle) left ).getStartTimestamp();
-			long rightEndTS = ((EventFactHandle)((ObjectVariableContextEntry) context).right).getEndTimestamp();
-			long distStart = leftStartTS - ((EventFactHandle)((ObjectVariableContextEntry) context).right).getStartTimestamp();
-			long distEnd = ((EventFactHandle) left ).getEndTimestamp()- rightEndTS;
-			return this.getOperator().isNegated() ^ ( distStart >= this.startMinDev && distStart <= this.startMaxDev
-					&& distEnd >= this.endMinDev && distEnd <= this.endMaxDev && leftStartTS < rightEndTS );
-		}
+            if ( context.rightNull ) {
+                return false;
+            }
+            long leftStartTS = ((EventFactHandle) left).getStartTimestamp();
+            long rightEndTS = ((EventFactHandle) ((ObjectVariableContextEntry) context).right).getEndTimestamp();
+            long dist = rightEndTS - leftStartTS;
+            return this.getOperator().isNegated() ^ ( ((EventFactHandle) ((ObjectVariableContextEntry) context).right).getStartTimestamp() < leftStartTS &&
+                                                      rightEndTS < ((EventFactHandle) left).getEndTimestamp() &&
+                                                      dist >= this.minDev && dist <= this.maxDev );
+        }
 
-		public boolean evaluateCachedLeft(InternalWorkingMemory workingMemory,
-			               final VariableContextEntry context,
-			               final Object right) {
-			if ( context.extractor.isNullValue( workingMemory,
-			                     right ) ) {
-			return false;
-			}
-			long leftStartTS = ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getStartTimestamp();
-			long rightEndTS = ((EventFactHandle) right ).getEndTimestamp();
-			long distStart = leftStartTS - ((EventFactHandle) right ).getStartTimestamp();
-			long distEnd = ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getEndTimestamp() - rightEndTS;
-			return this.getOperator().isNegated() ^ ( distStart >= this.startMinDev && distStart <= this.startMaxDev
-					&& distEnd >= this.endMinDev && distEnd <= this.endMaxDev && leftStartTS < rightEndTS );
-		}
+        public boolean evaluateCachedLeft(InternalWorkingMemory workingMemory,
+                                          final VariableContextEntry context,
+                                          final Object right) {
+            if ( context.extractor.isNullValue( workingMemory,
+                                                right ) ) {
+                return false;
+            }
+            long leftStartTS = ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getStartTimestamp();
+            long rightEndTS = ((EventFactHandle) right).getEndTimestamp();
+            long dist = rightEndTS - leftStartTS;
+            return this.getOperator().isNegated() ^ ( ((EventFactHandle) right).getStartTimestamp() < leftStartTS &&
+                    rightEndTS < ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getEndTimestamp() &&
+                    dist >= this.minDev && dist <= this.maxDev );
+        }
 
-		public boolean evaluate(InternalWorkingMemory workingMemory,
-			     final InternalReadAccessor extractor1,
-			     final Object object1,
-			     final InternalReadAccessor extractor2,
-			     final Object object2) {
-			if ( extractor1.isNullValue( workingMemory,
-			              object1 ) ) {
-			return false;
-			}
-			long o2startTS = ((EventFactHandle) object2 ).getStartTimestamp();
-			long o1endTS = ((EventFactHandle) object1 ).getEndTimestamp();
-			long distStart = o2startTS - ((EventFactHandle) object1 ).getStartTimestamp();
-			long distEnd = ((EventFactHandle) object2 ).getEndTimestamp() - o1endTS;
-			return this.getOperator().isNegated() ^ ( distStart >= this.startMinDev && distStart <= this.startMaxDev
-					&& distEnd >= this.endMinDev && distEnd <= this.endMaxDev && o2startTS < o1endTS );
-		}
+        public boolean evaluate(InternalWorkingMemory workingMemory,
+                                final InternalReadAccessor extractor1,
+                                final Object object1,
+                                final InternalReadAccessor extractor2,
+                                final Object object2) {
+            if ( extractor1.isNullValue( workingMemory,
+                                         object1 ) ) {
+                return false;
+            }
+            long startTS = ((EventFactHandle) object2).getStartTimestamp();
+            long endTS = ((EventFactHandle) object1).getEndTimestamp();
+            long dist = endTS - startTS;
+            return this.getOperator().isNegated() ^ ( ((EventFactHandle) object1).getStartTimestamp() < startTS &&
+                    endTS < ((EventFactHandle) object2).getEndTimestamp() &&
+                    dist >= this.minDev && dist <= this.maxDev );
+        }
 
         public String toString() {
-            return "overlaps[" + startMinDev + ", " + startMaxDev + ", " + endMinDev + ", " + endMaxDev + "]";
+            return "overlaps[" + ( ( paramText != null ) ? paramText : "" ) + "]";
         }
 
         /* (non-Javadoc)
@@ -257,10 +305,8 @@
         public int hashCode() {
             final int PRIME = 31;
             int result = super.hashCode();
-            result = PRIME * result + (int) (endMaxDev ^ (endMaxDev >>> 32));
-            result = PRIME * result + (int) (endMinDev ^ (endMinDev >>> 32));
-            result = PRIME * result + (int) (startMaxDev ^ (startMaxDev >>> 32));
-            result = PRIME * result + (int) (startMinDev ^ (startMinDev >>> 32));
+            result = PRIME * result + (int) (maxDev ^ (maxDev >>> 32));
+            result = PRIME * result + (int) (minDev ^ (minDev >>> 32));
             return result;
         }
 
@@ -273,55 +319,33 @@
             if ( !super.equals( obj ) ) return false;
             if ( getClass() != obj.getClass() ) return false;
             final OverlapsEvaluator other = (OverlapsEvaluator) obj;
-            return endMaxDev == other.endMaxDev && endMinDev == other.endMinDev
-            	&& startMaxDev == other.startMaxDev && startMinDev == other.startMinDev;
+            return maxDev == other.maxDev && minDev == other.minDev ;
         }
 
         /**
-         * This methods tries to parse the string of parameters to customize
-         * the evaluator.
+         * This methods sets the parameters appropriately.
          *
          * @param parameters
          */
-        private void parseParameters(String parameters) {
-            if ( parameters == null || parameters.trim().length() == 0 ) {
+        private void setParameters(Long[] parameters) {
+            if ( parameters == null || parameters.length == 0 ) {
+                // open bounded range
+                this.minDev = 1;
+                this.maxDev = Long.MAX_VALUE;
+            } else if ( parameters.length == 1 ) {
                 // open bounded ranges
-                this.startMinDev = 1;
-                this.startMaxDev = Long.MAX_VALUE;
-                this.endMinDev = 1;
-                this.endMaxDev = Long.MAX_VALUE;
-                return;
+                this.minDev = 1;
+                this.maxDev = parameters[0].longValue();
+            } else if ( parameters.length == 2 ) {
+                // open bounded ranges
+                this.minDev = parameters[0].longValue();
+                this.maxDev = parameters[1].longValue();
+            } else {
+                throw new RuntimeDroolsException( "[Overlaps Evaluator]: Not possible to use " + parameters.length + " parameters: '" + paramText + "'" );
             }
-
-            try {
-                String[] ranges = parameters.split( "," );
-                if ( ranges.length == 1 ) {
-                    // deterministic point in time for deviation of the starts of the intervals
-                    this.startMinDev = Long.parseLong( ranges[0] );
-                    this.startMaxDev = this.startMinDev;
-                    this.endMinDev = this.startMinDev;
-                    this.endMaxDev = this.startMinDev;
-                } else if ( ranges.length == 2 ) {
-                    // deterministic points in time for deviations of the starts and the ends of the intervals
-                    this.startMinDev = Long.parseLong( ranges[0] );
-                    this.startMaxDev = this.startMinDev;
-                    this.endMinDev = Long.parseLong( ranges[1] );
-                    this.endMaxDev = this.endMinDev;
-                } else if ( ranges.length == 4 ) {
-                    // ranges for deviations of the starts and the ends of the intervals
-                	this.startMinDev = Long.parseLong( ranges[0] );
-                    this.startMaxDev = Long.parseLong( ranges[1] );
-                    this.endMinDev = Long.parseLong( ranges[2] );
-                    this.endMaxDev = Long.parseLong( ranges[3] );
-                } else {
-                    throw new RuntimeDroolsException( "[Overlaps Evaluator]: Not possible to parse parameters: '" + parameters + "'" );
-                }
-            } catch ( NumberFormatException e ) {
-                throw new RuntimeDroolsException( "[Overlaps Evaluator]: Not possible to parse parameters: '" + parameters + "'",
-                                                  e );
-            }
         }
 
+
     }
 
 }

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/base/TemporalEvaluatorFactoryTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/base/TemporalEvaluatorFactoryTest.java	2008-12-02 02:36:47 UTC (rev 24190)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/base/TemporalEvaluatorFactoryTest.java	2008-12-02 03:10:07 UTC (rev 24191)
@@ -622,6 +622,226 @@
                           ValueType.OBJECT_TYPE );
     }
 
+    public void testMeets() {
+        registry.addEvaluatorDefinition( DuringEvaluatorDefinition.class.getName() );
+
+        EventFactHandle foo = new EventFactHandle( 1,
+                                                   "foo",
+                                                   1,
+                                                   2,
+                                                   8 );
+        EventFactHandle bar = new EventFactHandle( 2,
+                                                   "bar",
+                                                   1,
+                                                   10,
+                                                   7 );
+        EventFactHandle drool = new EventFactHandle( 1,
+                                                     "drool",
+                                                     1,
+                                                     8,
+                                                     5 );
+        EventFactHandle mole = new EventFactHandle( 1,
+                                                    "mole",
+                                                    1,
+                                                    11,
+                                                    4 );
+
+        final Object[][] data = {
+             {foo,   "meets", bar, Boolean.TRUE}, 
+             {foo,   "meets", drool, Boolean.FALSE}, 
+             {foo,   "meets", mole, Boolean.FALSE}, 
+             
+             {foo,   "not meets", bar, Boolean.FALSE}, 
+             {foo,   "not meets", drool, Boolean.TRUE}, 
+             {foo,   "not meets", mole, Boolean.TRUE}, 
+             
+             {foo,   "meets[1]", bar, Boolean.TRUE}, 
+             {foo,   "meets[1]", drool, Boolean.FALSE}, 
+             {foo,   "meets[1]", mole, Boolean.TRUE}, 
+             {foo,   "meets[2]", drool, Boolean.TRUE}, 
+             
+             {foo,   "not meets[1]", bar, Boolean.FALSE}, 
+             {foo,   "not meets[1]", drool, Boolean.TRUE}, 
+             {foo,   "not meets[1]", mole, Boolean.FALSE}, 
+             {foo,   "not meets[2]", drool, Boolean.FALSE} 
+            };
+
+        runEvaluatorTest( data,
+                          ValueType.OBJECT_TYPE );
+    }
+
+    public void testMetBy() {
+        registry.addEvaluatorDefinition( DuringEvaluatorDefinition.class.getName() );
+
+        EventFactHandle foo = new EventFactHandle( 1,
+                                                   "foo",
+                                                   1,
+                                                   10,
+                                                   8 );
+        EventFactHandle bar = new EventFactHandle( 2,
+                                                   "bar",
+                                                   1,
+                                                   2,
+                                                   8 );
+        EventFactHandle drool = new EventFactHandle( 1,
+                                                     "drool",
+                                                     1,
+                                                     5,
+                                                     3 );
+        EventFactHandle mole = new EventFactHandle( 1,
+                                                    "mole",
+                                                    1,
+                                                    4,
+                                                    7 );
+
+        final Object[][] data = {
+             {foo,   "metby", bar, Boolean.TRUE}, 
+             {foo,   "metby", drool, Boolean.FALSE}, 
+             {foo,   "metby", mole, Boolean.FALSE}, 
+             
+             {foo,   "not metby", bar, Boolean.FALSE}, 
+             {foo,   "not metby", drool, Boolean.TRUE}, 
+             {foo,   "not metby", mole, Boolean.TRUE}, 
+             
+             {foo,   "metby[1]", bar, Boolean.TRUE}, 
+             {foo,   "metby[1]", drool, Boolean.FALSE}, 
+             {foo,   "metby[1]", mole, Boolean.TRUE}, 
+             {foo,   "metby[2]", drool, Boolean.TRUE}, 
+             
+             {foo,   "not metby[1]", bar, Boolean.FALSE}, 
+             {foo,   "not metby[1]", drool, Boolean.TRUE}, 
+             {foo,   "not metby[1]", mole, Boolean.FALSE}, 
+             {foo,   "not metby[2]", drool, Boolean.FALSE} 
+            };
+
+        runEvaluatorTest( data,
+                          ValueType.OBJECT_TYPE );
+    }
+
+    public void testOverlaps() {
+        registry.addEvaluatorDefinition( DuringEvaluatorDefinition.class.getName() );
+
+        EventFactHandle foo = new EventFactHandle( 1,
+                                                   "foo",
+                                                   1,
+                                                   2,
+                                                   8 );
+        EventFactHandle bar = new EventFactHandle( 2,
+                                                   "bar",
+                                                   1,
+                                                   7,
+                                                   7 );
+        EventFactHandle drool = new EventFactHandle( 1,
+                                                     "drool",
+                                                     1,
+                                                     11,
+                                                     5 );
+        EventFactHandle mole = new EventFactHandle( 1,
+                                                    "mole",
+                                                    1,
+                                                    5,
+                                                    5 );
+
+        final Object[][] data = {
+             {foo,   "overlaps", bar, Boolean.TRUE}, 
+             {foo,   "overlaps", drool, Boolean.FALSE}, 
+             {foo,   "overlaps", mole, Boolean.FALSE}, 
+             
+             {foo,   "not overlaps", bar, Boolean.FALSE}, 
+             {foo,   "not overlaps", drool, Boolean.TRUE}, 
+             {foo,   "not overlaps", mole, Boolean.TRUE}, 
+             
+             {foo,   "overlaps[3]", bar, Boolean.TRUE}, 
+             {foo,   "overlaps[3]", drool, Boolean.FALSE}, 
+             {foo,   "overlaps[3]", mole, Boolean.FALSE}, 
+             {foo,   "overlaps[2]", bar, Boolean.FALSE}, 
+             {foo,   "overlaps[6]", mole, Boolean.FALSE}, 
+             
+             {foo,   "not overlaps[3]", bar, Boolean.FALSE}, 
+             {foo,   "not overlaps[3]", drool, Boolean.TRUE}, 
+             {foo,   "not overlaps[3]", mole, Boolean.TRUE}, 
+             {foo,   "not overlaps[2]", bar, Boolean.TRUE}, 
+             {foo,   "not overlaps[6]", mole, Boolean.TRUE},
+             
+             {foo,   "overlaps[1,3]", bar, Boolean.TRUE}, 
+             {foo,   "overlaps[1,3]", drool, Boolean.FALSE}, 
+             {foo,   "overlaps[1,3]", mole, Boolean.FALSE}, 
+             {foo,   "overlaps[4,6]", bar, Boolean.FALSE}, 
+             {foo,   "overlaps[1,8]", mole, Boolean.FALSE}, 
+             
+             {foo,   "not overlaps[1,3]", bar, Boolean.FALSE}, 
+             {foo,   "not overlaps[1,3]", drool, Boolean.TRUE}, 
+             {foo,   "not overlaps[1,3]", mole, Boolean.TRUE}, 
+             {foo,   "not overlaps[4,6]", bar, Boolean.TRUE}, 
+             {foo,   "not overlaps[1,8]", mole, Boolean.TRUE} 
+            };
+
+        runEvaluatorTest( data,
+                          ValueType.OBJECT_TYPE );
+    }
+
+    public void testOverlapedBy() {
+        registry.addEvaluatorDefinition( DuringEvaluatorDefinition.class.getName() );
+
+        EventFactHandle foo = new EventFactHandle( 1,
+                                                   "foo",
+                                                   1,
+                                                   7,
+                                                   8 );
+        EventFactHandle bar = new EventFactHandle( 2,
+                                                   "bar",
+                                                   1,
+                                                   2,
+                                                   8 );
+        EventFactHandle drool = new EventFactHandle( 1,
+                                                     "drool",
+                                                     1,
+                                                     11,
+                                                     5 );
+        EventFactHandle mole = new EventFactHandle( 1,
+                                                    "mole",
+                                                    1,
+                                                    7,
+                                                    3 );
+
+        final Object[][] data = {
+             {foo,   "overlappedby", bar, Boolean.TRUE}, 
+             {foo,   "overlappedby", drool, Boolean.FALSE}, 
+             {foo,   "overlappedby", mole, Boolean.FALSE}, 
+             
+             {foo,   "not overlappedby", bar, Boolean.FALSE}, 
+             {foo,   "not overlappedby", drool, Boolean.TRUE}, 
+             {foo,   "not overlappedby", mole, Boolean.TRUE}, 
+             
+             {foo,   "overlappedby[3]", bar, Boolean.TRUE}, 
+             {foo,   "overlappedby[3]", drool, Boolean.FALSE}, 
+             {foo,   "overlappedby[3]", mole, Boolean.FALSE}, 
+             {foo,   "overlappedby[2]", bar, Boolean.FALSE}, 
+             {foo,   "overlappedby[6]", mole, Boolean.FALSE}, 
+             
+             {foo,   "not overlappedby[3]", bar, Boolean.FALSE}, 
+             {foo,   "not overlappedby[3]", drool, Boolean.TRUE}, 
+             {foo,   "not overlappedby[3]", mole, Boolean.TRUE}, 
+             {foo,   "not overlappedby[2]", bar, Boolean.TRUE}, 
+             {foo,   "not overlappedby[6]", mole, Boolean.TRUE},
+             
+             {foo,   "overlappedby[1,3]", bar, Boolean.TRUE}, 
+             {foo,   "overlappedby[1,3]", drool, Boolean.FALSE}, 
+             {foo,   "overlappedby[1,3]", mole, Boolean.FALSE}, 
+             {foo,   "overlappedby[4,6]", bar, Boolean.FALSE}, 
+             {foo,   "overlappedby[1,8]", mole, Boolean.FALSE}, 
+             
+             {foo,   "not overlappedby[1,3]", bar, Boolean.FALSE}, 
+             {foo,   "not overlappedby[1,3]", drool, Boolean.TRUE}, 
+             {foo,   "not overlappedby[1,3]", mole, Boolean.TRUE}, 
+             {foo,   "not overlappedby[4,6]", bar, Boolean.TRUE}, 
+             {foo,   "not overlappedby[1,8]", mole, Boolean.TRUE} 
+            };
+
+        runEvaluatorTest( data,
+                          ValueType.OBJECT_TYPE );
+    }
+
     private void runEvaluatorTest(final Object[][] data,
                                   final ValueType valueType) {
         final InternalReadAccessor extractor = new MockExtractor();




More information about the jboss-svn-commits mailing list