1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package gov.nist.secauto.metaschema.core.metapath.function;
28
29 import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException;
30 import gov.nist.secauto.metaschema.core.metapath.item.atomic.IBase64BinaryItem;
31 import gov.nist.secauto.metaschema.core.metapath.item.atomic.IBooleanItem;
32 import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDateItem;
33 import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDateTimeItem;
34 import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDayTimeDurationItem;
35 import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDecimalItem;
36 import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDurationItem;
37 import gov.nist.secauto.metaschema.core.metapath.item.atomic.IIntegerItem;
38 import gov.nist.secauto.metaschema.core.metapath.item.atomic.INumericItem;
39 import gov.nist.secauto.metaschema.core.metapath.item.atomic.IYearMonthDurationItem;
40
41 import java.math.BigDecimal;
42 import java.math.BigInteger;
43 import java.time.Duration;
44 import java.time.Period;
45 import java.time.ZonedDateTime;
46 import java.time.temporal.TemporalAmount;
47
48 import edu.umd.cs.findbugs.annotations.NonNull;
49 import edu.umd.cs.findbugs.annotations.Nullable;
50
51 public final class OperationFunctions {
52 private OperationFunctions() {
53
54 }
55
56 @NonNull
57 public static IDateItem opAddYearMonthDurationToDate(@NonNull IDateItem arg1, @NonNull IYearMonthDurationItem arg2) {
58 return addDurationToDate(arg1.asZonedDateTime(), arg2.getValue());
59 }
60
61 @NonNull
62 public static IDateItem opAddDayTimeDurationToDate(@NonNull IDateItem arg1, @NonNull IDayTimeDurationItem arg2) {
63 return addDurationToDate(arg1.asZonedDateTime(), arg2.getValue());
64 }
65
66 @NonNull
67 private static IDateItem addDurationToDate(@NonNull ZonedDateTime dateTime, @NonNull TemporalAmount duration) {
68 ZonedDateTime result;
69 try {
70 result = dateTime.plus(duration);
71 } catch (ArithmeticException ex) {
72 throw new ArithmeticFunctionException(ArithmeticFunctionException.OVERFLOW_UNDERFLOW_ERROR, ex);
73 }
74 assert result != null;
75 return IDateItem.valueOf(result);
76 }
77
78 @NonNull
79 public static IYearMonthDurationItem opAddYearMonthDurations(@NonNull IYearMonthDurationItem arg1,
80 IYearMonthDurationItem arg2) {
81 Period duration1 = arg1.getValue();
82 Period duration2 = arg2.getValue();
83
84 Period result;
85 try {
86 result = duration1.plus(duration2);
87 } catch (ArithmeticException ex) {
88 throw new ArithmeticFunctionException(ArithmeticFunctionException.OVERFLOW_UNDERFLOW_ERROR, ex);
89 }
90 assert result != null;
91 return IYearMonthDurationItem.valueOf(result);
92 }
93
94 @NonNull
95 public static IDayTimeDurationItem opAddDayTimeDurations(@NonNull IDayTimeDurationItem arg1,
96 @NonNull IDayTimeDurationItem arg2) {
97 Duration duration1 = arg1.getValue();
98 Duration duration2 = arg2.getValue();
99
100 Duration result;
101 try {
102 result = duration1.plus(duration2);
103 } catch (ArithmeticException ex) {
104 throw new ArithmeticFunctionException(ArithmeticFunctionException.OVERFLOW_UNDERFLOW_ERROR, ex);
105 }
106 assert result != null;
107 return IDayTimeDurationItem.valueOf(result);
108 }
109
110 @NonNull
111 public static IDateTimeItem opAddYearMonthDurationToDateTime(@NonNull IDateTimeItem arg1,
112 @NonNull IYearMonthDurationItem arg2) {
113 ZonedDateTime result;
114 try {
115 result = arg1.asZonedDateTime().plus(arg2.getValue());
116 } catch (ArithmeticException ex) {
117 throw new ArithmeticFunctionException(ArithmeticFunctionException.OVERFLOW_UNDERFLOW_ERROR, ex);
118 }
119 assert result != null;
120 return IDateTimeItem.valueOf(result);
121 }
122
123 @NonNull
124 public static IDateTimeItem opAddDayTimeDurationToDateTime(@NonNull IDateTimeItem arg1,
125 @NonNull IDayTimeDurationItem arg2) {
126 ZonedDateTime result;
127 try {
128 result = arg1.asZonedDateTime().plus(arg2.getValue());
129 } catch (ArithmeticException ex) {
130 throw new ArithmeticFunctionException(ArithmeticFunctionException.OVERFLOW_UNDERFLOW_ERROR, ex);
131 }
132 assert result != null;
133 return IDateTimeItem.valueOf(result);
134 }
135
136 @NonNull
137 public static IDayTimeDurationItem opSubtractDates(@NonNull IDateItem arg1, @NonNull IDateItem arg2) {
138 return between(arg1.asZonedDateTime(), arg2.asZonedDateTime());
139 }
140
141 @NonNull
142 public static IDateItem opSubtractYearMonthDurationFromDate(@NonNull IDateItem arg1,
143 @NonNull IYearMonthDurationItem arg2) {
144 return subtractDurationFromDate(arg1.asZonedDateTime(), arg2.getValue());
145 }
146
147 @NonNull
148 public static IDateItem opSubtractDayTimeDurationFromDate(@NonNull IDateItem arg1,
149 @NonNull IDayTimeDurationItem arg2) {
150 return subtractDurationFromDate(arg1.asZonedDateTime(), arg2.getValue());
151 }
152
153 @NonNull
154 private static IDateItem subtractDurationFromDate(@NonNull ZonedDateTime dateTime,
155 @NonNull TemporalAmount duration) {
156 @SuppressWarnings("null")
157 @NonNull ZonedDateTime result = dateTime.minus(duration);
158 return IDateItem.valueOf(result);
159 }
160
161 @NonNull
162 public static IYearMonthDurationItem opSubtractYearMonthDurations(@NonNull IYearMonthDurationItem arg1,
163 IYearMonthDurationItem arg2) {
164 Period duration1 = arg1.getValue();
165 Period duration2 = arg2.getValue();
166
167 @SuppressWarnings("null")
168 @NonNull Period duration = duration1.minus(duration2);
169 return IYearMonthDurationItem.valueOf(duration);
170 }
171
172 @NonNull
173 public static IDayTimeDurationItem opSubtractDayTimeDurations(@NonNull IDayTimeDurationItem arg1,
174 @NonNull IDayTimeDurationItem arg2) {
175 Duration duration1 = arg1.getValue();
176 Duration duration2 = arg2.getValue();
177
178 @SuppressWarnings("null")
179 @NonNull Duration duration = duration1.minus(duration2);
180 return IDayTimeDurationItem.valueOf(duration);
181 }
182
183 @NonNull
184 public static IDayTimeDurationItem opSubtractDateTimes(@NonNull IDateTimeItem arg1, @NonNull IDateTimeItem arg2) {
185 return between(arg1.asZonedDateTime(), arg2.asZonedDateTime());
186 }
187
188 @NonNull
189 private static IDayTimeDurationItem between(@NonNull ZonedDateTime time1, @NonNull ZonedDateTime time2) {
190 @SuppressWarnings("null")
191 @NonNull Duration between = Duration.between(time1, time2);
192 return IDayTimeDurationItem.valueOf(between);
193 }
194
195 @NonNull
196 public static IDateTimeItem opSubtractYearMonthDurationFromDateTime(@NonNull IDateTimeItem arg1,
197 @NonNull IYearMonthDurationItem arg2) {
198 @SuppressWarnings("null")
199 @NonNull ZonedDateTime dateTime = arg1.asZonedDateTime().minus(arg2.getValue());
200 return IDateTimeItem.valueOf(dateTime);
201 }
202
203 @NonNull
204 public static IDateTimeItem opSubtractDayTimeDurationFromDateTime(@NonNull IDateTimeItem arg1,
205 @NonNull IDayTimeDurationItem arg2) {
206
207 @SuppressWarnings("null")
208 @NonNull ZonedDateTime dateTime = arg1.asZonedDateTime().plus(arg2.getValue());
209 return IDateTimeItem.valueOf(dateTime);
210 }
211
212 @NonNull
213 public static IYearMonthDurationItem opMultiplyYearMonthDuration(@NonNull IYearMonthDurationItem arg1,
214 @NonNull INumericItem arg2)
215 throws ArithmeticFunctionException {
216 int arg2Int;
217 try {
218 arg2Int = FunctionUtils.asInteger(arg2.round());
219 } catch (ArithmeticException ex) {
220 throw new ArithmeticFunctionException(ArithmeticFunctionException.OVERFLOW_UNDERFLOW_ERROR, ex);
221 }
222
223 @SuppressWarnings("null")
224 @NonNull Period period = arg1.getValue().multipliedBy(arg2Int);
225 return IYearMonthDurationItem.valueOf(period);
226 }
227
228 @NonNull
229 public static IDayTimeDurationItem opMultiplyDayTimeDuration(@NonNull IDayTimeDurationItem arg1,
230 @NonNull INumericItem arg2)
231 throws ArithmeticFunctionException {
232 long arg2Long;
233 try {
234 arg2Long = FunctionUtils.asLong(arg2.round());
235 } catch (ArithmeticException ex) {
236 throw new ArithmeticFunctionException(ArithmeticFunctionException.OVERFLOW_UNDERFLOW_ERROR, ex);
237 }
238
239 @SuppressWarnings("null")
240 @NonNull Duration duration = arg1.getValue().multipliedBy(arg2Long);
241 return IDayTimeDurationItem.valueOf(duration);
242 }
243
244 @NonNull
245 public static IYearMonthDurationItem opDivideYearMonthDuration(@NonNull IYearMonthDurationItem arg1,
246 @NonNull INumericItem arg2)
247 throws DateTimeFunctionException {
248 IIntegerItem totalMonths = IIntegerItem.valueOf(arg1.getValue().toTotalMonths());
249 IIntegerItem result = opNumericIntegerDivide(totalMonths, arg2);
250 int months;
251 try {
252 months = FunctionUtils.asInteger(result.asInteger());
253 } catch (ArithmeticException ex) {
254 throw new DateTimeFunctionException(DateTimeFunctionException.DURATION_OVERFLOW_UNDERFLOW_ERROR,
255 "Overflow/underflow in duration operation.", ex);
256 }
257 int years = months / 12;
258 months = months % 12;
259 return IYearMonthDurationItem.valueOf(years, months, 0);
260 }
261
262 @NonNull
263 public static IDayTimeDurationItem opDivideDayTimeDuration(@NonNull IDayTimeDurationItem arg1,
264 @NonNull INumericItem arg2)
265 throws ArithmeticFunctionException {
266 try {
267 @SuppressWarnings("null")
268 @NonNull Duration duration = arg1.getValue().dividedBy(FunctionUtils.asLong(arg2.round()));
269 return IDayTimeDurationItem
270 .valueOf(duration);
271 } catch (ArithmeticException ex) {
272 throw new ArithmeticFunctionException(ArithmeticFunctionException.DIVISION_BY_ZERO, "Division by zero", ex);
273 }
274 }
275
276 @NonNull
277 public static IDecimalItem opDivideDayTimeDurationByDayTimeDuration(@NonNull IDayTimeDurationItem arg1,
278 IDayTimeDurationItem arg2) {
279 return IDecimalItem.cast(
280 opNumericDivide(
281 IDecimalItem.valueOf(arg1.getValue().toSeconds()),
282 IDecimalItem.valueOf(arg2.getValue().toSeconds())));
283 }
284
285 @NonNull
286 public static IBooleanItem opDateEqual(@NonNull IDateItem arg1, @NonNull IDateItem arg2) {
287 return opDateTimeEqual(IDateTimeItem.cast(arg1), IDateTimeItem.cast(arg2));
288 }
289
290 @NonNull
291 public static IBooleanItem opDateTimeEqual(@NonNull IDateTimeItem arg1, @NonNull IDateTimeItem arg2) {
292 return IBooleanItem.valueOf(arg1.asZonedDateTime().equals(arg2.asZonedDateTime()));
293 }
294
295 @NonNull
296 public static IBooleanItem opDurationEqual(@NonNull IDurationItem arg1, @NonNull IDurationItem arg2) {
297 return IBooleanItem.valueOf(arg1.getValue().equals(arg2.getValue()));
298 }
299
300 @NonNull
301 public static IBooleanItem opBase64BinaryEqual(@NonNull IBase64BinaryItem arg1, @NonNull IBase64BinaryItem arg2) {
302 return IBooleanItem.valueOf(arg1.getValue().equals(arg2.getValue()));
303 }
304
305 @NonNull
306 public static IBooleanItem opDateGreaterThan(@NonNull IDateItem arg1, @NonNull IDateItem arg2) {
307 return opDateTimeGreaterThan(IDateTimeItem.cast(arg1), IDateTimeItem.cast(arg2));
308 }
309
310 @NonNull
311 public static IBooleanItem opDateTimeGreaterThan(@NonNull IDateTimeItem arg1, @NonNull IDateTimeItem arg2) {
312 return IBooleanItem.valueOf(arg1.asZonedDateTime().compareTo(arg2.asZonedDateTime()) > 0);
313 }
314
315 @NonNull
316 public static IBooleanItem opYearMonthDurationGreaterThan(@NonNull IYearMonthDurationItem arg1,
317 @NonNull IYearMonthDurationItem arg2) {
318 Period p1 = arg1.getValue();
319 Period p2 = arg2.getValue();
320
321
322 return IBooleanItem.valueOf(p1.toTotalMonths() > p2.toTotalMonths());
323 }
324
325 @NonNull
326 public static IBooleanItem opDayTimeDurationGreaterThan(
327 @NonNull IDayTimeDurationItem arg1,
328 @NonNull IDayTimeDurationItem arg2) {
329 return IBooleanItem.valueOf(arg1.getValue().compareTo(arg2.getValue()) > 0);
330 }
331
332 @NonNull
333 public static IBooleanItem opBase64BinaryGreaterThan(
334 @NonNull IBase64BinaryItem arg1,
335 @NonNull IBase64BinaryItem arg2) {
336 return IBooleanItem.valueOf(arg1.getValue().compareTo(arg2.getValue()) > 0);
337 }
338
339 @NonNull
340 public static IBooleanItem opDateLessThan(
341 @NonNull IDateItem arg1,
342 @NonNull IDateItem arg2) {
343 return opDateTimeLessThan(IDateTimeItem.cast(arg1), IDateTimeItem.cast(arg2));
344 }
345
346 @NonNull
347 public static IBooleanItem opDateTimeLessThan(
348 @NonNull IDateTimeItem arg1,
349 @NonNull IDateTimeItem arg2) {
350 return IBooleanItem.valueOf(arg1.asZonedDateTime().compareTo(arg2.asZonedDateTime()) < 0);
351 }
352
353 @NonNull
354 public static IBooleanItem opYearMonthDurationLessThan(@NonNull IYearMonthDurationItem arg1,
355 @NonNull IYearMonthDurationItem arg2) {
356 Period p1 = arg1.getValue();
357 Period p2 = arg2.getValue();
358
359
360 return IBooleanItem.valueOf(p1.toTotalMonths() < p2.toTotalMonths());
361 }
362
363 @NonNull
364 public static IBooleanItem opDayTimeDurationLessThan(
365 @NonNull IDayTimeDurationItem arg1,
366 @NonNull IDayTimeDurationItem arg2) {
367 return IBooleanItem.valueOf(arg1.getValue().compareTo(arg2.getValue()) < 0);
368 }
369
370 @NonNull
371 public static IBooleanItem opBase64BinaryLessThan(
372 @NonNull IBase64BinaryItem arg1,
373 @NonNull IBase64BinaryItem arg2) {
374 return IBooleanItem.valueOf(arg1.getValue().compareTo(arg2.getValue()) < 0);
375 }
376
377 @NonNull
378 public static INumericItem opNumericAdd(@NonNull INumericItem left, @NonNull INumericItem right) {
379 INumericItem retval;
380 if (left instanceof IDecimalItem || right instanceof IDecimalItem) {
381
382 BigDecimal decimalLeft = left.asDecimal();
383 BigDecimal decimalRight = right.asDecimal();
384
385 @SuppressWarnings("null")
386 @NonNull BigDecimal result = decimalLeft.add(decimalRight, FunctionUtils.MATH_CONTEXT);
387 retval = IDecimalItem.valueOf(result);
388 } else {
389
390 BigInteger integerLeft = left.asInteger();
391 BigInteger integerRight = right.asInteger();
392
393 @SuppressWarnings("null")
394 @NonNull BigInteger result = integerLeft.add(integerRight);
395 retval = IIntegerItem.valueOf(result);
396 }
397 return retval;
398 }
399
400 @NonNull
401 public static INumericItem opNumericSubtract(@NonNull INumericItem left, @NonNull INumericItem right) {
402 INumericItem retval;
403 if (left instanceof IDecimalItem || right instanceof IDecimalItem) {
404
405 BigDecimal decimalLeft = left.asDecimal();
406 BigDecimal decimalRight = right.asDecimal();
407
408 @SuppressWarnings("null")
409 @NonNull BigDecimal result = decimalLeft.subtract(decimalRight, FunctionUtils.MATH_CONTEXT);
410 retval = IDecimalItem.valueOf(result);
411 } else {
412
413 BigInteger integerLeft = left.asInteger();
414 BigInteger integerRight = right.asInteger();
415
416 @SuppressWarnings("null")
417 @NonNull BigInteger result = integerLeft.subtract(integerRight);
418 retval = IIntegerItem.valueOf(result);
419 }
420 return retval;
421 }
422
423 @NonNull
424 public static INumericItem opNumericMultiply(@NonNull INumericItem left, @NonNull INumericItem right) {
425 INumericItem retval;
426 if (left instanceof IDecimalItem || right instanceof IDecimalItem) {
427
428 BigDecimal decimalLeft = left.asDecimal();
429 BigDecimal decimalRight = right.asDecimal();
430
431 @SuppressWarnings("null")
432 @NonNull BigDecimal result = decimalLeft.multiply(decimalRight, FunctionUtils.MATH_CONTEXT);
433 retval = IDecimalItem.valueOf(result);
434 } else {
435
436 @SuppressWarnings("null")
437 @NonNull BigInteger result = left.asInteger().multiply(right.asInteger());
438 retval = IIntegerItem.valueOf(result);
439 }
440 return retval;
441 }
442
443 @NonNull
444 public static INumericItem opNumericDivide(@NonNull INumericItem dividend, @NonNull INumericItem divisor) {
445 INumericItem retval;
446 if (dividend instanceof IDecimalItem || divisor instanceof IDecimalItem) {
447
448 BigDecimal decimalDivisor = divisor.asDecimal();
449
450 if (BigDecimal.ZERO.equals(decimalDivisor)) {
451 throw new ArithmeticFunctionException(ArithmeticFunctionException.DIVISION_BY_ZERO,
452 ArithmeticFunctionException.DIVISION_BY_ZERO_MESSAGE);
453 }
454
455 BigDecimal decimalDividend = dividend.asDecimal();
456
457 @SuppressWarnings("null")
458 @NonNull BigDecimal result = decimalDividend.divide(decimalDivisor, FunctionUtils.MATH_CONTEXT);
459 retval = IDecimalItem.valueOf(result);
460 } else {
461
462 BigInteger integerDivisor = divisor.asInteger();
463
464 if (BigInteger.ZERO.equals(integerDivisor)) {
465 throw new ArithmeticFunctionException(ArithmeticFunctionException.DIVISION_BY_ZERO,
466 ArithmeticFunctionException.DIVISION_BY_ZERO_MESSAGE);
467 }
468
469 BigInteger integerDividend = dividend.asInteger();
470
471 @SuppressWarnings("null")
472 @NonNull BigInteger result = integerDividend.divide(integerDivisor);
473 retval = IIntegerItem.valueOf(result);
474 }
475 return retval;
476 }
477
478 @NonNull
479 public static IIntegerItem opNumericIntegerDivide(@NonNull INumericItem dividend, @NonNull INumericItem divisor) {
480 IIntegerItem retval;
481 if (dividend instanceof IDecimalItem || divisor instanceof IDecimalItem) {
482
483 BigDecimal decimalDivisor = divisor.asDecimal();
484
485 if (BigDecimal.ZERO.equals(decimalDivisor)) {
486 throw new ArithmeticFunctionException(ArithmeticFunctionException.DIVISION_BY_ZERO,
487 ArithmeticFunctionException.DIVISION_BY_ZERO_MESSAGE);
488 }
489
490 BigDecimal decimalDividend = dividend.asDecimal();
491
492 @SuppressWarnings("null")
493 @NonNull BigInteger result
494 = decimalDividend.divideToIntegralValue(decimalDivisor, FunctionUtils.MATH_CONTEXT).toBigInteger();
495 retval = IIntegerItem.valueOf(result);
496 } else {
497
498 BigInteger integerDivisor = divisor.asInteger();
499
500 if (BigInteger.ZERO.equals(integerDivisor)) {
501 throw new ArithmeticFunctionException(ArithmeticFunctionException.DIVISION_BY_ZERO,
502 ArithmeticFunctionException.DIVISION_BY_ZERO_MESSAGE);
503 }
504
505 @SuppressWarnings("null")
506 @NonNull BigInteger result = dividend.asInteger().divide(integerDivisor);
507 retval = IIntegerItem.valueOf(result);
508 }
509 return retval;
510 }
511
512
513
514
515
516
517
518
519
520
521
522 @NonNull
523 public static INumericItem opNumericMod(@NonNull INumericItem dividend, @NonNull INumericItem divisor) {
524 BigDecimal decimalDivisor = divisor.asDecimal();
525
526 if (BigDecimal.ZERO.equals(decimalDivisor)) {
527 throw new ArithmeticFunctionException(ArithmeticFunctionException.DIVISION_BY_ZERO,
528 ArithmeticFunctionException.DIVISION_BY_ZERO_MESSAGE);
529 }
530
531 BigDecimal decimalDividend = dividend.asDecimal();
532
533 INumericItem retval;
534 if (BigDecimal.ZERO.equals(decimalDividend)) {
535 retval = dividend;
536 } else {
537 @SuppressWarnings("null")
538 @NonNull BigDecimal result = decimalDividend.remainder(decimalDivisor, FunctionUtils.MATH_CONTEXT);
539 retval = IDecimalItem.valueOf(result);
540 }
541 return retval;
542 }
543
544 @NonNull
545 public static INumericItem opNumericUnaryMinus(@NonNull INumericItem item) {
546 INumericItem retval;
547 if (item instanceof IDecimalItem) {
548
549 BigDecimal decimal = item.asDecimal();
550
551 @SuppressWarnings("null")
552 @NonNull BigDecimal result = decimal.negate(FunctionUtils.MATH_CONTEXT);
553 retval = IDecimalItem.valueOf(result);
554 } else if (item instanceof IIntegerItem) {
555
556 BigInteger integer = item.asInteger();
557
558 @SuppressWarnings("null")
559 @NonNull BigInteger result = integer.negate();
560 retval = IIntegerItem.valueOf(result);
561 } else {
562 throw new InvalidTypeMetapathException(item);
563 }
564 return retval;
565 }
566
567 @NonNull
568 public static IBooleanItem opNumericEqual(@Nullable INumericItem arg1, @Nullable INumericItem arg2) {
569 IBooleanItem retval;
570 if (arg1 == null || arg2 == null) {
571 retval = IBooleanItem.FALSE;
572 } else if (arg1 instanceof IDecimalItem || arg2 instanceof IDecimalItem) {
573 retval = IBooleanItem.valueOf(arg1.asDecimal().equals(arg2.asDecimal()));
574 } else {
575 retval = IBooleanItem.valueOf(arg1.asInteger().equals(arg2.asInteger()));
576 }
577 return retval;
578 }
579
580 @NonNull
581 public static IBooleanItem opNumericGreaterThan(@Nullable INumericItem arg1, @Nullable INumericItem arg2) {
582 IBooleanItem retval;
583 if (arg1 == null || arg2 == null) {
584 retval = IBooleanItem.FALSE;
585 } else if (arg1 instanceof IDecimalItem || arg2 instanceof IDecimalItem) {
586 int result = arg1.asDecimal().compareTo(arg2.asDecimal());
587 retval = IBooleanItem.valueOf(result > 0);
588 } else {
589 int result = arg1.asInteger().compareTo(arg2.asInteger());
590 retval = IBooleanItem.valueOf(result > 0);
591 }
592 return retval;
593 }
594
595 @NonNull
596 public static IBooleanItem opNumericLessThan(@Nullable INumericItem arg1, @Nullable INumericItem arg2) {
597 IBooleanItem retval;
598 if (arg1 == null || arg2 == null) {
599 retval = IBooleanItem.FALSE;
600 } else if (arg1 instanceof IDecimalItem || arg2 instanceof IDecimalItem) {
601 int result = arg1.asDecimal().compareTo(arg2.asDecimal());
602 retval = IBooleanItem.valueOf(result < 0);
603 } else {
604 int result = arg1.asInteger().compareTo(arg2.asInteger());
605 retval = IBooleanItem.valueOf(result < 0);
606 }
607 return retval;
608 }
609
610 @NonNull
611 public static IBooleanItem opBooleanEqual(@Nullable IBooleanItem arg1, @Nullable IBooleanItem arg2) {
612 boolean left = arg1 != null && arg1.toBoolean();
613 boolean right = arg2 != null && arg2.toBoolean();
614
615 return IBooleanItem.valueOf(left == right);
616 }
617
618 @NonNull
619 public static IBooleanItem opBooleanGreaterThan(@Nullable IBooleanItem arg1, @Nullable IBooleanItem arg2) {
620 boolean left = arg1 != null && arg1.toBoolean();
621 boolean right = arg2 != null && arg2.toBoolean();
622
623 return IBooleanItem.valueOf(left && !right);
624 }
625
626 @NonNull
627 public static IBooleanItem opBooleanLessThan(@Nullable IBooleanItem arg1, @Nullable IBooleanItem arg2) {
628 boolean left = arg1 != null && arg1.toBoolean();
629 boolean right = arg2 != null && arg2.toBoolean();
630
631 return IBooleanItem.valueOf(!left && right);
632 }
633 }