use of org.kie.dmn.feel.runtime.Range in project drools by kiegroup.
the class EvalHelper method isEqual.
/**
* Compares left and right for equality applying FEEL semantics to specific data types
*
* @param left
* @param right
* @param ctx
* @return
*/
public static Boolean isEqual(Object left, Object right, EvaluationContext ctx) {
if (left == null || right == null) {
return left == right;
}
// and vice-versa
if (left instanceof Collection && !(right instanceof Collection) && ((Collection) left).size() == 1) {
left = ((Collection) left).toArray()[0];
} else if (right instanceof Collection && !(left instanceof Collection) && ((Collection) right).size() == 1) {
right = ((Collection) right).toArray()[0];
}
if (left instanceof Range && right instanceof Range) {
return isEqual((Range) left, (Range) right);
} else if (left instanceof Iterable && right instanceof Iterable) {
return isEqual((Iterable) left, (Iterable) right);
} else if (left instanceof Map && right instanceof Map) {
return isEqual((Map) left, (Map) right);
} else if (left instanceof ChronoPeriod && right instanceof ChronoPeriod) {
// periods have special compare semantics in FEEL as it ignores "days". Only months and years are compared
Long l = ComparablePeriod.toTotalMonths((ChronoPeriod) left);
Long r = ComparablePeriod.toTotalMonths((ChronoPeriod) right);
return isEqual(l, r);
} else if (left instanceof TemporalAccessor && right instanceof TemporalAccessor) {
// Handle specific cases when both time / datetime
TemporalAccessor l = (TemporalAccessor) left;
TemporalAccessor r = (TemporalAccessor) right;
if (BuiltInType.determineTypeFromInstance(left) == BuiltInType.TIME && BuiltInType.determineTypeFromInstance(right) == BuiltInType.TIME) {
return isEqual(valuet(l), valuet(r));
} else if (BuiltInType.determineTypeFromInstance(left) == BuiltInType.DATE_TIME && BuiltInType.determineTypeFromInstance(right) == BuiltInType.DATE_TIME) {
return isEqual(valuedt(l, r.query(TemporalQueries.zone())), valuedt(r, l.query(TemporalQueries.zone())));
}
// fallback; continue:
}
return compare(left, right, ctx, (l, r) -> l.compareTo(r) == 0);
}
use of org.kie.dmn.feel.runtime.Range in project drools by kiegroup.
the class EvalHelper method getDefinedValue.
public static PropertyValueResult getDefinedValue(final Object current, final String property) {
Object result;
if (current == null) {
return PropertyValueResult.notDefined();
} else if (current instanceof Map) {
result = ((Map) current).get(property);
if (result == null) {
// most cases "result" will be defined, so checking here only in case null was to signify missing key altogether.
if (!((Map) current).containsKey(property)) {
return PropertyValueResult.notDefined();
}
}
} else if (current instanceof ChronoPeriod) {
switch(property) {
case "years":
result = ((ChronoPeriod) current).get(ChronoUnit.YEARS);
break;
case "months":
result = ((ChronoPeriod) current).get(ChronoUnit.MONTHS) % 12;
break;
default:
return PropertyValueResult.notDefined();
}
} else if (current instanceof Duration) {
switch(property) {
case "days":
result = ((Duration) current).toDays();
break;
case "hours":
result = ((Duration) current).toHours() % 24;
break;
case "minutes":
result = ((Duration) current).toMinutes() % 60;
break;
case "seconds":
result = ((Duration) current).getSeconds() % 60;
break;
default:
return PropertyValueResult.notDefined();
}
} else if (current instanceof TemporalAccessor) {
switch(property) {
case "year":
result = ((TemporalAccessor) current).get(ChronoField.YEAR);
break;
case "month":
result = ((TemporalAccessor) current).get(ChronoField.MONTH_OF_YEAR);
break;
case "day":
result = ((TemporalAccessor) current).get(ChronoField.DAY_OF_MONTH);
break;
case "hour":
result = ((TemporalAccessor) current).get(ChronoField.HOUR_OF_DAY);
break;
case "minute":
result = ((TemporalAccessor) current).get(ChronoField.MINUTE_OF_HOUR);
break;
case "second":
result = ((TemporalAccessor) current).get(ChronoField.SECOND_OF_MINUTE);
break;
case "time offset":
if (((TemporalAccessor) current).isSupported(ChronoField.OFFSET_SECONDS)) {
result = Duration.ofSeconds(((TemporalAccessor) current).get(ChronoField.OFFSET_SECONDS));
} else {
result = null;
}
break;
case "timezone":
ZoneId zoneId = ((TemporalAccessor) current).query(TemporalQueries.zoneId());
if (zoneId != null) {
result = TimeZone.getTimeZone(zoneId).getID();
break;
} else {
return PropertyValueResult.notDefined();
}
case "weekday":
result = ((TemporalAccessor) current).get(ChronoField.DAY_OF_WEEK);
break;
default:
return PropertyValueResult.notDefined();
}
} else if (current instanceof Range) {
switch(property) {
case "start included":
result = ((Range) current).getLowBoundary() == RangeBoundary.CLOSED ? Boolean.TRUE : Boolean.FALSE;
break;
case "start":
result = ((Range) current).getLowEndPoint();
break;
case "end":
result = ((Range) current).getHighEndPoint();
break;
case "end included":
result = ((Range) current).getHighBoundary() == RangeBoundary.CLOSED ? Boolean.TRUE : Boolean.FALSE;
break;
default:
return PropertyValueResult.notDefined();
}
} else {
Method getter = getGenericAccessor(current.getClass(), property);
if (getter != null) {
try {
result = getter.invoke(current);
if (result instanceof Character) {
result = result.toString();
} else if (result instanceof java.util.Date) {
result = java.time.Instant.ofEpochMilli(((java.util.Date) result).getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
}
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
return PropertyValueResult.of(Either.ofLeft(e));
}
} else {
// WORST-CASE: if code reached here, means that "property" is not defined on the "current" object at all.
return PropertyValueResult.notDefined();
}
}
// before returning, coerce "result" into number.
result = coerceNumber(result);
return PropertyValueResult.ofValue(result);
}
use of org.kie.dmn.feel.runtime.Range in project drools by kiegroup.
the class MetByFunctionTest method invokeParamIsNull.
@Test
public void invokeParamIsNull() {
FunctionTestUtil.assertResultError(metByFunction.invoke((Range) null, (Range) new RangeImpl()), InvalidParametersEvent.class);
FunctionTestUtil.assertResultError(metByFunction.invoke((Range) new RangeImpl(), (Range) null), InvalidParametersEvent.class);
}
use of org.kie.dmn.feel.runtime.Range in project drools by kiegroup.
the class StartedByFunctionTest method invokeParamIsNull.
@Test
public void invokeParamIsNull() {
FunctionTestUtil.assertResultError(startedByFunction.invoke((Range) null, (Comparable) "b"), InvalidParametersEvent.class);
FunctionTestUtil.assertResultError(startedByFunction.invoke((Range) new RangeImpl(), (Comparable) null), InvalidParametersEvent.class);
}
use of org.kie.dmn.feel.runtime.Range in project drools by kiegroup.
the class OverlapsFunctionTest method invokeParamIsNull.
@Test
public void invokeParamIsNull() {
FunctionTestUtil.assertResultError(overlapsFunction.invoke((Range) null, (Range) new RangeImpl()), InvalidParametersEvent.class);
FunctionTestUtil.assertResultError(overlapsFunction.invoke((Range) new RangeImpl(), (Range) null), InvalidParametersEvent.class);
}
Aggregations