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 }