Package org.graphstream.stream.thread

Source Code of org.graphstream.stream.thread.ThreadProxyPipeOld

/*
* 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.stream.thread;

import org.graphstream.graph.Edge;
import org.graphstream.graph.Graph;
import org.graphstream.graph.Node;
import org.graphstream.stream.ProxyPipe;
import org.graphstream.stream.Sink;
import org.graphstream.stream.Source;
import org.graphstream.stream.SourceBase;
import org.miv.mbox.CannotPostException;
import org.miv.mbox.MBox;
import org.miv.mbox.MBoxListener;
import org.miv.mbox.MBoxStandalone;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Filter that allows to pass graph events between two threads without explicit
* synchronization.
*
* <p>
* This filter allows to register it as an output for some source of events in a
* source thread (hereafter called the input thread) and to register listening
* outputs in a destination thread (hereafter called the sink thread).
* </p>
*
* <pre>
*                       |
*   Source ---> ThreadProxyFilter ----> Sink
*  Thread 1             |              Thread 2
*                       |
* </pre>
*
* <p>
* In other words, this class allows to listen in a sink thread graph events
* that are produced in another source thread without any explicit
* synchronization on the source of events.
* </p>
*
* <p>
* The only restriction is that the sink thread must regularly call the
* {@link #pump()} method to dispatch events coming from the source to all sinks
* registered (see the explanation in {@link org.graphstream.stream.ProxyPipe}).
* </p>
*
* <p>
* You can register any kind of input as source of event, but if the input is a
* graph, then you can choose to "replay" all the content of the graph so that
* at the other end of the filter, all outputs receive the complete content of
* the graph. This is the default behavior if this filter is constructed with a
* graph as input.
* </p>
*
* @deprecated This is the old version of
*             {@link org.graphstream.stream.thread.ThreadProxyPipe}.
*/
@Deprecated
public class ThreadProxyPipeOld extends SourceBase implements ProxyPipe, MBoxListener {

    /**
     * class level logger
     */
    private static final Logger logger = Logger.getLogger(ThreadProxyPipe.class.getSimpleName());

  /**
   * Proxy id.
   */
  protected String id;

  /**
   * The event sender name, usually the graph name.
   */
  protected String from;

  /**
   * The message box used to exchange messages between the two threads.
   */
  protected MBox events;

  /**
   * Used only to remove the listener. We ensure this is done in the source
   * thread.
   */
  protected Source input;

  /**
   * Signals that this proxy must be removed from the source input.
   */
  protected boolean unregisterWhenPossible = false;

  /**
   * New thread proxy pipe with no input.
   */
  public ThreadProxyPipeOld() {
    this((Source) null);
  }

  /**
   * Listen at an input in a given thread and redirect all events to
   * GraphListeners that may be in another thread.
   *
   * @param input
   *            The source of graph events we listen at.
   */
  public ThreadProxyPipeOld(Source input) {
    this(input, new MBoxStandalone());
  }

  /**
   * Like {@link #ThreadProxyPipe(Source)}, but allow to share the message box
   * with another message processor. This can be needed to share the same
   * message stack, when message order is important.
   *
   * @param input
   *            The source of events we listen at.
   * @param sharedMBox
   *            The message box used to send and receive graph messages across
   *            the thread boundary.
   */
  public ThreadProxyPipeOld(Source input, MBox sharedMBox) {
    this.events = sharedMBox;
    this.from = "<in>";
    this.input = input;

    if (input != null)
      input.addSink(this);

    ((MBoxStandalone) this.events).addListener(this);
  }

  /**
   * Listen at an input graph in a given thread and redirect all events to
   * GraphListeners that may be in another thread. By default, if the graph
   * already contains some elements, they are "replayed". This means that
   * events are sent to mimic the fact they just appeared.
   *
   * @param inputGraph
   *            The graph we listen at.
   */
  public ThreadProxyPipeOld(Graph inputGraph) {
    this(inputGraph, true);
  }

  /**
   * Like {@link #ThreadProxyPipe(Graph)} but allow to avoid replaying the
   * graph.
   *
   * @param inputGraph
   *            The graph we listen at.
   * @param replayGraph
   *            If false, and if the input graph already contains element they
   *            are not replayed.
   */
  public ThreadProxyPipeOld(Graph inputGraph, boolean replayGraph) {
    this(inputGraph, null, replayGraph);
  }

  /**
   * Like {@link #ThreadProxyPipe(Graph,boolean)} but allows to pass an
   * initial listener, therefore specifying the input and output at once.
   *
   * @param inputGraph
   *            The graph we listen at.
   * @param firstListener
   *            The initial listener to register.
   * @param replayGraph
   *            If false, and if the input graph already contains element they
   *            are not replayed.
   */
  public ThreadProxyPipeOld(Graph inputGraph, Sink firstListener,
      boolean replayGraph) {
    this(inputGraph, firstListener, replayGraph, new MBoxStandalone());
  }

  /**
   * Like {@link #ThreadProxyPipe(Graph,Sink,boolean)}, but allows to share
   * the message box with another message processor. This can be needed to
   * share the same message stack, when message order is important.
   *
   * @param inputGraph
   *            The graph we listen at.
   * @param replayGraph
   *            If false, and if the input graph already contains element they
   *            are not replayed.
   * @param sharedMBox
   *            The message box used to send and receive graph messages across
   *            the thread boundary.
   */
  public ThreadProxyPipeOld(Graph inputGraph, Sink firstListener,
      boolean replayGraph, MBox sharedMBox) {
    this.events = sharedMBox;
    this.from = inputGraph.getId();
    this.input = inputGraph;

    if (firstListener != null)
      addSink(firstListener);

    if (replayGraph)
      replayGraph(inputGraph);

    input.addSink(this);
    ((MBoxStandalone) this.events).addListener(this);
  }

  @Override
  public String toString() {
    String dest = "nil";

    if (attrSinks.size() > 0)
      dest = attrSinks.get(0).toString();

    return String.format("thread-proxy(from %s to %s)", from, dest);
  }

  /**
   * Ask the proxy to unregister from the event input source (stop receive
   * events) as soon as possible (when the next event will occur in the
   * graph).
   */
  public void unregisterFromSource() {
    unregisterWhenPossible = true;
  }

  /**
   * This method must be called regularly in the output thread to check if the
   * input source sent events. If some event occurred, the listeners will be
   * called.
   */
  public void pump() {
    ((MBoxStandalone) events).processMessages();
  }

  /*
   * (non-Javadoc)
   *
   * @see org.graphstream.stream.ProxyPipe#blockingPump()
   */
  public void blockingPump() throws InterruptedException {
    throw new UnsupportedOperationException();
  }

  /*
   * (non-Javadoc)
   *
   * @see org.graphstream.stream.ProxyPipe#blockingPump(long)
   */
  public void blockingPump(long timeout) throws InterruptedException {
    throw new UnsupportedOperationException();
  }

  /**
   * Set of events sent via the message box.
   */
  protected static enum GraphEvents {
    ADD_NODE, DEL_NODE, ADD_EDGE, DEL_EDGE, STEP, CLEARED, ADD_GRAPH_ATTR, CHG_GRAPH_ATTR, DEL_GRAPH_ATTR, ADD_NODE_ATTR, CHG_NODE_ATTR, DEL_NODE_ATTR, ADD_EDGE_ATTR, CHG_EDGE_ATTR, DEL_EDGE_ATTR
  };

