1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.dbunit.dataset.xml;
22
23 import java.io.IOException;
24 import java.io.OutputStream;
25 import java.io.UnsupportedEncodingException;
26 import java.io.Writer;
27 import java.nio.charset.Charset;
28
29 import org.dbunit.dataset.Column;
30 import org.dbunit.dataset.DataSetException;
31 import org.dbunit.dataset.IDataSet;
32 import org.dbunit.dataset.ITable;
33 import org.dbunit.dataset.ITableMetaData;
34 import org.dbunit.dataset.datatype.DataType;
35 import org.dbunit.dataset.datatype.TypeCastException;
36 import org.dbunit.dataset.stream.DataSetProducerAdapter;
37 import org.dbunit.dataset.stream.IDataSetConsumer;
38 import org.dbunit.util.xml.XmlWriter;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42
43
44
45
46
47
48 public class XmlDataSetWriter implements IDataSetConsumer
49 {
50
51
52
53
54 private static final Logger logger = LoggerFactory.getLogger(XmlDataSetWriter.class);
55
56 private static final String DATASET = "dataset";
57 private static final String TABLE = "table";
58 private static final String NAME = "name";
59 private static final String COLUMN = "column";
60 private static final String ROW = "row";
61 private static final String VALUE = "value";
62 private static final String NULL = "null";
63 private static final String NONE = "none";
64
65 static char[] CDATA_DETECTION_CHARS = new char[] {
66 0x20, '\n', '\r', '\t',
67 '&', '<',
68 };
69
70 private XmlWriter _xmlWriter;
71 private ITableMetaData _activeMetaData;
72 private boolean includeColumnComments = false;
73
74
75
76
77
78
79
80
81 public XmlDataSetWriter(OutputStream outputStream, Charset charset)
82 {
83 _xmlWriter = new XmlWriter(outputStream, charset);
84 _xmlWriter.enablePrettyPrint(true);
85 }
86
87 public XmlDataSetWriter(Writer writer)
88 {
89 _xmlWriter = new XmlWriter(writer);
90 _xmlWriter.enablePrettyPrint(true);
91 }
92
93 public XmlDataSetWriter(Writer writer, Charset charset)
94 {
95 _xmlWriter = new XmlWriter(writer, charset);
96 _xmlWriter.enablePrettyPrint(true);
97 }
98
99
100
101
102
103
104
105 public void setPrettyPrint(boolean enabled)
106 {
107 _xmlWriter.enablePrettyPrint(enabled);
108 }
109
110
111
112
113
114 public void setIncludeColumnComments(boolean includeColumnComments)
115 {
116 this.includeColumnComments = includeColumnComments;
117 }
118
119
120
121
122
123
124 public void write(IDataSet dataSet) throws DataSetException
125 {
126 logger.trace("write(dataSet{}) - start", dataSet);
127
128 DataSetProducerAdapter provider = new DataSetProducerAdapter(dataSet);
129 provider.setConsumer(this);
130 provider.produce();
131 }
132
133 boolean needsCData(String text)
134 {
135 logger.trace("needsCData(text={}) - start", text);
136
137 if (text == null)
138 {
139 return false;
140 }
141
142 for (int i = 0; i < text.length(); i++)
143 {
144 char c = text.charAt(i);
145 for (int j = 0; j < CDATA_DETECTION_CHARS.length; j++)
146 {
147 if (CDATA_DETECTION_CHARS[j] == c)
148 {
149 return true;
150 }
151 }
152 }
153 return false;
154 }
155
156
157
158
159 public void startDataSet() throws DataSetException
160 {
161 logger.trace("startDataSet() - start");
162
163 try
164 {
165 _xmlWriter.writeDeclaration();
166 _xmlWriter.writeElement(DATASET);
167 }
168 catch (IOException e)
169 {
170 throw new DataSetException(e);
171 }
172 }
173
174 public void endDataSet() throws DataSetException
175 {
176 logger.trace("endDataSet() - start");
177
178 try
179 {
180 _xmlWriter.endElement();
181 _xmlWriter.close();
182 }
183 catch (IOException e)
184 {
185 throw new DataSetException(e);
186 }
187 }
188
189 public void startTable(ITableMetaData metaData) throws DataSetException
190 {
191 logger.trace("startTable(metaData={}) - start", metaData);
192
193 try
194 {
195 _activeMetaData = metaData;
196
197 String tableName = _activeMetaData.getTableName();
198 _xmlWriter.writeElement(TABLE);
199 _xmlWriter.writeAttribute(NAME, tableName);
200
201 Column[] columns = _activeMetaData.getColumns();
202 for (int i = 0; i < columns.length; i++)
203 {
204 String columnName = columns[i].getColumnName();
205 _xmlWriter.writeElementWithText(COLUMN, columnName);
206 }
207 }
208 catch (IOException e)
209 {
210 throw new DataSetException(e);
211 }
212
213 }
214
215 public void endTable() throws DataSetException
216 {
217 logger.trace("endTable() - start");
218
219 try
220 {
221 _xmlWriter.endElement();
222 _activeMetaData = null;
223 }
224 catch (IOException e)
225 {
226 throw new DataSetException(e);
227 }
228 }
229
230 public void row(Object[] values) throws DataSetException
231 {
232 logger.trace("row(values={}) - start", values);
233
234 try
235 {
236 _xmlWriter.writeElement(ROW);
237
238 Column[] columns = _activeMetaData.getColumns();
239 for (int i = 0; i < columns.length; i++)
240 {
241 String columnName = columns[i].getColumnName();
242 Object value = values[i];
243
244
245 if (value == null)
246 {
247 _xmlWriter.writeEmptyElement(NULL);
248 }
249
250 else if (value == ITable.NO_VALUE)
251 {
252 _xmlWriter.writeEmptyElement(NONE);
253 }
254
255 else
256 {
257 try
258 {
259 String stringValue = DataType.asString(value);
260
261 _xmlWriter.writeElement(VALUE);
262 if (needsCData(stringValue))
263 {
264 writeValueCData(stringValue);
265 }
266 else if (stringValue.length() > 0)
267 {
268 writeValue(stringValue);
269 }
270 _xmlWriter.endElement();
271 }
272 catch (TypeCastException e)
273 {
274 throw new DataSetException("table=" +
275 _activeMetaData.getTableName() + ", row=" + i +
276 ", column=" + columnName +
277 ", value=" + value, e);
278 }
279 }
280 if ( this.includeColumnComments ) {
281 _xmlWriter.writeComment( columnName );
282 }
283 }
284 _xmlWriter.endElement();
285 }
286 catch (IOException e)
287 {
288 throw new DataSetException(e);
289 }
290 }
291
292
293
294
295
296
297
298
299
300 protected void writeValueCData(String stringValue) throws IOException
301 {
302 logger.trace("writeValueCData(stringValue={}) - start", stringValue);
303 _xmlWriter.writeCData(stringValue);
304 }
305
306
307
308
309
310
311
312
313
314 protected void writeValue(String stringValue) throws IOException
315 {
316 logger.trace("writeValue(stringValue={}) - start", stringValue);
317 _xmlWriter.writeText(stringValue);
318 }
319
320
321
322
323
324 protected final XmlWriter getXmlWriter()
325 {
326 return _xmlWriter;
327 }
328 }