in core/src/main/java/org/apache/brooklyn/core/workflow/steps/variables/TransformMerge.java [81:152]
public Object apply(Object v) {
Object result = null;
if (v instanceof Iterable) {
// given an explicit list; we will merge each item
} else if (v instanceof String) {
v = qst((String) v).remainderRaw();
} else {
throw new IllegalStateException("Invalid value to merge: " + v);
}
if (!map && !list && !set) {
map = Iterables.any((Iterable) v, vi -> vi instanceof Map || ((vi instanceof String) && ((String) vi).startsWith("{")));
list = Iterables.any((Iterable) v, vi -> vi instanceof Iterable || ((vi instanceof String) && ((String) vi).startsWith("[")));
}
if (map && list)
throw new IllegalStateException("Invalid value to merge; contains combination of list and map");
Class<?> type = map ? Map.class : list ? List.class : set ? Set.class : Object.class;
Function<Class, Object> resultInit = t -> {
if (t == Map.class) return MutableMap.of();
if (t == List.class) return MutableList.of();
if (t == Set.class) return MutableSet.of();
throw new IllegalStateException("Unexpected type " + t);
};
for (Object vi : (Iterable) v) {
if (vi instanceof String && Strings.isBlank((String)vi)) continue;
try {
vi = wait ? context.resolveWaiting(WorkflowExpressionResolution.WorkflowExpressionStage.STEP_RUNNING, vi, TypeToken.of(type)) :
context.resolve(WorkflowExpressionResolution.WorkflowExpressionStage.STEP_RUNNING, vi, TypeToken.of(type));
} catch (Exception e) {
Exceptions.propagateIfFatal(e);
if (lax) {
log.debug("Ignoring entry " + vi + " when transforming for merge because cannot be resolved to " + type.getName());
continue;
} else {
throw Exceptions.propagate(e);
}
}
if (vi instanceof Map) {
type = Map.class;
if (result == null) result = resultInit.apply(type);
if (!(result instanceof Map))
throw new IllegalArgumentException("Invalid value to merge; contains a map when expected a list");
if (deep) {
result = CollectionMerger.builder().build().merge((Map) result, (Map) vi);
} else {
((Map) result).putAll((Map) vi);
}
} else if (vi instanceof Collection) {
type = set ? Set.class : List.class;
if (result == null) result = resultInit.apply(type);
if (!(result instanceof Collection))
throw new IllegalArgumentException("Invalid value to merge; contains a map when expected a list or set");
if (deep && !lax)
throw new IllegalArgumentException("Invalid value to deep merge; deep only applies to maps and a collection was encountered");
((Collection) result).addAll((Collection) vi);
} else {
if (lax) {
// ignore
} else {
throw new IllegalArgumentException("Invalid value to merge (specify lax mode to ignore): " + vi);
}
}
}
return result;
}