package org.aksw.jena_sparql_api.utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.jena.sparql.core.Var;
import org.apache.jena.sparql.graph.NodeTransform;
public class VarUtils {
public static final Pattern VARNAME = Pattern.compile("(\\?|\\$)?(?<varname>\\S*)");
/**
* Parse the patterns (?|$)\\S* as variables
*
* @return
*/
// public static Var parseVar(String str) {
// Matcher m = VARNAME.matcher(str);
// String s = m.find()
// ? m.group(2)
// : null;
//
// Var result = Var.alloc(s);
// return result;
// }
/**
* This method parses the string generated by Map<Var, Var>.toString() back into the Java object.
* Variable names must not contain symbols '=' and ','
*
* @param str
* @return
*/
public static Map<Var, Var> parseVarMap(String str) {
Map<Var, Var> result = new HashMap<>();
int l = str.length();
int start = str.startsWith("{") ? 1 : 0;
int end = str.endsWith("}") ? l - 1 : l;
String sub = str.substring(start, end);
String[] entries = sub.split(",");
for(String entry : entries) {
String[] kv = entry.split("=", 2);
Var k = parseVar(kv[0]);
Var v = parseVar(kv[1]);
result.put(k, v);
}
return result;
}
public static Var parseVar(String str) {
// Remove leading ? of the varName
String varName = str.trim();
char c = varName.charAt(0);
if(c != '?' && c != '$') {
throw new RuntimeException("var name must start with '?' or '$'");
}
varName = varName.substring(1);
Var result = Var.alloc(varName);
return result;
}
/**
* Create a generator which yields fresh variables that is not contained in the array 'vars'.
* The new var name will have the given prefix
*
*/
public static Generator<Var> createVarGen(String prefix, Collection<Var> excludeVars) {
prefix = prefix == null ? "v" : prefix;
Generator<Var> result = VarGeneratorBlacklist.create(prefix, excludeVars);
// Set<//Var> excludeVarNames = getVarNames(excludeVars);
//var generator = GenSym.create(prefix);
//var genVarName = new GeneratorBlacklist(generator, excludeVarNames);
//var result = new VarGen(genVarName);
return result;
}
/**
* Returns a list of variable names as strings for a given iterable of Var objects.
*
* @param vars
* @return
*/
public static List<String> getVarNames(Iterable<Var> vars) {
List<String> result = new ArrayList<String>();
for(Var var : vars) {
result.add(var.getName());
}
return result;
}
public static List<Var> toList(Collection<String> varNames) {
List<Var> result = new ArrayList<Var>(varNames.size());
for(String varName : varNames) {
Var var = Var.alloc(varName);
result.add(var);
}
return result;
}
public static Set<Var> toSet(Collection<String> varNames) {
Set<Var> result = new HashSet<Var>();
for(String varName : varNames) {
Var var = Var.alloc(varName);
result.add(var);
}
return result;
}
public static List<String> map(Collection<String> varNames, Map<Var, Var> varMap) {
List<String> result = new ArrayList<String>(varNames.size());
for(String varName : varNames) {
Var sourceVar = Var.alloc(varName);
Var targetVar = varMap.get(sourceVar);
if(targetVar == null) {
targetVar = sourceVar;
}
String targetVarName = targetVar.getVarName();
result.add(targetVarName);
}
return result;
}
public static Var applyNodeTransform(Var var, NodeTransform nodeTransform) {
Var result = applyNodeTransform(var, nodeTransform, var);
return result;
}
public static Var applyNodeTransform(Var var, NodeTransform nodeTransform, Var defaultVar) {
Var tmp = (Var)nodeTransform.apply(var);
Var result = tmp == null ? defaultVar : tmp;
return result;
}
/**
* Returns a map that maps *each* variable from vbs to a name that does not appear in vas.
*
* @param excludeSymmetry if true, exclude mappings from a var in vbs to itself.
*/
public static Map<Var, Var> createDistinctVarMap(Collection<Var> vas, Collection<Var> vbs, boolean excludeSymmetry, Generator<Var> generator) {
//var vans = vas.map(VarUtils.getVarName);
if (generator == null) {
generator = VarGeneratorBlacklist.create(vas);
//new VarGeneratorBlacklist(new VarGeneratorImpl(Gensym.create("v")), vas);
}
// Rename all variables that are in common
Map<Var, Var> result = new HashMap<Var, Var>();
for(Var oldVar : vbs) {
Var newVar;
if (vas.contains(oldVar)) {
newVar = generator.next();
} else {
newVar = oldVar;
}
boolean isSame = oldVar.equals(newVar);
if(!(excludeSymmetry && isSame)) {
result.put(oldVar, newVar);
}
}
return result;
}
public static Map<Var, Var> createJoinVarMap(Collection<Var> sourceVars, Collection<Var> targetVars, List<Var> sourceJoinVars, List<Var> targetJoinVars, Generator<Var> generator) {
if (sourceJoinVars.size() != targetJoinVars.size()) {
throw new RuntimeException("Cannot join on different number of columns");
}
Map<Var, Var> result = VarUtils.createDistinctVarMap(sourceVars, targetVars, true, generator);
for (int i = 0; i < sourceJoinVars.size(); ++i) {
Var sourceJoinVar = sourceJoinVars.get(i);
Var targetJoinVar = targetJoinVars.get(i);
// Map targetVar to sourceVar
result.put(targetJoinVar, sourceJoinVar);
// rename[targetVar.getName()] = sourceVar;
}
return result;
}
}