package edu.uci.ics.jung.graph;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import edu.uci.ics.jung.graph.event.GraphEvent;
import edu.uci.ics.jung.graph.event.GraphEventListener;
import edu.uci.ics.jung.graph.util.EdgeType;
/**
* A decorator class for graphs which generates events
*
* @author Joshua O'Madadhain
*/
@SuppressWarnings("serial")
public class ObservableGraph<V,E> extends GraphDecorator<V,E> {
List<GraphEventListener<V,E>> listenerList =
Collections.synchronizedList(new LinkedList<GraphEventListener<V,E>>());
/**
* Creates a new instance based on the provided {@code delegate}.
*/
public ObservableGraph(Graph<V, E> delegate) {
super(delegate);
}
/**
* Adds {@code l} as a listener to this graph.
*/
public void addGraphEventListener(GraphEventListener<V,E> l) {
listenerList.add(l);
}
/**
* Removes {@code l} as a listener to this graph.
*/
public void removeGraphEventListener(GraphEventListener<V,E> l) {
listenerList.remove(l);
}
protected void fireGraphEvent(GraphEvent<V,E> evt) {
for(GraphEventListener<V,E> listener : listenerList) {
listener.handleGraphEvent(evt);
}
}
/**
* @see edu.uci.ics.jung.graph.Hypergraph#addEdge(java.lang.Object, java.util.Collection)
*/
@Override
public boolean addEdge(E edge, Collection<? extends V> vertices) {
boolean state = super.addEdge(edge, vertices);
if(state) {
GraphEvent<V,E> evt = new GraphEvent.Edge<V,E>(delegate, GraphEvent.Type.EDGE_ADDED, edge);
fireGraphEvent(evt);
}
return state;
}
/**
* @see edu.uci.ics.jung.graph.Graph#addEdge(java.lang.Object, java.lang.Object, java.lang.Object, edu.uci.ics.jung.graph.util.EdgeType)
*/
@Override
public boolean addEdge(E e, V v1, V v2, EdgeType edgeType) {
boolean state = super.addEdge(e, v1, v2, edgeType);
if(state) {
GraphEvent<V,E> evt = new GraphEvent.Edge<V,E>(delegate, GraphEvent.Type.EDGE_ADDED, e);
fireGraphEvent(evt);
}
return state;
}
/**
* @see edu.uci.ics.jung.graph.Graph#addEdge(java.lang.Object, java.lang.Object, java.lang.Object)
*/
@Override
public boolean addEdge(E e, V v1, V v2) {
boolean state = super.addEdge(e, v1, v2);
if(state) {
GraphEvent<V,E> evt = new GraphEvent.Edge<V,E>(delegate, GraphEvent.Type.EDGE_ADDED, e);
fireGraphEvent(evt);
}
return state;
}
/**
* @see edu.uci.ics.jung.graph.Hypergraph#addVertex(java.lang.Object)
*/
@Override
public boolean addVertex(V vertex) {
boolean state = super.addVertex(vertex);
if(state) {
GraphEvent<V,E> evt = new GraphEvent.Vertex<V,E>(delegate, GraphEvent.Type.VERTEX_ADDED, vertex);
fireGraphEvent(evt);
}
return state;
}
/**
* @see edu.uci.ics.jung.graph.Hypergraph#removeEdge(java.lang.Object)
*/
@Override
public boolean removeEdge(E edge) {
boolean state = delegate.removeEdge(edge);
if(state) {
GraphEvent<V,E> evt = new GraphEvent.Edge<V,E>(delegate, GraphEvent.Type.EDGE_REMOVED, edge);
fireGraphEvent(evt);
}
return state;
}
/**
* @see edu.uci.ics.jung.graph.Hypergraph#removeVertex(java.lang.Object)
*/
@Override
public boolean removeVertex(V vertex) {
// remove all incident edges first, so that the appropriate events will
// be fired (otherwise they'll be removed inside {@code delegate.removeVertex}
// and the events will not be fired)
Collection<E> incident_edges = new ArrayList<E>(delegate.getIncidentEdges(vertex));
for (E e : incident_edges)
this.removeEdge(e);
boolean state = delegate.removeVertex(vertex);
if(state) {
GraphEvent<V,E> evt = new GraphEvent.Vertex<V,E>(delegate, GraphEvent.Type.VERTEX_REMOVED, vertex);
fireGraphEvent(evt);
}
return state;
}
}