org.graphstream.stream.file.dgs.OldFileSourceDGS Maven / Gradle / Ivy
/*
* This file is part of GraphStream .
*
* GraphStream is a library whose purpose is to handle static or dynamic
* graph, create them from scratch, file or any source and display them.
*
* This program is free software distributed under the terms of two licenses, the
* CeCILL-C license that fits European law, and the GNU Lesser General Public
* License. You can use, modify and/ or redistribute the software under the terms
* of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
* URL or under the terms of the GNU LGPL as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
*/
/**
* @since 2009-02-19
*
* @author Guilhelm Savin
* @author Hicham Brahimi
*/
package org.graphstream.stream.file.dgs;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StreamTokenizer;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.zip.GZIPInputStream;
import org.graphstream.stream.file.FileSource;
import org.graphstream.stream.file.FileSourceBase;
/**
* Class responsible for parsing files in the DGS format.
*
*
* The DGS file format is especially designed for storing dynamic graph
* definitions into a file. More information about the DGS file format will be
* found on the GraphStream web site:
* http://graphstream-project.org/
*
*
* The usual file name extension used for this format is ".dgs".
*
* @see FileSource
*/
public class OldFileSourceDGS extends FileSourceBase {
// Attribute
/**
* Format version.
*/
protected int version;
/**
* Name of the graph.
*/
protected String graphName;
/**
* Number of step given in the header.
*/
protected int stepCountAnnounced;
/**
* Number of events given in the header.
*/
protected int eventCountAnnounced;
/**
* Real number of step at current time.
*/
protected int stepCount;
/**
* Real number of events at current time.
*/
protected int eventCount;
/**
* An attribute set used everywhere.
*/
protected HashMap attributes = new HashMap();
/**
* True as soon as the end of file is reached.
*/
protected boolean finished;
// Construction
/**
* New reader for the DGS graph file format version 3.
*/
public OldFileSourceDGS() {
super(true /* EOL is significant */);
}
// Command -- Parsing
@Override
public boolean nextEvents() throws IOException {
if (finished)
return false;
return next(false, false);
}
public boolean nextStep() throws IOException {
if (finished)
return false;
return next(true, false);
}
/**
* Read either one event or several.
*
* @param readSteps
* If true, read several events (usually starting with a step event,
* but it may be preceded by other events), until another step is
* encountered.
* @param stop
* If true stop at the next step encountered (and push it back so
* that is is readable at the next call to this method).
* @return True if it remains things to read.
*/
protected boolean next(boolean readSteps, boolean stop) throws IOException {
String key = null;
boolean loop = readSteps;
// Sorted in probability of appearance ...
do {
key = getWordOrSymbolOrStringOrEolOrEof();
if (key.equals("ce")) {
readCE();
} else if (key.equals("cn")) {
readCN();
} else if (key.equals("ae")) {
readAE();
} else if (key.equals("an")) {
readAN();
} else if (key.equals("de")) {
readDE();
} else if (key.equals("dn")) {
readDN();
} else if (key.equals("cg")) {
readCG();
} else if (key.equals("st")) {
if (readSteps) {
if (stop) {
loop = false;
pushBack();
} else {
stop = true;
readST();
}
} else {
readST();
}
} else if (key.equals("#")) {
eatAllUntilEol();
return next(readSteps, stop);
} else if (key.equals("EOL")) {
// Probably an empty line.
// NOP
return next(readSteps, stop);
} else if (key.equals("EOF")) {
finished = true;
return false;
} else {
parseError("unknown token '" + key + "'");
}
} while (loop);
return true;
}
protected void readCE() throws IOException {
String tag = getStringOrWordOrNumber();
readAttributes(attributes);
for (String key : attributes.keySet()) {
Object value = attributes.get(key);
if (value == null)
sendEdgeAttributeRemoved(graphName, tag, key);
else
sendEdgeAttributeChanged(graphName, tag, key, null, value);
}
if (eatEolOrEof() == StreamTokenizer.TT_EOF)
pushBack();
}
protected void readCN() throws IOException {
String tag = getStringOrWordOrNumber();
readAttributes(attributes);
for (String key : attributes.keySet()) {
Object value = attributes.get(key);
if (value == null)
sendNodeAttributeRemoved(graphName, tag, key);
else
sendNodeAttributeChanged(graphName, tag, key, null, value);
}
if (eatEolOrEof() == StreamTokenizer.TT_EOF)
pushBack();
}
protected void readCG() throws IOException {
readAttributes(attributes);
for (String key : attributes.keySet()) {
Object value = attributes.get(key);
if (value == null)
sendGraphAttributeRemoved(graphName, key);
else
sendGraphAttributeChanged(graphName, key, null, value);
}
if (eatEolOrEof() == StreamTokenizer.TT_EOF)
pushBack();
}
protected void readAE() throws IOException {
int dir = 0;
boolean directed = false;
String dirc = null;
String tag = null;
String fromTag = null;
String toTag = null;
tag = getStringOrWordOrNumber();
fromTag = getStringOrWordOrNumber();
dirc = getWordOrSymbolOrNumberOrStringOrEolOrEof();
if (dirc.equals(">")) {
directed = true;
dir = 1;
} else if (dirc.equals("<")) {
directed = true;
dir = 2;
} else {
pushBack();
}
toTag = getStringOrWordOrNumber();
if (dir == 2) {
String tmp = toTag;
toTag = fromTag;
fromTag = tmp;
}
readAttributes(attributes);
sendEdgeAdded(graphName, tag, fromTag, toTag, directed);
for (String key : attributes.keySet()) {
Object value = attributes.get(key);
sendEdgeAttributeAdded(graphName, tag, key, value);
}
if (eatEolOrEof() == StreamTokenizer.TT_EOF)
pushBack();
}
protected void readAN() throws IOException {
String tag = getStringOrWordOrNumber();
readAttributes(attributes);
sendNodeAdded(graphName, tag);
for (String key : attributes.keySet()) {
Object value = attributes.get(key);
sendNodeAttributeAdded(graphName, tag, key, value);
}
if (eatEolOrEof() == StreamTokenizer.TT_EOF)
pushBack();
}
protected void readDE() throws IOException {
String tag = getStringOrWordOrNumber();
sendEdgeRemoved(graphName, tag);
if (eatEolOrEof() == StreamTokenizer.TT_EOF)
pushBack();
}
protected void readDN() throws IOException {
String tag = getStringOrWordOrNumber();
sendNodeRemoved(graphName, tag);
if (eatEolOrEof() == StreamTokenizer.TT_EOF)
pushBack();
}
protected void readST() throws IOException {
String w = getWordOrNumber();
try {
double time = Double.parseDouble(w);
sendStepBegins(graphName, time);
} catch (NumberFormatException e) {
parseError("expecting a number after `st', got `" + w + "'");
}
if (eatEolOrEof() == StreamTokenizer.TT_EOF)
pushBack();
}
protected void readAttributes(HashMap attributes) throws IOException {
boolean del = false;
String key = getWordOrSymbolOrStringOrEolOrEof();
attributes.clear();
if (key.equals("-")) {
key = getWordOrSymbolOrStringOrEolOrEof();
del = true;
}
if (key.equals("+"))
key = getWordOrSymbolOrStringOrEolOrEof();
while (!key.equals("EOF") && !key.equals("EOL") && !key.equals("]")) {
if (del)
attributes.put(key, null);
else
attributes.put(key, readAttributeValue(key));
key = getWordOrSymbolOrStringOrEolOrEof();
if (key.equals("-")) {
key = getWordOrStringOrEolOrEof();
del = true;
}
if (key.equals("+")) {
key = getWordOrStringOrEolOrEof();
del = false;
}
}
pushBack();
}
/**
* Read an attribute. The "key" (attribute name) is already read.
*
* @param key
* The attribute name, already read.
*/
protected Object readAttributeValue(String key) throws IOException {
ArrayList