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 * GraphStream is a library whose purpose is to handle static or dynamic
010 * graph, create them from scratch, file or any source and display them.
011 * 
012 * This program is free software distributed under the terms of two licenses, the
013 * CeCILL-C license that fits European law, and the GNU Lesser General Public
014 * License. You can  use, modify and/ or redistribute the software under the terms
015 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
016 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by
017 * the Free Software Foundation, either version 3 of the License, or (at your
018 * option) any later version.
019 * 
020 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
021 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
022 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
023 * 
024 * You should have received a copy of the GNU Lesser General Public License
025 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
026 * 
027 * The fact that you are presently reading this means that you have had
028 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
029 */
030package org.graphstream.util.cumulative;
031
032import java.util.HashMap;
033
034import org.graphstream.graph.Graph;
035import org.graphstream.graph.implementations.AdjacencyListGraph;
036import org.graphstream.stream.Sink;
037
038public class GraphSpells implements Sink {
039        CumulativeSpells graph;
040        CumulativeAttributes graphAttributes;
041
042        HashMap<String, CumulativeSpells> nodes;
043        HashMap<String, CumulativeAttributes> nodesAttributes;
044
045        HashMap<String, CumulativeSpells> edges;
046        HashMap<String, CumulativeAttributes> edgesAttributes;
047        HashMap<String, EdgeData> edgesData;
048
049        double date;
050
051        public GraphSpells() {
052                graph = new CumulativeSpells();
053                graphAttributes = new CumulativeAttributes(0);
054
055                nodes = new HashMap<String, CumulativeSpells>();
056                nodesAttributes = new HashMap<String, CumulativeAttributes>();
057
058                edges = new HashMap<String, CumulativeSpells>();
059                edgesAttributes = new HashMap<String, CumulativeAttributes>();
060                edgesData = new HashMap<String, EdgeData>();
061
062                date = Double.NaN;
063        }
064
065        public static class EdgeData {
066                String source;
067                String target;
068                boolean directed;
069                
070                public String getSource() {
071                        return source;
072                }
073                
074                public String getTarget() {
075                        return target;
076                }
077                
078                public boolean isDirected() {
079                        return directed;
080                }
081        }
082
083        public Iterable<String> getNodes() {
084                return nodes.keySet();
085        }
086
087        public Iterable<String> getEdges() {
088                return edges.keySet();
089        }
090
091        public CumulativeSpells getNodeSpells(String nodeId) {
092                return nodes.get(nodeId);
093        }
094
095        public CumulativeAttributes getNodeAttributes(String nodeId) {
096                return nodesAttributes.get(nodeId);
097        }
098
099        public CumulativeSpells getEdgeSpells(String edgeId) {
100                return edges.get(edgeId);
101        }
102
103        public CumulativeAttributes getEdgeAttributes(String edgeId) {
104                return edgesAttributes.get(edgeId);
105        }
106
107        public EdgeData getEdgeData(String edgeId) {
108                return edgesData.get(edgeId);
109        }
110
111        public void stepBegins(String sourceId, long timeId, double step) {
112                this.date = step;
113
114                graphAttributes.updateDate(step);
115                graph.updateCurrentSpell(step);
116
117                for (String id : nodes.keySet()) {
118                        nodes.get(id).updateCurrentSpell(step);
119                        nodesAttributes.get(id).updateDate(step);
120                }
121
122                for (String id : edges.keySet()) {
123                        edges.get(id).updateCurrentSpell(step);
124                        edgesAttributes.get(id).updateDate(step);
125                }
126        }
127
128        public void nodeAdded(String sourceId, long timeId, String nodeId) {
129                if (!nodes.containsKey(nodeId)) {
130                        nodes.put(nodeId, new CumulativeSpells());
131                        nodesAttributes.put(nodeId, new CumulativeAttributes(date));
132                }
133
134                nodes.get(nodeId).startSpell(date);
135        }
136
137        public void nodeRemoved(String sourceId, long timeId, String nodeId) {
138                if (nodes.containsKey(nodeId)) {
139                        nodes.get(nodeId).closeSpell();
140                        nodesAttributes.get(nodeId).remove();
141                }
142        }
143
144        public void edgeAdded(String sourceId, long timeId, String edgeId,
145                        String fromNodeId, String toNodeId, boolean directed) {
146                if (!edges.containsKey(edgeId)) {
147                        edges.put(edgeId, new CumulativeSpells());
148                        edgesAttributes.put(edgeId, new CumulativeAttributes(date));
149
150                        EdgeData data = new EdgeData();
151                        data.source = fromNodeId;
152                        data.target = toNodeId;
153                        data.directed = directed;
154
155                        edgesData.put(edgeId, data);
156                }
157
158                edges.get(edgeId).startSpell(date);
159
160                EdgeData data = edgesData.get(edgeId);
161
162                if (!data.source.equals(fromNodeId) || !data.target.equals(toNodeId)
163                                || data.directed != directed)
164                        System.err.printf("An edge with this id but different properties"
165                                        + " has already be created in the past.");
166        }
167
168        public void edgeRemoved(String sourceId, long timeId, String edgeId) {
169                if (edges.containsKey(edgeId)) {
170                        edges.get(edgeId).closeSpell();
171                        edgesAttributes.get(edgeId).remove();
172                }
173        }
174
175        public void graphCleared(String sourceId, long timeId) {
176                for (String id : nodes.keySet()) {
177                        nodes.get(id).closeSpell();
178                        nodesAttributes.get(id).remove();
179                }
180
181                for (String id : edges.keySet()) {
182                        edges.get(id).closeSpell();
183                        edgesAttributes.get(id).remove();
184                }
185        }
186
187        public void graphAttributeAdded(String sourceId, long timeId,
188                        String attribute, Object value) {
189                graphAttributes.set(attribute, value);
190        }
191
192        public void graphAttributeChanged(String sourceId, long timeId,
193                        String attribute, Object oldValue, Object newValue) {
194                graphAttributes.set(attribute, newValue);
195        }
196
197        public void graphAttributeRemoved(String sourceId, long timeId,
198                        String attribute) {
199                graphAttributes.remove(attribute);
200        }
201
202        public void nodeAttributeAdded(String sourceId, long timeId, String nodeId,
203                        String attribute, Object value) {
204                nodesAttributes.get(nodeId).set(attribute, value);
205        }
206
207        public void nodeAttributeChanged(String sourceId, long timeId,
208                        String nodeId, String attribute, Object oldValue, Object newValue) {
209                nodesAttributes.get(nodeId).set(attribute, newValue);
210        }
211
212        public void nodeAttributeRemoved(String sourceId, long timeId,
213                        String nodeId, String attribute) {
214                nodesAttributes.get(nodeId).remove(attribute);
215        }
216
217        public void edgeAttributeAdded(String sourceId, long timeId, String edgeId,
218                        String attribute, Object value) {
219                edgesAttributes.get(edgeId).set(attribute, value);
220        }
221
222        public void edgeAttributeChanged(String sourceId, long timeId,
223                        String edgeId, String attribute, Object oldValue, Object newValue) {
224                edgesAttributes.get(edgeId).set(attribute, newValue);
225        }
226
227        public void edgeAttributeRemoved(String sourceId, long timeId,
228                        String edgeId, String attribute) {
229                edgesAttributes.get(edgeId).remove(attribute);
230        }
231
232        public String toString() {
233                StringBuilder buffer = new StringBuilder();
234
235                for (String id : nodes.keySet()) {
236                        buffer.append("node#\"").append(id).append("\" ")
237                                        .append(nodes.get(id)).append(" ")
238                                        .append(nodesAttributes.get(id)).append("\n");
239                }
240
241                for (String id : edges.keySet()) {
242                        buffer.append("edge#\"").append(id).append("\" ")
243                                        .append(edges.get(id)).append("\n");
244                }
245
246                return buffer.toString();
247        }
248
249        public static void main(String... args) {
250                GraphSpells graphSpells = new GraphSpells();
251                Graph g = new AdjacencyListGraph("g");
252
253                g.addSink(graphSpells);
254
255                g.addNode("A");
256                g.addNode("B");
257                g.addNode("C");
258                g.stepBegins(1);
259                g.getNode("A").setAttribute("test1", 100);
260                g.addEdge("AB", "A", "B");
261                g.addEdge("AC", "A", "C");
262                g.stepBegins(2);
263                g.addEdge("CB", "C", "B");
264                g.removeNode("A");
265                g.stepBegins(3);
266                g.addNode("A");
267                g.addEdge("AB", "A", "B");
268                g.stepBegins(4);
269                g.removeNode("C");
270                g.stepBegins(5);
271
272                System.out.println(graphSpells);
273        }
274}