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; 031 032import org.graphstream.graph.Edge; 033import org.graphstream.graph.Graph; 034import org.graphstream.graph.Node; 035import org.graphstream.graph.implementations.AbstractElement.AttributeChangeEvent; 036import org.graphstream.stream.Pipe; 037import org.graphstream.stream.SourceBase; 038import org.graphstream.stream.sync.SinkTime; 039 040/** 041 * Helper object to handle events producted by a graph. 042 * 043 */ 044public class GraphListeners extends SourceBase implements Pipe { 045 SinkTime sinkTime; 046 boolean passYourWay; 047 Graph g; 048 049 public GraphListeners(Graph g) { 050 super(g.getId()); 051 052 this.sinkTime = new SinkTime(); 053 this.sourceTime.setSinkTime(sinkTime); 054 this.passYourWay = false; 055 this.g = g; 056 } 057 058 public long newEvent() { 059 return sourceTime.newEvent(); 060 } 061 062 public void sendAttributeChangedEvent(String eltId, ElementType eltType, 063 String attribute, AttributeChangeEvent event, Object oldValue, 064 Object newValue) { 065 // 066 // Attributes with name beginnig with a dot are hidden. 067 // 068 if (passYourWay || attribute.charAt(0) == '.') 069 return; 070 071 sendAttributeChangedEvent(sourceId, newEvent(), eltId, eltType, 072 attribute, event, oldValue, newValue); 073 } 074 075 public void sendNodeAdded(String nodeId) { 076 if (passYourWay) 077 return; 078 079 sendNodeAdded(sourceId, newEvent(), nodeId); 080 } 081 082 public void sendNodeRemoved(String nodeId) { 083 if (passYourWay) 084 return; 085 086 sendNodeRemoved(sourceId, newEvent(), nodeId); 087 } 088 089 public void sendEdgeAdded(String edgeId, String source, String target, 090 boolean directed) { 091 if (passYourWay) 092 return; 093 094 sendEdgeAdded(sourceId, newEvent(), edgeId, source, target, directed); 095 } 096 097 public void sendEdgeRemoved(String edgeId) { 098 if (passYourWay) 099 return; 100 101 sendEdgeRemoved(sourceId, newEvent(), edgeId); 102 } 103 104 public void sendGraphCleared() { 105 if (passYourWay) 106 return; 107 108 sendGraphCleared(sourceId, newEvent()); 109 } 110 111 public void sendStepBegins(double step) { 112 if (passYourWay) 113 return; 114 115 sendStepBegins(sourceId, newEvent(), step); 116 } 117 118 /* 119 * (non-Javadoc) 120 * 121 * @see org.graphstream.stream.AttributeSink#edgeAttributeAdded(java.lang 122 * .String, long, java.lang.String, java.lang.String, java.lang.Object) 123 */ 124 public void edgeAttributeAdded(String sourceId, long timeId, String edgeId, 125 String attribute, Object value) { 126 if (sinkTime.isNewEvent(sourceId, timeId)) { 127 Edge edge = g.getEdge(edgeId); 128 if (edge != null) { 129 passYourWay = true; 130 131 try { 132 edge.addAttribute(attribute, value); 133 } finally { 134 passYourWay = false; 135 } 136 137 sendEdgeAttributeAdded(sourceId, timeId, edgeId, attribute, 138 value); 139 } 140 } 141 } 142 143 /* 144 * (non-Javadoc) 145 * 146 * @see org.graphstream.stream.AttributeSink#edgeAttributeChanged(java.lang 147 * .String, long, java.lang.String, java.lang.String, java.lang.Object, 148 * java.lang.Object) 149 */ 150 public void edgeAttributeChanged(String sourceId, long timeId, 151 String edgeId, String attribute, Object oldValue, Object newValue) { 152 if (sinkTime.isNewEvent(sourceId, timeId)) { 153 Edge edge = g.getEdge(edgeId); 154 if (edge != null) { 155 passYourWay = true; 156 157 if (oldValue == null) 158 oldValue = edge.getAttribute(attribute); 159 160 try { 161 edge.changeAttribute(attribute, newValue); 162 } finally { 163 passYourWay = false; 164 } 165 166 sendEdgeAttributeChanged(sourceId, timeId, edgeId, attribute, 167 oldValue, newValue); 168 } 169 } 170 } 171 172 /* 173 * (non-Javadoc) 174 * 175 * @see org.graphstream.stream.AttributeSink#edgeAttributeRemoved(java.lang 176 * .String, long, java.lang.String, java.lang.String) 177 */ 178 public void edgeAttributeRemoved(String sourceId, long timeId, 179 String edgeId, String attribute) { 180 if (sinkTime.isNewEvent(sourceId, timeId)) { 181 Edge edge = g.getEdge(edgeId); 182 if (edge != null) { 183 sendEdgeAttributeRemoved(sourceId, timeId, edgeId, attribute); 184 passYourWay = true; 185 186 try { 187 edge.removeAttribute(attribute); 188 } finally { 189 passYourWay = false; 190 } 191 192 } 193 } 194 } 195 196 /* 197 * (non-Javadoc) 198 * 199 * @see org.graphstream.stream.AttributeSink#graphAttributeAdded(java.lang 200 * .String, long, java.lang.String, java.lang.Object) 201 */ 202 public void graphAttributeAdded(String sourceId, long timeId, 203 String attribute, Object value) { 204 if (sinkTime.isNewEvent(sourceId, timeId)) { 205 passYourWay = true; 206 207 try { 208 g.addAttribute(attribute, value); 209 } finally { 210 passYourWay = false; 211 } 212 213 sendGraphAttributeAdded(sourceId, timeId, attribute, value); 214 } 215 } 216 217 /* 218 * (non-Javadoc) 219 * 220 * @see org.graphstream.stream.AttributeSink#graphAttributeChanged(java.lang 221 * .String, long, java.lang.String, java.lang.Object, java.lang.Object) 222 */ 223 public void graphAttributeChanged(String sourceId, long timeId, 224 String attribute, Object oldValue, Object newValue) { 225 if (sinkTime.isNewEvent(sourceId, timeId)) { 226 passYourWay = true; 227 228 if (oldValue == null) 229 oldValue = g.getAttribute(attribute); 230 231 try { 232 g.changeAttribute(attribute, newValue); 233 } finally { 234 passYourWay = false; 235 } 236 237 sendGraphAttributeChanged(sourceId, timeId, attribute, oldValue, 238 newValue); 239 } 240 } 241 242 /* 243 * (non-Javadoc) 244 * 245 * @see org.graphstream.stream.AttributeSink#graphAttributeRemoved(java.lang 246 * .String, long, java.lang.String) 247 */ 248 public void graphAttributeRemoved(String sourceId, long timeId, 249 String attribute) { 250 if (sinkTime.isNewEvent(sourceId, timeId)) { 251 sendGraphAttributeRemoved(sourceId, timeId, attribute); 252 passYourWay = true; 253 254 try { 255 g.removeAttribute(attribute); 256 } finally { 257 passYourWay = false; 258 } 259 } 260 } 261 262 /* 263 * (non-Javadoc) 264 * 265 * @see org.graphstream.stream.AttributeSink#nodeAttributeAdded(java.lang 266 * .String, long, java.lang.String, java.lang.String, java.lang.Object) 267 */ 268 public void nodeAttributeAdded(String sourceId, long timeId, String nodeId, 269 String attribute, Object value) { 270 if (sinkTime.isNewEvent(sourceId, timeId)) { 271 Node node = g.getNode(nodeId); 272 if (node != null) { 273 passYourWay = true; 274 275 try { 276 node.addAttribute(attribute, value); 277 } finally { 278 passYourWay = false; 279 } 280 281 sendNodeAttributeAdded(sourceId, timeId, nodeId, attribute, 282 value); 283 } 284 } 285 } 286 287 /* 288 * (non-Javadoc) 289 * 290 * @see org.graphstream.stream.AttributeSink#nodeAttributeChanged(java.lang 291 * .String, long, java.lang.String, java.lang.String, java.lang.Object, 292 * java.lang.Object) 293 */ 294 public void nodeAttributeChanged(String sourceId, long timeId, 295 String nodeId, String attribute, Object oldValue, Object newValue) { 296 if (sinkTime.isNewEvent(sourceId, timeId)) { 297 Node node = g.getNode(nodeId); 298 if (node != null) { 299 passYourWay = true; 300 301 if (oldValue == null) 302 oldValue = node.getAttribute(attribute); 303 304 try { 305 node.changeAttribute(attribute, newValue); 306 } finally { 307 passYourWay = false; 308 } 309 310 sendNodeAttributeChanged(sourceId, timeId, nodeId, attribute, 311 oldValue, newValue); 312 } 313 } 314 } 315 316 /* 317 * (non-Javadoc) 318 * 319 * @see org.graphstream.stream.AttributeSink#nodeAttributeRemoved(java.lang 320 * .String, long, java.lang.String, java.lang.String) 321 */ 322 public void nodeAttributeRemoved(String sourceId, long timeId, 323 String nodeId, String attribute) { 324 if (sinkTime.isNewEvent(sourceId, timeId)) { 325 Node node = g.getNode(nodeId); 326 if (node != null) { 327 sendNodeAttributeRemoved(sourceId, timeId, nodeId, attribute); 328 passYourWay = true; 329 330 try { 331 node.removeAttribute(attribute); 332 } finally { 333 passYourWay = false; 334 } 335 } 336 } 337 } 338 339 /* 340 * (non-Javadoc) 341 * 342 * @see org.graphstream.stream.ElementSink#edgeAdded(java.lang.String, long, 343 * java.lang.String, java.lang.String, java.lang.String, boolean) 344 */ 345 public void edgeAdded(String sourceId, long timeId, String edgeId, 346 String fromNodeId, String toNodeId, boolean directed) { 347 if (sinkTime.isNewEvent(sourceId, timeId)) { 348 passYourWay = true; 349 350 try { 351 g.addEdge(edgeId, fromNodeId, toNodeId, directed); 352 } finally { 353 passYourWay = false; 354 } 355 356 sendEdgeAdded(sourceId, timeId, edgeId, fromNodeId, toNodeId, 357 directed); 358 } 359 } 360 361 /* 362 * (non-Javadoc) 363 * 364 * @see org.graphstream.stream.ElementSink#edgeRemoved(java.lang.String, 365 * long, java.lang.String) 366 */ 367 public void edgeRemoved(String sourceId, long timeId, String edgeId) { 368 if (sinkTime.isNewEvent(sourceId, timeId)) { 369 sendEdgeRemoved(sourceId, timeId, edgeId); 370 passYourWay = true; 371 372 try { 373 g.removeEdge(edgeId); 374 } finally { 375 passYourWay = false; 376 } 377 } 378 } 379 380 /* 381 * (non-Javadoc) 382 * 383 * @see org.graphstream.stream.ElementSink#graphCleared(java.lang.String, 384 * long) 385 */ 386 public void graphCleared(String sourceId, long timeId) { 387 if (sinkTime.isNewEvent(sourceId, timeId)) { 388 sendGraphCleared(sourceId, timeId); 389 passYourWay = true; 390 391 try { 392 g.clear(); 393 } finally { 394 passYourWay = false; 395 } 396 } 397 } 398 399 /* 400 * (non-Javadoc) 401 * 402 * @see org.graphstream.stream.ElementSink#nodeAdded(java.lang.String, long, 403 * java.lang.String) 404 */ 405 public void nodeAdded(String sourceId, long timeId, String nodeId) { 406 if (sinkTime.isNewEvent(sourceId, timeId)) { 407 passYourWay = true; 408 409 try { 410 g.addNode(nodeId); 411 } finally { 412 passYourWay = false; 413 } 414 415 sendNodeAdded(sourceId, timeId, nodeId); 416 } 417 } 418 419 /* 420 * (non-Javadoc) 421 * 422 * @see org.graphstream.stream.ElementSink#nodeRemoved(java.lang.String, 423 * long, java.lang.String) 424 */ 425 public void nodeRemoved(String sourceId, long timeId, String nodeId) { 426 if (sinkTime.isNewEvent(sourceId, timeId)) { 427 sendNodeRemoved(sourceId, timeId, nodeId); 428 passYourWay = true; 429 430 try { 431 g.removeNode(nodeId); 432 } finally { 433 passYourWay = false; 434 } 435 } 436 } 437 438 /* 439 * (non-Javadoc) 440 * 441 * @see org.graphstream.stream.ElementSink#stepBegins(java.lang.String, 442 * long, double) 443 */ 444 public void stepBegins(String sourceId, long timeId, double step) { 445 if (sinkTime.isNewEvent(sourceId, timeId)) { 446 passYourWay = true; 447 448 try { 449 g.stepBegins(step); 450 } finally { 451 passYourWay = false; 452 } 453 454 sendStepBegins(sourceId, timeId, step); 455 } 456 } 457 458 @Override 459 public String toString() { 460 return String.format("GraphListeners of %s.%s", g.getClass() 461 .getSimpleName(), g.getId()); 462 } 463}