  protected void replayGraph(Graph graph) {
    try {
      String graphId = "@replay";

      // Replay all graph attributes.

      if (graph.getAttributeKeySet() != null)
        for (String key : graph.getAttributeKeySet())
          events.post(from, GraphEvents.ADD_GRAPH_ATTR, graphId,
              sourceTime.newEvent(), key, graph.getAttribute(key));

      Thread.yield();

      // Replay all nodes and their attributes.

      for (Node node : graph) {
        events.post(from, GraphEvents.ADD_NODE, graphId,
            sourceTime.newEvent(), node.getId());

        if (node.getAttributeKeySet() != null)
          for (String key : node.getAttributeKeySet())
            events.post(from, GraphEvents.ADD_NODE_ATTR, graphId,
                sourceTime.newEvent(), node.getId(), key,
                node.getAttribute(key));
        Thread.yield();
      }

      // Replay all edges and their attributes.

      for (Edge edge : graph.getEachEdge()) {
        events.post(from, GraphEvents.ADD_EDGE, graphId, sourceTime
            .newEvent(), edge.getId(),
            edge.getSourceNode().getId(), edge.getTargetNode()
                .getId(), edge.isDirected());

        if (edge.getAttributeKeySet() != null)
          for (String key : edge.getAttributeKeySet())
            events.post(from, GraphEvents.ADD_EDGE_ATTR, graphId,
                sourceTime.newEvent(), edge.getId(), key,
                edge.getAttribute(key));
        Thread.yield();
      }
    } catch (CannotPostException e) {
            logger.log(Level.WARNING, "Unable to post message to listeners.", e);
    }
  }

  protected boolean maybeUnregister() {
    if (unregisterWhenPossible) {
      if (input != null)
        input.removeSink(this);
      return true;
    }

    return false;
  }

