package edu.asu.spring.quadriga.service.network.transform.impl;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
import com.tinkerpop.blueprints.util.io.graphml.GraphMLReader;
/**
* This class reads graphml files that describe patterns and mappings.
* It expects that createGraph() is called for the pattern file and
* createMapping() for the mapping file. It then holds a reference two both
* graphs by referring to the start node of these mappings.
*
* This class expects that there is only one graph with one start node that
* does not have any incoming edges.
*
* @author viraaj navalekar, Julia Damerow
*
*/
public class GraphMapper {
private Node startNode;
private TransformNode startNodeOfMapping;
public Node getStartNode() {
return startNode;
}
public void setStartNode(Node startNode) {
this.startNode = startNode;
}
/**
* This method creates the pattern from an graphml file.
* @param file Absolute path to the pattern file.
*/
public void createGraph(String file) {
Graph graph = getGraphFromFile(file);
Iterable<Vertex> vertices = graph.getVertices();
Iterator<Vertex> verticesIterator = vertices.iterator();
Map<Object, Node> nodeMap = new HashMap<Object, Node>();
Map<Object, Relation> relationMap = new HashMap<Object, Relation>();
createNodeMap(verticesIterator, nodeMap);
createRelationMap(vertices, nodeMap, relationMap);
createNestedReations(vertices, nodeMap, relationMap);
}
/**
* Creates the template mapping graph.
*
* @param templateFilePath the template graphml file path
* @param nodeInfo the node generator info
*/
public void createTemplateMappingGraph(String templateFilePath) {
// TODO Auto-generated method stub
Graph graph = getGraphFromFile(templateFilePath);
Iterable<Vertex> vertices = graph.getVertices();
Iterator<Vertex> verticesIterator = vertices.iterator();
Map<Object, Node> nodeMap = new HashMap<Object, Node>();
Map<Object, Relation> relationMap = new HashMap<Object, Relation>();
createNodeMap(verticesIterator, nodeMap);
createRelationMap(vertices, nodeMap, relationMap);
createNestedReations(vertices, nodeMap, relationMap);
}
/**
* Creates the node map.
*
* @param verticesIterator the vertices iterator
* @param nodeMap the node map
*/
private void createNodeMap(Iterator<Vertex> verticesIterator,
Map<Object, Node> nodeMap) {
while (verticesIterator.hasNext()) {
Vertex vertex = verticesIterator.next();
Object id = vertex.getId();
if (nodeMap.get(id) != null)
continue;
Node newNode = new Node();
String concept = (String) vertex.getProperty("Concept");
String nodeId = (String) vertex.getProperty("NodeId");
String type = (String) vertex.getProperty("Type");
newNode.setConcept(concept);
newNode.setId(nodeId);
newNode.setType(type);
nodeMap.put(id, newNode);
}
}
/**
* Gets the graph from the graphml file.
*
* @param file the graphml file path
* @return the graph from file
*/
private Graph getGraphFromFile(String file) {
Graph graph = new TinkerGraph();
GraphMLReader reader = new GraphMLReader(graph);
InputStream is = null;
try {
is = new BufferedInputStream(new FileInputStream(file));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
reader.inputGraph(is);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return graph;
}
/**
* Creates the nested reations.
*
* @param vertices the vertices
* @param nodeMap the node map
* @param relationMap the relation map
* @param nodeGenerator the node generator info. Will create relation nodes if not null.
*/
private void createNestedReations(Iterable<Vertex> vertices,
Map<Object, Node> nodeMap, Map<Object, Relation> relationMap) {
Iterator<Vertex> verticesIterator;
verticesIterator = vertices.iterator();
while (verticesIterator.hasNext()) {
Vertex vertex = verticesIterator.next();
Node node = nodeMap.get(vertex.getId());
Iterable<Edge> outEdges = vertex.getEdges(Direction.OUT, new String[0]);
Iterator<Edge> outEdgeIt = outEdges.iterator();
Node potSubject = null;
Object subjVertId = null;
Node potObject = null;
Object objVertId = null;
// get outgoing edges (= 2)
while (outEdgeIt.hasNext()) {
Edge outEdge = outEdgeIt.next();
Vertex outVertex = outEdge.getVertex(Direction.IN);
Node goingIn = nodeMap.get(outVertex.getId());
String nodeType = (String) outEdge.getProperty("relationship");
if (nodeType!=null && nodeType.equals("subject")) {
potSubject = goingIn;
subjVertId = outVertex.getId();
}
else if (nodeType!=null && nodeType.equals("object")) {
potObject = goingIn;
objVertId = outVertex.getId();
}
}
// if relType is set and there are potSubj and potObj
// node is nested relationship
if (potObject != null && potSubject != null) {
Relation rel = relationMap.get(vertex.getId());
Node subject = relationMap.get(subjVertId);
if (subject == null)
subject = potSubject;
Node object = relationMap.get(objVertId);
if (object == null)
object = potObject;
rel.setPredicate(node);
rel.setSubject(subject);
rel.setObject(object);
}
}
}
/**
* Creates the relation map.
*
* @param vertices the vertices
* @param nodeMap the node map
* @param relationMap the relation map
* @param startNode the start node
* @return the relation
*/
private void createRelationMap(Iterable<Vertex> vertices,
Map<Object, Node> nodeMap, Map<Object, Relation> relationMap) {
Iterator<Vertex> verticesIterator = null;
verticesIterator = vertices.iterator();
while (verticesIterator.hasNext()) {
Vertex vertex = verticesIterator.next();
Iterable<Edge> edges = vertex.getEdges(Direction.IN, new String[0]);
Iterator<Edge> edgesIterator = edges.iterator();
Iterable<Edge> outEdges = vertex.getEdges(Direction.OUT, new String[0]);
Iterator<Edge> outEdgeIt = outEdges.iterator();
String relType = null;
// get incoming edges (max 1)
while (edgesIterator.hasNext()) {
Edge edge = edgesIterator.next();
relType = (String) edge.getProperty("relationship");
}
Node potSubject = null;
Node potObject = null;
// get outgoing edges (max 2)
while (outEdgeIt.hasNext()) {
Edge outEdge = outEdgeIt.next();
Vertex outVertex = outEdge.getVertex(Direction.IN);
Node goingIn = nodeMap.get(outVertex.getId());
String nodeType = (String) outEdge.getProperty("relationship");
if (nodeType!=null && nodeType.equals("subject"))
potSubject = goingIn;
else if (nodeType!=null && nodeType.equals("object"))
potObject = goingIn;
}
if (potObject != null && potSubject != null) {
Relation rel = relationMap.get(vertex.getId());
if (rel == null) {
rel = new Relation();
rel.setId(nodeMap.get(vertex.getId()).getId());
relationMap.put(vertex.getId(), rel);
}
}
// if relType is null, no edge is going in and node can only be predicate
// (or single node)
if (relType == null) {
Relation rel = relationMap.get(vertex.getId());
if (rel == null) {
rel = new Relation();
rel.setId(nodeMap.get(vertex.getId()).getId());
relationMap.put(vertex.getId(), rel);
}
this.setStartNode(rel);
}
}
}
/**
* This method creates the mapping file.
* @param file Absolute path to the mapping file.
*/
public void createMapping(String file) {
Graph graph = getGraphFromFile(file);
Iterable<Vertex> vertices = graph.getVertices();
Iterator<Vertex> verticesIterator = vertices.iterator();
Map<Object, TransformNode> nodeMap = new HashMap<Object, TransformNode>();
while (verticesIterator.hasNext()) {
Vertex vertex = verticesIterator.next();
Object id = vertex.getId();
if (nodeMap.get(id) != null)
continue;
TransformNode newNode = new TransformNode();
String concept = (String) vertex.getProperty("Concept");
String nodeId = (String) vertex.getProperty("CorrespondingNodeId");
String type = (String) vertex.getProperty("Type");
newNode.setConcept(concept);
newNode.setCorrespondingId(nodeId);
newNode.setType(type);
nodeMap.put(id, newNode);
}
verticesIterator = vertices.iterator();
while (verticesIterator.hasNext()) {
Vertex vertex = verticesIterator.next();
TransformNode node = nodeMap.get(vertex.getId());
Iterable<Edge> inEdges = vertex.getEdges(Direction.IN, new String[0]);
Iterator<Edge> inEdgeIt = inEdges.iterator();
int nrOfincomingEdges = 0;
while (inEdgeIt.hasNext()) {
inEdgeIt.next();
nrOfincomingEdges++;
}
if (nrOfincomingEdges == 0) {
setStartNodeOfMapping(node);
}
Iterable<Edge> outEdges = vertex.getEdges(Direction.OUT, new String[0]);
Iterator<Edge> outEdgeIt = outEdges.iterator();
while (outEdgeIt.hasNext()) {
Edge outEdge = outEdgeIt.next();
Vertex outVertex = outEdge.getVertex(Direction.IN);
TransformNode goingIn = nodeMap.get(outVertex.getId());
String id = (String) outEdge.getProperty("CorrespondingNodeId");
TransformLink link = new TransformLink();
link.setCorrespondingId(id);
String type = (String) outEdge.getProperty("Type");
link.setType(type);
String concept = (String) outEdge.getProperty("Concept");
link.setConcept(concept);
String startTime = (String) outEdge.getProperty("NodeIdStartTime");
link.setStartTime(startTime);
String endTime = (String) outEdge.getProperty("NodeIdEndTime");
link.setEndTime(endTime);
String occurTime = (String) outEdge.getProperty("NodeIdOccurTime");
link.setOccurTime(occurTime);
String place = (String) outEdge.getProperty("NodeIdPlace");
link.setPlace(place);
String statement = (String) outEdge.getProperty("RepresentedStatement");
link.setRepresentedStatement(statement);
link.setObject(goingIn);
if (node.getLinks() == null)
node.setLinks( new ArrayList<TransformLink>());
node.getLinks().add(link);
}
}
}
public TransformNode getStartNodeOfMapping() {
return startNodeOfMapping;
}
public void setStartNodeOfMapping(TransformNode startNodeOfMapping) {
this.startNodeOfMapping = startNodeOfMapping;
}
}