io.cloudslang.lang.compiler.modeller.MetadataModellerImpl.java Source code

Java tutorial

Introduction

Here is the source code for io.cloudslang.lang.compiler.modeller.MetadataModellerImpl.java

Source

/*******************************************************************************
 * (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;

import io.cloudslang.lang.compiler.modeller.model.Metadata;
import io.cloudslang.lang.compiler.modeller.model.StepMetadata;
import io.cloudslang.lang.compiler.modeller.result.MetadataModellingResult;
import io.cloudslang.lang.compiler.parser.model.ParsedDescriptionData;
import io.cloudslang.lang.compiler.parser.model.ParsedDescriptionSection;
import io.cloudslang.lang.compiler.parser.utils.DescriptionTag;
import io.cloudslang.lang.compiler.parser.utils.StepDescriptionTag;
import io.cloudslang.lang.compiler.validator.matcher.DescriptionPatternMatcher;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;

public class MetadataModellerImpl implements MetadataModeller {
    private DescriptionPatternMatcher descriptionPatternMatcher;

    public MetadataModellerImpl() {
        descriptionPatternMatcher = new DescriptionPatternMatcher();
    }

    @Override
    public MetadataModellingResult createModel(ParsedDescriptionData parsedDescriptionData) {
        List<ParsedDescriptionSection> topLevelDescriptions = parsedDescriptionData.getTopLevelDescriptions();
        List<RuntimeException> errors = new ArrayList<>(parsedDescriptionData.getErrors());
        Pair<Metadata, List<RuntimeException>> executableMetadata = null;

        // executable metadata
        if (CollectionUtils.isNotEmpty(topLevelDescriptions)) {
            if (topLevelDescriptions.size() > 1) {
                errors.add(new RuntimeException("Multiple top level descriptions found at line numbers: "
                        + getLineNumbers(topLevelDescriptions)));
            }
            executableMetadata = transformToExecutableMetadata(topLevelDescriptions.get(0).getData());
            errors.addAll(executableMetadata.getRight());
        }

        // step metadata
        Pair<List<StepMetadata>, List<RuntimeException>> stepsModellingResult = transformStepsData(
                parsedDescriptionData.getStepDescriptions());
        List<StepMetadata> stepDescriptions = stepsModellingResult.getLeft();
        errors.addAll(stepsModellingResult.getRight());

        return new MetadataModellingResult(
                executableMetadata == null ? new Metadata() : executableMetadata.getLeft(), stepDescriptions,
                errors);
    }

    private String getLineNumbers(List<ParsedDescriptionSection> topLevelDescriptions) {
        int[] lineNumbers = new int[topLevelDescriptions.size()];
        for (int i = 0; i < topLevelDescriptions.size(); i++) {
            lineNumbers[i] = topLevelDescriptions.get(i).getStartLineNumber();
        }
        return Arrays.toString(lineNumbers);
    }

    private Pair<Metadata, List<RuntimeException>> transformToExecutableMetadata(Map<String, String> parsedData) {
        String description = "";
        String prerequisites = "";
        Map<String, String> inputs = new LinkedHashMap<>();
        Map<String, String> outputs = new LinkedHashMap<>();
        Map<String, String> results = new LinkedHashMap<>();
        Map<String, String> systemProperties = new LinkedHashMap<>();
        List<RuntimeException> errors = new ArrayList<>();

        for (Map.Entry<String, String> entry : parsedData.entrySet()) {
            String declaration = entry.getKey();
            String[] declarationElements = descriptionPatternMatcher.splitDeclaration(declaration);
            String tag = declarationElements[0];
            if (DescriptionTag.isDescriptionTag(tag)) {
                String content = entry.getValue();
                DescriptionTag descriptionTag = DescriptionTag.fromString(tag);
                if (descriptionTag != null) {
                    switch (descriptionTag) {
                    case DESCRIPTION:
                        description = content;
                        break;
                    case PREREQUISITES:
                        prerequisites = content;
                        break;
                    case INPUT:
                        processExecutableDeclaration(declarationElements, errors, tag, inputs, content);
                        break;
                    case OUTPUT:
                        processExecutableDeclaration(declarationElements, errors, tag, outputs, content);
                        break;
                    case RESULT:
                        processExecutableDeclaration(declarationElements, errors, tag, results, content);
                        break;
                    case SYSTEM_PROPERTY:
                        processExecutableDeclaration(declarationElements, errors, tag, systemProperties, content);
                        break;
                    default:
                        // shouldn't get here
                        errors.add(new NotImplementedException("Unrecognized tag: " + descriptionTag));
                    }
                } else {
                    // shouldn't get here
                    errors.add(new RuntimeException("Unrecognized tag: " + tag));
                }
            } else {
                errors.add(new RuntimeException("Unrecognized tag for executable description section: " + tag));
            }
        }

        Metadata executableMetadata = new Metadata(description, prerequisites, inputs, outputs, results,
                systemProperties);
        return new ImmutablePair<>(executableMetadata, errors);
    }

    private void processExecutableDeclaration(String[] declarationElements, List<RuntimeException> errors,
            String tag, Map<String, String> parameters, String content) {
        processDeclaration(declarationElements, errors, tag, parameters, content, "executable");
    }

    private void processStepDeclaration(String[] declarationElements, List<RuntimeException> errors, String tag,
            Map<String, String> parameters, String content, String stepName) {
        processDeclaration(declarationElements, errors, tag, parameters, content, "step[" + stepName + "]");
    }

    private void processDeclaration(String[] declarationElements, List<RuntimeException> errors, String tag,
            Map<String, String> parameters, String content, String identifier) {
        if (declarationElements.length != 2) {
            errors.add(new RuntimeException("For " + identifier + " parameter name for tag[" + tag
                    + "] is missing. " + "Format should be [" + tag + " name]"));
        } else {
            String name = declarationElements[1];
            parameters.put(name, content);
        }
    }

    private Pair<List<StepMetadata>, List<RuntimeException>> transformStepsData(
            Map<String, ParsedDescriptionSection> stepsData) {
        List<StepMetadata> stepsMetadata = new ArrayList<>();
        List<RuntimeException> errors = new ArrayList<>();
        for (Map.Entry<String, ParsedDescriptionSection> entry : stepsData.entrySet()) {
            String stepName = entry.getKey();
            ParsedDescriptionSection parsedData = entry.getValue();
            Pair<StepMetadata, List<RuntimeException>> transformResult = transformToStepMetadata(stepName,
                    parsedData.getData());
            stepsMetadata.add(transformResult.getLeft());
            errors.addAll(transformResult.getRight());
        }

        return new ImmutablePair<>(stepsMetadata, errors);
    }

    private Pair<StepMetadata, List<RuntimeException>> transformToStepMetadata(String stepName,
            Map<String, String> parsedData) {
        Map<String, String> inputs = new LinkedHashMap<>();
        Map<String, String> outputs = new LinkedHashMap<>();
        List<RuntimeException> errors = new ArrayList<>();

        for (Map.Entry<String, String> entry : parsedData.entrySet()) {
            String declaration = entry.getKey();
            String[] declarationElements = descriptionPatternMatcher.splitDeclaration(declaration);
            String tag = declarationElements[0];
            if (StepDescriptionTag.isStepDescriptionTag(tag)) {
                String content = entry.getValue();
                StepDescriptionTag descriptionTag = StepDescriptionTag.fromString(tag);
                if (descriptionTag != null) {
                    switch (descriptionTag) {
                    case INPUT:
                        processStepDeclaration(declarationElements, errors, tag, inputs, content, stepName);
                        break;
                    case OUTPUT:
                        processStepDeclaration(declarationElements, errors, tag, outputs, content, stepName);
                        break;
                    default:
                        // shouldn't get here
                        errors.add(new NotImplementedException("Unrecognized tag: " + descriptionTag));
                    }
                } else {
                    // shouldn't get here
                    errors.add(new RuntimeException("Unrecognized tag: " + tag));
                }
            } else {
                errors.add(new RuntimeException("Unrecognized tag for step description section: " + tag));
            }
        }

        StepMetadata stepMetadata = new StepMetadata(stepName, inputs, outputs);
        return new ImmutablePair<>(stepMetadata, errors);
    }

}