Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/sun/xacml/cond/ComparisonFunction.java


1   
2   /*
3    * @(#)ComparisonFunction.java
4    *
5    * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without
8    * modification, are permitted provided that the following conditions are met:
9    *
10   *   1. Redistribution of source code must retain the above copyright notice,
11   *      this list of conditions and the following disclaimer.
12   * 
13   *   2. Redistribution in binary form must reproduce the above copyright
14   *      notice, this list of conditions and the following disclaimer in the
15   *      documentation and/or other materials provided with the distribution.
16   *
17   * Neither the name of Sun Microsystems, Inc. or the names of contributors may
18   * be used to endorse or promote products derived from this software without
19   * specific prior written permission.
20   * 
21   * This software is provided "AS IS," without a warranty of any kind. ALL
22   * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
23   * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
24   * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
25   * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
26   * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
27   * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
28   * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
29   * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
30   * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
31   * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
32   *
33   * You acknowledge that this software is not designed or intended for use in
34   * the design, construction, operation or maintenance of any nuclear facility.
35   */
36  
37  package com.sun.xacml.cond;
38  
39  import com.sun.xacml.EvaluationCtx;
40  
41  import com.sun.xacml.attr.AttributeValue;
42  import com.sun.xacml.attr.BooleanAttribute;
43  import com.sun.xacml.attr.DateAttribute;
44  import com.sun.xacml.attr.DateTimeAttribute;
45  import com.sun.xacml.attr.DoubleAttribute;
46  import com.sun.xacml.attr.IntegerAttribute;
47  import com.sun.xacml.attr.StringAttribute;
48  import com.sun.xacml.attr.TimeAttribute;
49  
50  import java.util.Collections;
51  import java.util.Date;
52  import java.util.HashMap;
53  import java.util.HashSet;
54  import java.util.List;
55  import java.util.Set;
56  
57  
58  /**
59   * A class that implements all of the standard comparison functions.
60   *
61   * @since 1.0
62   * @author Steve Hanna
63   * @author Seth Proctor
64   */
65  public class ComparisonFunction extends FunctionBase
66  {
67  
68      /**
69       * Standard identifier for the integer-greater-than function.
70       */
71      public static final String NAME_INTEGER_GREATER_THAN =
72          FUNCTION_NS + "integer-greater-than";
73  
74      /**
75       * Standard identifier for the integer-greater-than-or-equal function.
76       */
77      public static final String NAME_INTEGER_GREATER_THAN_OR_EQUAL =
78          FUNCTION_NS + "integer-greater-than-or-equal";
79  
80      /**
81       * Standard identifier for the integer-less-than function.
82       */
83      public static final String NAME_INTEGER_LESS_THAN =
84          FUNCTION_NS + "integer-less-than";
85  
86      /**
87       * Standard identifier for the integer-less-than-or-equal function.
88       */
89      public static final String NAME_INTEGER_LESS_THAN_OR_EQUAL =
90          FUNCTION_NS + "integer-less-than-or-equal";
91  
92  
93      /**
94       * Standard identifier for the double-greater-than function.
95       */
96      public static final String NAME_DOUBLE_GREATER_THAN =
97          FUNCTION_NS + "double-greater-than";
98  
99      /**
100      * Standard identifier for the double-greater-than-or-equal function.
101      */
102     public static final String NAME_DOUBLE_GREATER_THAN_OR_EQUAL =
103         FUNCTION_NS + "double-greater-than-or-equal";
104 
105     /**
106      * Standard identifier for the double-less-than function.
107      */
108     public static final String NAME_DOUBLE_LESS_THAN =
109         FUNCTION_NS + "double-less-than";
110 
111     /**
112      * Standard identifier for the double-less-than-or-equal function.
113      */
114     public static final String NAME_DOUBLE_LESS_THAN_OR_EQUAL =
115         FUNCTION_NS + "double-less-than-or-equal";
116 
117 
118     /**
119      * Standard identifier for the string-greater-than function.
120      */
121     public static final String NAME_STRING_GREATER_THAN =
122         FUNCTION_NS + "string-greater-than";
123 
124     /**
125      * Standard identifier for the string-greater-than-or-equal function.
126      */
127     public static final String NAME_STRING_GREATER_THAN_OR_EQUAL =
128         FUNCTION_NS + "string-greater-than-or-equal";
129 
130     /**
131      * Standard identifier for the string-less-than function.
132      */
133     public static final String NAME_STRING_LESS_THAN =
134         FUNCTION_NS + "string-less-than";
135 
136     /**
137      * Standard identifier for the string-less-than-or-equal function.
138      */
139     public static final String NAME_STRING_LESS_THAN_OR_EQUAL =
140         FUNCTION_NS + "string-less-than-or-equal";
141 
142 
143     /**
144      * Standard identifier for the time-greater-than function.
145      */
146     public static final String NAME_TIME_GREATER_THAN =
147         FUNCTION_NS + "time-greater-than";
148 
149     /**
150      * Standard identifier for the time-greater-than-or-equal function.
151      */
152     public static final String NAME_TIME_GREATER_THAN_OR_EQUAL =
153         FUNCTION_NS + "time-greater-than-or-equal";
154 
155     /**
156      * Standard identifier for the time-less-than function.
157      */
158     public static final String NAME_TIME_LESS_THAN =
159         FUNCTION_NS + "time-less-than";
160 
161     /**
162      * Standard identifier for the time-less-than-or-equal function.
163      */
164     public static final String NAME_TIME_LESS_THAN_OR_EQUAL =
165         FUNCTION_NS + "time-less-than-or-equal";
166 
167 
168     /**
169      * Standard identifier for the dateTime-greater-than function.
170      */
171     public static final String NAME_DATETIME_GREATER_THAN =
172         FUNCTION_NS + "dateTime-greater-than";
173 
174     /**
175      * Standard identifier for the dateTime-greater-than-or-equal function.
176      */
177     public static final String NAME_DATETIME_GREATER_THAN_OR_EQUAL =
178         FUNCTION_NS + "dateTime-greater-than-or-equal";
179 
180     /**
181      * Standard identifier for the dateTime-less-than function.
182      */
183     public static final String NAME_DATETIME_LESS_THAN =
184         FUNCTION_NS + "dateTime-less-than";
185 
186     /**
187      * Standard identifier for the dateTime-less-than-or-equal function.
188      */
189     public static final String NAME_DATETIME_LESS_THAN_OR_EQUAL =
190         FUNCTION_NS + "dateTime-less-than-or-equal";
191 
192 
193     /**
194      * Standard identifier for the date-greater-than function.
195      */
196     public static final String NAME_DATE_GREATER_THAN =
197         FUNCTION_NS + "date-greater-than";
198 
199     /**
200      * Standard identifier for the date-greater-than-or-equal function.
201      */
202     public static final String NAME_DATE_GREATER_THAN_OR_EQUAL =
203         FUNCTION_NS + "date-greater-than-or-equal";
204 
205     /**
206      * Standard identifier for the date-less-than function.
207      */
208     public static final String NAME_DATE_LESS_THAN =
209         FUNCTION_NS + "date-less-than";
210 
211     /**
212      * Standard identifier for the date-less-than-or-equal function.
213      */
214     public static final String NAME_DATE_LESS_THAN_OR_EQUAL =
215         FUNCTION_NS + "date-less-than-or-equal";
216 
217     // private identifiers for the supported functions
218     private static final int ID_INTEGER_GREATER_THAN = 0;
219     private static final int ID_INTEGER_GREATER_THAN_OR_EQUAL = 1;
220     private static final int ID_INTEGER_LESS_THAN = 2;
221     private static final int ID_INTEGER_LESS_THAN_OR_EQUAL = 3;
222     private static final int ID_DOUBLE_GREATER_THAN = 4;
223     private static final int ID_DOUBLE_GREATER_THAN_OR_EQUAL = 5;
224     private static final int ID_DOUBLE_LESS_THAN = 6;
225     private static final int ID_DOUBLE_LESS_THAN_OR_EQUAL = 7;
226     private static final int ID_STRING_GREATER_THAN = 8;
227     private static final int ID_STRING_GREATER_THAN_OR_EQUAL = 9;
228     private static final int ID_STRING_LESS_THAN = 10;
229     private static final int ID_STRING_LESS_THAN_OR_EQUAL = 11;
230     private static final int ID_TIME_GREATER_THAN = 12;
231     private static final int ID_TIME_GREATER_THAN_OR_EQUAL = 13;
232     private static final int ID_TIME_LESS_THAN = 14;
233     private static final int ID_TIME_LESS_THAN_OR_EQUAL = 15;
234     private static final int ID_DATE_GREATER_THAN = 16;
235     private static final int ID_DATE_GREATER_THAN_OR_EQUAL = 17;
236     private static final int ID_DATE_LESS_THAN = 18;
237     private static final int ID_DATE_LESS_THAN_OR_EQUAL = 19;
238     private static final int ID_DATETIME_GREATER_THAN = 20;
239     private static final int ID_DATETIME_GREATER_THAN_OR_EQUAL = 21;
240     private static final int ID_DATETIME_LESS_THAN = 22;
241     private static final int ID_DATETIME_LESS_THAN_OR_EQUAL = 23;
242 
243     // mappings from name to private identifier and argument datatype
244     private static HashMap idMap;
245     private static HashMap typeMap;
246 
247     /**
248      * Static initializer to setup the two maps.
249      */
250     static {
251         idMap = new HashMap();
252 
253         idMap.put(NAME_INTEGER_GREATER_THAN,
254                   new Integer(ID_INTEGER_GREATER_THAN));
255         idMap.put(NAME_INTEGER_GREATER_THAN_OR_EQUAL,
256                   new Integer(ID_INTEGER_GREATER_THAN_OR_EQUAL));
257         idMap.put(NAME_INTEGER_LESS_THAN,
258                   new Integer(ID_INTEGER_LESS_THAN));
259         idMap.put(NAME_INTEGER_LESS_THAN_OR_EQUAL,
260                   new Integer(ID_INTEGER_LESS_THAN_OR_EQUAL));
261         idMap.put(NAME_DOUBLE_GREATER_THAN,
262                   new Integer(ID_DOUBLE_GREATER_THAN));
263         idMap.put(NAME_DOUBLE_GREATER_THAN_OR_EQUAL,
264                   new Integer(ID_DOUBLE_GREATER_THAN_OR_EQUAL));
265         idMap.put(NAME_DOUBLE_LESS_THAN,
266                   new Integer(ID_DOUBLE_LESS_THAN));
267         idMap.put(NAME_DOUBLE_LESS_THAN_OR_EQUAL,
268                   new Integer(ID_DOUBLE_LESS_THAN_OR_EQUAL));
269         idMap.put(NAME_STRING_GREATER_THAN,
270                   new Integer(ID_STRING_GREATER_THAN));
271         idMap.put(NAME_STRING_GREATER_THAN_OR_EQUAL,
272                   new Integer(ID_STRING_GREATER_THAN_OR_EQUAL));
273         idMap.put(NAME_STRING_LESS_THAN,
274                   new Integer(ID_STRING_LESS_THAN));
275         idMap.put(NAME_STRING_LESS_THAN_OR_EQUAL,
276                   new Integer(ID_STRING_LESS_THAN_OR_EQUAL));
277         idMap.put(NAME_TIME_GREATER_THAN,
278                   new Integer(ID_TIME_GREATER_THAN));
279         idMap.put(NAME_TIME_GREATER_THAN_OR_EQUAL,
280                   new Integer(ID_TIME_GREATER_THAN_OR_EQUAL));
281         idMap.put(NAME_TIME_LESS_THAN,
282                   new Integer(ID_TIME_LESS_THAN));
283         idMap.put(NAME_TIME_LESS_THAN_OR_EQUAL,
284                   new Integer(ID_TIME_LESS_THAN_OR_EQUAL));
285         idMap.put(NAME_DATE_GREATER_THAN,
286                   new Integer(ID_DATE_GREATER_THAN));
287         idMap.put(NAME_DATE_GREATER_THAN_OR_EQUAL,
288                   new Integer(ID_DATE_GREATER_THAN_OR_EQUAL));
289         idMap.put(NAME_DATE_LESS_THAN,
290                   new Integer(ID_DATE_LESS_THAN));
291         idMap.put(NAME_DATE_LESS_THAN_OR_EQUAL,
292                   new Integer(ID_DATE_LESS_THAN_OR_EQUAL));
293         idMap.put(NAME_DATETIME_GREATER_THAN,
294                   new Integer(ID_DATETIME_GREATER_THAN));
295         idMap.put(NAME_DATETIME_GREATER_THAN_OR_EQUAL,
296                   new Integer(ID_DATETIME_GREATER_THAN_OR_EQUAL));
297         idMap.put(NAME_DATETIME_LESS_THAN,
298                   new Integer(ID_DATETIME_LESS_THAN));
299         idMap.put(NAME_DATETIME_LESS_THAN_OR_EQUAL,
300                   new Integer(ID_DATETIME_LESS_THAN_OR_EQUAL));
301 
302         typeMap = new HashMap();
303 
304         typeMap.put(NAME_INTEGER_GREATER_THAN, IntegerAttribute.identifier);
305         typeMap.put(NAME_INTEGER_GREATER_THAN_OR_EQUAL,
306                     IntegerAttribute.identifier);
307         typeMap.put(NAME_INTEGER_LESS_THAN, IntegerAttribute.identifier);
308         typeMap.put(NAME_INTEGER_LESS_THAN_OR_EQUAL,
309                     IntegerAttribute.identifier);
310         typeMap.put(NAME_DOUBLE_GREATER_THAN, DoubleAttribute.identifier);
311         typeMap.put(NAME_DOUBLE_GREATER_THAN_OR_EQUAL,
312                     DoubleAttribute.identifier);
313         typeMap.put(NAME_DOUBLE_LESS_THAN, DoubleAttribute.identifier);
314         typeMap.put(NAME_DOUBLE_LESS_THAN_OR_EQUAL,
315                     DoubleAttribute.identifier);
316         typeMap.put(NAME_STRING_GREATER_THAN, StringAttribute.identifier);
317         typeMap.put(NAME_STRING_GREATER_THAN_OR_EQUAL,
318                     StringAttribute.identifier);
319         typeMap.put(NAME_STRING_LESS_THAN, StringAttribute.identifier);
320         typeMap.put(NAME_STRING_LESS_THAN_OR_EQUAL,
321                     StringAttribute.identifier);
322         typeMap.put(NAME_TIME_GREATER_THAN, TimeAttribute.identifier);
323         typeMap.put(NAME_TIME_GREATER_THAN_OR_EQUAL, TimeAttribute.identifier);
324         typeMap.put(NAME_TIME_LESS_THAN, TimeAttribute.identifier);
325         typeMap.put(NAME_TIME_LESS_THAN_OR_EQUAL, TimeAttribute.identifier);
326         typeMap.put(NAME_DATETIME_GREATER_THAN, DateTimeAttribute.identifier);
327         typeMap.put(NAME_DATETIME_GREATER_THAN_OR_EQUAL,
328                     DateTimeAttribute.identifier);
329         typeMap.put(NAME_DATETIME_LESS_THAN, DateTimeAttribute.identifier);
330         typeMap.put(NAME_DATETIME_LESS_THAN_OR_EQUAL,
331                     DateTimeAttribute.identifier);
332         typeMap.put(NAME_DATE_GREATER_THAN, DateAttribute.identifier);
333         typeMap.put(NAME_DATE_GREATER_THAN_OR_EQUAL, DateAttribute.identifier);
334         typeMap.put(NAME_DATE_LESS_THAN, DateAttribute.identifier);
335         typeMap.put(NAME_DATE_LESS_THAN_OR_EQUAL, DateAttribute.identifier);
336     };
337 
338     /**
339      * Creates a new <code>ComparisonFunction</code> object.
340      *
341      * @param functionName the standard XACML name of the function to be
342      *                     handled by this object, including the full namespace
343      *
344      * @throws IllegalArgumentException if the function isn't known
345      */
346     public ComparisonFunction(String functionName) {
347         super(functionName, getId(functionName), getArgumentType(functionName),
348               false, 2, BooleanAttribute.identifier, false);
349     }
350 
351     /**
352      * Private helper that returns the internal identifier used for the
353      * given standard function.
354      */
355     private static int getId(String functionName) {
356         Integer i = (Integer)(idMap.get(functionName));
357 
358         if (i == null)
359             throw new IllegalArgumentException("unknown comparison function " +
360                                                functionName);
361 
362         return i.intValue();
363     }
364 
365     /**
366      * Private helper that returns the type used for the given standard
367      * function. Note that this doesn't check on the return value since the
368      * method always is called after getId, so we assume that the function
369      * is present.
370      */
371     private static String getArgumentType(String functionName) {
372         return (String)(typeMap.get(functionName));
373     }
374 
375     /**
376      * Returns a <code>Set</code> containing all the function identifiers
377      * supported by this class.
378      *
379      * @return a <code>Set</code> of <code>String</code>s
380      */
381     public static Set getSupportedIdentifiers() {
382         return Collections.unmodifiableSet(idMap.keySet());
383     }
384 
385     /**
386      * Evaluate the function, using the specified parameters.
387      *
388      * @param inputs a <code>List</code> of <code>Evaluatable</code>
389      *               objects representing the arguments passed to the function
390      * @param context an <code>EvaluationCtx</code> so that the
391      *                <code>Evaluatable</code> objects can be evaluated
392      * @return an <code>EvaluationResult</code> representing the
393      *         function's result
394      */
395     public EvaluationResult evaluate(List inputs, EvaluationCtx context) {
396         // Evaluate the arguments
397         AttributeValue [] argValues = new AttributeValue [inputs.size()];
398         EvaluationResult result = evalArgs(inputs, context, argValues);
399         if (result != null)
400             return result;
401 
402         // Now that we have real values, perform the comparison operation
403 
404         boolean boolResult = false;
405 
406         switch (getFunctionId()) {
407 
408         case ID_INTEGER_GREATER_THAN: {
409             long arg0 = ((IntegerAttribute)(argValues[0])).getValue();
410             long arg1 = ((IntegerAttribute)(argValues[1])).getValue();
411 
412             boolResult = (arg0 > arg1);
413 
414             break;
415         }
416 
417         case ID_INTEGER_GREATER_THAN_OR_EQUAL: {
418             long arg0 = ((IntegerAttribute)(argValues[0])).getValue();
419             long arg1 = ((IntegerAttribute)(argValues[1])).getValue();
420 
421             boolResult = (arg0 >= arg1);
422 
423             break;
424         }
425 
426         case ID_INTEGER_LESS_THAN: {
427             long arg0 = ((IntegerAttribute)(argValues[0])).getValue();
428             long arg1 = ((IntegerAttribute)(argValues[1])).getValue();
429 
430             boolResult = (arg0 < arg1);
431 
432             break;
433         }
434 
435         case ID_INTEGER_LESS_THAN_OR_EQUAL: {
436             long arg0 = ((IntegerAttribute)(argValues[0])).getValue();
437             long arg1 = ((IntegerAttribute)(argValues[1])).getValue();
438 
439             boolResult = (arg0 <= arg1);
440 
441             break;
442         }
443 
444         case ID_DOUBLE_GREATER_THAN: {
445             double arg0 = ((DoubleAttribute)(argValues[0])).getValue();
446             double arg1 = ((DoubleAttribute)(argValues[1])).getValue();
447 
448             boolResult = (doubleCompare(arg0, arg1) > 0);
449 
450             break;
451         }
452 
453         case ID_DOUBLE_GREATER_THAN_OR_EQUAL: {
454             double arg0 = ((DoubleAttribute)(argValues[0])).getValue();
455             double arg1 = ((DoubleAttribute)(argValues[1])).getValue();
456 
457             boolResult = (doubleCompare(arg0, arg1) >= 0);
458 
459             break;
460         }
461 
462         case ID_DOUBLE_LESS_THAN: {
463             double arg0 = ((DoubleAttribute)(argValues[0])).getValue();
464             double arg1 = ((DoubleAttribute)(argValues[1])).getValue();
465 
466             boolResult = (doubleCompare(arg0, arg1) < 0);
467 
468             break;
469         }
470 
471         case ID_DOUBLE_LESS_THAN_OR_EQUAL: {
472             double arg0 = ((DoubleAttribute)(argValues[0])).getValue();
473             double arg1 = ((DoubleAttribute)(argValues[1])).getValue();
474 
475             boolResult = (doubleCompare(arg0, arg1) <= 0);
476 
477             break;
478         }
479 
480         case ID_STRING_GREATER_THAN: {
481             String arg0 = ((StringAttribute)(argValues[0])).getValue();
482             String arg1 = ((StringAttribute)(argValues[1])).getValue();
483 
484             boolResult = (arg0.compareTo(arg1) > 0);
485 
486             break;
487         }
488 
489         case ID_STRING_GREATER_THAN_OR_EQUAL: {
490             String arg0 = ((StringAttribute)(argValues[0])).getValue();
491             String arg1 = ((StringAttribute)(argValues[1])).getValue();
492 
493             boolResult = (arg0.compareTo(arg1) >= 0);
494 
495             break;
496         }
497 
498         case ID_STRING_LESS_THAN: {
499             String arg0 = ((StringAttribute)(argValues[0])).getValue();
500             String arg1 = ((StringAttribute)(argValues[1])).getValue();
501 
502             boolResult = (arg0.compareTo(arg1) < 0);
503 
504             break;
505         }
506 
507         case ID_STRING_LESS_THAN_OR_EQUAL: {
508             String arg0 = ((StringAttribute)(argValues[0])).getValue();
509             String arg1 = ((StringAttribute)(argValues[1])).getValue();
510 
511             boolResult = (arg0.compareTo(arg1) <= 0);
512 
513             break;
514         }
515 
516         case ID_TIME_GREATER_THAN: {
517             TimeAttribute arg0 = (TimeAttribute)(argValues[0]);
518             TimeAttribute arg1 = (TimeAttribute)(argValues[1]);
519 
520             boolResult =
521                 (dateCompare(arg0.getValue(), arg0.getNanoseconds(),
522                              arg1.getValue(), arg1.getNanoseconds()) > 0);
523 
524             break;
525         }
526 
527         case ID_TIME_GREATER_THAN_OR_EQUAL: {
528             TimeAttribute arg0 = (TimeAttribute)(argValues[0]);
529             TimeAttribute arg1 = (TimeAttribute)(argValues[1]);
530 
531             boolResult =
532                 (dateCompare(arg0.getValue(), arg0.getNanoseconds(),
533                              arg1.getValue(), arg1.getNanoseconds()) >= 0);
534 
535             break;
536         }
537 
538         case ID_TIME_LESS_THAN: {
539             TimeAttribute arg0 = (TimeAttribute)(argValues[0]);
540             TimeAttribute arg1 = (TimeAttribute)(argValues[1]);
541 
542             boolResult =
543                 (dateCompare(arg0.getValue(), arg0.getNanoseconds(),
544                              arg1.getValue(), arg1.getNanoseconds()) < 0);
545 
546             break;
547         }
548 
549         case ID_TIME_LESS_THAN_OR_EQUAL: {
550             TimeAttribute arg0 = (TimeAttribute)(argValues[0]);
551             TimeAttribute arg1 = (TimeAttribute)(argValues[1]);
552 
553             boolResult =
554                 (dateCompare(arg0.getValue(), arg0.getNanoseconds(),
555                              arg1.getValue(), arg1.getNanoseconds()) <= 0);
556 
557             break;
558         }
559 
560         case ID_DATETIME_GREATER_THAN: {
561             DateTimeAttribute arg0 = (DateTimeAttribute)(argValues[0]);
562             DateTimeAttribute arg1 = (DateTimeAttribute)(argValues[1]);
563 
564             boolResult =
565                 (dateCompare(arg0.getValue(), arg0.getNanoseconds(),
566                              arg1.getValue(), arg1.getNanoseconds()) > 0);
567 
568             break;
569         }
570 
571         case ID_DATETIME_GREATER_THAN_OR_EQUAL: {
572             DateTimeAttribute arg0 = (DateTimeAttribute)(argValues[0]);
573             DateTimeAttribute arg1 = (DateTimeAttribute)(argValues[1]);
574 
575             boolResult =
576                 (dateCompare(arg0.getValue(), arg0.getNanoseconds(),
577                              arg1.getValue(), arg1.getNanoseconds()) >= 0);
578 
579             break;
580         }
581 
582         case ID_DATETIME_LESS_THAN: {
583             DateTimeAttribute arg0 = (DateTimeAttribute)(argValues[0]);
584             DateTimeAttribute arg1 = (DateTimeAttribute)(argValues[1]);
585 
586             boolResult =
587                 (dateCompare(arg0.getValue(), arg0.getNanoseconds(),
588                              arg1.getValue(), arg1.getNanoseconds()) < 0);
589 
590             break;
591         }
592 
593         case ID_DATETIME_LESS_THAN_OR_EQUAL: {
594             DateTimeAttribute arg0 = (DateTimeAttribute)(argValues[0]);
595             DateTimeAttribute arg1 = (DateTimeAttribute)(argValues[1]);
596 
597             boolResult =
598                 (dateCompare(arg0.getValue(), arg0.getNanoseconds(),
599                              arg1.getValue(), arg1.getNanoseconds()) <= 0);
600 
601             break;
602         }
603 
604         case ID_DATE_GREATER_THAN: {
605             Date arg0 = ((DateAttribute)(argValues[0])).getValue();
606             Date arg1 = ((DateAttribute)(argValues[1])).getValue();
607 
608             boolResult = (arg0.compareTo(arg1) > 0);
609 
610             break;
611         }
612 
613         case ID_DATE_GREATER_THAN_OR_EQUAL: {
614             Date arg0 = ((DateAttribute)(argValues[0])).getValue();
615             Date arg1 = ((DateAttribute)(argValues[1])).getValue();
616 
617             boolResult = (arg0.compareTo(arg1) >= 0);
618 
619             break;
620         }
621 
622         case ID_DATE_LESS_THAN: {
623             Date arg0 = ((DateAttribute)(argValues[0])).getValue();
624             Date arg1 = ((DateAttribute)(argValues[1])).getValue();
625 
626             boolResult = (arg0.compareTo(arg1) < 0);
627 
628             break;
629         }
630 
631         case ID_DATE_LESS_THAN_OR_EQUAL: {
632             Date arg0 = ((DateAttribute)(argValues[0])).getValue();
633             Date arg1 = ((DateAttribute)(argValues[1])).getValue();
634 
635             boolResult = (arg0.compareTo(arg1) <= 0);
636 
637             break;
638         }
639 
640         }
641 
642         // Return the result as a BooleanAttribute.
643         return EvaluationResult.getInstance(boolResult);
644     }
645 
646     /**
647      * Helper function that does a comparison of the two doubles using the
648      * rules of XMLSchema. Like all compare methods, this returns 0 if they're
649      * equal, a positive value if d1 > d2, and a negative value if d1 < d2.
650      */
651     private int doubleCompare(double d1, double d2) {
652         // see if the numbers equal each other
653         if (d1 == d2) {
654             // these are not NaNs, and therefore we just need to check that
655             // that they're not zeros, which may have different signs
656             if (d1 != 0)
657                 return 0;
658 
659             // they're both zeros, so we compare strings to figure out
660             // the significance of any signs
661             return Double.toString(d1).compareTo(Double.toString(d2));
662         }
663 
664         // see if d1 is NaN
665         if (Double.isNaN(d1)) {
666             // d1 is NaN, so see if d2 is as well
667             if (Double.isNaN(d2)) {
668                 // they're both NaNs, so they're equal
669                 return 0;
670             } else {
671                 // d1 is always bigger than d2 since it's a NaN
672                 return 1;
673             }
674         }
675 
676         // see if d2 is NaN
677         if (Double.isNaN(d2)) {
678             // d2 is a NaN, though d1 isn't, so d2 is always bigger
679             return -1;
680         }
681 
682         // if we got here then neither is a NaN, and the numbers aren't
683         // equal...given those facts, basic comparison works the same in
684         // java as it's defined in XMLSchema, so now we can do the simple
685         // comparison and return whatever we find
686         return ((d1 > d2) ? 1 : -1);
687     }
688 
689     /**
690      * Helper function to compare two Date objects and their associated
691      * nanosecond values. Like all compare methods, this returns 0 if they're
692      * equal, a positive value if d1 > d2, and a negative value if d1 < d2.
693      */
694     private int dateCompare(Date d1, int n1, Date d2, int n2) {
695         int compareResult = d1.compareTo(d2);
696 
697         // we only worry about the nanosecond values if the Dates are equal
698         if (compareResult != 0)
699             return compareResult;
700 
701         // see if there's any difference
702         if (n1 == n2)
703             return 0;
704         
705         // there is some difference in the nanoseconds, and that's how
706         // we'll determine the comparison
707         return ((n1 > n2) ? 1 : -1);
708     }
709 
710 }