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));
});
}