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.stream.file.gexf; 031 032import java.lang.reflect.Array; 033import java.util.HashMap; 034 035import javax.xml.stream.XMLStreamException; 036 037import org.graphstream.stream.SinkAdapter; 038 039public class GEXFNodes extends SinkAdapter implements GEXFElement { 040 GEXF root; 041 HashMap<String, GEXFNode> nodes; 042 043 public GEXFNodes(GEXF root) { 044 this.root = root; 045 this.nodes = new HashMap<String, GEXFNode>(); 046 047 root.addSink(this); 048 } 049 050 private float[] convertToXYZ(Object value) { 051 if (value == null || !value.getClass().isArray()) 052 return null; 053 054 float[] xyz = new float[Array.getLength(value)]; 055 056 for (int i = 0; i < xyz.length; i++) { 057 Object o = Array.get(value, i); 058 059 if (o instanceof Number) 060 xyz[i] = ((Number) o).floatValue(); 061 else 062 return null; 063 } 064 065 return xyz; 066 } 067 068 /* 069 * (non-Javadoc) 070 * 071 * @see 072 * org.graphstream.stream.file.gexf.GEXFElement#export(org.graphstream.stream 073 * .file.gexf.SmartXMLWriter) 074 */ 075 public void export(SmartXMLWriter stream) throws XMLStreamException { 076 stream.startElement("nodes"); 077 078 for (GEXFNode node : nodes.values()) 079 node.export(stream); 080 081 stream.endElement(); // NODES 082 } 083 084 /* 085 * (non-Javadoc) 086 * 087 * @see org.graphstream.stream.SinkAdapter#nodeAdded(java.lang.String, long, 088 * java.lang.String) 089 */ 090 public void nodeAdded(String sourceId, long timeId, String nodeId) { 091 GEXFNode node = nodes.get(nodeId); 092 093 if (node == null) { 094 node = new GEXFNode(root, nodeId); 095 nodes.put(nodeId, node); 096 } 097 098 node.spells.start(); 099 } 100 101 /* 102 * (non-Javadoc) 103 * 104 * @see org.graphstream.stream.SinkAdapter#nodeRemoved(java.lang.String, 105 * long, java.lang.String) 106 */ 107 public void nodeRemoved(String sourceId, long timeId, String nodeId) { 108 GEXFNode node = nodes.get(nodeId); 109 110 if (node == null) { 111 System.err.printf("node removed but not added\n"); 112 return; 113 } 114 115 node.spells.end(); 116 } 117 118 /* 119 * (non-Javadoc) 120 * 121 * @see 122 * org.graphstream.stream.SinkAdapter#nodeAttributeAdded(java.lang.String, 123 * long, java.lang.String, java.lang.String, java.lang.Object) 124 */ 125 public void nodeAttributeAdded(String sourceId, long timeId, String nodeId, 126 String attribute, Object value) { 127 GEXFNode node = nodes.get(nodeId); 128 129 if (("ui.label".equals(attribute) || "label".equals(attribute)) 130 && value != null) 131 node.label = value.toString(); 132 133 if ("xyz".equals(attribute)) { 134 float[] xyz = convertToXYZ(value); 135 136 switch (xyz.length) { 137 default: 138 node.z = xyz[2]; 139 case 2: 140 node.y = xyz[1]; 141 case 1: 142 node.x = xyz[0]; 143 case 0: 144 break; 145 } 146 147 node.position = true; 148 } 149 150 node.attvalues 151 .attributeUpdated(root.getNodeAttribute(attribute), value); 152 } 153 154 /* 155 * (non-Javadoc) 156 * 157 * @see 158 * org.graphstream.stream.SinkAdapter#nodeAttributeChanged(java.lang.String, 159 * long, java.lang.String, java.lang.String, java.lang.Object, 160 * java.lang.Object) 161 */ 162 public void nodeAttributeChanged(String sourceId, long timeId, 163 String nodeId, String attribute, Object oldValue, Object newValue) { 164 nodeAttributeAdded(sourceId, timeId, nodeId, attribute, newValue); 165 } 166 167 /* 168 * (non-Javadoc) 169 * 170 * @see 171 * org.graphstream.stream.SinkAdapter#nodeAttributeRemoved(java.lang.String, 172 * long, java.lang.String, java.lang.String) 173 */ 174 public void nodeAttributeRemoved(String sourceId, long timeId, 175 String nodeId, String attribute) { 176 GEXFNode node = nodes.get(nodeId); 177 node.attvalues.attributeUpdated(root.getNodeAttribute(attribute), null); 178 } 179 180 /* 181 * (non-Javadoc) 182 * 183 * @see org.graphstream.stream.SinkAdapter#graphCleared(java.lang.String, 184 * long) 185 */ 186 public void graphCleared(String sourceId, long timeId) { 187 for (GEXFNode node : nodes.values()) 188 node.spells.end(); 189 } 190}