io.cloudslang.lang.tools.build.verifier.SlangContentVerifier Maven / Gradle / Ivy
/*******************************************************************************
* (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.tools.build.verifier;
import io.cloudslang.lang.commons.services.api.SlangCompilationService;
import io.cloudslang.lang.compiler.MetadataExtractor;
import io.cloudslang.lang.compiler.SlangCompiler;
import io.cloudslang.lang.compiler.SlangSource;
import io.cloudslang.lang.compiler.modeller.model.Executable;
import io.cloudslang.lang.compiler.modeller.model.Metadata;
import io.cloudslang.lang.compiler.modeller.result.ExecutableModellingResult;
import io.cloudslang.lang.compiler.modeller.result.MetadataModellingResult;
import io.cloudslang.lang.compiler.scorecompiler.ScoreCompiler;
import io.cloudslang.lang.entities.CompilationArtifact;
import io.cloudslang.lang.logging.LoggingService;
import io.cloudslang.lang.tools.build.validation.MetadataMissingException;
import io.cloudslang.lang.tools.build.validation.StaticValidator;
import java.io.File;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import org.apache.commons.lang.Validate;
import org.apache.logging.log4j.Level;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Created by stoneo on 3/15/2015.
**/
@Component
public class SlangContentVerifier {
@Autowired
private SlangCompiler slangCompiler;
@Autowired
private MetadataExtractor metadataExtractor;
@Autowired
private StaticValidator staticValidator;
@Autowired
private ScoreCompiler scoreCompiler;
@Autowired
private LoggingService loggingService;
@Autowired
private SlangCompilationService slangCompilationService;
public PreCompileResult createModelsAndValidate(String directoryPath, boolean shouldValidateDescription,
boolean shouldValidateCheckstyle) {
Validate.notEmpty(directoryPath, "You must specify a path");
Validate.isTrue(new File(directoryPath).isDirectory(), "Directory path argument \'" +
directoryPath + "\' does not lead to a directory");
Map slangModels = new HashMap<>();
Collection slangFiles = slangCompilationService.listSlangFiles(new File(directoryPath), true);
loggingService.logEvent(Level.INFO, "Start compiling all slang files under: " + directoryPath);
loggingService.logEvent(Level.INFO, slangFiles.size() + " .sl files were found");
loggingService.logEvent(Level.INFO, "");
Queue exceptions = new ArrayDeque<>();
String errorMessagePrefixMetadata = "";
for (File slangFile: slangFiles) {
Executable sourceModel = null;
try {
errorMessagePrefixMetadata = "Failed to extract metadata for file: \'" +
slangFile.getAbsoluteFile() + "\'.\n";
String errorMessagePrefixCompilation = "Failed to compile file: \'" +
slangFile.getAbsoluteFile() + "\'.\n";
Validate.isTrue(slangFile.isFile(), "file path \'" + slangFile.getAbsolutePath() +
"\' must lead to a file");
SlangSource slangSource = SlangSource.fromFile(slangFile);
ExecutableModellingResult preCompileResult = slangCompiler.preCompileSource(slangSource);
sourceModel = preCompileResult.getExecutable();
exceptions.addAll(prependPrefix(preCompileResult.getErrors(), errorMessagePrefixCompilation));
MetadataModellingResult metadataResult = metadataExtractor
.extractMetadataModellingResult(slangSource, shouldValidateCheckstyle);
Metadata sourceMetadata = metadataResult.getMetadata();
exceptions.addAll(prependPrefix(metadataResult.getErrors(), errorMessagePrefixMetadata));
if (sourceModel != null) {
int size = exceptions.size();
staticValidator.validateSlangFile(slangFile, sourceModel,
sourceMetadata, shouldValidateDescription, exceptions);
if (size == exceptions.size()) {
slangModels.put(getUniqueName(sourceModel), sourceModel);
}
}
} catch (Exception e) {
String errorMessage = errorMessagePrefixMetadata + e.getMessage();
loggingService.logEvent(Level.ERROR, errorMessage);
exceptions.add(new RuntimeException(errorMessage, e));
if (e instanceof MetadataMissingException && sourceModel != null) {
slangModels.put(getUniqueName(sourceModel), sourceModel);
}
}
}
if (slangFiles.size() != slangModels.size()) {
exceptions.add(new RuntimeException("Some Slang files were not pre-compiled.\nFound: " + slangFiles.size() +
" executable files in path: \'" + directoryPath +
"\' But managed to create slang models for only: " + slangModels.size()));
}
PreCompileResult preCompileResult = new PreCompileResult();
preCompileResult.addExceptions(exceptions);
preCompileResult.addResults(slangModels);
return preCompileResult;
}
private Collection prependPrefix(Collection errors, String prefix) {
List result = new ArrayList<>();
for (RuntimeException ex : errors) {
result.add(wrapWithPrefix(ex, prefix));
}
return result;
}
private RuntimeException wrapWithPrefix(RuntimeException rex, String prefix) {
return new RuntimeException(prefix + rex.getMessage(), rex);
}
public CompileResult compileSlangModels(Map slangModels) {
CompileResult compileResult = new CompileResult();
Map compiledArtifacts = new HashMap<>();
for (Map.Entry slangModelEntry : slangModels.entrySet()) {
Executable slangModel = slangModelEntry.getValue();
try {
CompilationArtifact compiledSource = compiledArtifacts.get(getUniqueName(slangModel));
if (compiledSource == null) {
Set dependenciesModels = getModelDependenciesRecursively(slangModels, slangModel);
compiledSource = scoreCompiler.compile(slangModel, dependenciesModels);
if (compiledSource != null) {
loggingService.logEvent(Level.INFO, "Compiled: \'" + slangModel.getNamespace() + "." +
slangModel.getName() + "\' successfully");
compiledArtifacts.put(getUniqueName(slangModel), compiledSource);
} else {
loggingService.logEvent(Level.ERROR, "Failed to compile source: \'" +
slangModel.getNamespace() + "." + slangModel.getName() + "\'");
}
}
} catch (Exception e) {
String errorMessage = "Failed compiling Slang source: \'" + slangModel.getNamespace() + "." +
slangModel.getName() + "\'.\n" + e.getMessage();
loggingService.logEvent(Level.ERROR, errorMessage);
compileResult.addException(new RuntimeException(errorMessage, e));
}
}
compileResult.addResults(compiledArtifacts);
return compileResult;
}
private Set getModelDependenciesRecursively(Map slangModels,
Executable slangModel) {
Set dependenciesModels = new HashSet<>();
for (String dependencyName : slangModel.getExecutableDependencies()) {
Executable dependency = slangModels.get(dependencyName);
if (dependency == null) {
throw new RuntimeException("Failed compiling slang source: " + slangModel.getNamespace() + "." +
slangModel.getName() + ". Missing dependency: " + dependencyName);
}
dependenciesModels.add(dependency);
dependenciesModels.addAll(getModelDependenciesRecursively(slangModels, dependency));
}
return dependenciesModels;
}
private String getUniqueName(Executable sourceModel) {
return sourceModel.getNamespace() + "." + sourceModel.getName();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy