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.net.URI;
033import java.net.URL;
034import java.util.Collection;
035import java.util.HashMap;
036
037import javax.xml.stream.XMLStreamException;
038
039import org.graphstream.stream.AttributeSink;
040
041public class GEXFAttributes implements GEXFElement, AttributeSink {
042        GEXF root;
043
044        ClassType type;
045        Mode mode;
046
047        HashMap<String, GEXFAttribute> attributes;
048
049        public GEXFAttributes(GEXF root, ClassType type) {
050                this.root = root;
051
052                this.type = type;
053                this.mode = Mode.STATIC;
054                this.attributes = new HashMap<String, GEXFAttribute>();
055
056                root.addAttributeSink(this);
057        }
058
059        protected void checkAttribute(String key, Object value) {
060                AttrType type = detectType(value);
061
062                if (!attributes.containsKey(key))
063                        attributes.put(key, new GEXFAttribute(root, key, type));
064                else {
065                        GEXFAttribute a = attributes.get(key);
066
067                        if (a.type != type && value != null)
068                                a.type = AttrType.STRING;
069                }
070        }
071
072        protected AttrType detectType(Object value) {
073                if (value == null)
074                        return AttrType.STRING;
075
076                if (value instanceof Integer || value instanceof Short)
077                        return AttrType.INTEGER;
078                else if (value instanceof Long)
079                        return AttrType.LONG;
080                else if (value instanceof Float)
081                        return AttrType.FLOAT;
082                else if (value instanceof Double)
083                        return AttrType.DOUBLE;
084                else if (value instanceof Boolean)
085                        return AttrType.BOOLEAN;
086                else if (value instanceof URL || value instanceof URI)
087                        return AttrType.ANYURI;
088                else if (value.getClass().isArray() || value instanceof Collection)
089                        return AttrType.LISTSTRING;
090
091                return AttrType.STRING;
092        }
093
094        /*
095         * (non-Javadoc)
096         * 
097         * @see
098         * org.graphstream.stream.file.gexf.GEXFElement#export(org.graphstream.stream
099         * .file.gexf.SmartXMLWriter)
100         */
101        public void export(SmartXMLWriter stream) throws XMLStreamException {
102                if (attributes.size() == 0)
103                        return;
104
105                stream.startElement("attributes");
106                stream.stream.writeAttribute("class", type.qname);
107
108                for (GEXFAttribute attribute : attributes.values())
109                        attribute.export(stream);
110
111                stream.endElement(); // ATTRIBUTES
112        }
113
114        /*
115         * (non-Javadoc)
116         * 
117         * @see
118         * org.graphstream.stream.AttributeSink#nodeAttributeAdded(java.lang.String,
119         * long, java.lang.String, java.lang.String, java.lang.Object)
120         */
121        public void nodeAttributeAdded(String sourceId, long timeId, String nodeId,
122                        String attribute, Object value) {
123                if (type == ClassType.NODE)
124                        checkAttribute(attribute, value);
125        }
126
127        /*
128         * (non-Javadoc)
129         * 
130         * @see
131         * org.graphstream.stream.AttributeSink#nodeAttributeChanged(java.lang.String
132         * , long, java.lang.String, java.lang.String, java.lang.Object,
133         * java.lang.Object)
134         */
135        public void nodeAttributeChanged(String sourceId, long timeId,
136                        String nodeId, String attribute, Object oldValue, Object newValue) {
137                if (type == ClassType.NODE)
138                        checkAttribute(attribute, newValue);
139        }
140
141        /*
142         * (non-Javadoc)
143         * 
144         * @see
145         * org.graphstream.stream.AttributeSink#edgeAttributeAdded(java.lang.String,
146         * long, java.lang.String, java.lang.String, java.lang.Object)
147         */
148        public void edgeAttributeAdded(String sourceId, long timeId, String edgeId,
149                        String attribute, Object value) {
150                if (type == ClassType.EDGE)
151                        checkAttribute(attribute, value);
152        }
153
154        /*
155         * (non-Javadoc)
156         * 
157         * @see
158         * org.graphstream.stream.AttributeSink#edgeAttributeChanged(java.lang.String
159         * , long, java.lang.String, java.lang.String, java.lang.Object,
160         * java.lang.Object)
161         */
162        public void edgeAttributeChanged(String sourceId, long timeId,
163                        String edgeId, String attribute, Object oldValue, Object newValue) {
164                if (type == ClassType.EDGE)
165                        checkAttribute(attribute, newValue);
166        }
167
168        /*
169         * (non-Javadoc)
170         * 
171         * @see
172         * org.graphstream.stream.AttributeSink#nodeAttributeRemoved(java.lang.String
173         * , long, java.lang.String, java.lang.String)
174         */
175        public void nodeAttributeRemoved(String sourceId, long timeId,
176                        String nodeId, String attribute) {
177        }
178
179        /*
180         * (non-Javadoc)
181         * 
182         * @see
183         * org.graphstream.stream.AttributeSink#graphAttributeAdded(java.lang.String
184         * , long, java.lang.String, java.lang.Object)
185         */
186        public void graphAttributeAdded(String sourceId, long timeId,
187                        String attribute, Object value) {
188        }
189
190        /*
191         * (non-Javadoc)
192         * 
193         * @see
194         * org.graphstream.stream.AttributeSink#graphAttributeChanged(java.lang.
195         * String, long, java.lang.String, java.lang.Object, java.lang.Object)
196         */
197        public void graphAttributeChanged(String sourceId, long timeId,
198                        String attribute, Object oldValue, Object newValue) {
199        }
200
201        /*
202         * (non-Javadoc)
203         * 
204         * @see
205         * org.graphstream.stream.AttributeSink#graphAttributeRemoved(java.lang.
206         * String, long, java.lang.String)
207         */
208        public void graphAttributeRemoved(String sourceId, long timeId,
209                        String attribute) {
210        }
211
212        /*
213         * (non-Javadoc)
214         * 
215         * @see
216         * org.graphstream.stream.AttributeSink#edgeAttributeRemoved(java.lang.String
217         * , long, java.lang.String, java.lang.String)
218         */
219        public void edgeAttributeRemoved(String sourceId, long timeId,
220                        String edgeId, String attribute) {
221        }
222}