package org.aksw.jena_sparql_api.jgrapht;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.apache.jena.graph.Graph;
import org.apache.jena.graph.GraphUtil;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.Triple;
import org.jgrapht.DirectedGraph;
import org.jgrapht.EdgeFactory;
/**
* Wrapper for exposing a Jena graph as a JGraphT directed pseudo graph.
*
*
*
* @author raven
*
*/
public class PseudoGraphJena
implements DirectedGraph<Node, Triple>
{
protected org.apache.jena.graph.Graph graph;
protected Node predicate; // May be Node.ANY
protected transient EdgeFactory<Node, Triple> edgeFactory;
public PseudoGraphJena(Graph graph, Node predicate) {
super();
this.graph = graph;
this.predicate = predicate;
edgeFactory = new EdgeFactoryJena(predicate);
}
@Override
public Set<Triple> getAllEdges(Node sourceVertex, Node targetVertex) {
return graph.find(sourceVertex, predicate, targetVertex).toSet();
}
@Override
public Triple getEdge(Node sourceVertex, Node targetVertex) {
Set<Triple> edges = getAllEdges(sourceVertex, targetVertex);
// TODO Maybe throw an exception or return null if there are multiple edges
Triple result = edges.iterator().next();
return result;
}
@Override
public EdgeFactory<Node, Triple> getEdgeFactory() {
return edgeFactory;
}
@Override
public Triple addEdge(Node sourceVertex, Node targetVertex) {
Triple result;
if(Node.ANY.equals(predicate)) {
throw new UnsupportedOperationException("Cannot insert edge if the predicate is Node.ANY");
} else {
result = new Triple(sourceVertex, predicate, targetVertex);
graph.add(result);
}
return result;
}
@Override
public boolean addEdge(Node sourceVertex, Node targetVertex, Triple e) {
boolean result = !graph.contains(e);
if(result) {
graph.add(e);
}
return true;
}
@Override
public boolean addVertex(Node v) {
// Silently ignore calls to this
return false;
}
@Override
public boolean containsEdge(Node sourceVertex, Node targetVertex) {
// TODO Not sure if contains works with Node.ANY - may have to use !.find().toSet().isEmpyt()
boolean result = graph.contains(sourceVertex, predicate, targetVertex);
return result;
}
@Override
public boolean containsEdge(Triple e) {
boolean result = graph.contains(e);
return result;
}
@Override
public boolean containsVertex(Node v) {
boolean result =
graph.contains(v, Node.ANY, Node.ANY) ||
graph.contains(Node.ANY, Node.ANY, v);
return result;
}
@Override
public Set<Triple> edgeSet() {
Set<Triple> result = graph.find(Node.ANY, Node.ANY, Node.ANY).toSet();
return result;
}
@Override
public Set<Triple> edgesOf(Node vertex) {
Set<Triple> result = new HashSet<>();
graph.find(vertex, predicate, Node.ANY).forEachRemaining(result::add);
graph.find(Node.ANY, predicate, vertex).forEachRemaining(result::add);
return result;
}
@Override
public boolean removeAllEdges(Collection<? extends Triple> edges) {
Iterator<Triple> it = edges.stream().map(e -> (Triple)e).iterator();
GraphUtil.delete(graph, it);
return true;
}
@Override
public Set<Triple> removeAllEdges(Node sourceVertex, Node targetVertex) {
graph.remove(sourceVertex, Node.ANY, targetVertex);
return null;
}
@Override
public boolean removeAllVertices(Collection<? extends Node> vertices) {
// TODO Auto-generated method stub
return false;
}
@Override
public Triple removeEdge(Node sourceVertex, Node targetVertex) {
Triple result = new Triple(sourceVertex, predicate, targetVertex);
removeEdge(result);
// graph.remove(result.get, p, o);
// return true;
return null;
}
@Override
public boolean removeEdge(Triple e) {
graph.remove(e.getSubject(), e.getPredicate(), e.getObject());
return true;
}
@Override
public boolean removeVertex(Node v) {
graph.remove(v, predicate, Node.ANY);
graph.remove(Node.ANY, predicate, v);
return true;
}
@Override
public Set<Node> vertexSet() {
Set<Node> result = new HashSet<>();
graph.find(Node.ANY, predicate, Node.ANY).forEachRemaining(triple -> {
result.add(triple.getSubject());
result.add(triple.getObject());
});
return result;
}
@Override
public Node getEdgeSource(Triple e) {
return e.getSubject();
}
@Override
public Node getEdgeTarget(Triple e) {
return e.getObject();
}
@Override
public double getEdgeWeight(Triple e) {
return 1;
}
@Override
public int inDegreeOf(Node vertex) {
int result = incomingEdgesOf(vertex).size();
return result;
}
@Override
public Set<Triple> incomingEdgesOf(Node vertex) {
Set<Triple> result = graph.find(Node.ANY, predicate, vertex).toSet();
return result;
}
@Override
public int outDegreeOf(Node vertex) {
int result = outgoingEdgesOf(vertex).size();
return result;
}
@Override
public Set<Triple> outgoingEdgesOf(Node vertex) {
Set<Triple> result = graph.find(vertex, predicate, Node.ANY).toSet();
return result;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((graph == null) ? 0 : graph.hashCode());
result = prime * result + ((predicate == null) ? 0 : predicate.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PseudoGraphJena other = (PseudoGraphJena) obj;
if (graph == null) {
if (other.graph != null)
return false;
} else if (!graph.equals(other.graph))
return false;
if (predicate == null) {
if (other.predicate != null)
return false;
} else if (!predicate.equals(other.predicate))
return false;
return true;
}
@Override
public String toString() {
return "PseudoGraphJena [graph=" + graph + ", predicate=" + predicate + "]";
}
}