Search in sources :

Example 11 with Range

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);
}
Also used : ChronoPeriod(java.time.chrono.ChronoPeriod) TemporalAccessor(java.time.temporal.TemporalAccessor) AtomicLong(java.util.concurrent.atomic.AtomicLong) Collection(java.util.Collection) Range(org.kie.dmn.feel.runtime.Range) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 12 with Range

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);
}
Also used : ChronoPeriod(java.time.chrono.ChronoPeriod) TemporalAccessor(java.time.temporal.TemporalAccessor) ZoneId(java.time.ZoneId) Duration(java.time.Duration) Method(java.lang.reflect.Method) Range(org.kie.dmn.feel.runtime.Range) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 13 with Range

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);
}
Also used : Range(org.kie.dmn.feel.runtime.Range) RangeImpl(org.kie.dmn.feel.runtime.impl.RangeImpl) Test(org.junit.Test)

Example 14 with Range

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);
}
Also used : Range(org.kie.dmn.feel.runtime.Range) RangeImpl(org.kie.dmn.feel.runtime.impl.RangeImpl) Test(org.junit.Test)

Example 15 with Range

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);
}
Also used : Range(org.kie.dmn.feel.runtime.Range) RangeImpl(org.kie.dmn.feel.runtime.impl.RangeImpl) Test(org.junit.Test)

Aggregations

Range (org.kie.dmn.feel.runtime.Range)23 RangeImpl (org.kie.dmn.feel.runtime.impl.RangeImpl)14 Test (org.junit.Test)12 ArrayList (java.util.ArrayList)6 List (java.util.List)6 Map (java.util.Map)6 DMNContext (org.kie.dmn.api.core.DMNContext)4 EvaluatorResult (org.kie.dmn.core.api.EvaluatorResult)4 DMNResultImpl (org.kie.dmn.core.impl.DMNResultImpl)4 ChronoPeriod (java.time.chrono.ChronoPeriod)3 TemporalAccessor (java.time.temporal.TemporalAccessor)3 Duration (java.time.Duration)2 ZoneId (java.time.ZoneId)2 LinkedList (java.util.LinkedList)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 EvaluatorResultImpl (org.kie.dmn.core.ast.EvaluatorResultImpl)2 IterableRange (org.kie.dmn.core.util.IterableRange)2 FEELFunction (org.kie.dmn.feel.runtime.FEELFunction)2 UnaryTest (org.kie.dmn.feel.runtime.UnaryTest)2 IterableRange (org.kie.dmn.trisotech.core.util.IterableRange)2