Package org.graphstream.graph.implementations

Source Code of org.graphstream.graph.implementations.Graphs$SynchronizedEdge

/*
* Copyright 2006 - 2013
*     Stefan Balev     <stefan.balev@graphstream-project.org>
*     Julien Baudry    <julien.baudry@graphstream-project.org>
*     Antoine Dutot    <antoine.dutot@graphstream-project.org>
*     Yoann Pigné      <yoann.pigne@graphstream-project.org>
*     Guilhelm Savin   <guilhelm.savin@graphstream-project.org>
*
* This file is part of GraphStream <http://graphstream-project.org>.
*
* 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 <http://www.cecill.info> 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 <http://www.gnu.org/licenses/>.
*
* 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.
*/
package org.graphstream.graph.implementations;

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;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;

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<? extends Graph> 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<? extends Graph> 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) {
    for (String key : source.getAttributeKeySet()) {
      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 (InstantiationException e) {
        e.printStackTrace();
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      }
    }

    return o;
  }

  static class SynchronizedElement<U extends Element> implements Element {

    private final ReentrantLock attributeLock;
    protected final U wrappedElement;

    SynchronizedElement(U e) {
      this.wrappedElement = e;
      this.attributeLock = new ReentrantLock();
    }

    public void addAttribute(String attribute, Object... values) {
      attributeLock.lock();
      wrappedElement.addAttribute(attribute, values);
      attributeLock.unlock();
    }

    public void addAttributes(Map<String, Object> attributes) {
      attributeLock.lock();
      wrappedElement.addAttributes(attributes);
      attributeLock.unlock();
    }

    public void changeAttribute(String attribute, Object... values) {
      attributeLock.lock();
      wrappedElement.changeAttribute(attribute, values);
      attributeLock.unlock();
    }

    public void clearAttributes() {
      attributeLock.lock();
      wrappedElement.clearAttributes();
      attributeLock.unlock();
    }

    public Object[] getArray(String key) {
      Object[] o;

      attributeLock.lock();
      o = wrappedElement.getArray(key);
      attributeLock.unlock();

      return o;
    }

    public <T> T getAttribute(String key) {
      T o;

      attributeLock.lock();
      o = wrappedElement.getAttribute(key);
      attributeLock.unlock();

      return o;
    }

    public <T> T getAttribute(String key, Class<T> clazz) {
      T o;

      attributeLock.lock();
      o = wrappedElement.getAttribute(key, clazz);
      attributeLock.unlock();

      return o;
    }

    public int getAttributeCount() {
      int c;

      attributeLock.lock();
      c = wrappedElement.getAttributeCount();
      attributeLock.unlock();

      return c;
    }

    public Iterator<String> getAttributeKeyIterator() {
      return getAttributeKeySet().iterator();
    }

    public Collection<String> getAttributeKeySet() {
      ArrayList<String> o;
      Iterator<String> it;

      attributeLock.lock();

      o = new ArrayList<String>(wrappedElement.getAttributeCount());
      it = wrappedElement.getAttributeKeyIterator();

      while (it.hasNext())
        o.add(it.next());

      attributeLock.unlock();

      return o;
    }
   
    public Iterable<String> getEachAttributeKey() {
      return getAttributeKeySet();
    }

    public <T> T getFirstAttributeOf(String... keys) {
      T o;

      attributeLock.lock();
      o = wrappedElement.getFirstAttributeOf(keys);
      attributeLock.unlock();

      return o;
    }

    public <T> T getFirstAttributeOf(Class<T> clazz, String... keys) {
      T o;

      attributeLock.lock();
      o = wrappedElement.getFirstAttributeOf(clazz, keys);
      attributeLock.unlock();

      return o;
    }

    public HashMap<?, ?> getHash(String key) {
      HashMap<?, ?> o;

      attributeLock.lock();
      o = wrappedElement.getHash(key);
      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();
      o = wrappedElement.getLabel(key);
      attributeLock.unlock();

      return o;
    }

    public double getNumber(String key) {
      double o;

      attributeLock.lock();
      o = wrappedElement.getNumber(key);
      attributeLock.unlock();

      return o;
    }

    public ArrayList<? extends Number> getVector(String key) {
      ArrayList<? extends Number> o;

      attributeLock.lock();
      o = wrappedElement.getVector(key);
      attributeLock.unlock();

      return o;
    }

    public boolean hasArray(String key) {
      boolean b;

      attributeLock.lock();
      b = wrappedElement.hasArray(key);
      attributeLock.unlock();

      return b;
    }

    public boolean hasAttribute(String key) {
      boolean b;

      attributeLock.lock();
      b = wrappedElement.hasAttribute(key);
      attributeLock.unlock();

      return b;
    }

    public boolean hasAttribute(String key, Class<?> clazz) {
      boolean b;

      attributeLock.lock();
      b = wrappedElement.hasAttribute(key, clazz);
      attributeLock.unlock();

      return b;
    }

    public boolean hasHash(String key) {
      boolean b;

      attributeLock.lock();
      b = wrappedElement.hasHash(key);
      attributeLock.unlock();

      return b;
    }

    public boolean hasLabel(String key) {
      boolean b;

      attributeLock.lock();
      b = wrappedElement.hasLabel(key);
      attributeLock.unlock();

      return b;
    }

    public boolean hasNumber(String key) {
      boolean b;

      attributeLock.lock();
      b = wrappedElement.hasNumber(key);
      attributeLock.unlock();

      return b;
    }

    public boolean hasVector(String key) {
      boolean b;

      attributeLock.lock();
      b = wrappedElement.hasVector(key);
      attributeLock.unlock();

      return b;
    }

    public void removeAttribute(String attribute) {
      attributeLock.lock();
      wrappedElement.removeAttribute(attribute);
      attributeLock.unlock();
    }

    public void setAttribute(String attribute, Object... values) {
      attributeLock.lock();
      wrappedElement.setAttribute(attribute, values);
      attributeLock.unlock();
    }   
  }

  static class SynchronizedGraph extends SynchronizedElement<Graph> implements
      Graph {

    final ReentrantLock elementLock;
    final HashMap<String, Node> synchronizedNodes;
    final HashMap<String, Edge> synchronizedEdges;

    SynchronizedGraph(Graph g) {
      super(g);

      elementLock = new ReentrantLock();
      synchronizedNodes = new HashMap<String, Node>();
      synchronizedEdges = new HashMap<String, Edge>();

      for (Node n : g.getEachNode())
        synchronizedNodes.put(n.getId(), new SynchronizedNode(this, n));

      for (Edge e : g.getEachEdge())
        synchronizedEdges.put(e.getId(), new SynchronizedEdge(this, e));
    }

    @SuppressWarnings("unchecked")
    public <T extends Edge> T addEdge(String id, String node1, String node2)
        throws IdAlreadyInUseException, ElementNotFoundException,
        EdgeRejectedException {
      T e;
      Edge se;

      elementLock.lock();

      e = wrappedElement.addEdge(id, node1, node2);
      se = new SynchronizedEdge(this, e);
      synchronizedEdges.put(id, se);

      elementLock.unlock();

      return (T) se;
    }

    @SuppressWarnings("unchecked")
    public <T extends Edge> T addEdge(String id, String from, String to,
        boolean directed) throws IdAlreadyInUseException,
        ElementNotFoundException {
      T e;
      Edge se;

      elementLock.lock();

      e = wrappedElement.addEdge(id, from, to, directed);
      se = new SynchronizedEdge(this, e);
      synchronizedEdges.put(id, se);

      elementLock.unlock();

      return (T) se;
    }

    @SuppressWarnings("unchecked")
    public <T extends Edge> T addEdge(String id, int index1, int index2) {
      T e;
      Edge se;

      elementLock.lock();

      e = wrappedElement.addEdge(id, index1, index2);
      se = new SynchronizedEdge(this, e);
      synchronizedEdges.put(id, se);

      elementLock.unlock();

      return (T) se;
    }

    @SuppressWarnings("unchecked")
    public <T extends Edge> T addEdge(String id, int fromIndex,
        int toIndex, boolean directed) {
      T e;
      Edge se;

      elementLock.lock();

      e = wrappedElement.addEdge(id, fromIndex, toIndex, directed);
      se = new SynchronizedEdge(this, e);
      synchronizedEdges.put(id, se);

      elementLock.unlock();

      return (T) se;
    }

    @SuppressWarnings("unchecked")
    public <T extends Edge> T addEdge(String id, Node node1, Node node2) {
      T e;
      Edge se;
      final Node unsyncNode1, unsyncNode2;

      unsyncNode1 = ((SynchronizedElement<Node>) node1).wrappedElement;
      unsyncNode2 = ((SynchronizedElement<Node>) node2).wrappedElement;

      elementLock.lock();

      e = wrappedElement.addEdge(id, unsyncNode1, unsyncNode2);
      se = new SynchronizedEdge(this, e);
      synchronizedEdges.put(id, se);

      elementLock.unlock();

      return (T) se;
    }

    @SuppressWarnings("unchecked")
    public <T extends Edge> T addEdge(String id, Node from, Node to,
        boolean directed) {
      T e;
      Edge se;
      final Node unsyncFrom, unsyncTo;

      unsyncFrom = ((SynchronizedElement<Node>) from).wrappedElement;
      unsyncTo = ((SynchronizedElement<Node>) to).wrappedElement;

      elementLock.lock();

      e = wrappedElement.addEdge(id, unsyncFrom, unsyncTo, directed);
      se = new SynchronizedEdge(this, e);
      synchronizedEdges.put(id, se);

      elementLock.unlock();

      return (T) se;
    }

    @SuppressWarnings("unchecked")
    public <T extends Node> T addNode(String id)
        throws IdAlreadyInUseException {
      T n;
      Node sn;

      elementLock.lock();

      n = wrappedElement.addNode(id);
      sn = new SynchronizedNode(this, n);
      synchronizedNodes.put(id, sn);

      elementLock.unlock();

      return (T) sn;
    }

    public Iterable<AttributeSink> attributeSinks() {
      LinkedList<AttributeSink> sinks = new LinkedList<AttributeSink>();

      elementLock.lock();

      for (AttributeSink as : wrappedElement.attributeSinks())
        sinks.add(as);

      elementLock.unlock();

      return sinks;
    }

    public void clear() {
      elementLock.lock();
      wrappedElement.clear();
      elementLock.unlock();
    }

    public Viewer display() {
      return wrappedElement.display();
    }

    public Viewer display(boolean autoLayout) {
      return wrappedElement.display(autoLayout);
    }

    public EdgeFactory<? extends Edge> edgeFactory() {
      return wrappedElement.edgeFactory();
    }

    public Iterable<ElementSink> elementSinks() {
      LinkedList<ElementSink> sinks = new LinkedList<ElementSink>();

      elementLock.lock();

      for (ElementSink es : wrappedElement.elementSinks())
        sinks.add(es);

      elementLock.unlock();

      return sinks;
    }

    public Iterable<Edge> getEachEdge() {
      LinkedList<Edge> edges;

      elementLock.lock();
      edges = new LinkedList<Edge>(synchronizedEdges.values());
      elementLock.unlock();

      return edges;
    }

    public Iterable<Node> getEachNode() {
      LinkedList<Node> nodes;

      elementLock.lock();
      nodes = new LinkedList<Node>(synchronizedNodes.values());
      elementLock.unlock();

      return nodes;
    }

    @SuppressWarnings("unchecked")
    public <T extends Edge> T getEdge(String id) {
      T e;

      elementLock.lock();
      e = (T) synchronizedEdges.get(id);
      elementLock.unlock();

      return e;
    }

    public <T extends Edge> T getEdge(int index)
        throws IndexOutOfBoundsException {
      Edge e;

      elementLock.lock();
      e = wrappedElement.getEdge(index);
      elementLock.unlock();

      return e == null ? null : this.<T> getEdge(e.getId());
    }

    public int getEdgeCount() {
      int c;

      elementLock.lock();
      c = synchronizedEdges.size();
      elementLock.unlock();

      return c;
    }

    public Iterator<Edge> getEdgeIterator() {
      return getEdgeSet().iterator();
    }

    public Collection<Edge> getEdgeSet() {
      LinkedList<Edge> l;

      elementLock.lock();
      l = new LinkedList<Edge>(synchronizedEdges.values());
      elementLock.unlock();

      return l;
    }

    @SuppressWarnings("unchecked")
    public <T extends Node> T getNode(String id) {
      T n;

      elementLock.lock();
      n = (T) synchronizedNodes.get(id);
      elementLock.unlock();

      return n;
    }

    public <T extends Node> T getNode(int index)
        throws IndexOutOfBoundsException {
      Node n;

      elementLock.lock();
      n = wrappedElement.getNode(index);
      elementLock.unlock();

      return n == null ? null : this.<T> getNode(n.getId());
    }

    public int getNodeCount() {
      int c;

      elementLock.lock();
      c = synchronizedNodes.size();
      elementLock.unlock();

      return c;
    }

    public Iterator<Node> getNodeIterator() {
      return getNodeSet().iterator();
    }

    public Collection<Node> getNodeSet() {
      LinkedList<Node> l;

      elementLock.lock();
      l = new LinkedList<Node>(synchronizedNodes.values());
      elementLock.unlock();

      return l;
    }

    public double getStep() {
      double s;

      elementLock.lock();
      s = wrappedElement.getStep();
      elementLock.unlock();

      return s;
    }

    public boolean isAutoCreationEnabled() {
      return wrappedElement.isAutoCreationEnabled();
    }

    public boolean isStrict() {
      return wrappedElement.isStrict();
    }

    public NodeFactory<? extends Node> nodeFactory() {
      return wrappedElement.nodeFactory();
    }

    public boolean nullAttributesAreErrors() {
      return wrappedElement.nullAttributesAreErrors();
    }

    public void read(String filename) throws IOException,
        GraphParseException, ElementNotFoundException {
      elementLock.lock();
      wrappedElement.read(filename);
      elementLock.unlock();
    }

    public void read(FileSource input, String filename) throws IOException,
        GraphParseException {
      elementLock.lock();
      wrappedElement.read(input, filename);
      elementLock.unlock();
    }

    @SuppressWarnings("unchecked")
    public <T extends Edge> T removeEdge(String from, String to)
        throws ElementNotFoundException {
      T e;
      Edge se;

      elementLock.lock();
      e = wrappedElement.removeEdge(from, to);
      se = synchronizedEdges.remove(e.getId());
      elementLock.unlock();

      return (T) se;
    }

    @SuppressWarnings("unchecked")
    public <T extends Edge> T removeEdge(String id)
        throws ElementNotFoundException {
      T e;
      Edge se;

      elementLock.lock();
      e = wrappedElement.removeEdge(id);
      se = synchronizedEdges.remove(e.getId());
      elementLock.unlock();

      return (T) se;
    }

    @SuppressWarnings("unchecked")
    public <T extends Edge> T removeEdge(int index) {
      T e;
      Edge se;

      elementLock.lock();
      e = wrappedElement.removeEdge(index);
      se = synchronizedEdges.remove(e.getId());
      elementLock.unlock();

      return (T) se;
    }

    @SuppressWarnings("unchecked")
    public <T extends Edge> T removeEdge(int fromIndex, int toIndex) {
      T e;
      Edge se;

      elementLock.lock();
      e = wrappedElement.removeEdge(fromIndex, toIndex);
      se = synchronizedEdges.remove(e.getId());
      elementLock.unlock();

      return (T) se;
    }

    @SuppressWarnings("unchecked")
    public <T extends Edge> T removeEdge(Node node1, Node node2) {
      T e;
      Edge se;

      if (node1 instanceof SynchronizedNode)
        node1 = ((SynchronizedNode) node1).wrappedElement;

      if (node2 instanceof SynchronizedNode)
        node2 = ((SynchronizedNode) node1).wrappedElement;

      elementLock.lock();
      e = wrappedElement.removeEdge(node1, node2);
      se = synchronizedEdges.remove(e.getId());
      elementLock.unlock();

      return (T) se;
    }

    @SuppressWarnings("unchecked")
    public <T extends Edge> T removeEdge(Edge edge) {
      T e;
      Edge se;

      if (edge instanceof SynchronizedEdge)
        edge = ((SynchronizedEdge) edge).wrappedElement;

      elementLock.lock();
      e = wrappedElement.removeEdge(edge);
      se = synchronizedEdges.remove(e.getId());
      elementLock.unlock();

      return (T) se;
    }

    @SuppressWarnings("unchecked")
    public <T extends Node> T removeNode(String id)
        throws ElementNotFoundException {
      T n;
      Node sn;

      elementLock.lock();
      n = wrappedElement.removeNode(id);
      sn = synchronizedNodes.remove(n.getId());
      elementLock.unlock();

      return (T) sn;
    }

    @SuppressWarnings("unchecked")
    public <T extends Node> T removeNode(int index) {
      T n;
      Node sn;

      elementLock.lock();
      n = wrappedElement.removeNode(index);
      sn = synchronizedNodes.remove(n.getId());
      elementLock.unlock();

      return (T) sn;
    }

    @SuppressWarnings("unchecked")
    public <T extends Node> T removeNode(Node node) {
      T n;
      Node sn;

      if (node instanceof SynchronizedNode)
        node = ((SynchronizedNode) node).wrappedElement;

      elementLock.lock();
      n = wrappedElement.removeNode(node);
      sn = synchronizedNodes.remove(n.getId());
      elementLock.unlock();

      return (T) sn;
    }

    public void setAutoCreate(boolean on) {
      elementLock.lock();
      wrappedElement.setAutoCreate(on);
      elementLock.unlock();
    }

    public void setEdgeFactory(EdgeFactory<? extends Edge> ef) {
      elementLock.lock();
      wrappedElement.setEdgeFactory(ef);
      elementLock.unlock();
    }

    public void setNodeFactory(NodeFactory<? extends Node> nf) {
      elementLock.lock();
      wrappedElement.setNodeFactory(nf);
      elementLock.unlock();
    }

    public void setNullAttributesAreErrors(boolean on) {
      elementLock.lock();
      wrappedElement.setNullAttributesAreErrors(on);
      elementLock.unlock();
    }

    public void setStrict(boolean on) {
      elementLock.lock();
      wrappedElement.setStrict(on);
      elementLock.unlock();
    }

    public void stepBegins(double time) {
      elementLock.lock();
      wrappedElement.stepBegins(time);
      elementLock.unlock();
    }

    public void write(String filename) throws IOException {
      elementLock.lock();
      wrappedElement.write(filename);
      elementLock.unlock();
    }

    public void write(FileSink output, String filename) throws IOException {
      elementLock.lock();
      wrappedElement.write(output, filename);
      elementLock.unlock();
    }

    public void addAttributeSink(AttributeSink sink) {
      elementLock.lock();
      wrappedElement.addAttributeSink(sink);
      elementLock.unlock();
    }

    public void addElementSink(ElementSink sink) {
      elementLock.lock();
      wrappedElement.addElementSink(sink);
      elementLock.unlock();
    }

    public void addSink(Sink sink) {
      elementLock.lock();
      wrappedElement.addSink(sink);
      elementLock.unlock();
    }

    public void clearAttributeSinks() {
      elementLock.lock();
      wrappedElement.clearAttributeSinks();
      elementLock.unlock();
    }

    public void clearElementSinks() {
      elementLock.lock();
      wrappedElement.clearElementSinks();
      elementLock.unlock();
    }

    public void clearSinks() {
      elementLock.lock();
      wrappedElement.clearSinks();
      elementLock.unlock();
    }

    public void removeAttributeSink(AttributeSink sink) {
      elementLock.lock();
      wrappedElement.removeAttributeSink(sink);
      elementLock.unlock();
    }

    public void removeElementSink(ElementSink sink) {
      elementLock.lock();
      wrappedElement.removeElementSink(sink);
      elementLock.unlock();
    }

    public void removeSink(Sink sink) {
      elementLock.lock();
      wrappedElement.removeSink(sink);
      elementLock.unlock();
    }

    public void edgeAttributeAdded(String sourceId, long timeId,
        String edgeId, String attribute, Object value) {
      wrappedElement.edgeAttributeAdded(sourceId, timeId, edgeId,
          attribute, value);
    }

    public void edgeAttributeChanged(String sourceId, long timeId,
        String edgeId, String attribute, Object oldValue,
        Object newValue) {
      wrappedElement.edgeAttributeChanged(sourceId, timeId, edgeId,
          attribute, oldValue, newValue);
    }

    public void edgeAttributeRemoved(String sourceId, long timeId,
        String edgeId, String attribute) {
      wrappedElement.edgeAttributeRemoved(sourceId, timeId, edgeId,
          attribute);
    }

    public void graphAttributeAdded(String sourceId, long timeId,
        String attribute, Object value) {
      wrappedElement.graphAttributeAdded(sourceId, timeId, attribute,
          value);
    }

    public void graphAttributeChanged(String sourceId, long timeId,
        String attribute, Object oldValue, Object newValue) {
      wrappedElement.graphAttributeChanged(sourceId, timeId, attribute,
          oldValue, newValue);
    }

    public void graphAttributeRemoved(String sourceId, long timeId,
        String attribute) {
      wrappedElement.graphAttributeRemoved(sourceId, timeId, attribute);
    }

    public void nodeAttributeAdded(String sourceId, long timeId,
        String nodeId, String attribute, Object value) {
      wrappedElement.nodeAttributeAdded(sourceId, timeId, nodeId,
          attribute, value);
    }

    public void nodeAttributeChanged(String sourceId, long timeId,
        String nodeId, String attribute, Object oldValue,
        Object newValue) {
      wrappedElement.nodeAttributeChanged(sourceId, timeId, nodeId,
          attribute, oldValue, newValue);
    }

    public void nodeAttributeRemoved(String sourceId, long timeId,
        String nodeId, String attribute) {
      wrappedElement.nodeAttributeRemoved(sourceId, timeId, nodeId,
          attribute);
    }

    public void edgeAdded(String sourceId, long timeId, String edgeId,
        String fromNodeId, String toNodeId, boolean directed) {
      wrappedElement.edgeAdded(sourceId, timeId, edgeId, fromNodeId,
          toNodeId, directed);
    }

    public void edgeRemoved(String sourceId, long timeId, String edgeId) {
      wrappedElement.edgeRemoved(sourceId, timeId, edgeId);
    }

    public void graphCleared(String sourceId, long timeId) {
      wrappedElement.graphCleared(sourceId, timeId);
    }

    public void nodeAdded(String sourceId, long timeId, String nodeId) {
      wrappedElement.nodeAdded(sourceId, timeId, nodeId);
    }

    public void nodeRemoved(String sourceId, long timeId, String nodeId) {
      wrappedElement.nodeRemoved(sourceId, timeId, nodeId);
    }

    public void stepBegins(String sourceId, long timeId, double step) {
      wrappedElement.stepBegins(sourceId, timeId, step);
    }

    public Iterator<Node> iterator() {
      return getEachNode().iterator();
    }
  }

  static class SynchronizedNode extends SynchronizedElement<Node> implements
      Node {

    private final SynchronizedGraph sg;
    private final ReentrantLock elementLock;

    SynchronizedNode(SynchronizedGraph sg, Node n) {
      super(n);

      this.sg = sg;
      this.elementLock = new ReentrantLock();
    }

    public Iterator<Node> getBreadthFirstIterator() {
      return getBreadthFirstIterator(false);
    }

    public Iterator<Node> getBreadthFirstIterator(boolean directed) {
      LinkedList<Node> l = new LinkedList<Node>();
      Iterator<Node> it;

      elementLock.lock();
      sg.elementLock.lock();

      it = wrappedElement.getBreadthFirstIterator(directed);

      while (it.hasNext())
        l.add(sg.getNode(it.next().getIndex()));

      sg.elementLock.unlock();
      elementLock.unlock();

      return l.iterator();
    }

    public int getDegree() {
      int d;

      elementLock.lock();
      d = wrappedElement.getDegree();
      elementLock.unlock();

      return d;
    }

    public Iterator<Node> getDepthFirstIterator() {
      return getDepthFirstIterator(false);
    }

    public Iterator<Node> getDepthFirstIterator(boolean directed) {
      LinkedList<Node> l = new LinkedList<Node>();
      Iterator<Node> it;

      elementLock.lock();
      sg.elementLock.lock();

      it = wrappedElement.getDepthFirstIterator();

      while (it.hasNext())
        l.add(sg.getNode(it.next().getIndex()));

      sg.elementLock.unlock();
      elementLock.unlock();

      return l.iterator();
    }

    public Iterable<Edge> getEachEdge() {
      return getEdgeSet();
    }

    public Iterable<Edge> getEachEnteringEdge() {
      return getEnteringEdgeSet();
    }

    public Iterable<Edge> getEachLeavingEdge() {
      return getLeavingEdgeSet();
    }

    public <T extends Edge> T getEdge(int i) {
      T e;

      elementLock.lock();
      e = sg.getEdge(wrappedElement.getEdge(i).getIndex());
      elementLock.unlock();

      return e;
    }

    public <T extends Edge> T getEnteringEdge(int i) {
      T e;

      elementLock.lock();
      e = sg.getEdge(wrappedElement.getEnteringEdge(i).getIndex());
      elementLock.unlock();

      return e;
    }

    public <T extends Edge> T getLeavingEdge(int i) {
      T e;

      elementLock.lock();
      e = sg.getEdge(wrappedElement.getLeavingEdge(i).getIndex());
      elementLock.unlock();

      return e;
    }

    public <T extends Edge> T getEdgeBetween(String id) {
      T e;

      elementLock.lock();
      e = sg.getEdge(wrappedElement.getEdgeBetween(id).getIndex());
      elementLock.unlock();

      return e;
    }

    public <T extends Edge> T getEdgeBetween(Node n) {
      T e;

      elementLock.lock();
      e = sg.getEdge(wrappedElement.getEdgeBetween(n).getIndex());
      elementLock.unlock();

      return e;
    }

    public <T extends Edge> T getEdgeBetween(int index) {
      T e;

      elementLock.lock();
      e = sg.getEdge(wrappedElement.getEdgeBetween(index).getIndex());
      elementLock.unlock();

      return e;
    }

    public <T extends Edge> T getEdgeFrom(String id) {
      T e;

      elementLock.lock();
      e = sg.getEdge(wrappedElement.getEdgeFrom(id).getIndex());
      elementLock.unlock();

      return e;
    }

    public <T extends Edge> T getEdgeFrom(Node n) {
      T e;

      elementLock.lock();
      e = sg.getEdge(wrappedElement.getEdgeFrom(n).getIndex());
      elementLock.unlock();

      return e;
    }

    public <T extends Edge> T getEdgeFrom(int index) {
      T e;

      elementLock.lock();
      e = sg.getEdge(wrappedElement.getEdgeFrom(index).getIndex());
      elementLock.unlock();

      return e;
    }

    public Iterator<Edge> getEdgeIterator() {
      return getEdgeSet().iterator();
    }

    public Collection<Edge> getEdgeSet() {
      ArrayList<Edge> l;
      Iterator<Edge> it;

      elementLock.lock();

      l = new ArrayList<Edge>(wrappedElement.getDegree());
      it = wrappedElement.getEachEdge().iterator();

      while (it.hasNext())
        l.add(sg.getEdge(it.next().getIndex()));

      elementLock.unlock();

      return l;
    }

    public <T extends Edge> T getEdgeToward(String id) {
      T e;

      elementLock.lock();
      e = sg.getEdge(wrappedElement.getEdgeToward(id).getIndex());
      elementLock.unlock();

      return e;
    }

    public <T extends Edge> T getEdgeToward(Node n) {
      T e;

      elementLock.lock();
      e = sg.getEdge(wrappedElement.getEdgeToward(n).getIndex());
      elementLock.unlock();

      return e;
    }

    public <T extends Edge> T getEdgeToward(int index) {
      T e;

      elementLock.lock();
      e = sg.getEdge(wrappedElement.getEdgeToward(index).getIndex());
      elementLock.unlock();

      return e;
    }

    public Iterator<Edge> getEnteringEdgeIterator() {
      return getEnteringEdgeSet().iterator();
    }

    public Collection<Edge> getEnteringEdgeSet() {
      ArrayList<Edge> l;
      Iterator<Edge> it;

      elementLock.lock();
      sg.elementLock.lock();

      l = new ArrayList<Edge>(wrappedElement.getInDegree());
      it = wrappedElement.getEachEnteringEdge().iterator();

      while (it.hasNext())
        l.add(sg.getEdge(it.next().getIndex()));

      sg.elementLock.unlock();
      elementLock.unlock();

      return l;
    }

    public Graph getGraph() {
      return sg;
    }

    public int getInDegree() {
      int d;

      elementLock.lock();
      d = wrappedElement.getInDegree();
      elementLock.unlock();

      return d;
    }

    public Iterator<Edge> getLeavingEdgeIterator() {
      return getLeavingEdgeSet().iterator();
    }

    public Collection<Edge> getLeavingEdgeSet() {
      ArrayList<Edge> l;
      Iterator<Edge> it;

      elementLock.lock();
      sg.elementLock.lock();

      l = new ArrayList<Edge>(wrappedElement.getOutDegree());
      it = wrappedElement.<Edge> getEachLeavingEdge().iterator();

      while (it.hasNext())
        l.add(sg.getEdge(it.next().getIndex()));

      sg.elementLock.unlock();
      elementLock.unlock();

      return l;
    }

    public Iterator<Node> getNeighborNodeIterator() {
      ArrayList<Node> l;
      Iterator<Node> it;

      elementLock.lock();
      sg.elementLock.lock();

      l = new ArrayList<Node>(wrappedElement.getDegree());
      it = wrappedElement.getNeighborNodeIterator();

      while (it.hasNext())
        l.add(sg.getNode(it.next().getIndex()));

      sg.elementLock.unlock();
      elementLock.unlock();

      return l.iterator();
    }

    public int getOutDegree() {
      int d;

      elementLock.lock();
      d = wrappedElement.getOutDegree();
      elementLock.unlock();

      return d;
    }

    public boolean hasEdgeBetween(String id) {
      boolean b;

      elementLock.lock();
      b = wrappedElement.hasEdgeBetween(id);
      elementLock.unlock();

      return b;
    }

    public boolean hasEdgeBetween(Node node) {
      boolean b;

      elementLock.lock();
      b = wrappedElement.hasEdgeBetween(node);
      elementLock.unlock();

      return b;
    }

    public boolean hasEdgeBetween(int index) {
      boolean b;

      elementLock.lock();
      b = wrappedElement.hasEdgeBetween(index);
      elementLock.unlock();

      return b;
    }

    public boolean hasEdgeFrom(String id) {
      boolean b;

      elementLock.lock();
      b = wrappedElement.hasEdgeFrom(id);
      elementLock.unlock();

      return b;
    }

    public boolean hasEdgeFrom(Node node) {
      boolean b;

      elementLock.lock();
      b = wrappedElement.hasEdgeFrom(node);
      elementLock.unlock();

      return b;
    }

    public boolean hasEdgeFrom(int index) {
      boolean b;

      elementLock.lock();
      b = wrappedElement.hasEdgeFrom(index);
      elementLock.unlock();

      return b;
    }

    public boolean hasEdgeToward(String id) {
      boolean b;

      elementLock.lock();
      b = wrappedElement.hasEdgeToward(id);
      elementLock.unlock();

      return b;
    }

    public boolean hasEdgeToward(Node node) {
      boolean b;

      elementLock.lock();
      b = wrappedElement.hasEdgeToward(node);
      elementLock.unlock();

      return b;
    }

    public boolean hasEdgeToward(int index) {
      boolean b;

      elementLock.lock();
      b = wrappedElement.hasEdgeToward(index);
      elementLock.unlock();

      return b;
    }

    public Iterator<Edge> iterator() {
      return getEdgeSet().iterator();
    }
  }

  static class SynchronizedEdge extends SynchronizedElement<Edge> implements
      Edge {

    final SynchronizedGraph sg;

    SynchronizedEdge(SynchronizedGraph sg, Edge e) {
      super(e);
      this.sg = sg;
    }

    public <T extends Node> T getNode0() {
      T n;

      sg.elementLock.lock();
      n = sg.getNode(wrappedElement.getNode0().getIndex());
      sg.elementLock.unlock();

      return n;
    }

    public <T extends Node> T getNode1() {
      T n;

      sg.elementLock.lock();
      n = sg.getNode(wrappedElement.getNode1().getIndex());
      sg.elementLock.unlock();

      return n;
    }

    public <T extends Node> T getOpposite(Node node) {
      T n;

      if (node instanceof SynchronizedNode)
        node = ((SynchronizedNode) node).wrappedElement;

      sg.elementLock.lock();
      n = sg.getNode(wrappedElement.getOpposite(node).getIndex());
      sg.elementLock.unlock();

      return n;
    }

    public <T extends Node> T getSourceNode() {
      T n;

      sg.elementLock.lock();
      n = sg.getNode(wrappedElement.getSourceNode().getIndex());
      sg.elementLock.unlock();

      return n;
    }

    public <T extends Node> T getTargetNode() {
      T n;

      sg.elementLock.lock();
      n = sg.getNode(wrappedElement.getTargetNode().getIndex());
      sg.elementLock.unlock();

      return n;
    }

    public boolean isDirected() {
      return wrappedElement.isDirected();
    }

    public boolean isLoop() {
      return wrappedElement.isLoop();
    }
  }
}
TOP

Related Classes of org.graphstream.graph.implementations.Graphs$SynchronizedEdge

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.