001: /*
002: *
003: * The DbUnit Database Testing Framework
004: * Copyright (C)2002-2006, DbUnit.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: */
021: package org.dbunit.dataset.xml;
022:
023: import org.slf4j.Logger;
024: import org.slf4j.LoggerFactory;
025:
026: import org.dbunit.dataset.*;
027: import org.dbunit.dataset.datatype.DataType;
028: import org.dbunit.dataset.datatype.TypeCastException;
029: import org.dbunit.dataset.stream.DataSetProducerAdapter;
030: import org.dbunit.dataset.stream.IDataSetConsumer;
031: import org.dbunit.util.xml.XmlWriter;
032:
033: import java.io.IOException;
034: import java.io.Writer;
035:
036: /**
037: * @author Manuel Laflamme
038: * @since Jun 13, 2003
039: * @version $Revision: 554 $
040: */
041: public class XmlDataSetWriter implements IDataSetConsumer {
042:
043: /**
044: * Logger for this class
045: */
046: private static final Logger logger = LoggerFactory
047: .getLogger(XmlDataSetWriter.class);
048:
049: private static final String DATASET = "dataset";
050: private static final String TABLE = "table";
051: private static final String NAME = "name";
052: private static final String COLUMN = "column";
053: private static final String ROW = "row";
054: private static final String VALUE = "value";
055: private static final String NULL = "null";
056: private static final String NONE = "none";
057:
058: static char[] CDATA_DETECTION_CHARS = new char[] { 0x20, '\n',
059: '\r', '\t', // whitespace
060: '&', '<', // forbiden char
061: };
062:
063: private XmlWriter _xmlWriter;
064: private ITableMetaData _activeMetaData;
065:
066: public XmlDataSetWriter(Writer writer) {
067: _xmlWriter = new XmlWriter(writer);
068: _xmlWriter.enablePrettyPrint(true);
069: }
070:
071: public XmlDataSetWriter(Writer writer, String encoding) {
072: _xmlWriter = new XmlWriter(writer, encoding);
073: _xmlWriter.enablePrettyPrint(true);
074: }
075:
076: public void write(IDataSet dataSet) throws DataSetException {
077: logger.debug("write(dataSet=" + dataSet + ") - start");
078:
079: DataSetProducerAdapter provider = new DataSetProducerAdapter(
080: dataSet);
081: provider.setConsumer(this );
082: provider.produce();
083: }
084:
085: boolean needsCData(String text) {
086: logger.debug("needsCData(text=" + text + ") - start");
087:
088: if (text == null) {
089: return false;
090: }
091:
092: for (int i = 0; i < text.length(); i++) {
093: char c = text.charAt(i);
094: for (int j = 0; j < CDATA_DETECTION_CHARS.length; j++) {
095: if (CDATA_DETECTION_CHARS[j] == c) {
096: return true;
097: }
098: }
099: }
100: return false;
101: }
102:
103: ////////////////////////////////////////////////////////////////////////////
104: // IDataSetConsumer interface
105:
106: public void startDataSet() throws DataSetException {
107: logger.debug("startDataSet() - start");
108:
109: try {
110: _xmlWriter.writeDeclaration();
111: _xmlWriter.writeElement(DATASET);
112: } catch (IOException e) {
113: logger.error("startDataSet()", e);
114:
115: throw new DataSetException(e);
116: }
117: }
118:
119: public void endDataSet() throws DataSetException {
120: logger.debug("endDataSet() - start");
121:
122: try {
123: _xmlWriter.endElement();
124: _xmlWriter.close();
125: } catch (IOException e) {
126: logger.error("endDataSet()", e);
127:
128: throw new DataSetException(e);
129: }
130: }
131:
132: public void startTable(ITableMetaData metaData)
133: throws DataSetException {
134: logger.debug("startTable(metaData=" + metaData + ") - start");
135:
136: try {
137: _activeMetaData = metaData;
138:
139: String tableName = _activeMetaData.getTableName();
140: _xmlWriter.writeElement(TABLE);
141: _xmlWriter.writeAttribute(NAME, tableName);
142:
143: Column[] columns = _activeMetaData.getColumns();
144: for (int i = 0; i < columns.length; i++) {
145: String columnName = columns[i].getColumnName();
146: _xmlWriter.writeElementWithText(COLUMN, columnName);
147: }
148: } catch (IOException e) {
149: logger.error("startTable()", e);
150:
151: throw new DataSetException(e);
152: }
153:
154: }
155:
156: public void endTable() throws DataSetException {
157: logger.debug("endTable() - start");
158:
159: try {
160: _xmlWriter.endElement();
161: _activeMetaData = null;
162: } catch (IOException e) {
163: logger.error("endTable()", e);
164:
165: throw new DataSetException(e);
166: }
167: }
168:
169: public void row(Object[] values) throws DataSetException {
170: logger.debug("row(values=" + values + ") - start");
171:
172: try {
173: _xmlWriter.writeElement(ROW);
174:
175: Column[] columns = _activeMetaData.getColumns();
176: for (int i = 0; i < columns.length; i++) {
177: String columnName = columns[i].getColumnName();
178: Object value = values[i];
179:
180: // null
181: if (value == null) {
182: _xmlWriter.writeEmptyElement(NULL);
183: }
184: // none
185: else if (value == ITable.NO_VALUE) {
186: _xmlWriter.writeEmptyElement(NONE);
187: }
188: // values
189: else {
190: try {
191: String stringValue = DataType.asString(value);
192:
193: _xmlWriter.writeElement(VALUE);
194: if (needsCData(stringValue)) {
195: _xmlWriter.writeCData(stringValue);
196: } else if (stringValue.length() > 0) {
197: _xmlWriter.writeText(stringValue);
198: }
199: _xmlWriter.endElement();
200: } catch (TypeCastException e) {
201: logger.error("row()", e);
202:
203: throw new DataSetException("table="
204: + _activeMetaData.getTableName()
205: + ", row=" + i + ", column="
206: + columnName + ", value=" + value, e);
207: }
208: }
209: if (this .includeColumnComments) {
210: _xmlWriter.writeComment(columnName);
211: }
212: }
213: _xmlWriter.endElement();
214: } catch (IOException e) {
215: logger.error("row()", e);
216:
217: throw new DataSetException(e);
218: }
219: }
220:
221: private boolean includeColumnComments = false;
222:
223: public void setIncludeColumnComments(boolean b) {
224: logger.debug("setIncludeColumnComments(b=" + b + ") - start");
225:
226: this.includeColumnComments = b;
227: }
228: }
|