Package org.graphstream.util

Source Code of org.graphstream.util.GraphDiff$AttributeAdded

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

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.LinkedList;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import org.graphstream.graph.Edge;
import org.graphstream.graph.Element;
import org.graphstream.graph.ElementNotFoundException;
import org.graphstream.graph.Graph;
import org.graphstream.graph.Node;
import org.graphstream.graph.implementations.AdjacencyListGraph;
import org.graphstream.stream.Sink;
import org.graphstream.stream.file.FileSinkDGS;
import org.graphstream.stream.file.FileSourceDGS;

public class GraphDiff {
  protected static enum ElementType {
    NODE, EDGE, GRAPH
  }

  private Bridge bridge;
  private final LinkedList<Event> events;

  /**
   * Create a new empty diff.
   */
  public GraphDiff() {
    this.events = new LinkedList<Event>();
    this.bridge = null;
  }

  /**
   * Create a diff between two graphs.
   *
   * @param g1
   * @param g2
   */
  public GraphDiff(Graph g1, Graph g2) {
    this();

    if (g2.getNodeCount() == 0 && g2.getEdgeCount() == 0
        && g2.getAttributeCount() == 0
        && (g1.getNodeCount() > 0 || g1.getEdgeCount() > 0)) {
      events.add(new GraphCleared(g1));
    } else {
      for (int idx = 0; idx < g2.getNodeCount(); idx++) {
        Node n2 = g2.getNode(idx);
        Node n1 = g1.getNode(n2.getId());

        if (n1 == null)
          events.add(new NodeAdded(n2.getId()));

        attributeDiff(ElementType.NODE, n1, n2);
      }

      for (int idx = 0; idx < g1.getNodeCount(); idx++) {
        Node n1 = g1.getNode(idx);
        Node n2 = g2.getNode(n1.getId());

        if (n2 == null) {
          attributeDiff(ElementType.NODE, n1, n2);
          events.add(new NodeRemoved(n1.getId()));
        }
      }

      for (int idx = 0; idx < g2.getEdgeCount(); idx++) {
        Edge e2 = g2.getEdge(idx);
        Edge e1 = g1.getEdge(e2.getId());

        if (e1 == null)
          events.add(new EdgeAdded(e2.getId(), e2.getSourceNode()
              .getId(), e2.getTargetNode().getId(), e2
              .isDirected()));

        attributeDiff(ElementType.EDGE, e1, e2);
      }

      for (int idx = 0; idx < g1.getEdgeCount(); idx++) {
        Edge e1 = g1.getEdge(idx);
        Edge e2 = g2.getEdge(e1.getId());

        if (e2 == null) {
          attributeDiff(ElementType.EDGE, e1, e2);
          events.add(new EdgeRemoved(e1.getId(), e1.getSourceNode()
              .getId(), e1.getTargetNode().getId(), e1
              .isDirected()));
        }
      }

      attributeDiff(ElementType.GRAPH, g1, g2);
    }
  }

  /**
   * Start to record changes. If a record is already started, then it will be
   * ended.
   *
   * @param g
   *            the graph to start listening for changes.
   */
  public void start(Graph g) {
    if (bridge != null)
      end();

    bridge = new Bridge(g);
  }

  /**
   * Stop to record changes. If there is no record, calling this method has no
   * effect.
   */
  public void end() {
    if (bridge != null) {
      bridge.end();
      bridge = null;
    }
  }

  /**
   * Clear all recorded changes.
   */
  public void reset() {
    events.clear();
  }

  /**
   * Considering this object is a diff between g1 and g2, calling this method
   * will applied changes on g1 such that g1 will look like g2.
   *
   * @param g1
   */
  public void apply(Sink g1) {
    String sourceId = String.format("GraphDiff@%x", System.nanoTime());
    apply(sourceId, g1);
  }

  public void apply(String sourceId, Sink g1) {
    for (int i = 0; i < events.size(); i++)
      events.get(i).apply(sourceId, i, g1);
  }

