[jboss-svn-commits] JBL Code SVN: r24155 - in labs/jbossrules/trunk/drools-core/src: test/java/org/drools/base and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Sun Nov 30 16:04:10 EST 2008


Author: tirelli
Date: 2008-11-30 16:04:09 -0500 (Sun, 30 Nov 2008)
New Revision: 24155

Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/FinishesEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartedByEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartsEvaluatorDefinition.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/base/evaluators/FinishesEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/FinishesEvaluatorDefinition.java	2008-11-30 19:58:57 UTC (rev 24154)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/FinishesEvaluatorDefinition.java	2008-11-30 21:04:09 UTC (rev 24155)
@@ -40,8 +40,8 @@
 /**
  * <p>The implementation of the <code>finishes</code> evaluator definition.</p>
  * 
- * <p>The <b><code>finishes</code></b> evaluator correlates two events and matches when the current event 
- * start timestamp happens after the correlated event start timestamp, but both end timestamps occur at
+ * <p>The <b><code>finishes</code></b> evaluator correlates two events and matches when the current event's 
+ * start timestamp happens after the correlated event's start timestamp, but both end timestamps occur at
  * the same time.</p> 
  * 
  * <p>Lets look at an example:</p>

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartedByEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartedByEvaluatorDefinition.java	2008-11-30 19:58:57 UTC (rev 24154)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartedByEvaluatorDefinition.java	2008-11-30 21:04:09 UTC (rev 24155)
@@ -38,8 +38,40 @@
 import org.drools.time.Interval;
 
 /**
- * The implementation of the 'startedby' evaluator definition
+ * <p>The implementation of the <code>startedby</code> evaluator definition.</p>
+ * 
+ * <p>The <b><code>startedby</code></b> evaluator correlates two events and matches when the correlating event's 
+ * end timestamp happens before the current event's end timestamp, but both start timestamps occur at
+ * the same time.</p> 
+ * 
+ * <p>Lets look at an example:</p>
+ * 
+ * <pre>$eventA : EventA( this startedby $eventB )</pre>
  *
+ * <p>The previous pattern will match if and only if the $eventB finishes before $eventA finishes and starts
+ * at the same time $eventB starts. In other words:</p>
+ * 
+ * <pre> 
+ * $eventA.startTimestamp == $eventB.startTimestamp &&
+ * $eventA.endTimestamp > $eventB.endTimestamp 
+ * </pre>
+ * 
+ * <p>The <b><code>startedby</code></b> evaluator accepts one optional parameter. If it is defined, it determines
+ * the maximum distance between the start timestamp of both events in order for the operator to match. Example:</p>
+ * 
+ * <pre>$eventA : EventA( this starts[ 5s ] $eventB )</pre>
+ * 
+ * Will match if and only if:
+ * 
+ * <pre> 
+ * abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 5s &&
+ * $eventA.endTimestamp > $eventB.endTimestamp 
+ * </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 StartedByEvaluatorDefinition
@@ -54,7 +86,9 @@
     private static final String[] SUPPORTED_IDS = { STARTED_BY.getOperatorString() };
 
     private Map<String, StartedByEvaluator> cache        = Collections.emptyMap();
+    private volatile TimeIntervalParser  parser        = new TimeIntervalParser();
 
+    @SuppressWarnings("unchecked")
     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
         cache  = (Map<String, StartedByEvaluator>)in.readObject();
     }
@@ -99,8 +133,10 @@
         String key = isNegated + ":" + parameterText;
         StartedByEvaluator eval = this.cache.get( key );
         if ( eval == null ) {
+            Long[] params = parser.parse( parameterText );
             eval = new StartedByEvaluator( type,
                                        isNegated,
+                                       params,
                                        parameterText );
             this.cache.put( key,
                             eval );
@@ -145,31 +181,31 @@
 		private static final long serialVersionUID = -2655549435451501420L;
 
 		private long                  startDev;
-        private long                  endMinDev, endMaxDev;
+        private String            paramText;
 
         public StartedByEvaluator() {
         }
 
         public StartedByEvaluator(final ValueType type,
                               final boolean isNegated,
-                              final String parameters) {
+                              final Long[] params,
+                              final String paramText) {
             super( type,
                    isNegated ? NOT_STARTED_BY : STARTED_BY );
-            this.parseParameters( parameters );
+            this.paramText = paramText;
+            this.setParameters( params );
         }
 
         public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
             super.readExternal(in);
             startDev = in.readLong();
-            endMinDev   = in.readLong();
-            endMaxDev   = in.readLong();
+            paramText = (String) in.readObject();
         }
 
         public void writeExternal(ObjectOutput out) throws IOException {
             super.writeExternal(out);
             out.writeLong(startDev);
-            out.writeLong(endMinDev);
-            out.writeLong(endMaxDev);
+            out.writeObject( paramText );
         }
 
         @Override
@@ -206,8 +242,7 @@
 				}
 			long distStart = Math.abs(((EventFactHandle)((ObjectVariableContextEntry) context).right).getStartTimestamp() - ((EventFactHandle) left ).getStartTimestamp());
 			long distEnd = ((EventFactHandle)((ObjectVariableContextEntry) context).right).getEndTimestamp() - ((EventFactHandle) left ).getEndTimestamp();
-			return this.getOperator().isNegated() ^ ( distStart <= this.startDev
-					&& distEnd >= this.endMinDev && distEnd <= this.endMaxDev );
+			return this.getOperator().isNegated() ^ ( distStart <= this.startDev && distEnd > 0 );
 		}
 
 		public boolean evaluateCachedLeft(InternalWorkingMemory workingMemory,
@@ -219,8 +254,7 @@
 			}
 			long distStart = Math.abs(((EventFactHandle) right ).getStartTimestamp() - ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getStartTimestamp());
 			long distEnd = ((EventFactHandle) right ).getEndTimestamp() - ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getEndTimestamp();
-			return this.getOperator().isNegated() ^ ( distStart <= this.startDev
-					&& distEnd >= this.endMinDev && distEnd <= this.endMaxDev );
+            return this.getOperator().isNegated() ^ ( distStart <= this.startDev && distEnd > 0 );
 		}
 
 		public boolean evaluate(InternalWorkingMemory workingMemory,
@@ -234,12 +268,11 @@
 			}
 			long distStart = Math.abs(((EventFactHandle) object1 ).getStartTimestamp() - ((EventFactHandle) object2 ).getStartTimestamp());
 			long distEnd = ((EventFactHandle) object1 ).getEndTimestamp() - ((EventFactHandle) object2 ).getEndTimestamp();
-			return this.getOperator().isNegated() ^ ( distStart  <= this.startDev
-					&& distEnd >= this.endMinDev && distEnd <= this.endMaxDev );
+            return this.getOperator().isNegated() ^ ( distStart <= this.startDev && distEnd > 0 );
 		}
 
         public String toString() {
-            return "startedby[" + startDev + ", " + endMinDev + ", " + endMaxDev + "]";
+            return "startedby[" + ((paramText != null) ? paramText : "") + "]";
         }
 
         /* (non-Javadoc)
@@ -249,8 +282,6 @@
         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) (startDev ^ (startDev >>> 32));
             return result;
         }
@@ -264,50 +295,26 @@
             if ( !super.equals( obj ) ) return false;
             if ( getClass() != obj.getClass() ) return false;
             final StartedByEvaluator other = (StartedByEvaluator) obj;
-            return endMaxDev == other.endMaxDev && endMinDev == other.endMinDev && startDev == other.startDev;
+            return startDev == other.startDev;
         }
 
         /**
-         * 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 matching at the beginning of the intervals, open bounded ranges for the ends
+        private void setParameters(Long[] parameters) {
+            if ( parameters == null || parameters.length == 0 ) {
                 this.startDev = 0;
-                this.endMinDev = 1;
-                this.endMaxDev = Long.MAX_VALUE;
-                return;
-            }
-
-            try {
-                String[] ranges = parameters.split( "," );
-                if ( ranges.length == 1 ) {
-                    // exact matching at the beginning of the intervals
-                	// deterministic point in time for deviations of the ends of the intervals
-                	this.startDev = 0;
-                	this.endMinDev = Long.parseLong( ranges[0] );
-                    this.endMaxDev = this.endMinDev;
-                } else if ( ranges.length == 2 ) {
-                    // exact matching at the beginning of the intervals
-                	// range for deviations of the ends of the intervals
-                	this.startDev = 0;
-                    this.endMinDev = Long.parseLong( ranges[0] );
-                    this.endMaxDev = Long.parseLong( ranges[1] );
-                } else if ( ranges.length == 3 ) {
-                	// max. deviation at the starts of the intervals
-                	// range for deviations of the ends of the intervals
-                	this.startDev = Long.parseLong( ranges[0] );;
-                    this.endMinDev = Long.parseLong( ranges[1] );
-                    this.endMaxDev = Long.parseLong( ranges[2] );
+            } else if ( parameters.length == 1 ) {
+                if( parameters[0].longValue() >= 0 ) {
+                    // defined deviation for end timestamp
+                    this.startDev = parameters[0].longValue();
                 } else {
-                    throw new RuntimeDroolsException( "[StartedBy Evaluator]: Not possible to parse parameters: '" + parameters + "'" );
+                    throw new RuntimeDroolsException("[StartedBy Evaluator]: Not possible to use negative parameter: '" + paramText + "'");
                 }
-            } catch ( NumberFormatException e ) {
-                throw new RuntimeDroolsException( "[StartedBy Evaluator]: Not possible to parse parameters: '" + parameters + "'",
-                                                  e );
+            } else {
+                throw new RuntimeDroolsException( "[StartedBy Evaluator]: Not possible to use " + parameters.length + " parameters: '" + paramText + "'" );
             }
         }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartsEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartsEvaluatorDefinition.java	2008-11-30 19:58:57 UTC (rev 24154)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartsEvaluatorDefinition.java	2008-11-30 21:04:09 UTC (rev 24155)
@@ -38,29 +38,64 @@
 import org.drools.time.Interval;
 
 /**
- * The implementation of the 'starts' evaluator definition
+ * <p>The implementation of the <code>starts</code> evaluator definition.</p>
+ * 
+ * <p>The <b><code>starts</code></b> evaluator correlates two events and matches when the current event's 
+ * end timestamp happens before the correlated event's end timestamp, but both start timestamps occur at
+ * the same time.</p> 
+ * 
+ * <p>Lets look at an example:</p>
+ * 
+ * <pre>$eventA : EventA( this starts $eventB )</pre>
  *
+ * <p>The previous pattern will match if and only if the $eventA finishes before $eventB finishes and starts
+ * at the same time $eventB starts. In other words:</p>
+ * 
+ * <pre> 
+ * $eventA.startTimestamp == $eventB.startTimestamp &&
+ * $eventA.endTimestamp < $eventB.endTimestamp 
+ * </pre>
+ * 
+ * <p>The <b><code>starts</code></b> evaluator accepts one optional parameter. If it is defined, it determines
+ * the maximum distance between the start timestamp of both events in order for the operator to match. Example:</p>
+ * 
+ * <pre>$eventA : EventA( this starts[ 5s ] $eventB )</pre>
+ * 
+ * Will match if and only if:
+ * 
+ * <pre> 
+ * abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 5s &&
+ * $eventA.endTimestamp < $eventB.endTimestamp 
+ * </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 StartsEvaluatorDefinition
     implements
     EvaluatorDefinition {
 
-    public static final Operator  STARTS       = Operator.addOperatorToRegistry( "starts",
-                                                                                  false );
-    public static final Operator  STARTS_NOT   = Operator.addOperatorToRegistry( "starts",
-                                                                                  true );
+    public static final Operator         STARTS        = Operator.addOperatorToRegistry( "starts",
+                                                                                         false );
+    public static final Operator         STARTS_NOT    = Operator.addOperatorToRegistry( "starts",
+                                                                                         true );
 
-    private static final String[] SUPPORTED_IDS = { STARTS.getOperatorString() };
+    private static final String[]        SUPPORTED_IDS = {STARTS.getOperatorString()};
 
-    private Map<String, StartsEvaluator> cache        = Collections.emptyMap();
+    private Map<String, StartsEvaluator> cache         = Collections.emptyMap();
+    private volatile TimeIntervalParser  parser        = new TimeIntervalParser();
 
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        cache  = (Map<String, StartsEvaluator>)in.readObject();
+    @SuppressWarnings("unchecked")
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        cache = (Map<String, StartsEvaluator>) in.readObject();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(cache);
+        out.writeObject( cache );
     }
 
     /**
@@ -99,9 +134,11 @@
         String key = isNegated + ":" + parameterText;
         StartsEvaluator eval = this.cache.get( key );
         if ( eval == null ) {
+            Long[] params = parser.parse( parameterText );
             eval = new StartsEvaluator( type,
-                                       isNegated,
-                                       parameterText );
+                                        isNegated,
+                                        params,
+                                        parameterText );
             this.cache.put( key,
                             eval );
         }
@@ -142,34 +179,35 @@
      * Implements the 'starts' evaluator itself
      */
     public static class StartsEvaluator extends BaseEvaluator {
-		private static final long serialVersionUID = 5622952247746290865L;
+        private static final long serialVersionUID = 5622952247746290865L;
 
-		private long                  startDev;
-        private long                  endMinDev, endMaxDev;
+        private long              startDev;
+        private String            paramText;
 
         public StartsEvaluator(final ValueType type,
-                              final boolean isNegated,
-                              final String parameters) {
+                               final boolean isNegated,
+                               final Long[] params,
+                               final String paramText) {
             super( type,
                    isNegated ? STARTS_NOT : STARTS );
-            this.parseParameters( parameters );
+            this.paramText = paramText;
+            this.setParameters( params );
         }
 
         public StartsEvaluator() {
         }
 
-        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-            super.readExternal(in);
+        public void readExternal(ObjectInput in) throws IOException,
+                                                ClassNotFoundException {
+            super.readExternal( in );
             startDev = in.readLong();
-            endMinDev   = in.readLong();
-            endMaxDev   = in.readLong();
+            paramText = (String) in.readObject();
         }
 
         public void writeExternal(ObjectOutput out) throws IOException {
-            super.writeExternal(out);
-            out.writeLong(startDev);
-            out.writeLong(endMinDev);
-            out.writeLong(endMaxDev);
+            super.writeExternal( out );
+            out.writeLong( startDev );
+            out.writeObject( paramText );
         }
 
         @Override
@@ -181,15 +219,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, 0 );
+            return new Interval( 0,
+                                 0 );
         }
