com.xlrit.gears.runner.runnertarget.GrqlResolver Maven / Gradle / Ivy
package com.xlrit.gears.runner.runnertarget;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class GrqlResolver {
private final String key;
private final GraphQLRunnerTarget runnerTarget;
private final Pattern variableRegex = Pattern.compile("@\\w+");
public Map resolved;
public GrqlResolver(String key, GraphQLRunnerTarget runnerTarget) {
this.key = key;
this.runnerTarget = runnerTarget;
}
public String toJpql(String grql) {
List variables = extractVariables(grql);
resolved = resolve(variables);
return interpolate(grql, resolved);
}
/** replace all resolve runner variables in the grql query to create a jpql query */
private String interpolate(String grql, Map resolved) {
String result = grql;
for (var entry : resolved.entrySet()) {
result = result.replace(entry.getKey(), normalize(entry.getValue()));
}
return result;
}
/** numbers can be inserted into the jpql query as is, but anything else should be wrapped in quotes. */
private String normalize(String resolved) {
try {
Double.parseDouble(resolved);
// parse was successful since we don't move to catch block
return resolved;
} catch (NumberFormatException e) {
// parse was unsuccessful
return String.format("'%s'", resolved);
}
}
/** resolve all variables to values */
private Map resolve(List variables) {
return variables.stream().collect(Collectors.toMap(var -> var, this::resolve));
}
private String resolve(String variable) {
if (key == null) throw new InterpreterException(String.format("Cannot resolve variable %s in GRQL because no process has been started", variable));
return switch (variable.substring(1)) {
case "startTime" -> runnerTarget.getProcessInstance(key).startTime();
case "id" -> runnerTarget.getProcessInstance(key).processInstanceId();
default -> throw new InterpreterException(String.format("No resolver available for variable '%s' in GRQL", variable));
};
}
private List extractVariables(String grql) {
List matches = new ArrayList<>();
Matcher matcher = variableRegex.matcher(grql);
while (matcher.find()) {
matches.add(matcher.group());
}
return matches;
}
}