/******************************************************************************* * (c) Copyright 2016 Hewlett-Packard Development Company, L.P. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Apache License v2.0 which accompany this distribution. * * The Apache License is available at * http://www.apache.org/licenses/LICENSE-2.0 * *******************************************************************************/ package io.cloudslang.lang.compiler.modeller.transformers; import io.cloudslang.lang.compiler.modeller.result.BasicTransformModellingResult; import io.cloudslang.lang.compiler.modeller.result.TransformModellingResult; import io.cloudslang.lang.compiler.validator.ExecutableValidator; import io.cloudslang.lang.compiler.validator.PreCompileValidator; import io.cloudslang.lang.entities.ScoreLangConstants; import io.cloudslang.lang.entities.bindings.InOutParam; import io.cloudslang.lang.entities.bindings.Output; import io.cloudslang.lang.entities.bindings.values.ValueFactory; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.commons.collections4.CollectionUtils; public abstract class AbstractOutputsTransformer extends InOutTransformer { private PreCompileValidator preCompileValidator; private ExecutableValidator executableValidator; public TransformModellingResult<List<Output>> transform(List<Object> rawData) { List<Output> transformedData = new ArrayList<>(); List<RuntimeException> errors = new ArrayList<>(); if (CollectionUtils.isEmpty(rawData)) { return new BasicTransformModellingResult<>(transformedData, errors); } for (Object rawOutput : rawData) { try { if (rawOutput instanceof Map) { @SuppressWarnings("unchecked") Map.Entry<String, ?> entry = ((Map<String, ?>) rawOutput).entrySet().iterator().next(); Serializable entryValue = (Serializable) entry.getValue(); if (entryValue == null) { throw new RuntimeException("Could not transform Output : " + rawOutput + " since it has a null value.\n\n" + "Make sure a value is specified or that indentation is properly done."); } if (entryValue instanceof Map) { // - some_output: // property1: value1 // property2: value2 // this is the verbose way of defining outputs with all of the properties available handleOutputProperties(transformedData, entry, errors); } else { // - some_output: some_expression addOutput(transformedData, createOutput(entry.getKey(), entryValue, false), errors); } } else { //- some_output //this is our default behavior that if the user specifies only a key, // the key is also the ref we look for addOutput(transformedData, createRefOutput((String) rawOutput, false), errors); } } catch (RuntimeException rex) { errors.add(rex); } } return new BasicTransformModellingResult<>(transformedData, errors); } @Override public Class<? extends InOutParam> getTransformedObjectsClass() { return Output.class; } abstract void handleOutputProperties(List<Output> transformedData, Map.Entry<String, ?> entry, List<RuntimeException> errors); void addOutput(List<Output> outputs, Output element, List<RuntimeException> errors) { List<RuntimeException> validationErrors = preCompileValidator.validateNoDuplicateInOutParams(outputs, element); if (CollectionUtils.isEmpty(validationErrors)) { outputs.add(element); } else { errors.addAll(validationErrors); } } Output createOutput(String outputName, Serializable outputExpression, boolean sensitive) { executableValidator.validateOutputName(outputName); preCompileValidator.validateStringValue(outputName, outputExpression, this); Accumulator accumulator = extractFunctionData(outputExpression); return new Output( outputName, ValueFactory.create(outputExpression, sensitive), accumulator.getFunctionDependencies(), accumulator.getSystemPropertyDependencies() ); } Output createRefOutput(String rawOutput, boolean sensitive) { return createOutput(rawOutput, transformNameToExpression(rawOutput), sensitive); } private String transformNameToExpression(String name) { return ScoreLangConstants.EXPRESSION_START_DELIMITER + name + ScoreLangConstants.EXPRESSION_END_DELIMITER; } public void setPreCompileValidator(PreCompileValidator preCompileValidator) { this.preCompileValidator = preCompileValidator; } public void setExecutableValidator(ExecutableValidator executableValidator) { this.executableValidator = executableValidator; } }