public Object apply()

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