All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.graphstream.graph.Graph Maven / Gradle / Ivy

Go to download

The GraphStream library. With GraphStream you deal with graphs. Static and Dynamic. You create them from scratch, from a file or any source. You display and render them. This is the core package that contains the minimal needed to read and write a graph.

There is a newer version: 2.0
Show newest version
/*
 * Copyright 2006 - 2011 
 *     Julien Baudry	
 *     Antoine Dutot	
 *     Yoann Pigné		
 *     Guilhelm Savin	
 * 
 * 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.
 */
package org.graphstream.graph;

import java.io.IOException;
import java.util.Iterator;
import java.util.Collection;

import org.graphstream.stream.AttributeSink;
import org.graphstream.stream.ElementSink;
import org.graphstream.stream.GraphParseException;
import org.graphstream.stream.Pipe;
import org.graphstream.stream.file.FileSink;
import org.graphstream.stream.file.FileSource;

/**
 * An Interface that advises general purpose methods for handling graphs.
 * 
 * 

* This interface is one of the main interfaces of GraphStream. It defines the * services provided by a graph structure. Graphs implementations must at least * implement this interface (but are free to provide more services). *

* *

* With {@link org.graphstream.stream.Source}, * {@link org.graphstream.stream.Sink} and {@link org.graphstream.stream.Pipe}, * this interface is one of the most important. A graph is a * {@link org.graphstream.stream.Pipe} that buffers the graph events and present * the graph structure as it is actually. *

* *

* In other words, it allows to browse the graph structure, to explore it, to * modify it, and to implement algorithms on it. This class can be seen as a * snapshot of a stream of event at current time. *

* *

* With factories ({@link org.graphstream.graph.NodeFactory}, * {@link org.graphstream.graph.EdgeFactory}), users can define their own models * of nodes or edges. Problem is that when you define such model, you want to * access to elements with the valid type, without cast if possible. To improve * the access to elements in such cases, Graph offers implicit genericity to * access nodes or edges. The following is an example of an access without * genericity : * *

 * 	Graph g = ... ;
 * 	g.setNodeFactory( new MyNodeFactory() );
 *  g.addNode("root");
 *  
 *  MyNode n = (MyNode) g.getNode("root");
 *  
 *  for( Node o : g.getEachNode() )
 *  {
 *  	MyNode node = (MyNode) o;
 *  	// Do something with node
 *  }
 * 
* * With implicit genericity offers by Graph, this can be done easier: * *
 *  Graph g = ... ;
 * 	g.setNodeFactory( new MyNodeFactory() );
 *  g.addNode("root");
 *  
 *  MyNode n = g.getNode("root");
 *  
 *  for( MyNode node : g.getEachNode() )
 *  {
 *  	// Do something with node
 *  }
 * 
* *

*/ public interface Graph extends Element, Pipe, Iterable { // Access /** * Get a node by its identifier. This method is implicitly generic and * return something which extends Node. The return type is the one of the * left part of the assignment. For example, in the following call : * *
	 * ExtendedNode node = graph.getNode("...");
	 * 
* * the method will return an ExtendedNode node. If no left part exists, * method will just return a Node. * * @param id * Identifier of the node to find. * @return The searched node or null if not found. */ T getNode(String id); /** * Get an edge by its identifier. This method is implicitly generic and * return something which extends Edge. The return type is the one of the * left part of the assignment. For example, in the following call : * *
	 * ExtendedEdge edge = graph.getEdge("...");
	 * 
* * the method will return an ExtendedEdge edge. If no left part exists, * method will just return an Edge. * * @param id * Identifier of the edge to find. * @return The searched edge or null if not found. */ T getEdge(String id); /** * Number of nodes in this graph. * * @return The number of nodes. */ int getNodeCount(); /** * Number of edges in this graph. * * @return The number of edges. */ int getEdgeCount(); /** * Iterator on the set of nodes, in an undefined order. This method is * implicitly generic and return an Iterator over something which extends * Node. The return type is the one of the left part of the assignment. For * example, in the following call : * *
	 * Iterator<ExtendedNode> ite = graph.getNodeIterator();
	 * 
* * the method will return an Iterator<ExtendedNode>. If no left part * exists, method will just return an Iterator<Node>. * * @return The iterator. */ Iterator getNodeIterator(); /** * Iterator on the set of edges, in an undefined order. This method is * implicitly generic and return an Iterator over something which extends * Edge. The return type is the one of the left part of the assignment. For * example, in the following call : * *
	 * Iterator<ExtendedEdge> ite = graph.getEdgeIterator();
	 * 
* * the method will return an Iterator<ExtendedEdge>. If no left part * exists, method will just return an Iterator<Edge>. * * @return The iterator. */ Iterator getEdgeIterator(); /** * Set of nodes usable in a for-each instruction. This method is implicitly * generic and return an Iterable over something which extends Node. The * return type is the one of the left part of the assignment. For example, * in the following call : * *
	 * Iterable<ExtendedNode> ite = graph.getEachNode();
	 * 
* * the method will return an Iterable<ExtendedNode>. If no left part * exists, method will just return an Iterable<Node>. It is possible * to use it in a for-each loop by giving the parameter : * *
	 * for (ExtendedNode n : graph.<ExtendedNode> getEachNode()) {
	 * 	// ...
	 * }
	 * 
* * @return An "iterable" view of the set of nodes. * @see #getNodeIterator() * @see #getEachNode() */ Iterable getEachNode(); /** * Set of edges usable in a for-each instruction. This method is implicitly * generic and return an Iterable over something which extends Edge. The * return type is the one of the left part of the assignment. For example, * in the following call : * *
	 * Iterable<ExtendedNEdge> ite = graph.getEachEdge();
	 * 
* * the method will return an Iterable<ExtendedEdge>. If no left part * exists, method will just return an Iterable<Edge>. It is possible * to use it in a for-each loop by giving the parameter : * *
	 * for (ExtendedEdge e : graph.<ExtendedEdge> getEachEdge()) {
	 * 	// ...
	 * }
	 * 
* * @return An "iterable" view of the set of edges. * @see #getEdgeIterator() * @see #getEdgeSet() */ Iterable getEachEdge(); /** * Unmodifiable view of the set of nodes. This method is implicitly generic * and return a Collection of something which extends Node. The return type * is the one of the left part of the assignment. For example, in the * following call : * *
	 * Collection<ExtendedNode> c = graph.getNodeSet();
	 * 
* * the method will return a Collection<ExtendedNode>. If no left part * exists, method will just return a Collection<Node>. * * @return A set of nodes that can only be read, not changed. * @see #getNodeIterator() * @see #getEachNode() */ Collection getNodeSet(); /** * Unmodifiable view of the set of edges. This method is implicitly generic * and return a Collection of something which extends Edge. The return type * is the one of the left part of the assignment. For example, in the * following call : * *
	 * Collection<ExtendedEdge> c = graph.getEdgeSet();
	 * 
* * the method will return a Collection<ExtendedEdge>. If no left part * exists, method will just return a Collection<Edge>. * * @return A set of edges that can only be read, not changed. * @see #getEdgeIterator() * @see #getEachEdge() */ Collection getEdgeSet(); /** * The factory used to create node instances. The factory can be changed to * refine the node class generated for this graph. * * @see #setNodeFactory(NodeFactory) * @see #edgeFactory() */ NodeFactory nodeFactory(); /** * The factory used to create edge instances. The factory can be changed to * refine the edge class generated for this graph. * * @see #setEdgeFactory(EdgeFactory) * @see #nodeFactory() */ EdgeFactory edgeFactory(); /** * Is strict checking enabled? If strict checking is enabled the graph * checks for name space conflicts (e.g. insertion of two nodes with the * same name), removal of non-existing elements, use of non existing * elements (create an edge between two non existing nodes). Graph * implementations are free to respect strict checking or not. * * @return True if enabled. */ boolean isStrict(); /** * Is the automatic creation of missing elements enabled?. If enabled, when * an edge is created and one or two of its nodes are not already present in * the graph, the nodes are automatically created. * * @return True if enabled. */ boolean isAutoCreationEnabled(); /** * If true, when accessing an attribute that does not exist (or is not of the * expected type), a {@link NullAttributeException} is thrown. Else null is * returned. * @return True if exceptions must be thrown when accessing a null attribute. */ boolean nullAttributesAreErrors(); /** * The current step. * * @return The step. */ double getStep(); // Command /** * Should a {@link NullAttributeException} be thrown when one tries to access * a non existing attribute, or an attribute whose type is not the expected one?. * * @param on * if true, exceptions will be thrown when accessing a non existing attribute. */ void setNullAttributesAreErrors(boolean on); /** * Set the node factory used to create nodes. * * @param nf * the new NodeFactory */ void setNodeFactory(NodeFactory nf); /** * Set the edge factory used to create edges. * * @param ef * the new EdgeFactory */ void setEdgeFactory(EdgeFactory ef); /** * Enable or disable strict checking. * * @see #isStrict() * @param on * True or false. */ void setStrict(boolean on); /** * Enable or disable the automatic creation of missing elements. * * @see #isAutoCreationEnabled() * @param on * True or false. */ void setAutoCreate(boolean on); // Graph construction /** * Empty the graph completely by removing any references to nodes or edges. * Every attribute is also removed. However, listeners are kept. * * @see #clearSinks() */ void clear(); /** * Add a node in the graph. *

* This acts as a factory, creating the node instance automatically (and * eventually using the node factory provided). An event is generated toward * the listeners. If strict checking is enabled, and a node already exists * with this identifier, a singleton exception is raised. Else the error is * silently ignored and the already existing node is returned. *

*

* This method is implicitly generic and return something which extends * Node. The return type is the one of the left part of the assignment. For * example, in the following call : * *

	 * ExtendedNode n = graph.addNode("...");
	 * 
* * the method will return an ExtendedNode. If no left part exists, method * will just return a Node. *

* * @param id * Arbitrary and unique string identifying the node. * @return The created node (or the already existing node). * @throws IdAlreadyInUseException * If the identifier is already used. */ T addNode(String id) throws IdAlreadyInUseException; /** * Remove the node using its identifier. *

* An event is generated toward the listeners. Note that removing a node may * remove all edges it is connected to. In this case corresponding events * will also be generated toward the listeners. *

*

* This method is implicitly generic and return something which extends * Node. The return type is the one of the left part of the assignment. For * example, in the following call : * *

	 * ExtendedNode n = graph.removeNode("...");
	 * 
* * the method will return an ExtendedNode. If no left part exists, method * will just return a Node. *

* * @param id * The unique identifier of the node to remove. * @return The removed node, if strict checking is disabled, it can return * null if the node to remove does not exist. * @complexity O(1) * @throws ElementNotFoundException * If no node matches the given identifier. */ T removeNode(String id) throws ElementNotFoundException; /** * Add an undirected edge between nodes. *

* An event is sent toward the listeners. If strict checking is enabled and * at least one of the two given nodes do not exist, a "not found" exception * is raised. Else if the auto-creation feature is disabled, the error is * silently ignored, and null is returned. If the auto-creation feature is * enabled (see {@link #setAutoCreate(boolean)}) and one or two of the given * nodes do not exist, they are automatically created. *

*

* This method is implicitly generic and return something which extends * Edge. The return type is the one of the left part of the assignment. For * example, in the following call : * *

	 * ExtendedEdge e = graph.addEdge("...", "...", "...");
	 * 
* * the method will return an ExtendedEdge. If no left part exists, method * will just return an Edge. *

* * @param id * Unique an arbitrary string identifying the edge. * @param node1 * The first node identifier. * @param node2 * The second node identifier. * * @return The newly created edge (this can return null, if strict checking * is disabled, auto-creation disabled, and one or two of the given * nodes do not exist). * @throws IdAlreadyInUseException * If an edge already exist between 'from' and 'to', strict * checking is enabled and the graph is not a multi-graph. * @throws ElementNotFoundException * If strict checking is enabled, and the 'from' or 'to' node is * not registered in the graph. */ T addEdge(String id, String node1, String node2) throws IdAlreadyInUseException, ElementNotFoundException; /** * Like {@link #addEdge(String, String, String)}, but this edge can be * directed between the two given nodes. If directed, the edge goes in the * 'from' -> 'to' direction. An event is sent toward the listeners. * * @param id * Unique an arbitrary string identifying the node. * @param from * The source node identifier. * @param to * The target node identifier. * @param directed * Is the edge directed?. * * @return The newly created edge (this can return null, if strict checking * is disabled, auto-creation disabled, and one or two of the given * nodes do not exist). * @throws IdAlreadyInUseException * If an edge already exist between 'from' and 'to', strict * checking is enabled, and the graph is not a multi-graph. * @throws ElementNotFoundException * If strict checking is enabled, and the 'from' or 'to' node is * not registered in the graph. */ T addEdge(String id, String from, String to, boolean directed) throws IdAlreadyInUseException, ElementNotFoundException; /** * Remove an edge given the identifier of its two linked nodes. *

* If the edge is directed it is removed only if its source and destination * nodes are identified by 'from' and 'to' respectively. If the graph is a * multi-graph and there are several edges between the two nodes, one of the * edge at random is removed. An event is sent toward the listeners. If * strict checking is enabled and at least one of the two given nodes does * not exist, a not found exception is raised. Else the error is silently * ignored, and null is returned. *

*

* This method is implicitly generic and return something which extends * Edge. The return type is the one of the left part of the assignment. For * example, in the following call : * *

	 * ExtendedEdge e = graph.removeEdge("...", "...");
	 * 
* * the method will return an ExtendedEdge. If no left part exists, method * will just return an Edge. *

* * @param from * The origin node identifier to select the edge. * @param to * The destination node identifier to select the edge. * @return The removed edge, or null if strict checking is disabled and at * least one of the two given nodes does not exist. * @throws ElementNotFoundException * If the 'from' or 'to' node is not registered in the graph and * strict checking is enabled. */ T removeEdge(String from, String to) throws ElementNotFoundException; /** * Remove the edge knowing its identifier. An event is sent toward the * listeners. If strict checking is enabled and the edge does not exist, a * not found exception is raised. Else the error is silently ignored and * null is returned. *

* This method is implicitly generic and return something which extends * Edge. The return type is the one of the left part of the assignment. For * example, in the following call : * *

	 * ExtendedEdge e = graph.removeEdge("...");
	 * 
* * the method will return an ExtendedEdge. If no left part exists, method * will just return an Edge. *

* * @param id * Identifier of the edge to remove. * @return The removed edge, or null if strict checking is disabled and the * edge does not exist. * @throws ElementNotFoundException * If no edge matches the identifier and strict checking is * enabled. */ T removeEdge(String id) throws ElementNotFoundException; /** *

* Since dynamic graphs are based on discrete event modifications, the * notion of step is defined to simulate elapsed time between events. So a * step is a event that occurs in the graph, it does not modify it but it * gives a kind of timestamp that allows the tracking of the progress of the * graph over the time. *

*

* This kind of event is useful for dynamic algorithms that listen to the * dynamic graph and need to measure the time in the graph's evolution. *

* * @param time * A numerical value that may give a timestamp to track the * evolution of the graph over the time. */ void stepBegins(double time); // Source // XXX do we put the iterable attributeSinks and elementSinks in Source ? /** * Returns an "iterable" of {@link AttributeSink} objects registered to this * graph. * * @return the set of {@link AttributeSink} under the form of an iterable * object. */ Iterable attributeSinks(); /** * Returns an "iterable" of {@link ElementSink} objects registered to this * graph. * * @return the list of {@link ElementSink} under the form of an iterable * object. */ Iterable elementSinks(); // Utility shortcuts (should be mixins or traits, what are you doing Mr Java // ?) // XXX use a Readable/Writable/Displayable interface for this ? /** * Utility method to read a graph. This method tries to identify the graph * format by itself and instantiates the corresponding reader automatically. * If this process fails, a NotFoundException is raised. * * @param filename * The graph filename (or URL). * @throws ElementNotFoundException * If the file cannot be found or if the format is not * recognized. * @throws GraphParseException * If there is a parsing error while reading the file. * @throws IOException * If an input output error occurs during the graph reading. */ void read(String filename) throws IOException, GraphParseException, ElementNotFoundException; /** * Utility method to read a graph using the given reader. * * @param input * An appropriate reader for the filename. * @param filename * The graph filename (or URL). * @throws ElementNotFoundException * If the file cannot be found or if the format is not * recognised. * @throws GraphParseException * If there is a parsing error while reading the file. * @throws IOException * If an input/output error occurs during the graph reading. */ void read(FileSource input, String filename) throws IOException, GraphParseException; /** * Utility method to write a graph in DGS format to a file. * * @param filename * The file that will contain the saved graph (or URL). * @throws IOException * If an input/output error occurs during the graph writing. */ void write(String filename) throws IOException; /** * Utility method to write a graph in the chosen format to a file. * * @param filename * The file that will contain the saved graph (or URL). * @param output * The output format to use. * @throws IOException * If an input/output error occurs during the graph writing. */ void write(FileSink output, String filename) throws IOException; /** * Utility method that creates a new graph viewer, and register the graph in * it. Notice that this method is a quick way to see a graph, and only this. * It can be used to prototype a program, but may be limited. This method * automatically launch a graph layout algorithm in its own thread to * compute best node positions. * * @see org.graphstream.ui.swingViewer.Viewer * @see #display(boolean ) * @return a graph viewer that allows to command the viewer (it often run in * another thread). */ org.graphstream.ui.swingViewer.Viewer display(); /** * Utility method that creates a new graph viewer, and register the graph in * it. Notice that this method is a quick way to see a graph, and only this. * It can be used to prototype a program, but is very limited. * * @param autoLayout * If true a layout algorithm is launched in its own thread to * compute best node positions. * @see org.graphstream.ui.swingViewer.Viewer * @see #display() * @return a graph viewer that allows to command the viewer (it often run in * another thread). */ org.graphstream.ui.swingViewer.Viewer display(boolean autoLayout); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy