io.cloudslang.lang.compiler.parser.utils.MetadataValidatorImpl.java Source code

Java tutorial

Introduction

Here is the source code for io.cloudslang.lang.compiler.parser.utils.MetadataValidatorImpl.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.parser.utils;

import io.cloudslang.lang.compiler.SlangSource;
import io.cloudslang.lang.compiler.parser.MetadataParser;
import io.cloudslang.lang.compiler.parser.model.ParsedDescriptionData;
import io.cloudslang.lang.compiler.parser.model.ParsedDescriptionSection;
import io.cloudslang.lang.compiler.utils.MetadataUtils;
import io.cloudslang.lang.compiler.utils.SlangSourceUtils;
import io.cloudslang.lang.compiler.validator.matcher.DescriptionPatternMatcher;
import io.cloudslang.lang.entities.constants.Regex;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.tuple.Pair;

public class MetadataValidatorImpl implements MetadataValidator {

    private MetadataParser metadataParser;
    private DescriptionPatternMatcher descriptionPatternMatcher;

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

    @Override
    public List<RuntimeException> validateCheckstyle(SlangSource source) {
        Validate.notNull(source.getContent(), "Source " + source.getName() + " cannot be null");
        try {
            return extractCheckstyleData(source);
        } catch (Throwable e) {
            throw new RuntimeException("There was a problem extracting checkstyle data for source ["
                    + source.getName() + "]  - " + e.getMessage(), e);
        }
    }

    private List<RuntimeException> extractCheckstyleData(SlangSource source) {
        List<String> lines = SlangSourceUtils.readLines(source);
        ParsedDescriptionData parsedDescriptionData = metadataParser.parse(source);
        List<RuntimeException> errors = new ArrayList<>();

        // process flow descriptions
        List<ParsedDescriptionSection> topLevelDescriptions = parsedDescriptionData.getTopLevelDescriptions();
        for (ParsedDescriptionSection topLevelDescription : topLevelDescriptions) {
            errors.addAll(processCommonRules(lines, topLevelDescription, false));
        }

        // process step descriptions
        Collection<ParsedDescriptionSection> stepDescriptions = parsedDescriptionData.getStepDescriptions()
                .values();
        for (ParsedDescriptionSection stepDescription : stepDescriptions) {
            errors.addAll(processCommonRules(lines, stepDescription, true));
        }

        return errors;
    }

    private List<RuntimeException> processCommonRules(List<String> lines,
            ParsedDescriptionSection parsedDescriptionSection, boolean isStep) {
        List<RuntimeException> errors = new ArrayList<>();
        int startLineNumberZeroBased = parsedDescriptionSection.getStartLineNumber() - 1;

        // validate begin wrapper line
        validateBeginWrapperLine(lines, isStep, errors, startLineNumberZeroBased);

        boolean finished = false;
        String previousTag = null;
        int previousItemEndLineNumber = -1;
        for (int lineNrZeroBased = startLineNumberZeroBased + 1; !finished
                && lineNrZeroBased < lines.size(); lineNrZeroBased++) {
            String currentLine = lines.get(lineNrZeroBased);

            // #! @tag var: content
            // #! @tag: content
            boolean variableLine = isVariableLine(currentLine);
            boolean isGeneralLine = isGeneralLine(currentLine);
            if (variableLine || isGeneralLine || isVariableLineDeclarationOnly(currentLine)) {
                // extract tag
                String currentTag;
                if (variableLine) {
                    Pair<String, String> declaration = descriptionPatternMatcher
                            .getDescriptionVariableLineData(currentLine);
                    String[] declarationElements = descriptionPatternMatcher
                            .splitDeclaration(declaration.getLeft());
                    currentTag = declarationElements[0];
                } else if (isGeneralLine) {
                    Pair<String, String> declaration = descriptionPatternMatcher
                            .getDescriptionGeneralLineData(currentLine);
                    String[] declarationElements = descriptionPatternMatcher
                            .splitDeclaration(declaration.getLeft());
                    currentTag = declarationElements[0];
                } else {
                    Pair<String, String> declaration = descriptionPatternMatcher
                            .getDescriptionVariableLineDataDeclarationOnly(currentLine);
                    String[] declarationElements = descriptionPatternMatcher
                            .splitDeclaration(declaration.getLeft());
                    currentTag = declarationElements[0];
                }

                // validate empty line
                validateEmptyLine(lines, errors, previousTag, previousItemEndLineNumber, currentTag);

                previousTag = currentTag;
                previousItemEndLineNumber = lineNrZeroBased;
            } else {
                // #! continued from previous line
                if (isNonEmptyComplementaryLine(currentLine)) {
                    previousItemEndLineNumber = lineNrZeroBased;
                } else {
                    // #!!#
                    if (descriptionPatternMatcher.matchesDescriptionEnd(currentLine)) {
                        // validate ending wrapper line
                        validateEndingWrapperLine(lines, isStep, errors, lineNrZeroBased);

                        finished = true;
                    }
                    // otherwise ignore
                }
            }
        }
        return errors;
    }

