package outputModules.neo4j.importers; import java.util.Map; import neo4j.batchInserter.GraphNodeStore; import neo4j.batchInserter.Neo4JBatchInserter; import org.neo4j.graphdb.DynamicRelationshipType; import org.neo4j.graphdb.RelationshipType; import cfg.CFG; import cfg.CFGEdge; import cfg.nodes.ASTNodeContainer; import cfg.nodes.CFGNode; import databaseNodes.EdgeTypes; import databaseNodes.FunctionDatabaseNode; import databaseNodes.NodeKeys; public class CFGImporter { GraphNodeStore nodeStore; private FunctionDatabaseNode currentFunction; public CFGImporter(GraphNodeStore aNodeStore) { nodeStore = aNodeStore; } public void setCurrentFunction(FunctionDatabaseNode func) { currentFunction = func; } public void addCFGToDatabase(CFG cfg) { if (cfg == null) return; createEmptyCFGNodes(cfg); addCFGEdges(cfg); } private void createEmptyCFGNodes(CFG cfg) { // This deserves some explanation: // Our CFG creation code currently inserts empty-blocks // in some places, e.g., nodes that join prior control-flows. // These nodes do not have to exist in theory but as long // as we have them in our CFG, we need to create corresponding // database nodes when importing the CFG. All other CFG nodes // are nodes of the AST and hence are already in the database. for (CFGNode statement : cfg.getVertices()) { Map<String, Object> properties; if (statement instanceof ASTNodeContainer) { // nothing to do for nodes that have already // been imported by the ASTImporter. continue; } else { properties = statement.getProperties(); } properties.put(NodeKeys.FUNCTION_ID, nodeStore.getIdForObject(currentFunction)); nodeStore.addNeo4jNode(statement, properties); nodeStore.indexNode(statement, properties); } } private void addCFGEdges(CFG cfg) { Object src; Object dst; for (CFGEdge edge : cfg.getEdges()) { src = edge.getSource(); dst = edge.getDestination(); if (src instanceof ASTNodeContainer) src = ((ASTNodeContainer) src).getASTNode(); if (dst instanceof ASTNodeContainer) dst = ((ASTNodeContainer) dst).getASTNode(); addFlowToLink(src, dst, edge.getProperties()); } } private void addFlowToLink(Object srcBlock, Object dstBlock, Map<String, Object> properties) { long srcId = nodeStore.getIdForObject(srcBlock); long dstId = nodeStore.getIdForObject(dstBlock); RelationshipType rel = DynamicRelationshipType .withName(EdgeTypes.FLOWS_TO); // Map<String, Object> properties = null; Neo4JBatchInserter.addRelationship(srcId, dstId, rel, properties); } }