package com.neo4j.jena.graph; import java.util.HashMap; import java.util.Map; import org.neo4j.graphdb.DynamicLabel; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.ResourceIterator; import org.neo4j.graphdb.index.UniqueFactory; import com.hp.hpl.jena.graph.Graph; /** * Jena graph wrapper for Neo4J graph database service. * * @author Khalid Latif, Mahek Hanfi (2014-02-14) */ public class UniqueNodeFactory extends UniqueFactory.UniqueNodeFactory { /** Holds nodes in memory during bulk loading */ private Map<com.hp.hpl.jena.graph.Node, Node> bulkNodes; /** Reference to Jena Graph */ private final Graph graph; /** * Initialize the factory. * * @param A GraphDatabaseService instance to store newly create node. * @param A Jena graph to process new node creation. */ public UniqueNodeFactory(GraphDatabaseService graphdb, Graph graph) { super(graphdb, "Resources"); this.graph = graph; } /** * Initializes the node. */ @Override protected void initialize(Node created, Map<String, Object> properties) { created.addLabel(DynamicLabel.label(NeoGraph.LABEL_URI)); created.setProperty(NeoGraph.PROPERTY_URI, properties.get(NeoGraph.PROPERTY_URI)); } /** * Get an existing node or return null. */ public Node get(com.hp.hpl.jena.graph.Node node) { Node neoNode = null; //StopWatch watch = new StopWatch(); if(bulkNodes!=null) { neoNode = bulkNodes.get(node); if(neoNode!=null) return neoNode; } if(node.isLiteral()) { Label label = DynamicLabel.label(NeoGraph.LABEL_LITERAL); try ( ResourceIterator<org.neo4j.graphdb.Node> nodes = super.graphDatabase().findNodesByLabelAndProperty( label, NeoGraph.PROPERTY_VALUE, node.getLiteralValue()).iterator() ) { if ( nodes.hasNext() ) { neoNode = nodes.next(); } } } else if(node.isBlank()) { Label label = DynamicLabel.label(NeoGraph.LABEL_BNODE); //FIXME Blank node id might not be unique across multiple loads of same RDF data try ( ResourceIterator<org.neo4j.graphdb.Node> nodes = super.graphDatabase().findNodesByLabelAndProperty( label, NeoGraph.PROPERTY_VALUE, node.getBlankNodeId().toString()).iterator() ) { if ( nodes.hasNext() ) { neoNode = nodes.next(); } } } else { Label label = DynamicLabel.label(NeoGraph.LABEL_URI); String prefixed = graph.getPrefixMapping().shortForm(node.getURI()); try ( ResourceIterator<org.neo4j.graphdb.Node> nodes = super.graphDatabase().findNodesByLabelAndProperty( label, NeoGraph.PROPERTY_URI, prefixed).iterator() ) { if ( nodes.hasNext() ) { neoNode = nodes.next(); } } } //System.out.println("Get " + node + " took: " + watch.stop()); if(neoNode!=null && bulkNodes!=null) bulkNodes.put(node, neoNode); return neoNode; } /** * Get or create a Neo4J node for a given Jena node object. * * @param Jena node (either resource or a literal) * @return Neo4J node */ public Node getOrCreate(com.hp.hpl.jena.graph.Node node) { Node created; if(bulkNodes!=null) { Node neoNode = bulkNodes.get(node); if(neoNode!=null){ //System.out.println(node + " already exist"); return neoNode; } } else System.out.println("Bulk node is null"); //StopWatch watch = new StopWatch(); // Literals get special treatment (duplicates allowed) if(node.isLiteral()) { Label label = DynamicLabel.label(NeoGraph.LABEL_LITERAL); created = super.graphDatabase().createNode(label); created.setProperty(NeoGraph.PROPERTY_VALUE, node.getLiteralValue().toString()); // Add data-type tag if(node.getLiteralDatatype()!=null) created.setProperty(NeoGraph.PROPERTY_DATATYPE, node.getLiteralDatatype().toString()); // Add language tag if(node.getLiteralLanguage()!=null) created.setProperty(NeoGraph.PROPERTY_LANGUAGE, node.getLiteralLanguage()); return created; } else if(node.isBlank()) { Label label = DynamicLabel.label(NeoGraph.LABEL_BNODE); created = super.graphDatabase().createNode(label); created.setProperty(NeoGraph.PROPERTY_URI, node.getBlankNodeId().toString()); } else { String prefixed = graph.getPrefixMapping().shortForm(node.getURI()); // Back to normal procedure for resources created = getOrCreate(NeoGraph.PROPERTY_URI, prefixed); } //System.out.println("Get or create " + node + " took:" + watch.stop()); if(bulkNodes!=null) bulkNodes.put(node, created); return created; } public void startBulkLoad() { bulkNodes = new HashMap<com.hp.hpl.jena.graph.Node, Node>(); } public void stopBulkLoad() { bulkNodes = null; } }