Skip to content

Commit

Permalink
Add conversion for opProject and opBGP. Tests working
Browse files Browse the repository at this point in the history
  • Loading branch information
LakshyAAAgrawal committed Apr 14, 2021
1 parent 3231efa commit 485428d
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 13 deletions.
25 changes: 20 additions & 5 deletions src/main/java/com/KRacR/s2c/CreateCypher.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,36 @@
// TODO: Check if there exists a unique id for every node in Neo4j

class CreateCypher implements RDFVisitor {
String operation;
String label;
public CreateCypher() {
this.label = "";
this.operation = "";
}

public CreateCypher(String operation) {
this.label = "";
this.operation = operation + " ";
}

@Override
public String visitBlank(Resource r, AnonId id) {
return String.format(
"MERGE (%s {uri:\"\", id:\"%s\"})",
"%s(%s {uri:\"\", id:\"%s\", stringrep:\"%s\"})",
this.operation,
this.label,
id.getBlankNodeId().toString(),
id.getBlankNodeId().toString()
);
}

@Override
public String visitURI(Resource r, String uri) {
return String.format(
"MERGE (%s {uri:\"%s\"})",
"%s(%s {uri:\"%s\", stringrep:\"%s\"})",
this.operation,
this.label,
uri,
uri
);
}
Expand All @@ -38,17 +49,21 @@ public String visitLiteral(Literal l) {
(l.getDatatype() instanceof org.apache.jena.datatypes.xsd.impl.RDFLangString)?
(
String.format(
"MERGE (%s {uri:\"\", typeiri:\"%s\", lexform:\"%s\", langtag:\"%s\"})",
"%s(%s {uri:\"\", typeiri:\"%s\", lexform:\"%s\", langtag:\"%s\", stringrep:\"%s\"})",
this.operation,
this.label,
l.getDatatypeURI(),
l.getLexicalForm(),
l.getLanguage()
l.getLanguage(),
l.getLexicalForm() + "@" + l.getLanguage()
)
):(
String.format(
"MERGE (%s {uri:\"\", typeiri:\"%s\", lexform:\"%s\"})",
"%s(%s {uri:\"\", typeiri:\"%s\", lexform:\"%s\", stringrep:\"%s\"})",
this.operation,
this.label,
l.getDatatypeURI(),
l.getLexicalForm(),
l.getLexicalForm()
)
);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/KRacR/s2c/RDFtoCypher.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ public static List<String> RDFtoCypherDirect(Model model) {
while (it.hasNext()) {
Statement stmt = it.next();
String cypher_q = "";
CreateCypher visitor = new CreateCypher();
CreateCypher visitor = new CreateCypher("MERGE");
visitor.set_label("s");
cypher_q = cypher_q.concat((String) stmt.getSubject().visitWith(visitor));
cypher_q = cypher_q.concat("\n");
visitor.set_label("o");
cypher_q = cypher_q.concat((String) stmt.getObject().visitWith(visitor));
cypher_q = cypher_q.concat("\n");
cypher_q = cypher_q.concat(
String.format("MERGE (s)-[:Edge {uri:\"%s\"}]->(o);", stmt.getPredicate().getURI())
String.format("MERGE (s)-[:Edge {uri:\"%s\", stringrep:\"%s\"}]->(o);", stmt.getPredicate().getURI(), stmt.getPredicate().getURI())
);
cypher_qs.add(cypher_q);
}
Expand Down
129 changes: 123 additions & 6 deletions src/main/java/com/KRacR/s2c/SparqlAlgebraToCypherVisitor.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
package com.KRacR.s2c;

import java.util.HashMap;
import java.util.Map;

import org.apache.jena.graph.BlankNodeId;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.NodeVisitor;
import org.apache.jena.graph.Node_ANY;
import org.apache.jena.graph.Node_Blank;
import org.apache.jena.graph.Node_Literal;
import org.apache.jena.graph.Node_URI;
import org.apache.jena.graph.Node_Variable;
import org.apache.jena.graph.Triple;
import org.apache.jena.graph.impl.LiteralLabel;
import org.apache.jena.sparql.algebra.OpVisitor;
import org.apache.jena.sparql.algebra.Transform;
import org.apache.jena.sparql.algebra.op.OpAssign;
import org.apache.jena.sparql.algebra.op.OpBGP;
import org.apache.jena.sparql.algebra.op.OpConditional;
Expand Down Expand Up @@ -35,18 +49,114 @@
import org.apache.jena.sparql.algebra.op.OpTopN;
import org.apache.jena.sparql.algebra.op.OpTriple;
import org.apache.jena.sparql.algebra.op.OpUnion;
import org.apache.jena.sparql.core.Var;
import org.apache.lucene.util.packed.PackedLongValues.Iterator;

public class SparqlAlgebraToCypherVisitor implements OpVisitor {
String cypher;
private String cypher;
private Map<Var, String> Sparql_to_cypher_variable_map;
private Map<String, Object> Cypher_to_sparql_variable_map;
private int blank_node_num = 0;
private Map<Node_Blank, Var> Sparql_blank_node_to_var_map;

public SparqlAlgebraToCypherVisitor() {
cypher = new String();
Sparql_blank_node_to_var_map = new HashMap<Node_Blank, Var>();
Sparql_to_cypher_variable_map = new HashMap<Var, String>();
Cypher_to_sparql_variable_map = new HashMap<String, Object>();
}

@Override
public void visit(OpBGP opBGP) {
// TODO Auto-generated method stub
System.out.println("In opBGP\n" + opBGP.toString());
}

@Override
public void visit(OpQuadPattern quadPattern) {
java.util.Iterator<Triple> it = opBGP.getPattern().iterator();
while(it.hasNext()) {
Triple t = it.next();
CreateCypher visitor = new CreateCypher();
NodeVisitor cypherNodeMatcher = new NodeVisitor() {

@Override
public String visitAny(Node_ANY it) {
// TODO Auto-generated method stub
return null;
}

@Override
public String visitBlank(Node_Blank it, BlankNodeId id) {
// TODO Auto-generated method stub
return create_or_get_variable(it);
}

@Override
public String visitLiteral(Node_Literal it, LiteralLabel lit) {
// TODO Auto-generated method stub
return
(lit.language().equals(""))?
(
String.format(
"{uri:\"\", typeiri:\"%s\", lexform:\"%s\"}",
lit.getDatatypeURI(),
lit.getLexicalForm()
)
):(
String.format(
"{uri:\"\", typeiri:\"%s\", lexform:\"%s\", langtag:\"%s\"}",
lit.getDatatypeURI(),
lit.getLexicalForm(),
lit.language()
)
);
}

@Override
public String visitURI(Node_URI it, String uri) {
// TODO Auto-generated method stub
return String.format("{uri:\"%s\"}", uri);
}

@Override
public String visitVariable(Node_Variable it, String name) {
// TODO Auto-generated method stub
return create_or_get_variable(Var.alloc(it));
}

};

cypher = cypher + "MATCH ("
+ t.getMatchSubject().visitWith(cypherNodeMatcher)
+ ")-["
+ t.getMatchPredicate().visitWith(cypherNodeMatcher)
+ "]->("
+ t.getMatchObject().visitWith(cypherNodeMatcher)
+ ")\n";
}
}

protected String create_or_get_variable(Node_Blank it) {
// TODO Auto-generated method stub
String var_name = "blankvar" + (blank_node_num++);
Var var = Var.alloc(var_name + it.getBlankNodeId().toString());
Sparql_blank_node_to_var_map.put(it, var);
String created_var = create_or_get_variable(var);
return created_var;
}

protected String create_or_get_variable(Var allocated_var) {
// TODO Auto-generated method stub
// TODO Account for variable names to ensure that there is no collision, and the created variable is valid in Cypher conventions
// https://neo4j.com/docs/cypher-manual/current/syntax/naming/
// https://www.w3.org/TR/sparql11-query/#rVARNAME
if(Sparql_to_cypher_variable_map.containsKey(allocated_var)) return Sparql_to_cypher_variable_map.get(allocated_var);
else {
Sparql_to_cypher_variable_map.put(allocated_var, allocated_var.getName());
Cypher_to_sparql_variable_map.put(allocated_var.getName(), allocated_var);
return Sparql_to_cypher_variable_map.get(allocated_var);
}
}

@Override
public void visit(OpQuadPattern quadPattern){
// TODO Auto-generated method stub
System.out.println("In quadPattern\n" + quadPattern.toString());
}
Expand Down Expand Up @@ -211,6 +321,13 @@ public void visit(OpOrder opOrder) {
public void visit(OpProject opProject) {
// TODO Auto-generated method stub
System.out.println("In opProject\n" + opProject.toString());
opProject.getSubOp().visit(this);
cypher = cypher.concat("RETURN ");
for(Var var: opProject.getVars()) {
cypher = cypher.concat(Sparql_to_cypher_variable_map.get(var) + ".stringrep AS " + Sparql_to_cypher_variable_map.get(var) + ", ");
}
cypher = cypher.substring(0, cypher.length() - 2);
cypher = cypher.concat("\n");
}

@Override
Expand Down Expand Up @@ -245,7 +362,7 @@ public void visit(OpTopN opTop) {

public String getCypher() {
// TODO Auto-generated method stub
return "match (n)-[e:Edge]->(r {uri:\"http://localhost/persons/Paul_Erdoes\"}) return n.uri as subject, e.uri as predicate";
return cypher; //"match (n)-[e:Edge]->(r {uri:\"http://localhost/persons/Paul_Erdoes\"}) return n.uri as subject, e.uri as predicate";
}

}
7 changes: 7 additions & 0 deletions src/test/java/com/KRacR/s2c/SparqlToCypherTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ public boolean accept(File file) {
}
cypher_result.add(res);
}
}catch(Exception e) {
System.out.println("Running the returned Cypher query FAILED with exception:");
System.out.println(e.getMessage());
}

// Execute the sparql query on the database
Expand All @@ -114,6 +117,10 @@ public boolean accept(File file) {
System.out.println("\nTEST PASSED\n");
}else {
System.out.println("\nTEST FAILED\n");
System.out.println("-------Sparql-------");
System.out.println(sparql_result);
System.out.println("-------Cypher-------");
System.out.println(cypher_result);
}

// TODO: Account for ORDER BY queries
Expand Down

0 comments on commit 485428d

Please sign in to comment.