1 | /* | |
2 | * Copyright 2006 - 2013 | |
3 | * Stefan Balev <stefan.balev@graphstream-project.org> | |
4 | * Julien Baudry <julien.baudry@graphstream-project.org> | |
5 | * Antoine Dutot <antoine.dutot@graphstream-project.org> | |
6 | * Yoann Pign�� <yoann.pigne@graphstream-project.org> | |
7 | * Guilhelm Savin <guilhelm.savin@graphstream-project.org> | |
8 | * | |
9 | * This file is part of GraphStream <http://graphstream-project.org>. | |
10 | * | |
11 | * GraphStream is a library whose purpose is to handle static or dynamic | |
12 | * graph, create them from scratch, file or any source and display them. | |
13 | * | |
14 | * This program is free software distributed under the terms of two licenses, the | |
15 | * CeCILL-C license that fits European law, and the GNU Lesser General Public | |
16 | * License. You can use, modify and/ or redistribute the software under the terms | |
17 | * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following | |
18 | * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by | |
19 | * the Free Software Foundation, either version 3 of the License, or (at your | |
20 | * option) any later version. | |
21 | * | |
22 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY | |
23 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | |
24 | * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. | |
25 | * | |
26 | * You should have received a copy of the GNU Lesser General Public License | |
27 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
28 | * | |
29 | * The fact that you are presently reading this means that you have had | |
30 | * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms. | |
31 | */ | |
32 | package org.graphstream.stream.file; | |
33 | ||
34 | import java.io.IOException; | |
35 | import java.io.PrintWriter; | |
36 | import java.util.Locale; | |
37 | ||
38 | /** | |
39 | * Transform the input events into a GML graph. | |
40 | * | |
41 | * <p> | |
42 | * THIS CLASS IS REALLY NOT APPROPRIATE FOR GENERAL USE. Indeed the GML format | |
43 | * is not dynamic and it is very difficult to export the correct attributes of | |
44 | * nodes if the declaration of the attribute is far from the declaration of the | |
45 | * node. The only way would be to store the graph in a buffer and output it at | |
46 | * once when the file is closed. | |
47 | * </p> | |
48 | * | |
49 | * <p> | |
50 | * Therefore this class outputs attributes of nodes and edges only if their | |
51 | * addition directly follows the corresponding node or edge. | |
52 | * </p> | |
53 | */ | |
54 | public class FileSinkGML extends FileSinkBase { | |
55 | // Attributes | |
56 | ||
57 | /** Alias on the output OutputStream. */ | |
58 | protected PrintWriter out; | |
59 | ||
60 | protected String nodeToFinish = null; | |
61 | ||
62 | protected String edgeToFinish = null; | |
63 | ||
64 | // Construction | |
65 | ||
66 | public FileSinkGML() { | |
67 | // NOP | |
68 | } | |
69 | ||
70 | // File format events | |
71 | ||
72 | @Override | |
73 | protected void outputHeader() throws IOException { | |
74 | out = (PrintWriter) output; | |
75 | ||
76 | out.printf("graph [%n"); | |
77 | } | |
78 | ||
79 | @Override | |
80 | protected void outputEndOfFile() throws IOException { | |
81 |
1
1. outputEndOfFile : removed call to org/graphstream/stream/file/FileSinkGML::ensureToFinish → NO_COVERAGE |
ensureToFinish(); |
82 | out.printf("]%n"); | |
83 | } | |
84 | ||
85 | // Attribute events | |
86 | ||
87 | public void graphAttributeAdded(String sourceId, long timeId, | |
88 | String attribute, Object value) { | |
89 |
1
1. graphAttributeAdded : removed call to org/graphstream/stream/file/FileSinkGML::ensureToFinish → NO_COVERAGE |
ensureToFinish(); |
90 | ||
91 | String val = valueToString(value); | |
92 | ||
93 |
1
1. graphAttributeAdded : negated conditional → NO_COVERAGE |
if (val != null) { |
94 | out.printf("\t%s %s%n", attribute, val); | |
95 | } | |
96 | } | |
97 | ||
98 | public void graphAttributeChanged(String sourceId, long timeId, | |
99 | String attribute, Object oldValue, Object newValue) { | |
100 |
1
1. graphAttributeChanged : removed call to org/graphstream/stream/file/FileSinkGML::ensureToFinish → NO_COVERAGE |
ensureToFinish(); |
101 | // GML is not a dynamic file format ? | |
102 | } | |
103 | ||
104 | public void graphAttributeRemoved(String sourceId, long timeId, | |
105 | String attribute) { | |
106 |
1
1. graphAttributeRemoved : removed call to org/graphstream/stream/file/FileSinkGML::ensureToFinish → NO_COVERAGE |
ensureToFinish(); |
107 | // GML is not a dynamic file format ? | |
108 | } | |
109 | ||
110 | public void nodeAttributeAdded(String sourceId, long timeId, String nodeId, | |
111 | String attribute, Object value) { | |
112 |
2
1. nodeAttributeAdded : negated conditional → NO_COVERAGE 2. nodeAttributeAdded : negated conditional → NO_COVERAGE |
if (nodeToFinish != null && nodeToFinish.equals(nodeId)) { |
113 | String val = valueToString(value); | |
114 | ||
115 |
1
1. nodeAttributeAdded : negated conditional → NO_COVERAGE |
if (val != null) { |
116 | out.printf("\t\t%s %s%n", attribute, val); | |
117 | } | |
118 | } else { | |
119 |
1
1. nodeAttributeAdded : removed call to org/graphstream/stream/file/FileSinkGML::ensureToFinish → NO_COVERAGE |
ensureToFinish(); |
120 | } | |
121 | } | |
122 | ||
123 | public void nodeAttributeChanged(String sourceId, long timeId, | |
124 | String nodeId, String attribute, Object oldValue, Object newValue) { | |
125 |
1
1. nodeAttributeChanged : negated conditional → NO_COVERAGE |
if (edgeToFinish != null) |
126 |
1
1. nodeAttributeChanged : removed call to org/graphstream/stream/file/FileSinkGML::ensureToFinish → NO_COVERAGE |
ensureToFinish(); |
127 | // GML is not a dynamic file format ? | |
128 | } | |
129 | ||
130 | public void nodeAttributeRemoved(String sourceId, long timeId, | |
131 | String nodeId, String attribute) { | |
132 |
1
1. nodeAttributeRemoved : negated conditional → NO_COVERAGE |
if (edgeToFinish != null) |
133 |
1
1. nodeAttributeRemoved : removed call to org/graphstream/stream/file/FileSinkGML::ensureToFinish → NO_COVERAGE |
ensureToFinish(); |
134 | // GML is not a dynamic file format ? | |
135 | } | |
136 | ||
137 | public void edgeAttributeAdded(String sourceId, long timeId, String edgeId, | |
138 | String attribute, Object value) { | |
139 |
2
1. edgeAttributeAdded : negated conditional → NO_COVERAGE 2. edgeAttributeAdded : negated conditional → NO_COVERAGE |
if (edgeToFinish != null && edgeToFinish.equals(edgeId)) { |
140 | String val = valueToString(value); | |
141 | ||
142 |
1
1. edgeAttributeAdded : negated conditional → NO_COVERAGE |
if (val != null) { |
143 | out.printf("\t\t%s %s%n", attribute, val); | |
144 | } | |
145 | } else { | |
146 |
1
1. edgeAttributeAdded : removed call to org/graphstream/stream/file/FileSinkGML::ensureToFinish → NO_COVERAGE |
ensureToFinish(); |
147 | } | |
148 | } | |
149 | ||
150 | public void edgeAttributeChanged(String sourceId, long timeId, | |
151 | String edgeId, String attribute, Object oldValue, Object newValue) { | |
152 |
1
1. edgeAttributeChanged : negated conditional → NO_COVERAGE |
if (nodeToFinish != null) |
153 |
1
1. edgeAttributeChanged : removed call to org/graphstream/stream/file/FileSinkGML::ensureToFinish → NO_COVERAGE |
ensureToFinish(); |
154 | // GML is not a dynamic file format ? | |
155 | } | |
156 | ||
157 | public void edgeAttributeRemoved(String sourceId, long timeId, | |
158 | String edgeId, String attribute) { | |
159 |
1
1. edgeAttributeRemoved : negated conditional → NO_COVERAGE |
if (nodeToFinish != null) |
160 |
1
1. edgeAttributeRemoved : removed call to org/graphstream/stream/file/FileSinkGML::ensureToFinish → NO_COVERAGE |
ensureToFinish(); |
161 | // GML is not a dynamic file format ? | |
162 | } | |
163 | ||
164 | // Element events | |
165 | ||
166 | public void nodeAdded(String sourceId, long timeId, String nodeId) { | |
167 |
1
1. nodeAdded : removed call to org/graphstream/stream/file/FileSinkGML::ensureToFinish → NO_COVERAGE |
ensureToFinish(); |
168 | out.printf("\tnode [%n"); | |
169 | out.printf("\t\tid \"%s\"%n", nodeId); | |
170 | nodeToFinish = nodeId; | |
171 | } | |
172 | ||
173 | public void nodeRemoved(String sourceId, long timeId, String nodeId) { | |
174 |
1
1. nodeRemoved : removed call to org/graphstream/stream/file/FileSinkGML::ensureToFinish → NO_COVERAGE |
ensureToFinish(); |
175 | } | |
176 | ||
177 | public void edgeAdded(String sourceId, long timeId, String edgeId, | |
178 | String fromNodeId, String toNodeId, boolean directed) { | |
179 |
1
1. edgeAdded : removed call to org/graphstream/stream/file/FileSinkGML::ensureToFinish → NO_COVERAGE |
ensureToFinish(); |
180 | out.printf("\tedge [%n"); | |
181 | out.printf("\t\tid \"%s\"%n", edgeId); | |
182 | out.printf("\t\tsource \"%s\"%n", fromNodeId); | |
183 | out.printf("\t\ttarget \"%s\"%n", toNodeId); | |
184 | edgeToFinish = edgeId; | |
185 | } | |
186 | ||
187 | public void edgeRemoved(String sourceId, long timeId, String edgeId) { | |
188 |
1
1. edgeRemoved : removed call to org/graphstream/stream/file/FileSinkGML::ensureToFinish → NO_COVERAGE |
ensureToFinish(); |
189 | } | |
190 | ||
191 | public void graphCleared(String sourceId, long timeId) { | |
192 | // Ah ah ah !! | |
193 | } | |
194 | ||
195 | public void stepBegins(String sourceId, long timeId, double step) { | |
196 | // NOP | |
197 | } | |
198 | ||
199 | // Commands | |
200 | ||
201 | protected String valueToString(Object value) { | |
202 |
1
1. valueToString : negated conditional → NO_COVERAGE |
if (value instanceof CharSequence) { |
203 |
1
1. valueToString : mutated return of Object value for org/graphstream/stream/file/FileSinkGML::valueToString to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return String.format("\"%s\"", (CharSequence) value); |
204 |
1
1. valueToString : negated conditional → NO_COVERAGE |
} else if (value instanceof Number) { |
205 | double val = ((Number)value).doubleValue(); | |
206 |
2
1. valueToString : Replaced double subtraction with addition → NO_COVERAGE 2. valueToString : negated conditional → NO_COVERAGE |
if((val-((int)val)) == 0) |
207 |
1
1. valueToString : mutated return of Object value for org/graphstream/stream/file/FileSinkGML::valueToString to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return String.format(Locale.US, "%d", (int)val); |
208 |
1
1. valueToString : mutated return of Object value for org/graphstream/stream/file/FileSinkGML::valueToString to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
else return String.format(Locale.US, "%f", val); |
209 |
1
1. valueToString : negated conditional → NO_COVERAGE |
} else if (value != null) { |
210 |
1
1. valueToString : mutated return of Object value for org/graphstream/stream/file/FileSinkGML::valueToString to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return String.format("\"%s\"", value.toString()); |
211 | } | |
212 | ||
213 |
1
1. valueToString : mutated return of Object value for org/graphstream/stream/file/FileSinkGML::valueToString to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return null; |
214 | } | |
215 | ||
216 | protected void ensureToFinish() { | |
217 | assert ((nodeToFinish != null && edgeToFinish == null) | |
218 | || (nodeToFinish == null && edgeToFinish != null) || (nodeToFinish == null && edgeToFinish == null)); | |
219 | ||
220 |
2
1. ensureToFinish : negated conditional → NO_COVERAGE 2. ensureToFinish : negated conditional → NO_COVERAGE |
if (nodeToFinish != null || edgeToFinish != null) { |
221 | out.printf("\t]%n"); | |
222 | nodeToFinish = null; | |
223 | edgeToFinish = null; | |
224 | } | |
225 | } | |
226 | } | |
Mutations | ||
81 |
1.1 |
|
89 |
1.1 |
|
93 |
1.1 |
|
100 |
1.1 |
|
106 |
1.1 |
|
112 |
1.1 2.2 |
|
115 |
1.1 |
|
119 |
1.1 |
|
125 |
1.1 |
|
126 |
1.1 |
|
132 |
1.1 |
|
133 |
1.1 |
|
139 |
1.1 2.2 |
|
142 |
1.1 |
|
146 |
1.1 |
|
152 |
1.1 |
|
153 |
1.1 |
|
159 |
1.1 |
|
160 |
1.1 |
|
167 |
1.1 |
|
174 |
1.1 |
|
179 |
1.1 |
|
188 |
1.1 |
|
202 |
1.1 |
|
203 |
1.1 |
|
204 |
1.1 |
|
206 |
1.1 2.2 |
|
207 |
1.1 |
|
208 |
1.1 |
|
209 |
1.1 |
|
210 |
1.1 |
|
213 |
1.1 |
|
220 |
1.1 2.2 |