1 21 package org.dbunit.dataset.xml; 22 23 import org.dbunit.dataset.*; 24 import org.dbunit.dataset.datatype.DataType; 25 import org.dbunit.dataset.stream.DefaultConsumer; 26 import org.dbunit.dataset.stream.IDataSetConsumer; 27 import org.dbunit.dataset.stream.IDataSetProducer; 28 import org.xml.sax.*; 29 import org.xml.sax.helpers.DefaultHandler ; 30 31 import javax.xml.parsers.ParserConfigurationException ; 32 import javax.xml.parsers.SAXParserFactory ; 33 import java.io.IOException ; 34 import java.io.StringReader ; 35 36 41 public class FlatXmlProducer extends DefaultHandler 42 implements IDataSetProducer, ContentHandler 43 { 44 private static final IDataSetConsumer EMPTY_CONSUMER = new DefaultConsumer(); 45 private static final String DATASET = "dataset"; 46 47 private final InputSource _inputSource; 48 private final EntityResolver _resolver; 49 private final boolean _dtdMetadata; 50 private boolean _validating = false; 51 private IDataSet _metaDataSet; 52 53 private IDataSetConsumer _consumer = EMPTY_CONSUMER; 54 private ITableMetaData _activeMetaData; 55 56 public FlatXmlProducer(InputSource xmlSource) 57 { 58 _inputSource = xmlSource; 59 _resolver = this; 60 _dtdMetadata = true; 61 _validating = false; 62 } 63 64 public FlatXmlProducer(InputSource xmlSource, boolean dtdMetadata) 65 { 66 _inputSource = xmlSource; 67 _resolver = this; 68 _dtdMetadata = dtdMetadata; 69 _validating = false; 70 } 71 72 public FlatXmlProducer(InputSource xmlSource, IDataSet metaDataSet) 73 { 74 _inputSource = xmlSource; 75 _metaDataSet = metaDataSet; 76 _resolver = this; 77 _dtdMetadata = false; 78 _validating = false; 79 } 80 81 public FlatXmlProducer(InputSource xmlSource, EntityResolver resolver) 82 { 83 _inputSource = xmlSource; 84 _resolver = resolver; 85 _dtdMetadata = true; 86 _validating = false; 87 } 88 89 95 private ITableMetaData createTableMetaData(String tableName, 96 Attributes attributes) throws DataSetException 97 { 98 if (_metaDataSet != null) 99 { 100 return _metaDataSet.getTableMetaData(tableName); 101 } 102 103 Column[] columns = new Column[attributes.getLength()]; 105 for (int i = 0; i < attributes.getLength(); i++) 106 { 107 columns[i] = new Column(attributes.getQName(i), 108 DataType.UNKNOWN); 109 } 110 111 return new DefaultTableMetaData(tableName, columns); 112 } 113 114 public void setValidating(boolean validating) 115 { 116 _validating = validating; 117 } 118 119 122 public void setConsumer(IDataSetConsumer consumer) throws DataSetException 123 { 124 _consumer = consumer; 125 } 126 127 public void produce() throws DataSetException 128 { 129 try 130 { 131 SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); 132 saxParserFactory.setValidating(_validating); 133 XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader(); 134 135 if (_dtdMetadata) 136 { 137 FlatDtdHandler dtdHandler = new FlatDtdHandler(); 138 FlatDtdHandler.setLexicalHandler(xmlReader, dtdHandler); 139 FlatDtdHandler.setDeclHandler(xmlReader, dtdHandler); 140 } 141 142 xmlReader.setContentHandler(this); 143 xmlReader.setErrorHandler(this); 144 xmlReader.setEntityResolver(_resolver); 145 xmlReader.parse(_inputSource); 146 } 147 catch (ParserConfigurationException e) 148 { 149 throw new DataSetException(e); 150 } 151 catch (SAXException e) 152 { 153 int lineNumber = -1; 154 if (e instanceof SAXParseException) 155 { 156 lineNumber = ((SAXParseException)e).getLineNumber(); 157 } 158 Exception exception = e.getException() == null ? e : e.getException(); 159 160 if (lineNumber >= 0) 161 { 162 String message = "Line " + lineNumber + ": " + exception.getMessage(); 163 throw new DataSetException(message, e); 164 } 165 throw new DataSetException(exception); 166 } 167 catch (IOException e) 168 { 169 throw new DataSetException(e); 170 } 171 } 172 173 176 public InputSource resolveEntity(String publicId, String systemId) 177 throws SAXException 178 { 179 if (!_dtdMetadata) 180 { 181 return new InputSource(new StringReader ("")); 182 } 183 return null; 184 } 185 186 189 public void error(SAXParseException e) throws SAXException 190 { 191 throw e; 192 193 } 194 195 198 public void startElement(String uri, String localName, String qName, 199 Attributes attributes) throws SAXException 200 { 201 try 202 { 203 if (_activeMetaData == null && qName.equals(DATASET)) 205 { 206 _consumer.startDataSet(); 207 return; 208 } 209 210 if (_activeMetaData == null || 212 !_activeMetaData.getTableName().equals(qName)) 213 { 214 if (_activeMetaData != null) 216 { 217 _consumer.endTable(); 218 } 219 220 _activeMetaData = createTableMetaData(qName, attributes); 222 _consumer.startTable(_activeMetaData); 223 } 224 225 if (attributes.getLength() > 0) 227 { 228 Column[] columns = _activeMetaData.getColumns(); 229 Object [] rowValues = new Object [columns.length]; 230 for (int i = 0; i < columns.length; i++) 231 { 232 Column column = columns[i]; 233 rowValues[i] = attributes.getValue(column.getColumnName()); 234 } 235 _consumer.row(rowValues); 236 } 237 } 238 catch (DataSetException e) 239 { 240 throw new SAXException(e); 241 } 242 } 243 244 public void endElement(String uri, String localName, String qName) throws SAXException 245 { 246 if (qName.equals(DATASET)) 248 { 249 try 250 { 251 if (_activeMetaData != null) 253 { 254 _consumer.endTable(); 255 } 256 257 _consumer.endDataSet(); 259 } 260 catch (DataSetException e) 261 { 262 throw new SAXException(e); 263 } 264 } 265 } 266 267 private class FlatDtdHandler extends FlatDtdProducer 268 { 269 public FlatDtdHandler() 270 { 271 } 272 273 276 public void startDTD(String name, String publicId, String systemId) 277 throws SAXException 278 { 279 try 280 { 281 FlatDtdDataSet metaDataSet = new FlatDtdDataSet(); 283 this.setConsumer(metaDataSet); 284 _metaDataSet = metaDataSet; 285 286 super.startDTD(name, publicId, systemId); 287 } 288 catch (DataSetException e) 289 { 290 throw new SAXException(e); 291 } 292 } 293 } 294 295 } 296 | Popular Tags |