-        
+
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,
@@ -198,48 +238,45 @@
         }
 
         public boolean evaluateCachedRight(InternalWorkingMemory workingMemory,
-                final VariableContextEntry context,
-                final Object left) {
+                                           final VariableContextEntry context,
+                                           final Object left) {
 
-        	if ( context.rightNull ) {
-        		return false;
-				}
-			long distStart = Math.abs(((EventFactHandle)((ObjectVariableContextEntry) context).right).getStartTimestamp() - ((EventFactHandle) left ).getStartTimestamp());
-			long distEnd = ((EventFactHandle) left ).getEndTimestamp() - ((EventFactHandle)((ObjectVariableContextEntry) context).right).getEndTimestamp();
-			return this.getOperator().isNegated() ^ ( distStart <= this.startDev
-					&& distEnd >= this.endMinDev && distEnd <= this.endMaxDev );
-		}
+            if ( context.rightNull ) {
+                return false;
+            }
+            long distStart = Math.abs( ((EventFactHandle) ((ObjectVariableContextEntry) context).right).getStartTimestamp() - ((EventFactHandle) left).getStartTimestamp() );
+            long distEnd = ((EventFactHandle) left).getEndTimestamp() - ((EventFactHandle) ((ObjectVariableContextEntry) context).right).getEndTimestamp();
+            return this.getOperator().isNegated() ^ (distStart <= this.startDev && distEnd > 0 );
+        }
 
