001/*
002 * Copyright 2006 - 2013
003 *     Stefan Balev     <stefan.balev@graphstream-project.org>
004 *     Julien Baudry    <julien.baudry@graphstream-project.org>
005 *     Antoine Dutot    <antoine.dutot@graphstream-project.org>
006 *     Yoann Pigné      <yoann.pigne@graphstream-project.org>
007 *     Guilhelm Savin   <guilhelm.savin@graphstream-project.org>
008 * 
009 * This file is part of GraphStream <http://graphstream-project.org>.
010 * 
011 * GraphStream is a library whose purpose is to handle static or dynamic
012 * graph, create them from scratch, file or any source and display them.
013 * 
014 * This program is free software distributed under the terms of two licenses, the
015 * CeCILL-C license that fits European law, and the GNU Lesser General Public
016 * License. You can  use, modify and/ or redistribute the software under the terms
017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by
019 * the Free Software Foundation, either version 3 of the License, or (at your
020 * option) any later version.
021 * 
022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
024 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
025 * 
026 * You should have received a copy of the GNU Lesser General Public License
027 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
028 * 
029 * The fact that you are presently reading this means that you have had
030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
031 */
032package org.graphstream.stream.file;
033
034/**
035 * Transform the input events into a GML graph.
036 * 
037 * <p>
038 * THIS CLASS IS REALLY NOT APPROPRIATE FOR GENERAL USE. Indeed the GML format
039 * is not dynamic and it is very difficult to export the correct attributes of
040 * nodes if the declaration of the attribute is far from the declaration of the
041 * node. The only way would be to store the graph in a buffer and output it at
042 * once when the file is closed.
043 * </p>
044 * 
045 * <p>
046 * Therefore this class outputs attributes of nodes and edges only if their
047 * addition directly follows the corresponding node or edge.
048 * </p>
049 */
050public class FileSinkDynamicGML extends FileSinkGML {
051        // Construction
052
053        public FileSinkDynamicGML() {
054                // NOP
055        }
056
057        // Attribute events
058
059        @Override
060        public void graphAttributeAdded(String sourceId, long timeId,
061                        String attribute, Object value) {
062                ensureToFinish();
063
064                String val = valueToString(value);
065
066                if (val != null) {
067                        out.printf("\t%s %s%n", attribute, val);
068                }
069        }
070
071        @Override
072        public void graphAttributeChanged(String sourceId, long timeId,
073                        String attribute, Object oldValue, Object newValue) {
074                ensureToFinish();
075                graphAttributeAdded(sourceId, timeId, attribute, newValue);
076        }
077
078        @Override
079        public void graphAttributeRemoved(String sourceId, long timeId,
080                        String attribute) {
081                ensureToFinish();
082                out.printf("\t-%s%n", attribute);
083        }
084
085        @Override
086        public void nodeAttributeAdded(String sourceId, long timeId, String nodeId,
087                        String attribute, Object value) {
088                nodeAttributeChanged(sourceId, timeId, nodeId, attribute, null, value);
089        }
090
091        @Override
092        public void nodeAttributeChanged(String sourceId, long timeId,
093                        String nodeId, String attribute, Object oldValue, Object newValue) {
094
095                if(nodeToFinish == null || (!nodeToFinish.equals(nodeId))) {
096                        ensureToFinish();
097                        out.printf("\t+node [%n");
098                        out.printf("\t\tid \"%s\"%n", nodeId);
099                        nodeToFinish = nodeId;
100                }
101
102                if(newValue != null) {
103                        String val = valueToString(newValue);
104                        
105                        if (val != null) {
106                                out.printf("\t\t%s %s%n", attribute, val);
107                        }
108                } else {
109                        out.printf("\t\t-%s%n", attribute);
110                }
111        }
112
113        @Override
114        public void nodeAttributeRemoved(String sourceId, long timeId,
115                        String nodeId, String attribute) {
116                nodeAttributeChanged(sourceId, timeId, nodeId, attribute, null, null);
117        }
118
119        @Override
120        public void edgeAttributeAdded(String sourceId, long timeId, String edgeId,
121                        String attribute, Object value) {
122                edgeAttributeChanged(sourceId, timeId, edgeId, attribute, null, value);
123        }
124
125        @Override
126        public void edgeAttributeChanged(String sourceId, long timeId,
127                        String edgeId, String attribute, Object oldValue, Object newValue) {
128
129                if(edgeToFinish == null || (!edgeToFinish.equals(edgeId))) {
130                        ensureToFinish();
131                        out.printf("\t+edge [%n");
132                        out.printf("\t\tid \"%s\"%n", edgeId);
133                        edgeToFinish = edgeId;
134                }
135
136                if(newValue != null) {
137                        String val = valueToString(newValue);
138                        
139                        if (val != null) {
140                                out.printf("\t\t%s %s%n", attribute, val);
141                        }
142                } else {
143                        out.printf("\t\t-%s%n", attribute);
144                }
145        }
146
147        @Override
148        public void edgeAttributeRemoved(String sourceId, long timeId,
149                        String edgeId, String attribute) {
150                edgeAttributeChanged(sourceId, timeId, edgeId, attribute, null, null);
151        }
152
153        // Element events
154
155        @Override
156        public void nodeAdded(String sourceId, long timeId, String nodeId) {
157                ensureToFinish();
158                out.printf("\tnode [%n");
159                out.printf("\t\tid \"%s\"%n", nodeId);
160                nodeToFinish = nodeId;
161        }
162
163        @Override
164        public void nodeRemoved(String sourceId, long timeId, String nodeId) {
165                ensureToFinish();
166                out.printf("\t-node \"%s\"%n", nodeId);
167        }
168
169        @Override
170        public void edgeAdded(String sourceId, long timeId, String edgeId,
171                        String fromNodeId, String toNodeId, boolean directed) {
172                ensureToFinish();
173                out.printf("\tedge [%n");
174                out.printf("\t\tid \"%s\"%n", edgeId);
175                out.printf("\t\tsource \"%s\"%n", fromNodeId);
176                out.printf("\t\ttarget \"%s\"%n", toNodeId);
177                out.printf("\t\tdirected %s%n", directed ? "1" : "0");
178                edgeToFinish = edgeId;
179        }
180
181        @Override
182        public void edgeRemoved(String sourceId, long timeId, String edgeId) {
183                ensureToFinish();
184                out.printf("\t-edge \"%s\"%n", edgeId);
185        }
186
187        @Override
188        public void graphCleared(String sourceId, long timeId) {
189                // Ah ah ah !!
190        }
191
192        @Override
193        public void stepBegins(String sourceId, long timeId, double step) {
194                ensureToFinish();
195                if((step-((int)step))==0) 
196                     out.printf("\tstep %d%n", (int)step);
197                else out.printf("\tstep %f%n", step);
198        }
199}