public static PropertyValueResult getDefinedValue()

in kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/EvalHelper.java [92:217]


    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();
            }
            if (result instanceof UndefinedValueComparable) {
                result = null;
            }
        } 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) {
                    LOG.error("Exception", e);
                    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 = NumberEvalHelper.coerceNumber(result);

        return PropertyValueResult.ofValue(result);
    }