Adding dynamic management of variables

This commit is contained in:
Luca Frosini 2023-01-11 11:11:12 +01:00
parent cc82089aa7
commit 46738f588d
5 changed files with 233 additions and 10 deletions

View File

@ -30,14 +30,14 @@ public class SoftwareConceptAnalyser {
this.objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
}
public void analyse(File jsonFile) throws Exception {
SoftwareConcept deposition = objectMapper.readValue(jsonFile, SoftwareConcept.class);
analyse(deposition);
public SoftwareConcept getSoftwareConcept(File jsonFile) throws Exception {
SoftwareConcept softwareConcept = objectMapper.readValue(jsonFile, SoftwareConcept.class);
return softwareConcept;
}
public void analyse(String json) throws Exception {
SoftwareConcept deposition = objectMapper.readValue(json, SoftwareConcept.class);
analyse(deposition);
public SoftwareConcept getSoftwareConcept(String json) throws Exception {
SoftwareConcept softwareConcept = objectMapper.readValue(json, SoftwareConcept.class);
return softwareConcept;
}
public void analyse(SoftwareConcept softwareConcept) throws Exception {

View File

@ -3,6 +3,7 @@ package org.gcube.common.software.model;
import java.util.List;
import org.gcube.com.fasterxml.jackson.annotation.JsonFormat;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnore;
import org.gcube.com.fasterxml.jackson.annotation.JsonProperty;
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
@ -50,6 +51,9 @@ public class SoftwareConcept {
@JsonProperty(METADATA_PROPERTY_NAME)
protected JsonNode metadata;
@JsonIgnore
protected Variables variables;
public String getName() {
return name;
}
@ -85,5 +89,13 @@ public class SoftwareConcept {
public JsonNode getMetadata() {
return metadata;
}
@JsonIgnore
public Variables getVariables() {
if(variables==null) {
}
return variables;
}
}

View File

@ -0,0 +1,158 @@
package org.gcube.common.software.model;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.gcube.com.fasterxml.jackson.annotation.JsonAnySetter;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnore;
import org.gcube.common.software.utils.Utils;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class Variables {
public static final String REGEX;
public static final Pattern PATTERN;
static {
REGEX = "\\{\\{[a-zA-Z\\-\\_]+\\}\\}";
PATTERN = Pattern.compile(REGEX);
}
protected Set<String> keysToBeExcluded;
protected Map<String, Object> properties;
public Variables() {
properties = new LinkedHashMap<>();
}
@JsonIgnore
public void setKeysToBeExcluded(Set<String> keysToBeExcluded) {
if(keysToBeExcluded==null) {
return;
}
if(this.keysToBeExcluded!=null) {
return;
}
this.keysToBeExcluded = keysToBeExcluded;
if(properties!=null) {
for(String key : keysToBeExcluded) {
properties.remove(key);
}
}
}
/**
* Search the variables used in the String provided as argument
* @param string the string to analyze to find variables
* @return the list of used variables
*/
protected Set<String> findVariables(String value) {
Set<String> variables = new HashSet<>();
Matcher m = Variables.PATTERN.matcher(value);
if(m.find()) {
do {
String variable = m.group();
variable = variable.replaceAll("\\{", "");
variable = variable.replaceAll("\\}", "");
variables.add(variable);
} while(m.find(m.start()+1));
}
return variables;
}
protected Set<String> replaceAllVariables(String key, String value) throws Exception {
Set<String> missingVariables = new HashSet<>();
Set<String> variableNames = findVariables(value);
for(String variableName : variableNames) {
if(variableName.compareTo(key)==0) {
throw new Exception("You can't define self as variable in the value");
}
if(properties.containsKey(variableName)) {
String variableValue = properties.get(variableName).toString();
value = Utils.replaceVariable(variableName, variableValue, value);
}else {
missingVariables.add(variableName);
}
}
properties.replace(key, value);
return missingVariables;
}
protected Set<String> parseAndReplace() throws Exception {
Set<String> missingVariables = new HashSet<>();
Set<String> keys = properties.keySet();
for(String key : keys) {
Object objectValue = properties.get(key);
if(objectValue instanceof String) {
String value = (String) objectValue;
missingVariables.addAll(replaceAllVariables(key, value));
}
// TODO check variables in nested obj
}
return missingVariables;
}
protected Set<String> parse() throws Exception {
Set<String> missingVariables = parseAndReplace();
while(missingVariables.size()>0) {
Set<String> newMissingVariables = parseAndReplace();
if(newMissingVariables.containsAll(missingVariables)) {
return missingVariables;
}else {
missingVariables = newMissingVariables;
}
}
return missingVariables;
}
@JsonIgnore
public Map<String, Object> getProperties() {
return properties;
}
@JsonIgnore
public void setProperties(Map<String, Object> properties) {
this.properties = properties;
}
@JsonAnySetter
public void addProperty(String key, Object value) {
if(keysToBeExcluded!=null && keysToBeExcluded.contains(key)) {
return;
}
this.properties.put(key, value);
}
/**
* Add to this object the missing properties
* and replace the properties already present
* with the values contained in the provided
* object as argument
* @param variables the properties to merge with this object
* @throws Exception
*/
@JsonIgnore
public void merge(Variables variables) throws Exception {
Map<String, Object> properties = variables.getProperties();
Set<String> keys = properties.keySet();
for(String key : keys) {
if(keysToBeExcluded!=null && keysToBeExcluded.contains(key)) {
return;
}
Object value = properties.get(key);
this.properties.put(key, value);
}
parse();
}
}

View File

@ -2,6 +2,7 @@ package org.gcube.common.software.analyser;
import java.io.File;
import org.gcube.common.software.model.SoftwareConcept;
import org.gcube.common.software.utils.FileUtils;
import org.junit.Test;
@ -10,13 +11,14 @@ import org.junit.Test;
*/
public class SoftwareConceptAnalyserTest {
public static final String CONCEPT_FILENAME = "gcat-test-sandbox.json";
public static final String FILENAME = "gcat-test-sandbox.json";
@Test
public void testUsingTestFile() throws Exception {
SoftwareConceptAnalyser zenodoDeposit = new SoftwareConceptAnalyser();
File file = FileUtils.getFileFromFilename(CONCEPT_FILENAME);
zenodoDeposit.analyse(file);
SoftwareConceptAnalyser softwareConceptAnalyser = new SoftwareConceptAnalyser();
File file = FileUtils.getFileFromFilename(FILENAME);
SoftwareConcept softwareConcept = softwareConceptAnalyser.getSoftwareConcept(file);
softwareConceptAnalyser.analyse(softwareConcept);
}
}

View File

@ -0,0 +1,51 @@
package org.gcube.common.software.model;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.common.software.analyser.SoftwareConceptAnalyser;
import org.gcube.common.software.analyser.SoftwareConceptAnalyserTest;
import org.gcube.common.software.utils.FileUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class VariablesTest {
private static final Logger logger = LoggerFactory.getLogger(VariablesTest.class);
@Test
public void testFindVariables() {
Variables variables = new Variables();
Set<String> vars = variables.findVariables("https://nexus.d4science.org/nexus/service/local/repo_groups/gcube-releases-all/content/org/gcube/data-catalogue/{{name}}/{{version}}/{{name}}-{{version}}.war");
logger.info("Found variables are {}", vars);
}
@Test
public void test() throws Exception {
SoftwareConceptAnalyser softwareConceptAnalyser = new SoftwareConceptAnalyser();
File file = FileUtils.getFileFromFilename(SoftwareConceptAnalyserTest.FILENAME);
SoftwareConcept softwareConcept = softwareConceptAnalyser.getSoftwareConcept(file);
ObjectMapper objectMapper = new ObjectMapper();
String serialized = objectMapper.writeValueAsString(softwareConcept);
Variables variables = objectMapper.readValue(serialized, Variables.class);
Set<String> keyToBeExcluded = new HashSet<>();
keyToBeExcluded.add("versions");
variables.setKeysToBeExcluded(keyToBeExcluded);
logger.info("Variables are {}\n\n", variables.getProperties());
Set<String> missingVariables = variables.parse();
logger.info("Variables after parsing are {}\\n\\n", variables.getProperties());
logger.info("Missing variables are {}", missingVariables);
}
}