    private void validateEndingWrapperLine(List<String> lines, boolean isStep, List<RuntimeException> errors,
            int lineNrZeroBased) {
        int targetedLineNumberZeroBased = lineNrZeroBased + 1;
        String nextLine = tryExtractLine(lines, targetedLineNumberZeroBased);
        if (isStep) {
            if (nextLine == null || !descriptionPatternMatcher.matchesStepDelimiterLine(nextLine)) {
                errors.add(new RuntimeException(generateErrorMessage(lineNrZeroBased,
                        "Next line should be delimiter line (90 characters of `#`)")));
            }
        } else {
            if (nextLine == null || !descriptionPatternMatcher.matchesExecutableDelimiterLine(nextLine)) {
                errors.add(new RuntimeException(generateErrorMessage(lineNrZeroBased,
                        "Next line should be delimiter line (120 characters of `#`)")));
            }
        }
    }

    private void validateEmptyLine(List<String> lines, List<RuntimeException> errors, String previousTag,
            int previousItemEndLineNumber, String currentTag) {
        if (previousTag != null && !previousTag.equals(currentTag)) {
            int targetedLineNumberZeroBased = previousItemEndLineNumber + 1;
            String targetedLine = lines.get(targetedLineNumberZeroBased);
            if (!descriptionPatternMatcher.matchesEmptyLine(targetedLine)) {
                errors.add(new RuntimeException(generateErrorMessage(targetedLineNumberZeroBased,
                        "There should be an empty line between two sections of different tags" + " (" + previousTag
                                + " and " + currentTag + ")")));
            }
        }
    }

    private void validateBeginWrapperLine(List<String> lines, boolean isStep, List<RuntimeException> errors,
            int startLineNumberZeroBased) {
        int targetedLineNumberZeroBased = startLineNumberZeroBased - 1;
        String previousLine = tryExtractLine(lines, targetedLineNumberZeroBased);
        if (isStep) {
            if (previousLine == null || !descriptionPatternMatcher.matchesStepDelimiterLine(previousLine)) {
                errors.add(new RuntimeException(generateErrorMessage(startLineNumberZeroBased,
                        "Previous line should be delimiter line (90 characters of `#`)")));
            }
        } else {
            if (previousLine == null || !descriptionPatternMatcher.matchesExecutableDelimiterLine(previousLine)) {
                errors.add(new RuntimeException(generateErrorMessage(startLineNumberZeroBased,
                        "Previous line should be delimiter line (120 characters of `#`)")));
            }
        }
    }

    private String generateErrorMessage(int lineNumberZeroBased, String data) {
        return MetadataUtils.generateErrorMessage(lineNumberZeroBased, data);
    }

    private boolean isNonEmptyComplementaryLine(String currentLine) {
        return descriptionPatternMatcher.matchesDescriptionComplementaryLine(currentLine)
                && !currentLine.trim().equals(Regex.DESCRIPTION_TOKEN);
    }

    private boolean isGeneralLine(String currentLine) {
        return descriptionPatternMatcher.matchesDescriptionGeneralLine(currentLine);
    }

    private boolean isVariableLine(String currentLine) {
        return descriptionPatternMatcher.matchesDescriptionVariableLine(currentLine);
    }

    private boolean isVariableLineDeclarationOnly(String currentLine) {
        return descriptionPatternMatcher.matchesVariableLineDeclarationOnlyLine(currentLine);
    }

    private String tryExtractLine(List<String> lines, int lineNr) {
        if (lineNr >= 0 && lineNr < lines.size()) {
            return lines.get(lineNr);
        }
        return null;
    }

    public void setMetadataParser(MetadataParser metadataParser) {
        this.metadataParser = metadataParser;
    }

}