protected void collectApplicableSpecialFieldTargetResolvers()

in core/src/main/java/org/apache/brooklyn/util/core/predicates/DslPredicates.java [352:446]


        protected void collectApplicableSpecialFieldTargetResolvers(Map<String,Function<Object,Maybe<Object>>> resolvers) {
            if (key!=null) resolvers.put("key", (value) -> {
                if (value instanceof Map) {
                    if (((Map) value).containsKey(key)) {
                        return Maybe.ofAllowingNull( ((Map) value).get(key) );
                    } else {
                        return Maybe.absent("Cannot find indicated key '"+key+"' in map");
                    }
                } else {
                    return Maybe.absent("Cannot evaluate key on non-map target "+classOf(value));
                }
            });

            if (index != null) resolvers.put("index", (value) -> {
                Integer i = index;
                Object v0 = value;
                if (value instanceof Map) value = ((Map)value).entrySet();
                if (value instanceof Iterable) {
                    int size = Iterables.size((Iterable) value);
                    if (i<0) {
                        i = size + i;
                    }
                    if (i<0 || i>=size) return Maybe.absent("No element at index "+i+" ("+classOf(v0)+" size "+size+")");
                    return Maybe.of(Iterables.get((Iterable)value, i));
                } else {
                    return Maybe.absent("Cannot evaluate index on non-list target "+classOf(v0));
                }
            });

            if (filter != null) resolvers.put("filter", (value) -> {
                if (value instanceof Map) value = ((Map)value).entrySet();
                if (value instanceof Iterable) {
                    return Maybe.of(Iterables.filter((Iterable) value, filter));
                } else {
                    return Maybe.absent("Cannot evaluate filter on non-list target "+classOf(value));
                }
            });

            if (jsonpath!=null) resolvers.put("jsonpath", (value) -> {
                Entity entity = BrooklynTaskTags.getContextEntity(Tasks.current());
                String json;
                try {
                    json = BeanWithTypeUtils.newMapper(entity!=null ? ((EntityInternal)entity).getManagementContext() : null, false, null, false).writeValueAsString(value);
                } catch (Exception e) {
                    Exceptions.propagateIfFatal(e);
                    if (LOG.isTraceEnabled()) LOG.trace("Unable to consider jsonpath for non-serializable '"+value+"' due to: "+e, e);
                    return Maybe.absent("Cannot serialize object as JSON: "+e);
                }

                String jsonpathTidied = jsonpath;
                if (jsonpathTidied!=null && !jsonpathTidied.startsWith("$")) {
                    if (jsonpathTidied.startsWith("@") || jsonpathTidied.startsWith(".") || jsonpathTidied.startsWith("[")) {
                        jsonpathTidied = '$' + jsonpathTidied;
                    } else {
                        jsonpathTidied = "$." + jsonpathTidied;
                    }
                }
                Object result;
                try {
                    result = JsonPath.read(json, jsonpathTidied);
                } catch (Exception e) {
                    Exceptions.propagateIfFatal(e);
                    if (LOG.isTraceEnabled()) LOG.trace("Unable to evaluate jsonpath '"+jsonpathTidied+"' for '"+value+"' due to: "+e, e);
                    return Maybe.absent("No jsonpath matches");
                }

                // above will throw if jsonpath doesn't match anything
                // this will return single object possibly null, or a list possibly empty
                return Maybe.ofAllowingNull(result);
            });

            if (errorField!=null) resolvers.put("error-field", (value) -> {
                if (!(value instanceof Throwable)) return Maybe.absent("Unable to apply error-field to non-throwable "+value);
                Throwable t = (Throwable)value;

                Maybe<Method> m = Reflections.getMethodFromArgs(value, "get" + Strings.toInitialCapOnly(errorField), MutableList.of());
                if (m.isPresent()) return m.map(mm -> {
                    try {
                        return mm.invoke(t);
                    } catch (Exception e) {
                        throw Exceptions.propagate(e);
                    }
                });

                Maybe<Object> v = Reflections.getFieldValueMaybe(value, errorField);
                if (v.isPresent()) return v;

                return Maybe.absent("No such field or getter for '"+errorField+"'");
            });

            if (errorCause!=null) resolvers.put("error-cause", (value) -> {
                if (!(value instanceof Throwable)) return Maybe.absent("Unable to apply error-field to non-throwable "+value);
                return Maybe.cast(findErrorCause(errorCause, value));
            });
        }