package eu.play_project.play_platformservices_querydispatcher.bdpl.visitor.realtime; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import com.hp.hpl.jena.graph.Node; import com.hp.hpl.jena.graph.Node_Blank; import com.hp.hpl.jena.graph.Node_Literal; import com.hp.hpl.jena.graph.Node_URI; import com.hp.hpl.jena.graph.Node_Variable; import com.hp.hpl.jena.graph.impl.LiteralLabel; import com.hp.hpl.jena.rdf.model.AnonId; import com.hp.hpl.jena.sparql.core.TriplePath; import com.hp.hpl.jena.sparql.syntax.Element; import com.hp.hpl.jena.sparql.syntax.ElementEventGraph; import com.hp.hpl.jena.sparql.syntax.ElementGroup; import com.hp.hpl.jena.sparql.syntax.ElementPathBlock; /** * Generate code for variable representative. * For each variable one query is needed which provides all possible values of this variable. * @author sobermeier * */ public class RdfQueryRepresentativeQueryVisitor extends GenericVisitor { private StringBuffer code; private Map<String, String> varRepresentative; // For each variable in the // query exists a // representative query. // This query is used to get // all possible values. E.g. // P : rdf(:e, P, O, 1234). public RdfQueryRepresentativeQueryVisitor() { code = new StringBuffer(); } // Start @Override public void visit(ElementEventGraph el) { code =new StringBuffer(); varRepresentative = new HashMap<String, String>(); // Visit triples el.getElement().visit(this); } @Override public void visit(ElementGroup elg) { // Visit all group elements for (Element el : elg.getElements()) { el.visit(this); } } public Map<String, String> getRdfQueryRepresentativeQuery() { return varRepresentative; } @Override public Object visitBlank(Node_Blank it, AnonId id) { throw new RuntimeException("Node_Blank is not allowed."); } @Override public Object visitLiteral(Node_Literal it, LiteralLabel lit) { code.append("'" + lit.getLexicalForm() + "'"); return lit; } @Override public Object visitURI(Node_URI it, String uri) { code.append("'" + uri + "'"); return uri; } @Override public Object visitVariable(Node_Variable it, String name) { StringBuffer resultNode = new StringBuffer(); //FIXME wats wrong? // It is part of a blank node. if (name.startsWith("?")) { // Transform number to uppercase char. for (int i = 1; i < name.length(); ++i) { char c = name.charAt(i); resultNode.append("V" + (char) (c + 17)); } code.append(resultNode.toString()); return resultNode.toString(); } else { // It is a ordinary vraible. code.append("V" + name); return "V" + name; } } @Override public void visit(ElementPathBlock el) { // Generate representative queries for variables. Result will be stored // in "varRepresentative" variable. for (TriplePath tp : el.getPattern().getList()) { generadeCodeForNewVariable(tp.getSubject(), tp); generadeCodeForNewVariable(tp.getPredicate(), tp); generadeCodeForNewVariable(tp.getObject(), tp); } } // Check if a representative exists for given Variable and generate code. private void generadeCodeForNewVariable(Node node, TriplePath triple) { if (node.isVariable()) { String name = ((Node_Variable) node).getName(); if (!varRepresentative.containsKey(name)) { code.append("rdf("); // Use existing visitors. triple.getSubject().visitWith(this); code.append(","); triple.getPredicate().visitWith(this); code.append(","); triple.getObject().visitWith(this); code.append(")"); varRepresentative.put(name, code.toString()); code = new StringBuffer(); } } } /** * Return all variables used in this query. */ public List<String> getVariables(){ List<String> vars = new LinkedList<String>(); for (String var : varRepresentative.keySet()) { vars.add(var); } return vars; } }