software-versions-processor.../src/main/java/org/gcube/common/software/model/Variables.java

156 lines
4.4 KiB
Java

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 Map<String, Object> properties;
public Variables() {
properties = new LinkedHashMap<>();
}
/**
* 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;
}
public String replaceAllVariables(String value) throws Exception {
Set<String> missingVariables = new HashSet<>();
Set<String> variableNames = findVariables(value);
for(String variableName : variableNames) {
if(properties.containsKey(variableName)) {
try {
String variableValue = properties.get(variableName).toString();
value = Utils.replaceVariable(variableName, variableValue, value);
}catch (Exception e) {
missingVariables.add(variableName);
}
}else {
missingVariables.add(variableName);
}
}
if(missingVariables.size()>0) {
throw new Exception("The following variables cannot be replaced because they don't exists " + missingVariables.toString());
}
return value;
}
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;
}
public 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) {
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) {
// Object value = properties.get(key);
// this.properties.put(key, value);
// }
// parse();
// }
}