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

146 lines
5.5 KiB
Java

package org.gcube.common.software.analyser;
import java.io.File;
import java.net.URL;
import java.util.Set;
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.JsonNodeType;
import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode;
import org.gcube.common.software.model.SoftwareConcept;
import org.gcube.common.software.model.SoftwareVersion;
import org.gcube.common.software.model.Variables;
import org.gcube.common.software.utils.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class SoftwareConceptAnalyser {
private static final Logger logger = LoggerFactory.getLogger(SoftwareConceptAnalyser.class);
public static final String CONCEPT_FILENAME_EXTENSION = ".json";
public static final String CONCEPT_PROPERTY_NAME = "concept";
public static final String VERSIONS_PROPERTY_NAME = "versions";
public static final String PUBLISHERS_PROPERTY_NAME = "publishers";
public static final String EXPORTERS_PROPERTY_NAME = "exporters";
protected ObjectMapper objectMapper;
protected JsonNode jsonNode;
public SoftwareConceptAnalyser(File jsonFile) throws Exception {
this.objectMapper = Utils.getObjectMapper();
this.jsonNode = objectMapper.readTree(jsonFile);
}
public SoftwareConceptAnalyser(String json) throws Exception {
this.objectMapper = Utils.getObjectMapper();
this.jsonNode = objectMapper.readTree(json);
}
protected SoftwareVersion actualize(JsonNode version) throws Exception {
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);
SoftwareVersion softwareVersion = objectMapper.treeToValue(swVersion, SoftwareVersion.class);
// softwareVersion.setVariables(variables);
return softwareVersion;
}
public void analyse() throws Exception {
ObjectNode concept = (ObjectNode) jsonNode.get(CONCEPT_PROPERTY_NAME).deepCopy();
SoftwareConcept softwareConcept = objectMapper.treeToValue(concept, SoftwareConcept.class);
ArrayNode versions = (ArrayNode) jsonNode.get(VERSIONS_PROPERTY_NAME);
String name = softwareConcept.getName();
SoftwareVersion previous = null;
int i = 0;
ArrayNode exportingVersions = objectMapper.createArrayNode();
try {
for(i=0; i<versions.size(); i++) {
ObjectNode originalVersion = (ObjectNode) versions.get(i).deepCopy();
exportingVersions.add(originalVersion);
JsonNode version = Utils.merge(concept, originalVersion);
SoftwareVersion softwareVersion = actualize(version);
boolean newDOI = false;
if(softwareVersion.getDOIURL()==null) {
newDOI = true;
}
softwareVersion.setPrevious(previous);
if(previous!=null) {
previous.setNext(softwareVersion);
}
logger.trace("Going to process {} {} (previous version {})",
name, softwareVersion.getVersion(),
softwareVersion.getPrevious()!=null ? softwareVersion.getPrevious().getVersion(): null);
try {
SoftwareVersionAnalyser softwareVersionAnalyser = new SoftwareVersionAnalyser(softwareVersion);
softwareVersionAnalyser.setOriginalJson(jsonNode);
softwareVersionAnalyser.setFirst(i==0);
softwareVersionAnalyser.analyse();
previous = softwareVersion;
}finally {
/* Need to export the original file with the version doi */
if(originalVersion.has(SoftwareVersion.DOI_URL_PROPERTY_NAME)
&& originalVersion.get(SoftwareVersion.DOI_URL_PROPERTY_NAME).getNodeType()==JsonNodeType.NULL
&& softwareVersion.getDOIURL()!=null) {
originalVersion.put(SoftwareVersion.DOI_URL_PROPERTY_NAME, softwareVersion.getDOIURL().toString());
}
if((!originalVersion.has(SoftwareVersion.VERSION_DOI_URL_PROPERTY_NAME) || originalVersion.get(SoftwareVersion.VERSION_DOI_URL_PROPERTY_NAME).getNodeType()==JsonNodeType.NULL)
&& softwareVersion.getVersionDOIURL()!=null) {
originalVersion.put(SoftwareVersion.VERSION_DOI_URL_PROPERTY_NAME, softwareVersion.getVersionDOIURL().toString());
}
if(newDOI) {
URL doiURL = softwareVersion.getDOIURL();
softwareConcept.setDOIURL(doiURL);
concept.put(SoftwareConcept.DOI_URL_PROPERTY_NAME, doiURL.toString());
originalVersion.put(SoftwareVersion.DOI_URL_PROPERTY_NAME, doiURL.toString());
}
}
}
} catch (Exception e) {
for(int j=i+1; j<versions.size(); j++) {
ObjectNode originalVersion = (ObjectNode) versions.get(j).deepCopy();
exportingVersions.add(originalVersion);
}
throw e;
}finally {
ObjectNode toBeExported = objectMapper.createObjectNode();
toBeExported.replace(CONCEPT_PROPERTY_NAME, concept);
toBeExported.replace(VERSIONS_PROPERTY_NAME, exportingVersions);
toBeExported.replace(PUBLISHERS_PROPERTY_NAME, jsonNode.get(PUBLISHERS_PROPERTY_NAME).deepCopy());
toBeExported.replace(EXPORTERS_PROPERTY_NAME, jsonNode.get(EXPORTERS_PROPERTY_NAME).deepCopy());
File file = new File(name+CONCEPT_FILENAME_EXTENSION);
objectMapper.writeValue(file, toBeExported);
}
}
}