software-versions-processor.../src/main/java/org/gcube/common/software/analyser/Analyser.java

182 lines
6.6 KiB
Java

package org.gcube.common.software.analyser;
import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode;
import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode;
import org.gcube.common.software.model.ProcessorConfig;
import org.gcube.common.software.model.GlobalConfig;
import org.gcube.common.software.model.SoftwareArtifactMetadata;
import org.gcube.common.software.model.SoftwareArtifactFile;
import org.gcube.common.software.model.Variables;
import org.gcube.common.software.processor.SoftwareArtifactProcessor;
import org.gcube.common.software.utils.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class Analyser {
private static final Logger logger = LoggerFactory.getLogger(Analyser.class);
protected ObjectMapper objectMapper;
protected File outputDirectory;
protected ObjectNode globalConfiguration;
protected ArrayNode artifactMetadataArray;
public Analyser() throws Exception {
this.objectMapper = Utils.getObjectMapper();
}
public void setOutputDirectory(File outputDirectory) {
this.outputDirectory = outputDirectory;
}
public ObjectNode getGlobalConfiguration() {
return globalConfiguration;
}
public void setGlobalConfiguration(ObjectNode originalGlobalConfiguration) {
this.globalConfiguration = originalGlobalConfiguration.deepCopy();
}
public ArrayNode getArtifactMetadataArray() {
return artifactMetadataArray;
}
public void setArtifactMetadataArray(ArrayNode original) {
this.artifactMetadataArray = original.deepCopy();
}
protected SoftwareArtifactMetadata actualizeSoftwareArtifactConfig(JsonNode version) throws Exception {
((ObjectNode) version).remove(GlobalConfig.PROCESSORS_PROPERTY_NAME);
Variables variables = objectMapper.treeToValue(version, Variables.class);
Set<String> missingVariables = variables.parse();
int size = missingVariables.size();
if(size>0) {
throw new Exception("The following variables has been used but not defined or cannot be actualised" +
missingVariables.toArray(new String[size]).toString());
}
JsonNode swVersion = objectMapper.convertValue(variables.getProperties(), JsonNode.class);
SoftwareArtifactMetadata softwareVersionConfig = objectMapper.treeToValue(swVersion, SoftwareArtifactMetadata.class);
List<SoftwareArtifactFile> svfs = softwareVersionConfig.getFiles();
for(SoftwareArtifactFile svf : svfs) {
URL url = svf.getURL();
String urlString = variables.replaceAllVariables(url.toString());
svf.setURL(new URL(urlString));
String desiredName = svf.getDesiredName();
desiredName = variables.replaceAllVariables(desiredName);
svf.setDesiredName(desiredName);
}
return softwareVersionConfig;
}
protected GlobalConfig getGlobalConfig(JsonNode node) throws Exception {
Variables variables = objectMapper.treeToValue(node, Variables.class);
variables.parse();
JsonNode sc = objectMapper.convertValue(variables.getProperties(), JsonNode.class);
GlobalConfig globalConfig = objectMapper.treeToValue(sc, GlobalConfig.class);
globalConfig.setOriginalJson(globalConfiguration);
return globalConfig;
}
protected ProcessorConfig actualizeProcessorConfig(ProcessorConfig processorConfig, SoftwareArtifactMetadata softwareArtifactMetadata) throws Exception {
ObjectNode versionNode = objectMapper.valueToTree(softwareArtifactMetadata);
Variables versionVariables = objectMapper.treeToValue(versionNode, Variables.class);
ObjectNode node = objectMapper.valueToTree(processorConfig);
Variables variables = objectMapper.treeToValue(node, Variables.class);
variables.parseWith(versionVariables);
JsonNode ec = objectMapper.convertValue(variables.getProperties(), JsonNode.class);
return objectMapper.treeToValue(ec, ProcessorConfig.class);
}
protected void checkProcessors(Set<String> availableProcessorNames, Set<String> requestedProcessorNames) throws Exception {
if(!availableProcessorNames.containsAll(requestedProcessorNames)) {
requestedProcessorNames.removeAll(availableProcessorNames);
throw new Exception("The following requested exporters does not exists " + requestedProcessorNames);
}
}
public List<File> analyse() throws Exception {
GlobalConfig globalConfig = getGlobalConfig(globalConfiguration);
Map<String, Class<? extends SoftwareArtifactProcessor>> availableProcessors = SoftwareArtifactProcessor.getAvailableProcessors();
Map<String,ProcessorConfig> requestedProcessors = globalConfig.getProcessorConfigurations();
checkProcessors(availableProcessors.keySet(), requestedProcessors.keySet());
if(outputDirectory==null) {
outputDirectory = new File(globalConfig.getFileName());
}
if(!outputDirectory.exists()) {
Files.createDirectories(outputDirectory.toPath());
}
SoftwareArtifactMetadata previous = null;
int i = 0;
List<File> outputFiles = new ArrayList<>();
for(i=0; i<artifactMetadataArray.size(); i++) {
ObjectNode artifactMetadata = (ObjectNode) artifactMetadataArray.get(i).deepCopy();
JsonNode mergedArtifactMetadata = Utils.merge(globalConfiguration, artifactMetadata);
SoftwareArtifactMetadata softwareArtifactMetadata = actualizeSoftwareArtifactConfig(mergedArtifactMetadata);
softwareArtifactMetadata.setOriginalJson(artifactMetadata);
softwareArtifactMetadata.setPrevious(previous);
logger.trace("Going to process {}", softwareArtifactMetadata.getTitle());
for(String className : requestedProcessors.keySet()) {
logger.debug("Going to export with {}", className);
Class<? extends SoftwareArtifactProcessor> processorClass = availableProcessors.get(className);
ProcessorConfig processorConfig = requestedProcessors.get(className);
processorConfig = actualizeProcessorConfig(processorConfig, softwareArtifactMetadata);
SoftwareArtifactProcessor sap = processorClass.newInstance();
sap.setOutputDirectory(outputDirectory);
sap.setGlobalConfig(globalConfig);
sap.setSoftwareArtifactConfig(softwareArtifactMetadata);
sap.setProcessorConfig(processorConfig);
sap.setFirst(i==0);
boolean last = i==(artifactMetadataArray.size()-1);
sap.setLast(last);
sap.export();
if(last) {
outputFiles.add(sap.getOutputFile());
}
}
Thread.sleep(TimeUnit.SECONDS.toMillis(2));
previous = softwareArtifactMetadata;
}
return outputFiles;
}
}