org.aksw.jena_sparql_api.views.VarBinding Maven / Gradle / Ivy
The newest version!
package org.aksw.jena_sparql_api.views;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.aksw.commons.collections.multimaps.BiHashMultimap;
import org.aksw.commons.collections.multimaps.IBiSetMultimap;
import org.aksw.jena_sparql_api.utils.QuadUtils;
import org.apache.jena.graph.Node;
import org.apache.jena.sparql.core.Quad;
import org.apache.jena.sparql.core.Var;
class BindingVal
extends VarConst
{
public BindingVal() {
super();
}
public BindingVal(Set keys, Node value) {
super(keys, value);
}
}
/**
* A variable binding maps query vars to sets of view variables.
*
*
*
*
* @author Claus Stadler
*
*/
public class VarBinding {
private Map keyToToken = new HashMap();
private Map valueToToken = new HashMap();
private Map tokenToSet = new HashMap();
//private Map tokenToValue = new HashMap();
private int nextToken;
public VarBinding() {
}
public Map getQueryVarToConstant() {
Map result = new HashMap();
for(Entry entry : keyToToken.entrySet()) {
Var value = entry.getKey();
Integer token = entry.getValue();
BindingVal val = tokenToSet.get(token);
Node constant = val.getValue();
result.put(value, constant);
}
return result;
}
public IBiSetMultimap getQueryVarToViewVars() {
IBiSetMultimap result = new BiHashMultimap();
for(Entry entry : keyToToken.entrySet()) {
Var value = entry.getKey();
Integer token = entry.getValue();
BindingVal val = tokenToSet.get(token);
Set keys = val.getKeys();
result.putAll(value, keys);
}
return result;
}
/*
* Return a mapping from view to query vars
*
*/
public IBiSetMultimap getViewVarToQueryVars() {
IBiSetMultimap tmp = getQueryVarToViewVars();
IBiSetMultimap result = tmp.getInverse();
return result;
/*
Multimap result = HashMultimap.create();
for(Entry entry : valueToToken.entrySet()) {
Var value = entry.getKey();
Integer token = entry.getValue();
BindingVal val = tokenToSet.get(token);
Set keys = val.getKeys();
result.putAll(value, keys);
}
return result;
*/
}
public Set getQueryVars() {
return keyToToken.keySet();
}
public Set getViewVars(Var queryVar) {
BindingVal tmp = get(queryVar);
if(tmp == null) {
return null;
}
return tmp.getKeys();
}
public Node getConstant(Var queryVar) {
BindingVal tmp = get(queryVar);
if(tmp == null) {
return null;
}
return tmp.getValue();
}
public BindingVal get(Var queryVar) {
Integer token = keyToToken.get(queryVar);
if(token == null) {
return null;
}
BindingVal result = tokenToSet.get(token);
return result;
}
/*
public VarBinding(IBiSetMultimap queryVarToViewVars) {
this.queryVarToViewVars = queryVarToViewVars;
}
*/
/*
public boolean putAll(VarBinding other) {
for(other.ge)
}
*/
public boolean put(Var queryVar, Var viewVar) {
Integer keyToken = keyToToken.get(queryVar);
Integer valueToken = valueToToken.get(viewVar);
if(valueToken == null) {
if(keyToken == null) {
Integer token = nextToken++;
valueToToken.put(viewVar, token);
keyToToken.put(queryVar, token);
BindingVal val = new BindingVal();
val.getKeys().add(viewVar);
tokenToSet.put(token, val);
} else {
// The value already exists - point the key to the token
valueToToken.put(viewVar, keyToken);
BindingVal val = tokenToSet.get(keyToken);
val.getKeys().add(viewVar);
}
} else {
if(keyToken == null) {
// The value exists, but has not yet been associated with the key
keyToToken.put(queryVar, valueToken);
} else {
if(keyToken.equals(valueToken)) {
return true;
}
// Merge both the key and value token things
BindingVal a = tokenToSet.get(keyToken);
BindingVal b = tokenToSet.get(valueToken);
Node valA = a.getValue();
Node valB = b.getValue();
Node res = valA == null ? valB : valB;
if(valB != null && valB != res) {
return false;
}
a.setValue(res);
for(Var vv : b.getKeys()) {
valueToToken.put(vv, keyToken);
}
tokenToSet.remove(valueToken);
a.getKeys().addAll(b.getKeys());
}
}
return true;
}
public boolean put(Var queryVar, Node node) {
if(node == null) {
return true;
} else if(node.isVariable()) {
return put(queryVar, (Var)node);
}
Integer token = keyToToken.get(queryVar);
if(token == null) {
token = nextToken++;
keyToToken.put(queryVar, token);
BindingVal val = new BindingVal();
tokenToSet.put(token, val);
val.setValue(node);
return true;
} else {
BindingVal val = tokenToSet.get(token);
Node existing = val.getValue();
if(existing == null) {
val.setValue(node);
return true;
} else if(existing.equals(node)) {
return true;
} else {
return false;
}
}
}
public void putAll(VarBinding that) {
for(Entry entry : that.getQueryVarToViewVars().entries()) {
this.put(entry.getKey(), entry.getValue());
}
for(Entry entry : that.getQueryVarToConstant().entrySet()) {
this.put(entry.getKey(), entry.getValue());
}
}
public static VarBinding create(Quad a, Quad b)
{
VarBinding result = new VarBinding();
List nAs = QuadUtils.quadToList(a);
List nBs = QuadUtils.quadToList(b);
for(int i = 0; i < 4; ++i) {
Var nA = (Var)nAs.get(i);
Node nB = nBs.get(i);
if(!result.put(nA, nB)) {
return null;
}
}
return result;
}
@Override
public String toString() {
String result = "{";
boolean isFirst = true;
for(Entry entry : keyToToken.entrySet()) {
Var key = entry.getKey();
Integer token = entry.getValue();
BindingVal val = tokenToSet.get(token);
if(isFirst) {
isFirst = false;
} else {
result += ", ";
}
result += key + ": (" + token + ")" + val;
}
result += "}";
return result;
//return "keyToToken: " + keyToToken + ", tokenToSet:" + tokenToSet;
}
/*
public Set getQueryVars() {
return queryVarToViewVars.asMap().keySet();
}
public Set get(Var queryVar) {
return queryVarToViewVars.get(queryVar);
}
public IBiSetMultimap getMap()
{
return queryVarToViewVars;
}
public VarBinding computeClosure() {
Map> state = new HashMap>();
// Invert the binding: For the set of viewVars, get the set of queryVars that map to them
IBiSetMultimap viewVarsToQueryVars = queryVarToViewVars.getInverse();
for(Entry> entry : queryVarToViewVars.asMap().entrySet()) {
Var queryVar = entry.getKey(); //open.iterator().next();
Collection viewVars = entry.getValue();
// Re-use a corresponding viewVar-set
// in the state, otherwise create a new one
Set mergedViewVars = state.get(queryVar);
if(mergedViewVars == null) {
mergedViewVars = new HashSet(viewVars);
}
for(Var viewVar : viewVars) {
Set queryVarsB = viewVarsToQueryVars.get(viewVar);
for(Var queryVarB : queryVarsB) {
if(queryVarB.equals(queryVar)) {
continue;
}
Set viewVarsC = state.get(queryVarB);
// A viewVars set might not exist for a key yet
if(viewVarsC == null) {
viewVarsC = queryVarToViewVars.get(queryVarB);
}
mergedViewVars.addAll(viewVarsC);
state.put(queryVarB, mergedViewVars);
}
}
}
// OPTIMIZE: Use some batch function for this - or at least hide the complexity here
IBiSetMultimap map = new BiHashMultimap();
for(Entry> entry : state.entrySet()) {
Var queryVar = entry.getKey();
for(Var viewVar : entry.getValue()) {
map.put(queryVar, viewVar);
}
}
VarBinding result = new VarBinding(map);
return result;
}
// public static Set getAll(Collection keys, IBiSetMultimap map) {
// Set result
// }
/*
public Set getEquivalences(Var key, boolean reflexiv)
{
Set result = MultimapUtils.transitiveGetBoth(queryVarToViewVars, key);
if(reflexiv) {
result.add(key);
}
return result;
}
public Set getAllEquivalences(Collection keys, boolean reflexiv)
{
Set result = new HashSet();
Set open = new HashSet(keys);
while(!open.isEmpty()) {
Var key = open.iterator().next();
open.remove(key);
Set equivs = getEquivalences(key, reflexiv);
open.removeAll(equivs);
result.addAll(equivs);
}
return result;
}
* /
@Override
public String toString() {
return "" + queryVarToViewVars;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime
* result
+ ((queryVarToViewVars == null) ? 0 : queryVarToViewVars
.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
VarBinding other = (VarBinding) obj;
if (queryVarToViewVars == null) {
if (other.queryVarToViewVars != null)
return false;
} else if (!queryVarToViewVars.equals(other.queryVarToViewVars))
return false;
return true;
}
*/
}