  public void edgeAttributeAdded(String graphId, long timeId, String edgeId,
      String attribute, Object value) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.ADD_EDGE_ATTR, graphId, timeId,
          edgeId, attribute, value);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  public void edgeAttributeChanged(String graphId, long timeId,
      String edgeId, String attribute, Object oldValue, Object newValue) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.CHG_EDGE_ATTR, graphId, timeId,
          edgeId, attribute, oldValue, newValue);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  public void edgeAttributeRemoved(String graphId, long timeId,
      String edgeId, String attribute) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.DEL_EDGE_ATTR, graphId, timeId,
          edgeId, attribute);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  public void graphAttributeAdded(String graphId, long timeId,
      String attribute, Object value) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.ADD_GRAPH_ATTR, graphId, timeId,
          attribute, value);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  public void graphAttributeChanged(String graphId, long timeId,
      String attribute, Object oldValue, Object newValue) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.CHG_GRAPH_ATTR, graphId, timeId,
          attribute, oldValue, newValue);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  public void graphAttributeRemoved(String graphId, long timeId,
      String attribute) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.DEL_GRAPH_ATTR, graphId, timeId,
          attribute);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  public void nodeAttributeAdded(String graphId, long timeId, String nodeId,
      String attribute, Object value) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.ADD_NODE_ATTR, graphId, timeId,
          nodeId, attribute, value);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  public void nodeAttributeChanged(String graphId, long timeId,
      String nodeId, String attribute, Object oldValue, Object newValue) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.CHG_NODE_ATTR, graphId, timeId,
          nodeId, attribute, oldValue, newValue);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  public void nodeAttributeRemoved(String graphId, long timeId,
      String nodeId, String attribute) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.DEL_NODE_ATTR, graphId, timeId,
          nodeId, attribute);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  public void edgeAdded(String graphId, long timeId, String edgeId,
      String fromNodeId, String toNodeId, boolean directed) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.ADD_EDGE, graphId, timeId, edgeId,
          fromNodeId, toNodeId, directed);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  public void edgeRemoved(String graphId, long timeId, String edgeId) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.DEL_EDGE, graphId, timeId, edgeId);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  public void graphCleared(String graphId, long timeId) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.CLEARED, graphId, timeId);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  public void nodeAdded(String graphId, long timeId, String nodeId) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.ADD_NODE, graphId, timeId, nodeId);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  public void nodeRemoved(String graphId, long timeId, String nodeId) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.DEL_NODE, graphId, timeId, nodeId);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  public void stepBegins(String graphId, long timeId, double step) {
    if (maybeUnregister())
      return;

    try {
      events.post(from, GraphEvents.STEP, graphId, timeId, step);
    } catch (CannotPostException e) {
      e.printStackTrace();
    }
  }

  // MBoxListener

  public void processMessage(String from, Object[] data) {
    if (data[0].equals(GraphEvents.ADD_NODE)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];
      String nodeId = (String) data[3];

      sendNodeAdded(graphId, timeId, nodeId);
    } else if (data[0].equals(GraphEvents.DEL_NODE)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];
      String nodeId = (String) data[3];

      sendNodeRemoved(graphId, timeId, nodeId);
    } else if (data[0].equals(GraphEvents.ADD_EDGE)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];
      String edgeId = (String) data[3];
      String fromId = (String) data[4];
      String toId = (String) data[5];
      boolean directed = (Boolean) data[6];

      sendEdgeAdded(graphId, timeId, edgeId, fromId, toId, directed);
    } else if (data[0].equals(GraphEvents.DEL_EDGE)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];
      String edgeId = (String) data[3];

      sendEdgeRemoved(graphId, timeId, edgeId);
    } else if (data[0].equals(GraphEvents.STEP)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];
      double step = (Double) data[3];

      sendStepBegins(graphId, timeId, step);
    } else if (data[0].equals(GraphEvents.ADD_GRAPH_ATTR)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];
      String attribute = (String) data[3];
      Object value = data[4];

      sendGraphAttributeAdded(graphId, timeId, attribute, value);
    } else if (data[0].equals(GraphEvents.CHG_GRAPH_ATTR)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];
      String attribute = (String) data[3];
      Object oldValue = data[4];
      Object newValue = data[5];

      sendGraphAttributeChanged(graphId, timeId, attribute, oldValue,
          newValue);
    } else if (data[0].equals(GraphEvents.DEL_GRAPH_ATTR)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];
      String attribute = (String) data[3];

      sendGraphAttributeRemoved(graphId, timeId, attribute);
    } else if (data[0].equals(GraphEvents.ADD_EDGE_ATTR)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];
      String edgeId = (String) data[3];
      String attribute = (String) data[4];
      Object value = data[5];

      sendEdgeAttributeAdded(graphId, timeId, edgeId, attribute, value);
    } else if (data[0].equals(GraphEvents.CHG_EDGE_ATTR)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];
      String edgeId = (String) data[3];
      String attribute = (String) data[4];
      Object oldValue = data[5];
      Object newValue = data[6];

      sendEdgeAttributeChanged(graphId, timeId, edgeId, attribute,
          oldValue, newValue);
    } else if (data[0].equals(GraphEvents.DEL_EDGE_ATTR)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];
      String edgeId = (String) data[3];
      String attribute = (String) data[4];

      sendEdgeAttributeRemoved(graphId, timeId, edgeId, attribute);
    } else if (data[0].equals(GraphEvents.ADD_NODE_ATTR)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];
      String nodeId = (String) data[3];
      String attribute = (String) data[4];
      Object value = data[5];

      sendNodeAttributeAdded(graphId, timeId, nodeId, attribute, value);
    } else if (data[0].equals(GraphEvents.CHG_NODE_ATTR)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];
      String nodeId = (String) data[3];
      String attribute = (String) data[4];
      Object oldValue = data[5];
      Object newValue = data[6];

      sendNodeAttributeChanged(graphId, timeId, nodeId, attribute,
          oldValue, newValue);
    } else if (data[0].equals(GraphEvents.DEL_NODE_ATTR)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];
      String nodeId = (String) data[3];
      String attribute = (String) data[4];

      sendNodeAttributeRemoved(graphId, timeId, nodeId, attribute);
    } else if (data[0].equals(GraphEvents.CLEARED)) {
      String graphId = (String) data[1];
      Long timeId = (Long) data[2];

      sendGraphCleared(graphId, timeId);
    } else {
            logger.warning(String.format("Unknown message %s.", data[0]));
    }
  }
}
TOP

Related Classes of org.graphstream.stream.thread.ThreadProxyPipeOld

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.