-		public boolean evaluateCachedLeft(InternalWorkingMemory workingMemory,
-			               final VariableContextEntry context,
-			               final Object right) {
-			if ( context.extractor.isNullValue( workingMemory,
-			                     right ) ) {
-			return false;
-			}
-			long distStart = Math.abs(((EventFactHandle) right ).getStartTimestamp() - ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getStartTimestamp());
-			long distEnd = ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getEndTimestamp() - ((EventFactHandle) right ).getEndTimestamp();
-			return this.getOperator().isNegated() ^ ( distStart <= this.startDev
-					&& distEnd >= this.endMinDev && distEnd <= this.endMaxDev );
-		}
+        public boolean evaluateCachedLeft(InternalWorkingMemory workingMemory,
+                                          final VariableContextEntry context,
+                                          final Object right) {
+            if ( context.extractor.isNullValue( workingMemory,
+                                                right ) ) {
+                return false;
+            }
+            long distStart = Math.abs( ((EventFactHandle) right).getStartTimestamp() - ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getStartTimestamp() );
+            long distEnd = ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getEndTimestamp() - ((EventFactHandle) right).getEndTimestamp();
+            return this.getOperator().isNegated() ^ (distStart <= this.startDev && distEnd > 0 );
+        }
 
-		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 distStart = Math.abs(((EventFactHandle) object1 ).getStartTimestamp() - ((EventFactHandle) object2 ).getStartTimestamp());
-			long distEnd = ((EventFactHandle) object2 ).getEndTimestamp() - ((EventFactHandle) object1 ).getEndTimestamp();
-			return this.getOperator().isNegated() ^ ( distStart  <= this.startDev
-					&& distEnd >= this.endMinDev && distEnd <= this.endMaxDev );
-		}
+        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 distStart = Math.abs( ((EventFactHandle) object1).getStartTimestamp() - ((EventFactHandle) object2).getStartTimestamp() );
+            long distEnd = ((EventFactHandle) object2).getEndTimestamp() - ((EventFactHandle) object1).getEndTimestamp();
+            return this.getOperator().isNegated() ^ (distStart <= this.startDev && distEnd > 0 );
+        }
 
         public String toString() {
-            return "starts[" + startDev + ", " + endMinDev + ", " + endMaxDev + "]";
+            return "starts[" + ((paramText != null) ? paramText : "") + "]";
         }
 
         /* (non-Javadoc)
@@ -249,8 +286,6 @@
         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) (startDev ^ (startDev >>> 32));
             return result;
         }
@@ -264,53 +299,30 @@
             if ( !super.equals( obj ) ) return false;
             if ( getClass() != obj.getClass() ) return false;
             final StartsEvaluator other = (StartsEvaluator) obj;
-            return endMaxDev == other.endMaxDev && endMinDev == other.endMinDev && startDev == other.startDev;
+            return startDev == other.startDev;
         }
 
         /**
-         * 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 matching at the beginning of the intervals, open bounded ranges for the ends
+        private void setParameters(Long[] parameters) {
+            if ( parameters == null || parameters.length == 0 ) {
                 this.startDev = 0;
-                this.endMinDev = 1;
-                this.endMaxDev = Long.MAX_VALUE;
-                return;
-            }
-
-            try {
-                String[] ranges = parameters.split( "," );
-                if ( ranges.length == 1 ) {
-                    // exact matching at the beginning of the intervals
-                	// deterministic point in time for deviations of the ends of the intervals
-                	this.startDev = 0;
-                	this.endMinDev = Long.parseLong( ranges[0] );
-                    this.endMaxDev = this.endMinDev;
-                } else if ( ranges.length == 2 ) {
-                    // exact matching at the beginning of the intervals
-                	// range for deviations of the ends of the intervals
-                	this.startDev = 0;
-                    this.endMinDev = Long.parseLong( ranges[0] );
-                    this.endMaxDev = Long.parseLong( ranges[1] );
-                } else if ( ranges.length == 3 ) {
-                	// max. deviation at the starts of the intervals
-                	// range for deviations of the ends of the intervals
-                	this.startDev = Long.parseLong( ranges[0] );;
-                    this.endMinDev = Long.parseLong( ranges[1] );
-                    this.endMaxDev = Long.parseLong( ranges[2] );
+            } else if ( parameters.length == 1 ) {
+                if( parameters[0].longValue() >= 0 ) {
+                    // defined deviation for end timestamp
+                    this.startDev = parameters[0].longValue();
                 } else {
-                    throw new RuntimeDroolsException( "[Starts Evaluator]: Not possible to parse parameters: '" + parameters + "'" );
+                    throw new RuntimeDroolsException("[Starts Evaluator]: Not possible to use negative parameter: '" + paramText + "'");
                 }
-            } catch ( NumberFormatException e ) {
-                throw new RuntimeDroolsException( "[Starts Evaluator]: Not possible to parse parameters: '" + parameters + "'",
-                                                  e );
+            } else {
+                throw new RuntimeDroolsException( "[Starts Evaluator]: Not possible to use " + parameters.length + " parameters: '" + paramText + "'" );
             }
         }
 
+
     }
 
 }

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-11-30 19:58:57 UTC (rev 24154)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/base/TemporalEvaluatorFactoryTest.java	2008-11-30 21:04:09 UTC (rev 24155)
@@ -518,6 +518,110 @@
                           ValueType.OBJECT_TYPE );
     }
 
+    public void testStarts() {
+        registry.addEvaluatorDefinition( DuringEvaluatorDefinition.class.getName() );
+
+        EventFactHandle foo = new EventFactHandle( 1,
+                                                   "foo",
+                                                   1,
+                                                   2,
+                                                   10 );
+        EventFactHandle bar = new EventFactHandle( 2,
+                                                   "bar",
+                                                   1,
+                                                   2,
+                                                   7 );
+        EventFactHandle drool = new EventFactHandle( 1,
+                                                     "drool",
+                                                     1,
+                                                     2,
+                                                     10 );
+        EventFactHandle mole = new EventFactHandle( 1,
+                                                    "mole",
+                                                    1,
+                                                    1,
+                                                    4 );
+
+        final Object[][] data = {
+                 {bar,   "starts", foo, Boolean.TRUE}, 
+                 {drool, "starts", foo, Boolean.FALSE}, 
+                 {mole,  "starts", foo, Boolean.FALSE}, 
+                 {foo,   "starts", bar, Boolean.FALSE},
+                 
+                 {bar,   "not starts", foo, Boolean.FALSE}, 
+                 {drool, "not starts", foo, Boolean.TRUE}, 
+                 {mole,  "not starts", foo, Boolean.TRUE}, 
+                 {foo,   "not starts", bar, Boolean.TRUE},
+                 
+                 {bar,   "starts[1]", foo, Boolean.TRUE}, 
+                 {drool, "starts[1]", foo, Boolean.FALSE}, 
+                 {mole,  "starts[1]", foo, Boolean.TRUE}, 
+                 {foo,   "starts[1]", bar, Boolean.FALSE},
+                 
+                 {bar,   "not starts[1]", foo, Boolean.FALSE}, 
+                 {drool, "not starts[1]", foo, Boolean.TRUE}, 
+                 {mole,  "not starts[1]", foo, Boolean.FALSE}, 
+                 {foo,   "not starts[1]", bar, Boolean.TRUE},
+                 
+                 {mole,  "starts[3]", foo, Boolean.TRUE}, 
+                };
+
+        runEvaluatorTest( data,
+                          ValueType.OBJECT_TYPE );
+    }
+
+    public void testStartedBy() {
+        registry.addEvaluatorDefinition( DuringEvaluatorDefinition.class.getName() );
+
+        EventFactHandle foo = new EventFactHandle( 1,
+                                                   "foo",
+                                                   1,
+                                                   2,
+                                                   10 );
+        EventFactHandle bar = new EventFactHandle( 2,
+                                                   "bar",
+                                                   1,
+                                                   2,
+                                                   7 );
+        EventFactHandle drool = new EventFactHandle( 1,
+                                                     "drool",
+                                                     1,
+                                                     2,
+                                                     10 );
+        EventFactHandle mole = new EventFactHandle( 1,
+                                                    "mole",
+                                                    1,
+                                                    1,
+                                                    6 );
+
+        final Object[][] data = {
+                 {foo, "startedby", bar, Boolean.TRUE}, 
+                 {foo, "startedby", drool, Boolean.FALSE}, 
+                 {foo, "startedby", mole, Boolean.FALSE}, 
+                 {bar, "startedby", foo, Boolean.FALSE},
+                 
+                 {foo, "not startedby", bar, Boolean.FALSE}, 
+                 {foo, "not startedby", drool, Boolean.TRUE}, 
+                 {foo, "not startedby", mole, Boolean.TRUE}, 
+                 {bar, "not startedby", foo, Boolean.TRUE},
+                 
+                 {foo, "startedby[1]", bar, Boolean.TRUE}, 
+                 {foo, "startedby[1]", drool, Boolean.FALSE}, 
+                 {foo, "startedby[1]", mole, Boolean.TRUE}, 
+                 {bar, "startedby[1]", foo, Boolean.FALSE},
+                 
+                 {foo, "not startedby[1]", bar, Boolean.FALSE}, 
+                 {foo, "not startedby[1]", drool, Boolean.TRUE}, 
+                 {foo, "not startedby[1]", mole, Boolean.FALSE}, 
+                 {bar, "not startedby[1]", foo, Boolean.TRUE},
+                 
+                 {foo, "startedby[3]", 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