  /**
   * Considering this object is a diff between g1 and g2, calling this method
   * will applied changes on g2 such that g2 will look like g1.
   *
   * @param g2
   */
  public void reverse(Sink g2) {
    String sourceId = String.format("GraphDiff@%x", System.nanoTime());
    reverse(sourceId, g2);
  }

  public void reverse(String sourceId, Sink g2) {
    for (int i = events.size() - 1; i >= 0; i--)
      events.get(i).reverse(sourceId, events.size() + 1 - i, g2);
  }

  private void attributeDiff(ElementType type, Element e1, Element e2) {
    if (e1 == null && e2 == null)
      return;
    else if (e1 == null) {
      for (String key : e2.getAttributeKeySet())
        events.add(new AttributeAdded(type, e2.getId(), key, e2
            .getAttribute(key)));
    } else if (e2 == null) {
      for (String key : e1.getAttributeKeySet())
        events.add(new AttributeRemoved(type, e1.getId(), key, e1
            .getAttribute(key)));
    } else {
      for (String key : e2.getAttributeKeySet()) {
        if (e1.hasAttribute(key)) {
          Object o1 = e1.getAttribute(key);
          Object o2 = e2.getAttribute(key);

          if (!(o1 == null ? o2 == null : o1.equals(o2)))
            events.add(new AttributeChanged(type, e1.getId(), key,
                o2, o1));
        } else
          events.add(new AttributeAdded(type, e1.getId(), key, e2
              .getAttribute(key)));
      }

      for (String key : e1.getAttributeKeySet()) {
        if (!e2.hasAttribute(key))
          events.add(new AttributeRemoved(type, e1.getId(), key, e1
              .getAttribute(key)));
      }
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString() {
    StringBuilder buffer = new StringBuilder();

    for (int i = 0; i < events.size(); i++)
      buffer.append(events.get(i).toString()).append("\n");

    return buffer.toString();
  }

  protected abstract class Event {
    /**
     * Apply this event on a given graph.
     *
     * @param g
     *            the graph on which the action should be applied
     */
    abstract void apply(String sourceId, long timeId, Sink g);

    /**
     * Apply the dual event on a given graph.
     *
     * @param g
     *            the graph on which the dual action should be applied.
     */
    abstract void reverse(String sourceId, long timeId, Sink g);
  }

  protected class NodeAdded extends Event {
    String nodeId;

    public NodeAdded(String nodeId) {
      this.nodeId = nodeId;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.Event#apply(org.graphstream.graph.
     * Graph)
     */
    public void apply(String sourceId, long timeId, Sink g) {
      g.nodeAdded(sourceId, timeId, nodeId);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.Event#reverse(org.graphstream.graph
     * .Graph)
     */
    public void reverse(String sourceId, long timeId, Sink g) {
      g.nodeRemoved(sourceId, timeId, nodeId);
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
      return String.format("an \"%s\"", nodeId);
    }
  }

  protected class NodeRemoved extends NodeAdded {
    public NodeRemoved(String nodeId) {
      super(nodeId);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.NodeAdded#apply(org.graphstream.graph
     * .Graph)
     */
    public void apply(String sourceId, long timeId, Sink g) {
      super.reverse(sourceId, timeId, g);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.NodeAdded#reverse(org.graphstream.
     * graph.Graph)
     */
    public void reverse(String sourceId, long timeId, Sink g) {
      super.apply(sourceId, timeId, g);
    }

    /*
     * (non-Javadoc)
     *
     * @see org.graphstream.util.GraphDiff.NodeAdded#toString()
     */
    @Override
    public String toString() {
      return String.format("dn \"%s\"", nodeId);
    }
  }

  protected abstract class ElementEvent extends Event {
    ElementType type;
    String elementId;

    protected ElementEvent(ElementType type, String elementId) {
      this.type = type;
      this.elementId = elementId;
    }

    protected Element getElement(Graph g) {
      Element e;

      switch (type) {
      case NODE:
        e = g.getNode(elementId);
        break;
      case EDGE:
        e = g.getEdge(elementId);
        break;
      case GRAPH:
        e = g;
        break;
      default:
        e = null;
      }

      if (e == null)
        throw new ElementNotFoundException();

      return e;
    }

    protected String toStringHeader() {
      String header;

      switch (type) {
      case NODE:
        header = "cn";
        break;
      case EDGE:
        header = "ce";
        break;
      case GRAPH:
        header = "cg";
        break;
      default:
        header = "??";
        break;
      }

      return String.format("%s \"%s\"", header, elementId);
    }

    protected String toStringValue(Object o) {
      if (o == null)
        return "null";
      else if (o instanceof String)
        return "\"" + o.toString() + "\"";
      else if (o instanceof Number)
        return o.toString();
      else
        return o.toString();
    }
  }

  protected class AttributeAdded extends ElementEvent {
    String attrId;
    Object value;

    public AttributeAdded(ElementType type, String elementId,
        String attrId, Object value) {
      super(type, elementId);

      this.attrId = attrId;
      this.value = value;

      if (value != null && value.getClass().isArray()
          && Array.getLength(value) > 0) {
        Object o = Array.newInstance(Array.get(value, 0).getClass(),
            Array.getLength(value));

        for (int i = 0; i < Array.getLength(value); i++)
          Array.set(o, i, Array.get(value, i));

        this.value = o;
      }
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.Event#apply(org.graphstream.graph.
     * Graph)
     */
    public void apply(String sourceId, long timeId, Sink g) {
      switch (type) {
      case NODE:
        g.nodeAttributeAdded(sourceId, timeId, elementId, attrId, value);
        break;
      case EDGE:
        g.edgeAttributeAdded(sourceId, timeId, elementId, attrId, value);
        break;
      case GRAPH:
        g.graphAttributeAdded(sourceId, timeId, attrId, value);
        break;
      }
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.Event#reverse(org.graphstream.graph
     * .Graph)
     */
    public void reverse(String sourceId, long timeId, Sink g) {
      switch (type) {
      case NODE:
        g.nodeAttributeRemoved(sourceId, timeId, elementId, attrId);
        break;
      case EDGE:
        g.edgeAttributeRemoved(sourceId, timeId, elementId, attrId);
        break;
      case GRAPH:
        g.graphAttributeRemoved(sourceId, timeId, attrId);
        break;
      }
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
      return String.format("%s +\"%s\":%s", toStringHeader(), attrId,
          toStringValue(value));
    }
  }

  protected class AttributeChanged extends ElementEvent {
    String attrId;
    Object newValue;
    Object oldValue;

    public AttributeChanged(ElementType type, String elementId,
        String attrId, Object newValue, Object oldValue) {
      super(type, elementId);

      this.attrId = attrId;
      this.newValue = newValue;
      this.oldValue = oldValue;

      if (newValue != null && newValue.getClass().isArray()
          && Array.getLength(newValue) > 0) {
        Object o = Array.newInstance(Array.get(newValue, 0).getClass(),
            Array.getLength(newValue));

        for (int i = 0; i < Array.getLength(newValue); i++)
          Array.set(o, i, Array.get(newValue, i));

        this.newValue = o;
      }

      if (oldValue != null && oldValue.getClass().isArray()
          && Array.getLength(oldValue) > 0) {
        Object o = Array.newInstance(Array.get(oldValue, 0).getClass(),
            Array.getLength(oldValue));

        for (int i = 0; i < Array.getLength(oldValue); i++)
          Array.set(o, i, Array.get(oldValue, i));

        this.oldValue = o;
      }
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.Event#apply(org.graphstream.graph.
     * Graph)
     */
    public void apply(String sourceId, long timeId, Sink g) {
      switch (type) {
      case NODE:
        g.nodeAttributeChanged(sourceId, timeId, elementId, attrId,
            oldValue, newValue);
        break;
      case EDGE:
        g.edgeAttributeChanged(sourceId, timeId, elementId, attrId,
            oldValue, newValue);
        break;
      case GRAPH:
        g.graphAttributeChanged(sourceId, timeId, attrId, oldValue,
            newValue);
        break;
      }
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.Event#reverse(org.graphstream.graph
     * .Graph)
     */
    public void reverse(String sourceId, long timeId, Sink g) {
      switch (type) {
      case NODE:
        g.nodeAttributeChanged(sourceId, timeId, elementId, attrId,
            newValue, oldValue);
        break;
      case EDGE:
        g.edgeAttributeChanged(sourceId, timeId, elementId, attrId,
            newValue, oldValue);
        break;
      case GRAPH:
        g.graphAttributeChanged(sourceId, timeId, attrId, newValue,
            oldValue);
        break;
      }
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
      return String.format("%s \"%s\":%s", toStringHeader(), attrId,
          toStringValue(newValue));
    }
  }

  protected class AttributeRemoved extends ElementEvent {
    String attrId;
    Object oldValue;

    public AttributeRemoved(ElementType type, String elementId,
        String attrId, Object oldValue) {
      super(type, elementId);

      this.attrId = attrId;
      this.oldValue = oldValue;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.Event#apply(org.graphstream.graph.
     * Graph)
     */
    public void apply(String sourceId, long timeId, Sink g) {
      switch (type) {
      case NODE:
        g.nodeAttributeRemoved(sourceId, timeId, elementId, attrId);
        break;
      case EDGE:
        g.edgeAttributeRemoved(sourceId, timeId, elementId, attrId);
        break;
      case GRAPH:
        g.graphAttributeRemoved(sourceId, timeId, attrId);
        break;
      }
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.Event#reverse(org.graphstream.graph
     * .Graph)
     */
    public void reverse(String sourceId, long timeId, Sink g) {
      switch (type) {
      case NODE:
        g.nodeAttributeAdded(sourceId, timeId, elementId, attrId,
            oldValue);
        break;
      case EDGE:
        g.edgeAttributeAdded(sourceId, timeId, elementId, attrId,
            oldValue);
        break;
      case GRAPH:
        g.graphAttributeAdded(sourceId, timeId, attrId, oldValue);
        break;
      }
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
      return String.format("%s -\"%s\":%s", toStringHeader(), attrId,
          toStringValue(oldValue));
    }
  }

  protected class EdgeAdded extends Event {
    String edgeId;
    String source, target;
    boolean directed;

    public EdgeAdded(String edgeId, String source, String target,
        boolean directed) {
      this.edgeId = edgeId;
      this.source = source;
      this.target = target;
      this.directed = directed;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.Event#apply(org.graphstream.graph.
     * Graph)
     */
    public void apply(String sourceId, long timeId, Sink g) {
      g.edgeAdded(sourceId, timeId, edgeId, source, target, directed);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.Event#reverse(org.graphstream.graph
     * .Graph)
     */
    public void reverse(String sourceId, long timeId, Sink g) {
      g.edgeRemoved(sourceId, timeId, edgeId);
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
      return String.format("ae \"%s\" \"%s\" %s \"%s\"", edgeId, source,
          directed ? ">" : "--", target);
    }
  }

  protected class EdgeRemoved extends EdgeAdded {
    public EdgeRemoved(String edgeId, String source, String target,
        boolean directed) {
      super(edgeId, source, target, directed);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.EdgeAdded#apply(org.graphstream.graph
     * .Graph)
     */
    public void apply(String sourceId, long timeId, Sink g) {
      super.reverse(sourceId, timeId, g);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.EdgeAdded#reverse(org.graphstream.
     * graph.Graph)
     */
    public void reverse(String sourceId, long timeId, Sink g) {
      super.apply(sourceId, timeId, g);
    }

    /*
     * (non-Javadoc)
     *
     * @see org.graphstream.util.GraphDiff.EdgeAdded#toString()
     */
    @Override
    public String toString() {
      return String.format("de \"%s\"", edgeId);
    }
  }

  protected class StepBegins extends Event {
    double newStep, oldStep;

    public StepBegins(double oldStep, double newStep) {
      this.newStep = newStep;
      this.oldStep = oldStep;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.Event#apply(org.graphstream.graph.
     * Graph)
     */
    public void apply(String sourceId, long timeId, Sink g) {
      g.stepBegins(sourceId, timeId, newStep);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.Event#reverse(org.graphstream.graph
     * .Graph)
     */
    public void reverse(String sourceId, long timeId, Sink g) {
      g.stepBegins(sourceId, timeId, oldStep);
    }

    @Override
    public String toString() {
      return String.format("st %f", newStep);
    }
  }

  protected class GraphCleared extends Event {
    byte[] data;

    public GraphCleared(Graph g) {
      this.data = null;

      try {
        FileSinkDGS sink = new FileSinkDGS();
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        GZIPOutputStream out = new GZIPOutputStream(bytes);

        sink.writeAll(g, out);
        out.flush();
        out.close();

        this.data = bytes.toByteArray();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.Event#apply(org.graphstream.graph.
     * Graph)
     */
    public void apply(String sourceId, long timeId, Sink g) {
      g.graphCleared(sourceId, timeId);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.util.GraphDiff.Event#reverse(org.graphstream.graph
     * .Graph)
     */
    public void reverse(String sourceId, long timeId, Sink g) {
      try {
        ByteArrayInputStream bytes = new ByteArrayInputStream(this.data);
        GZIPInputStream in = new GZIPInputStream(bytes);
        FileSourceDGS dgs = new FileSourceDGS();

        dgs.addSink(g);
        dgs.readAll(in);
        dgs.removeSink(g);

        in.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
      return "cl";
    }
  }

  private class Bridge implements Sink {
    Graph g;

    Bridge(Graph g) {

      this.g = g;
      g.addSink(this);
    }

    void end() {
      g.removeSink(this);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.stream.AttributeSink#graphAttributeAdded(java.lang
     * .String, long, java.lang.String, java.lang.Object)
     */
    public void graphAttributeAdded(String sourceId, long timeId,
        String attribute, Object value) {
      Event e;
      e = new AttributeAdded(ElementType.GRAPH, null, attribute, value);
      events.add(e);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.stream.AttributeSink#graphAttributeChanged(java.lang
     * .String, long, java.lang.String, java.lang.Object, java.lang.Object)
     */
    public void graphAttributeChanged(String sourceId, long timeId,
        String attribute, Object oldValue, Object newValue) {
      Event e;
      e = new AttributeChanged(ElementType.GRAPH, null, attribute,
          newValue, g.getAttribute(attribute));
      events.add(e);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.stream.AttributeSink#graphAttributeRemoved(java.lang
     * .String, long, java.lang.String)
     */
    public void graphAttributeRemoved(String sourceId, long timeId,
        String attribute) {
      Event e;
      e = new AttributeRemoved(ElementType.GRAPH, null, attribute,
          g.getAttribute(attribute));
      events.add(e);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.stream.AttributeSink#nodeAttributeAdded(java.lang
     * .String, long, java.lang.String, java.lang.String, java.lang.Object)
     */
    public void nodeAttributeAdded(String sourceId, long timeId,
        String nodeId, String attribute, Object value) {
      Event e;
      e = new AttributeAdded(ElementType.NODE, nodeId, attribute, value);
      events.add(e);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.stream.AttributeSink#nodeAttributeChanged(java.lang
     * .String, long, java.lang.String, java.lang.String, java.lang.Object,
     * java.lang.Object)
     */
    public void nodeAttributeChanged(String sourceId, long timeId,
        String nodeId, String attribute, Object oldValue,
        Object newValue) {
      Event e;
      e = new AttributeChanged(ElementType.NODE, nodeId, attribute,
          newValue, g.getNode(nodeId).getAttribute(attribute));
      events.add(e);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.stream.AttributeSink#nodeAttributeRemoved(java.lang
     * .String, long, java.lang.String, java.lang.String)
     */
    public void nodeAttributeRemoved(String sourceId, long timeId,
        String nodeId, String attribute) {
      Event e;
      e = new AttributeRemoved(ElementType.NODE, nodeId, attribute, g
          .getNode(nodeId).getAttribute(attribute));
      events.add(e);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.stream.AttributeSink#edgeAttributeAdded(java.lang
     * .String, long, java.lang.String, java.lang.String, java.lang.Object)
     */
    public void edgeAttributeAdded(String sourceId, long timeId,
        String edgeId, String attribute, Object value) {
      Event e;
      e = new AttributeAdded(ElementType.EDGE, edgeId, attribute, value);
      events.add(e);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.stream.AttributeSink#edgeAttributeChanged(java.lang
     * .String, long, java.lang.String, java.lang.String, java.lang.Object,
     * java.lang.Object)
     */
    public void edgeAttributeChanged(String sourceId, long timeId,
        String edgeId, String attribute, Object oldValue,
        Object newValue) {
      Event e;
      e = new AttributeChanged(ElementType.EDGE, edgeId, attribute,
          newValue, g.getEdge(edgeId).getAttribute(attribute));
      events.add(e);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.stream.AttributeSink#edgeAttributeRemoved(java.lang
     * .String, long, java.lang.String, java.lang.String)
     */
    public void edgeAttributeRemoved(String sourceId, long timeId,
        String edgeId, String attribute) {
      Event e;
      e = new AttributeRemoved(ElementType.EDGE, edgeId, attribute, g
          .getEdge(edgeId).getAttribute(attribute));
      events.add(e);
    }

    /*
     * (non-Javadoc)
     *
     * @see org.graphstream.stream.ElementSink#nodeAdded(java.lang.String,
     * long, java.lang.String)
     */
    public void nodeAdded(String sourceId, long timeId, String nodeId) {
      Event e;
      e = new NodeAdded(nodeId);
      events.add(e);
    }

    /*
     * (non-Javadoc)
     *
     * @see org.graphstream.stream.ElementSink#nodeRemoved(java.lang.String,
     * long, java.lang.String)
     */
    public void nodeRemoved(String sourceId, long timeId, String nodeId) {
      Node n = g.getNode(nodeId);

      for (String key : n.getAttributeKeySet())
        nodeAttributeRemoved(sourceId, timeId, nodeId, key);

      Event e;
      e = new NodeRemoved(nodeId);
      events.add(e);
    }

    /*
     * (non-Javadoc)
     *
     * @see org.graphstream.stream.ElementSink#edgeAdded(java.lang.String,
     * long, java.lang.String, java.lang.String, java.lang.String, boolean)
     */
    public void edgeAdded(String sourceId, long timeId, String edgeId,
        String fromNodeId, String toNodeId, boolean directed) {
      Event e;
      e = new EdgeAdded(edgeId, fromNodeId, toNodeId, directed);
      events.add(e);
    }

    /*
     * (non-Javadoc)
     *
     * @see org.graphstream.stream.ElementSink#edgeRemoved(java.lang.String,
     * long, java.lang.String)
     */
    public void edgeRemoved(String sourceId, long timeId, String edgeId) {
      Edge edge = g.getEdge(edgeId);

      for (String key : edge.getAttributeKeySet())
        edgeAttributeRemoved(sourceId, timeId, edgeId, key);

      Event e;
      e = new EdgeRemoved(edgeId, edge.getSourceNode().getId(), edge
          .getTargetNode().getId(), edge.isDirected());
      events.add(e);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.graphstream.stream.ElementSink#graphCleared(java.lang.String,
     * long)
     */
    public void graphCleared(String sourceId, long timeId) {
      Event e = new GraphCleared(g);
      events.add(e);
    }

    /*
     * (non-Javadoc)
     *
     * @see org.graphstream.stream.ElementSink#stepBegins(java.lang.String,
     * long, double)
     */
    public void stepBegins(String sourceId, long timeId, double step) {
      Event e = new StepBegins(g.getStep(), step);
      events.add(e);
    }
  }

  public static void main(String... args) throws Exception {
    Graph g1 = new AdjacencyListGraph("g1");
    Graph g2 = new AdjacencyListGraph("g2");

    Node a1 = g1.addNode("A");
    a1.addAttribute("attr1", "test");
    a1.addAttribute("attr2", 10.0);
    a1.addAttribute("attr3", 12);

    Node a2 = g2.addNode("A");
    a2.addAttribute("attr1", "test1");
    a2.addAttribute("attr2", 10.0);
    g2.addNode("B");
    g2.addNode("C");

    GraphDiff diff = new GraphDiff(g2, g1);
    System.out.println(diff);
  }
}
TOP

Related Classes of org.graphstream.util.GraphDiff$AttributeAdded

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.