Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.graphstream.graph.implementations.Graphs Maven / Gradle / Ivy
/*
* This file is part of GraphStream .
*
* GraphStream is a library whose purpose is to handle static or dynamic
* graph, create them from scratch, file or any source and display them.
*
* This program is free software distributed under the terms of two licenses, the
* CeCILL-C license that fits European law, and the GNU Lesser General Public
* License. You can use, modify and/ or redistribute the software under the terms
* of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
* URL or under the terms of the GNU LGPL as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
*/
/**
* @since 2011-08-23
*
* @author Guilhelm Savin
* @author Stefan Balev
* @author Alex Bowen
* @author Hicham Brahimi
* @author Yoann Pigné
*/
package org.graphstream.graph.implementations;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Spliterator;
import java.util.Vector;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.graphstream.graph.Edge;
import org.graphstream.graph.EdgeFactory;
import org.graphstream.graph.EdgeRejectedException;
import org.graphstream.graph.Element;
import org.graphstream.graph.ElementNotFoundException;
import org.graphstream.graph.Graph;
import org.graphstream.graph.IdAlreadyInUseException;
import org.graphstream.graph.Node;
import org.graphstream.graph.NodeFactory;
import org.graphstream.stream.AttributeSink;
import org.graphstream.stream.ElementSink;
import org.graphstream.stream.GraphParseException;
import org.graphstream.stream.GraphReplay;
import org.graphstream.stream.Sink;
import org.graphstream.stream.file.FileSink;
import org.graphstream.stream.file.FileSource;
import org.graphstream.ui.view.Viewer;
public class Graphs {
private static final Logger logger = Logger.getLogger(Graphs.class.getSimpleName());
public static Graph unmutableGraph(Graph g) {
return null;
}
/**
* Synchronizes a graph. The returned graph can be accessed and modified by
* several threads. You lose genericity in methods returning edge or node
* because each element (graph, nodes and edges) is wrapped into a synchronized
* wrapper which breaks original elements class.
*
* @param g
* the graph to synchronize
* @return a synchronized wrapper for g
*/
public static Graph synchronizedGraph(Graph g) {
return new SynchronizedGraph(g);
}
/**
* Merge several graphs in one. A new graph is created, that will contain the
* result. The method will try to create a graph of the same class that the
* first graph to merge (it needs to have a constructor with a String). Else, a
* MultiGraph is used.
*
* @param graphs
* graphs to merge
* @return merge result
*/
public static Graph merge(Graph... graphs) {
if (graphs == null)
return new DefaultGraph("void-merge");
String id = "merge";
for (Graph g : graphs)
id += "-" + g.getId();
Graph result;
try {
Class cls = graphs[0].getClass();
result = cls.getConstructor(String.class).newInstance(id);
} catch (Exception e) {
logger.warning(String.format("Cannot create a graph of %s.", graphs[0].getClass().getName()));
result = new MultiGraph(id);
}
mergeIn(result, graphs);
return result;
}
/**
* Merge several graphs in one. The first parameter is the graph in which the
* other graphs will be merged.
*
* @param result
* destination graph.
* @param graphs
* all graphs that will be merged in result.
*/
public static void mergeIn(Graph result, Graph... graphs) {
boolean strict = result.isStrict();
GraphReplay replay = new GraphReplay(String.format("replay-%x", System.nanoTime()));
replay.addSink(result);
result.setStrict(false);
if (graphs != null)
for (Graph g : graphs)
replay.replay(g);
replay.removeSink(result);
result.setStrict(strict);
}
/**
* Clone a given graph with same node/edge structure and same attributes.
*
* @param g
* the graph to clone
* @return a copy of g
*/
public static Graph clone(Graph g) {
Graph copy;
try {
Class cls = g.getClass();
copy = cls.getConstructor(String.class).newInstance(g.getId());
} catch (Exception e) {
logger.warning(String.format("Cannot create a graph of %s.", g.getClass().getName()));
copy = new AdjacencyListGraph(g.getId());
}
copyAttributes(g, copy);
for (int i = 0; i < g.getNodeCount(); i++) {
Node source = g.getNode(i);
Node target = copy.addNode(source.getId());
copyAttributes(source, target);
}
for (int i = 0; i < g.getEdgeCount(); i++) {
Edge source = g.getEdge(i);
Edge target = copy.addEdge(source.getId(), source.getSourceNode().getId(), source.getTargetNode().getId(),
source.isDirected());
copyAttributes(source, target);
}
return copy;
}
/**
* @param source
* @param target
*/
public static void copyAttributes(Element source, Element target) {
source.attributeKeys().forEach(key -> {
Object value = source.getAttribute(key);
value = checkedArrayOrCollectionCopy(value);
target.setAttribute(key, value);
});
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static Object checkedArrayOrCollectionCopy(Object o) {
if (o == null)
return null;
if (o.getClass().isArray()) {
Object c = Array.newInstance(o.getClass().getComponentType(), Array.getLength(o));
for (int i = 0; i < Array.getLength(o); i++) {
Object t = checkedArrayOrCollectionCopy(Array.get(o, i));
Array.set(c, i, t);
}
return c;
}
if (Collection.class.isAssignableFrom(o.getClass())) {
Collection t;
try {
t = (Collection) o.getClass().newInstance();
t.addAll((Collection) o);
return t;
} catch (Exception e) {
e.printStackTrace();
}
}
return o;
}
static class SynchronizedElement implements Element {
private static final ReentrantLock attributeLock = new ReentrantLock(); // Static to lock the attributes from different sources (graph/node/edge). Fix issue #293
protected final U wrappedElement;
SynchronizedElement(U e) {
this.wrappedElement = e;
}
public void setAttribute(String attribute, Object... values) {
attributeLock.lock();
try {
wrappedElement.setAttribute(attribute, values);
} finally {
attributeLock.unlock();
}
}
public void setAttributes(Map attributes) {
attributeLock.lock();
try {
wrappedElement.setAttributes(attributes);
} finally {
attributeLock.unlock();
}
}
public void clearAttributes() {
attributeLock.lock();
try {
wrappedElement.clearAttributes();
} finally {
attributeLock.unlock();
}
}
public Object[] getArray(String key) {
Object[] o;
attributeLock.lock();
try {
o = wrappedElement.getArray(key);
} finally {
attributeLock.unlock();
}
return o;
}
public Object getAttribute(String key) {
Object o;
attributeLock.lock();
try {
o = wrappedElement.getAttribute(key);
} finally {
attributeLock.unlock();
}
return o;
}
public T getAttribute(String key, Class clazz) {
T o;
attributeLock.lock();
try {
o = wrappedElement.getAttribute(key, clazz);
} finally {
attributeLock.unlock();
}
return o;
}
public int getAttributeCount() {
int c;
attributeLock.lock();
try {
c = wrappedElement.getAttributeCount();
} finally {
attributeLock.unlock();
}
return c;
}
@Override
public Stream attributeKeys() {
Stream s = null;
attributeLock.lock();
try {
s = wrappedElement.attributeKeys();
if (!s.spliterator().hasCharacteristics(Spliterator.CONCURRENT))
s = s.collect(Collectors.toList()).stream();
} finally {
attributeLock.unlock();
}
return s;
}
public Object getFirstAttributeOf(String... keys) {
Object o;
attributeLock.lock();
try {
o = wrappedElement.getFirstAttributeOf(keys);
} finally {
attributeLock.unlock();
}
return o;
}
public T getFirstAttributeOf(Class clazz, String... keys) {
T o;
attributeLock.lock();
try {
o = wrappedElement.getFirstAttributeOf(clazz, keys);
} finally {
attributeLock.unlock();
}
return o;
}
public Map getMap(String key) {
Map o;
attributeLock.lock();
try {
o = wrappedElement.getMap(key);
} finally {
attributeLock.unlock();
}
return o;
}
public String getId() {
return wrappedElement.getId();
}
public int getIndex() {
return wrappedElement.getIndex();
}
public CharSequence getLabel(String key) {
CharSequence o;
attributeLock.lock();
try {
o = wrappedElement.getLabel(key);
} finally {
attributeLock.unlock();
}
return o;
}
public double getNumber(String key) {
double o;
attributeLock.lock();
try {
o = wrappedElement.getNumber(key);
} finally {
attributeLock.unlock();
}
return o;
}
public List getVector(String key) {
List o;
attributeLock.lock();
try {
o = wrappedElement.getVector(key);
} finally {
attributeLock.unlock();
}
return o;
}
public boolean hasArray(String key) {
boolean b;
attributeLock.lock();
try {
b = wrappedElement.hasArray(key);
} finally {
attributeLock.unlock();
}
return b;
}
public boolean hasAttribute(String key) {
boolean b;
attributeLock.lock();
try {
b = wrappedElement.hasAttribute(key);
} finally {
attributeLock.unlock();
}
return b;
}
public boolean hasAttribute(String key, Class clazz) {
boolean b;
attributeLock.lock();
try {
b = wrappedElement.hasAttribute(key, clazz);
} finally {
attributeLock.unlock();
}
return b;
}
public boolean hasMap(String key) {
boolean b;
attributeLock.lock();
try {
b = wrappedElement.hasMap(key);
} finally {
attributeLock.unlock();
}
return b;
}
public boolean hasLabel(String key) {
boolean b;
attributeLock.lock();
try {
b = wrappedElement.hasLabel(key);
} finally {
attributeLock.unlock();
}
return b;
}
public boolean hasNumber(String key) {
boolean b;
attributeLock.lock();
try {
b = wrappedElement.hasNumber(key);
} finally {
attributeLock.unlock();
}
return b;
}
public boolean hasVector(String key) {
boolean b;
attributeLock.lock();
try {
b = wrappedElement.hasVector(key);
} finally {
attributeLock.unlock();
}
return b;
}
public void removeAttribute(String attribute) {
attributeLock.lock();
try {
wrappedElement.removeAttribute(attribute);
} finally {
attributeLock.unlock();
}
}
}
static class SynchronizedGraph extends SynchronizedElement implements Graph {
final ReentrantLock elementLock;
final Map synchronizedNodes;
final Map synchronizedEdges;
SynchronizedGraph(Graph g) {
super(g);
elementLock = new ReentrantLock();
synchronizedNodes = g.nodes().collect(Collectors.toMap(Node::getId, n -> new SynchronizedNode(this, n)));
synchronizedEdges = g.edges().collect(Collectors.toMap(Edge::getId, e -> new SynchronizedEdge(this, e)));
}
@Override
public Stream nodes() {
Collection nodes;
elementLock.lock();
try {
nodes = new Vector<>(synchronizedNodes.values());
} finally {
elementLock.unlock();
}
return nodes.stream();
}
@Override
public Stream edges() {
Collection edges;
elementLock.lock();
try {
edges = new Vector<>(synchronizedEdges.values());
} finally {
elementLock.unlock();
}
return edges.stream();
}
@Override
public Edge addEdge(String id, String node1, String node2)
throws IdAlreadyInUseException, ElementNotFoundException, EdgeRejectedException {
Edge e;
Edge se;
elementLock.lock();
try {
e = wrappedElement.addEdge(id, node1, node2);
se = new SynchronizedEdge(this, e);
synchronizedEdges.put(id, se);
} finally {
elementLock.unlock();
}
return se;
}
@Override
public Edge addEdge(String id, String from, String to, boolean directed)
throws IdAlreadyInUseException, ElementNotFoundException {
Edge e;
Edge se;
elementLock.lock();
try {
e = wrappedElement.addEdge(id, from, to, directed);
se = new SynchronizedEdge(this, e);
synchronizedEdges.put(id, se);
} finally {
elementLock.unlock();
}
return se;
}
@Override
public Edge addEdge(String id, int index1, int index2) {
Edge e;
Edge se;
elementLock.lock();
try {
e = wrappedElement.addEdge(id, index1, index2);
se = new SynchronizedEdge(this, e);
synchronizedEdges.put(id, se);
} finally {
elementLock.unlock();
}
return se;
}
@Override
public Edge addEdge(String id, int fromIndex, int toIndex, boolean directed) {
Edge e;
Edge se;
elementLock.lock();
try {
e = wrappedElement.addEdge(id, fromIndex, toIndex, directed);
se = new SynchronizedEdge(this, e);
synchronizedEdges.put(id, se);
} finally {
elementLock.unlock();
}
return se;
}
@SuppressWarnings("unchecked")
@Override
public Edge addEdge(String id, Node node1, Node node2) {
Edge e;
Edge se;
final Node unsyncNode1, unsyncNode2;
unsyncNode1 = ((SynchronizedElement) node1).wrappedElement;
unsyncNode2 = ((SynchronizedElement) node2).wrappedElement;
elementLock.lock();
try {
e = wrappedElement.addEdge(id, unsyncNode1, unsyncNode2);
se = new SynchronizedEdge(this, e);
synchronizedEdges.put(id, se);
} finally {
elementLock.unlock();
}
return se;
}
@SuppressWarnings("unchecked")
@Override
public Edge addEdge(String id, Node from, Node to, boolean directed) {
Edge e;
Edge se;
final Node unsyncFrom, unsyncTo;
unsyncFrom = ((SynchronizedElement) from).wrappedElement;
unsyncTo = ((SynchronizedElement) to).wrappedElement;
elementLock.lock();
try {
e = wrappedElement.addEdge(id, unsyncFrom, unsyncTo, directed);
se = new SynchronizedEdge(this, e);
synchronizedEdges.put(id, se);
} finally {
elementLock.unlock();
}
return se;
}
@Override
public Node addNode(String id) throws IdAlreadyInUseException {
Node n;
Node sn;
elementLock.lock();
try {
n = wrappedElement.addNode(id);
sn = new SynchronizedNode(this, n);
synchronizedNodes.put(id, sn);
} finally {
elementLock.unlock();
}
return sn;
}
@Override
public Iterable attributeSinks() {
LinkedList sinks = new LinkedList();
elementLock.lock();
try {
for (AttributeSink as : wrappedElement.attributeSinks())
sinks.add(as);
} finally {
elementLock.unlock();
}
return sinks;
}
@Override
public void clear() {
elementLock.lock();
try {
wrappedElement.clear();
} finally {
elementLock.unlock();
}
}
@Override
public EdgeFactory edgeFactory() {
return wrappedElement.edgeFactory();
}
@Override
public Iterable elementSinks() {
LinkedList sinks = new LinkedList();
elementLock.lock();
try {
for (ElementSink es : wrappedElement.elementSinks())
sinks.add(es);
} finally {
elementLock.unlock();
}
return sinks;
}
@Override
public Edge getEdge(String id) {
Edge e;
elementLock.lock();
try {
e = synchronizedEdges.get(id);
} finally {
elementLock.unlock();
}
return e;
}
@Override
public Edge getEdge(int index) throws IndexOutOfBoundsException {
Edge e;
elementLock.lock();
try {
e = wrappedElement.getEdge(index);
} finally {
elementLock.unlock();
}
return e == null ? null : getEdge(e.getId());
}
@Override
public int getEdgeCount() {
int c;
elementLock.lock();
try {
c = synchronizedEdges.size();
} finally {
elementLock.unlock();
}
return c;
}
@Override
public Node getNode(String id) {
Node n;
elementLock.lock();
try {
n = synchronizedNodes.get(id);
} finally {
elementLock.unlock();
}
return n;
}
@Override
public Node getNode(int index) throws IndexOutOfBoundsException {
Node n;
elementLock.lock();
try {
n = wrappedElement.getNode(index);
} finally {
elementLock.unlock();
}
return n == null ? null : getNode(n.getId());
}
@Override
public int getNodeCount() {
int c;
elementLock.lock();
try {
c = synchronizedNodes.size();
} finally {
elementLock.unlock();
}
return c;
}
@Override
public double getStep() {
double s;
elementLock.lock();
try {
s = wrappedElement.getStep();
} finally {
elementLock.unlock();
}
return s;
}
@Override
public boolean isAutoCreationEnabled() {
return wrappedElement.isAutoCreationEnabled();
}
public Viewer display() {
return wrappedElement.display();
}
public Viewer display(boolean autoLayout) {
return wrappedElement.display(autoLayout);
}
@Override
public boolean isStrict() {
return wrappedElement.isStrict();
}
@Override
public NodeFactory nodeFactory() {
return wrappedElement.nodeFactory();
}
@Override
public void read(String filename) throws IOException, GraphParseException, ElementNotFoundException {
elementLock.lock();
try {
wrappedElement.read(filename);
} finally {
elementLock.unlock();
}
}
@Override
public void read(FileSource input, String filename) throws IOException, GraphParseException {
elementLock.lock();
try {
wrappedElement.read(input, filename);
} finally {
elementLock.unlock();
}
}
@Override
public Edge removeEdge(String from, String to) throws ElementNotFoundException {
Edge e;
Edge se;
elementLock.lock();
try {
e = wrappedElement.removeEdge(from, to);
se = synchronizedEdges.remove(e.getId());
} finally {
elementLock.unlock();
}
return se;
}
@Override
public Edge removeEdge(String id) throws ElementNotFoundException {
Edge e;
Edge se;
elementLock.lock();
try {
e = wrappedElement.removeEdge(id);
se = synchronizedEdges.remove(e.getId());
} finally {
elementLock.unlock();
}
return se;
}
@Override
public Edge removeEdge(int index) {
Edge e;
Edge se;
elementLock.lock();
try {
e = wrappedElement.removeEdge(index);
se = synchronizedEdges.remove(e.getId());
} finally {
elementLock.unlock();
}
return se;
}
@Override
public Edge removeEdge(int fromIndex, int toIndex) {
Edge e;
Edge se;
elementLock.lock();
try {
e = wrappedElement.removeEdge(fromIndex, toIndex);
se = synchronizedEdges.remove(e.getId());
} finally {
elementLock.unlock();
}
return se;
}
@Override
public Edge removeEdge(Node node1, Node node2) {
Edge e;
Edge se;
if (node1 instanceof SynchronizedNode)
node1 = ((SynchronizedNode) node1).wrappedElement;
if (node2 instanceof SynchronizedNode)
node2 = ((SynchronizedNode) node1).wrappedElement;
elementLock.lock();
try {
e = wrappedElement.removeEdge(node1, node2);
se = synchronizedEdges.remove(e.getId());
} finally {
elementLock.unlock();
}
return se;
}
@Override
public Edge removeEdge(Edge edge) {
Edge e;
Edge se;
if (edge instanceof SynchronizedEdge)
edge = ((SynchronizedEdge) edge).wrappedElement;
elementLock.lock();
try {
e = wrappedElement.removeEdge(edge);
se = synchronizedEdges.remove(e.getId());
} finally {
elementLock.unlock();
}
return se;
}
@Override
public Node removeNode(String id) throws ElementNotFoundException {
Node n;
Node sn;
elementLock.lock();
try {
n = wrappedElement.removeNode(id);
sn = synchronizedNodes.remove(n.getId());
} finally {
elementLock.unlock();
}
return sn;
}
@Override
public Node removeNode(int index) {
Node n;
Node sn;
elementLock.lock();
try {
n = wrappedElement.removeNode(index);
sn = synchronizedNodes.remove(n.getId());
} finally {
elementLock.unlock();
}
return sn;
}
@Override
public Node removeNode(Node node) {
Node n;
Node sn;
if (node instanceof SynchronizedNode)
node = ((SynchronizedNode) node).wrappedElement;
elementLock.lock();
try {
n = wrappedElement.removeNode(node);
sn = synchronizedNodes.remove(n.getId());
} finally {
elementLock.unlock();
}
return sn;
}
@Override
public void setAutoCreate(boolean on) {
elementLock.lock();
try {
wrappedElement.setAutoCreate(on);
} finally {
elementLock.unlock();
}
}
@Override
public void setEdgeFactory(EdgeFactory ef) {
elementLock.lock();
try {
wrappedElement.setEdgeFactory(ef);
} finally {
elementLock.unlock();
}
}
@Override
public void setNodeFactory(NodeFactory nf) {
elementLock.lock();
try {
wrappedElement.setNodeFactory(nf);
} finally {
elementLock.unlock();
}
}
@Override
public void setStrict(boolean on) {
elementLock.lock();
try {
wrappedElement.setStrict(on);
} finally {
elementLock.unlock();
}
}
@Override
public void stepBegins(double time) {
elementLock.lock();
try {
wrappedElement.stepBegins(time);
} finally {
elementLock.unlock();
}
}
@Override
public void write(String filename) throws IOException {
elementLock.lock();
try {
wrappedElement.write(filename);
} finally {
elementLock.unlock();
}
}
@Override
public void write(FileSink output, String filename) throws IOException {
elementLock.lock();
try {
wrappedElement.write(output, filename);
} finally {
elementLock.unlock();
}
}
@Override
public void addAttributeSink(AttributeSink sink) {
elementLock.lock();
try {
wrappedElement.addAttributeSink(sink);
} finally {
elementLock.unlock();
}
}
@Override
public void addElementSink(ElementSink sink) {
elementLock.lock();
try {
wrappedElement.addElementSink(sink);
} finally {
elementLock.unlock();
}
}
@Override
public void addSink(Sink sink) {
elementLock.lock();
try {
wrappedElement.addSink(sink);
} finally {
elementLock.unlock();
}
}
@Override
public void clearAttributeSinks() {
elementLock.lock();
try {
wrappedElement.clearAttributeSinks();
} finally {
elementLock.unlock();
}
}
@Override
public void clearElementSinks() {
elementLock.lock();
try {
wrappedElement.clearElementSinks();
} finally {
elementLock.unlock();
}
}
@Override
public void clearSinks() {
elementLock.lock();
try {
wrappedElement.clearSinks();
} finally {
elementLock.unlock();
}
}
@Override
public void removeAttributeSink(AttributeSink sink) {
elementLock.lock();
try {
wrappedElement.removeAttributeSink(sink);
} finally {
elementLock.unlock();
}
}
@Override
public void removeElementSink(ElementSink sink) {
elementLock.lock();
try {
wrappedElement.removeElementSink(sink);
} finally {
elementLock.unlock();
}
}
@Override
public void removeSink(Sink sink) {
elementLock.lock();
try {
wrappedElement.removeSink(sink);
} finally {
elementLock.unlock();
}
}
@Override
public void edgeAttributeAdded(String sourceId, long timeId, String edgeId, String attribute, Object value) {
wrappedElement.edgeAttributeAdded(sourceId, timeId, edgeId, attribute, value);
}
@Override
public void edgeAttributeChanged(String sourceId, long timeId, String edgeId, String attribute, Object oldValue,
Object newValue) {
wrappedElement.edgeAttributeChanged(sourceId, timeId, edgeId, attribute, oldValue, newValue);
}
@Override
public void edgeAttributeRemoved(String sourceId, long timeId, String edgeId, String attribute) {
wrappedElement.edgeAttributeRemoved(sourceId, timeId, edgeId, attribute);
}
@Override
public void graphAttributeAdded(String sourceId, long timeId, String attribute, Object value) {
wrappedElement.graphAttributeAdded(sourceId, timeId, attribute, value);
}
@Override
public void graphAttributeChanged(String sourceId, long timeId, String attribute, Object oldValue,
Object newValue) {
wrappedElement.graphAttributeChanged(sourceId, timeId, attribute, oldValue, newValue);
}
@Override
public void graphAttributeRemoved(String sourceId, long timeId, String attribute) {
wrappedElement.graphAttributeRemoved(sourceId, timeId, attribute);
}
@Override
public void nodeAttributeAdded(String sourceId, long timeId, String nodeId, String attribute, Object value) {
wrappedElement.nodeAttributeAdded(sourceId, timeId, nodeId, attribute, value);
}
@Override
public void nodeAttributeChanged(String sourceId, long timeId, String nodeId, String attribute, Object oldValue,
Object newValue) {
wrappedElement.nodeAttributeChanged(sourceId, timeId, nodeId, attribute, oldValue, newValue);
}
@Override
public void nodeAttributeRemoved(String sourceId, long timeId, String nodeId, String attribute) {
wrappedElement.nodeAttributeRemoved(sourceId, timeId, nodeId, attribute);
}
@Override
public void edgeAdded(String sourceId, long timeId, String edgeId, String fromNodeId, String toNodeId,
boolean directed) {
wrappedElement.edgeAdded(sourceId, timeId, edgeId, fromNodeId, toNodeId, directed);
}
@Override
public void edgeRemoved(String sourceId, long timeId, String edgeId) {
wrappedElement.edgeRemoved(sourceId, timeId, edgeId);
}
@Override
public void graphCleared(String sourceId, long timeId) {
wrappedElement.graphCleared(sourceId, timeId);
}
@Override
public void nodeAdded(String sourceId, long timeId, String nodeId) {
wrappedElement.nodeAdded(sourceId, timeId, nodeId);
}
@Override
public void nodeRemoved(String sourceId, long timeId, String nodeId) {
wrappedElement.nodeRemoved(sourceId, timeId, nodeId);
}
@Override
public void stepBegins(String sourceId, long timeId, double step) {
wrappedElement.stepBegins(sourceId, timeId, step);
}
@Override
public Iterator iterator() {
return nodes().iterator();
}
}
static class SynchronizedNode extends SynchronizedElement implements Node {
private final SynchronizedGraph sg;
private final ReentrantLock elementLock;
SynchronizedNode(SynchronizedGraph sg, Node n) {
super(n);
this.sg = sg;
this.elementLock = new ReentrantLock();
}
@Override
public Stream neighborNodes() {
List nodes;
elementLock.lock();
sg.elementLock.lock();
try {
nodes = wrappedElement.neighborNodes().map(n -> sg.getNode(n.getIndex())).collect(Collectors.toList());
} finally {
sg.elementLock.unlock();
elementLock.unlock();
}
return nodes.stream();
}
@Override
public Stream edges() {
List edges;
elementLock.lock();
sg.elementLock.lock();
try {
edges = wrappedElement.edges().map(e -> sg.getEdge(e.getIndex())).collect(Collectors.toList());
} finally {
sg.elementLock.unlock();
elementLock.unlock();
}
return edges.stream();
}
@Override
public Stream leavingEdges() {
List edges;
elementLock.lock();
sg.elementLock.lock();
try {
edges = wrappedElement.leavingEdges().map(e -> sg.getEdge(e.getIndex())).collect(Collectors.toList());
} finally {
sg.elementLock.unlock();
elementLock.unlock();
}
return edges.stream();
}
@Override
public Stream enteringEdges() {
List edges;
elementLock.lock();
sg.elementLock.lock();
try {
edges = wrappedElement.enteringEdges().map(e -> sg.getEdge(e.getIndex())).collect(Collectors.toList());
} finally {
sg.elementLock.unlock();
elementLock.unlock();
}
return edges.stream();
}
@Override
public Iterator getBreadthFirstIterator() {
return getBreadthFirstIterator(false);
}
@Override
public Iterator getBreadthFirstIterator(boolean directed) {
LinkedList l = new LinkedList();
Iterator it;
elementLock.lock();
sg.elementLock.lock();
try {
it = wrappedElement.getBreadthFirstIterator(directed);
while (it.hasNext())
l.add(sg.getNode(it.next().getIndex()));
} finally {
sg.elementLock.unlock();
elementLock.unlock();
}
return l.iterator();
}
@Override
public int getDegree() {
int d;
elementLock.lock();
try {
d = wrappedElement.getDegree();
} finally {
elementLock.unlock();
}
return d;
}
@Override
public Iterator getDepthFirstIterator() {
return getDepthFirstIterator(false);
}
@Override
public Iterator getDepthFirstIterator(boolean directed) {
LinkedList l = new LinkedList();
Iterator it;
elementLock.lock();
sg.elementLock.lock();
try {
it = wrappedElement.getDepthFirstIterator();
while (it.hasNext())
l.add(sg.getNode(it.next().getIndex()));
} finally {
sg.elementLock.unlock();
elementLock.unlock();
}
return l.iterator();
}
@Override
public Edge getEdge(int i) {
Edge e;
elementLock.lock();
try {
e = sg.getEdge(wrappedElement.getEdge(i).getIndex());
} finally {
elementLock.unlock();
}
return e;
}
@Override
public Edge getEnteringEdge(int i) {
Edge e;
elementLock.lock();
try {
e = sg.getEdge(wrappedElement.getEnteringEdge(i).getIndex());
} finally {
elementLock.unlock();
}
return e;
}
@Override
public Edge getLeavingEdge(int i) {
Edge e;
elementLock.lock();
try {
e = sg.getEdge(wrappedElement.getLeavingEdge(i).getIndex());
} finally {
elementLock.unlock();
}
return e;
}
@Override
public Edge getEdgeBetween(String id) {
Edge e;
elementLock.lock();
try {
e = sg.getEdge(wrappedElement.getEdgeBetween(id).getIndex());
} finally {
elementLock.unlock();
}
return e;
}
@Override
public Edge getEdgeBetween(Node n) {
Edge e;
elementLock.lock();
try {
e = sg.getEdge(wrappedElement.getEdgeBetween(n).getIndex());
} finally {
elementLock.unlock();
}
return e;
}
@Override
public Edge getEdgeBetween(int index) {
Edge e;
elementLock.lock();
try {
e = sg.getEdge(wrappedElement.getEdgeBetween(index).getIndex());
} finally {
elementLock.unlock();
}
return e;
}
@Override
public Edge getEdgeFrom(String id) {
Edge e;
elementLock.lock();
try {
e = sg.getEdge(wrappedElement.getEdgeFrom(id).getIndex());
} finally {
elementLock.unlock();
}
return e;
}
@Override
public Edge getEdgeFrom(Node n) {
Edge e;
elementLock.lock();
try {
e = sg.getEdge(wrappedElement.getEdgeFrom(n).getIndex());
} finally {
elementLock.unlock();
}
return e;
}
@Override
public Edge getEdgeFrom(int index) {
Edge e;
elementLock.lock();
try {
e = sg.getEdge(wrappedElement.getEdgeFrom(index).getIndex());
} finally {
elementLock.unlock();
}
return e;
}
@Override
public Edge getEdgeToward(String id) {
Edge e;
elementLock.lock();
try {
e = sg.getEdge(wrappedElement.getEdgeToward(id).getIndex());
} finally {
elementLock.unlock();
}
return e;
}
@Override
public Edge getEdgeToward(Node n) {
Edge e;
elementLock.lock();
try {
e = sg.getEdge(wrappedElement.getEdgeToward(n).getIndex());
} finally {
elementLock.unlock();
}
return e;
}
@Override
public Edge getEdgeToward(int index) {
Edge e;
elementLock.lock();
try {
e = sg.getEdge(wrappedElement.getEdgeToward(index).getIndex());
} finally {
elementLock.unlock();
}
return e;
}
@Override
public Graph getGraph() {
return sg;
}
@Override
public int getInDegree() {
int d;
elementLock.lock();
try {
d = wrappedElement.getInDegree();
} finally {
elementLock.unlock();
}
return d;
}
@Override
public int getOutDegree() {
int d;
elementLock.lock();
try {
d = wrappedElement.getOutDegree();
} finally {
elementLock.unlock();
}
return d;
}
@Override
public Iterator iterator() {
return edges().iterator();
}
}
static class SynchronizedEdge extends SynchronizedElement implements Edge {
final SynchronizedGraph sg;
SynchronizedEdge(SynchronizedGraph sg, Edge e) {
super(e);
this.sg = sg;
}
@Override
public Node getNode0() {
Node n;
sg.elementLock.lock();
try {
n = sg.getNode(wrappedElement.getNode0().getIndex());
} finally {
sg.elementLock.unlock();
}
return n;
}
@Override
public Node getNode1() {
Node n;
sg.elementLock.lock();
try {
n = sg.getNode(wrappedElement.getNode1().getIndex());
} finally {
sg.elementLock.unlock();
}
return n;
}
@Override
public Node getOpposite(Node node) {
Node n;
if (node instanceof SynchronizedNode)
node = ((SynchronizedNode) node).wrappedElement;
sg.elementLock.lock();
try {
n = sg.getNode(wrappedElement.getOpposite(node).getIndex());
} finally {
sg.elementLock.unlock();
}
return n;
}
@Override
public Node getSourceNode() {
Node n;
sg.elementLock.lock();
try {
n = sg.getNode(wrappedElement.getSourceNode().getIndex());
} finally {
sg.elementLock.unlock();
}
return n;
}
@Override
public Node getTargetNode() {
Node n;
sg.elementLock.lock();
try {
n = sg.getNode(wrappedElement.getTargetNode().getIndex());
} finally {
sg.elementLock.unlock();
}
return n;
}
@Override
public boolean isDirected() {
return wrappedElement.isDirected();
}
@Override
public boolean isLoop() {
return wrappedElement.isLoop();
}
}
}