package nl.tudelft.lifetiles.graph.model.jgrapht;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import nl.tudelft.lifetiles.core.util.Logging;
import nl.tudelft.lifetiles.graph.model.Edge;
import nl.tudelft.lifetiles.graph.model.Graph;
import nl.tudelft.lifetiles.graph.model.GraphFactory;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.DirectedSubgraph;
/**
* @author Rutger van den Berg
*
* @param <V>
* The type of Vertex to use.
*/
public class JGraphTGraphFactory<V extends Comparable<V>> implements
GraphFactory<V> {
/**
* The edgefactory associated with this graph factory.
*/
private final JGraphTEdgeFactory<V> edgeFact;
/**
* Create a new graph factory.
*/
public JGraphTGraphFactory() {
edgeFact = new JGraphTEdgeFactory<>();
}
/**
* @return a new empty Graph.
*/
@Override
public Graph<V> getGraph() {
return new JGraphTGraphAdapter<V>(edgeFact);
}
/**
* @param base
* the graph to create a subgraph from.
* @param vertexSubSet
* the vertices to include in the subgraph
* @return a subgraph based on the base graph
* @throws NotAJGraphTAdapterException
* if the base graph is not a JGraphT library
*/
@Override
public Graph<V> getSubGraph(final Graph<V> base, final Set<V> vertexSubSet)
throws NotAJGraphTAdapterException {
if (base instanceof JGraphTGraphAdapter) {
JGraphTGraphAdapter<V> baseGraph = (JGraphTGraphAdapter<V>) base;
return new JGraphTGraphAdapter<V>(
new DirectedSubgraph<V, DefaultEdge>(
baseGraph.getInternalGraph(), vertexSubSet, null),
edgeFact, baseGraph.getVertexIdentifiers());
} else {
throw new NotAJGraphTAdapterException();
}
}
/**
* {@inheritDoc}
*/
@Override
public Graph<V> deepcopy(final Graph<V> graph) {
Graph<V> copygraph = new JGraphTGraphAdapter<V>(edgeFact);
Map<Object, Object> convertVertices = new HashMap<Object, Object>();
for (V vertex : graph.getAllVertices()) {
try {
Constructor<?> method = vertex.getClass().getConstructor(
vertex.getClass());
Object copy = method.newInstance(vertex);
// can't not be a V, so no need to explicitly check.
@SuppressWarnings("unchecked")
V newVertex = (V) copy;
copygraph.addVertex(newVertex);
convertVertices.put(vertex, copy);
} catch (NoSuchMethodException | SecurityException
| IllegalAccessException | IllegalArgumentException
| InvocationTargetException | InstantiationException exception) {
Logging.exception(exception);
}
}
for (Edge<V> edge : graph.getAllEdges()) {
Object from = convertVertices.get(graph.getSource(edge));
Object destination = convertVertices
.get(graph.getDestination(edge));
@SuppressWarnings("unchecked")
V fromVertex = (V) from;
@SuppressWarnings("unchecked")
V destinationVertex = (V) destination;
copygraph.addEdge(fromVertex, destinationVertex);
}
return copygraph;
}
/**
* {@inheritDoc}
*/
@Override
public Graph<V> copy(final Graph<V> graph) {
Graph<V> copyGraph = new JGraphTGraphAdapter<V>(edgeFact);
for (V vertex : graph.getAllVertices()) {
copyGraph.addVertex(vertex);
}
for (Edge<V> edge : graph.getAllEdges()) {
copyGraph
.addEdge(graph.getSource(edge), graph.getDestination(edge));
}
return copyGraph;
}
}