View Javadoc
1   /*
2   *
3   * The DbUnit Database Testing Framework
4   * Copyright (C)2002-2004, DbUnit.org
5   *
6   * This library is free software; you can redistribute it and/or
7   * modify it under the terms of the GNU Lesser General Public
8   * License as published by the Free Software Foundation; either
9   * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21  package org.dbunit.dataset.csv;
22  
23  import org.slf4j.Logger;
24  import org.slf4j.LoggerFactory;
25  
26  import java.io.IOException;
27  import java.net.URL;
28  import java.util.Iterator;
29  import java.util.List;
30  
31  import org.dbunit.dataset.Column;
32  import org.dbunit.dataset.DataSetException;
33  import org.dbunit.dataset.DefaultTableMetaData;
34  import org.dbunit.dataset.ITableMetaData;
35  import org.dbunit.dataset.datatype.DataType;
36  import org.dbunit.dataset.stream.DefaultConsumer;
37  import org.dbunit.dataset.stream.IDataSetConsumer;
38  import org.dbunit.dataset.stream.IDataSetProducer;
39  
40  /**
41   * A {@link IDataSetProducer Data Set Producer} that produces datasets from 
42   * CVS files found at a base URL.
43   * 
44   * Based HEAVILY on {@link org.dbunit.dataset.csv.CsvProducer}.
45   *  
46   * @author Dion Gillard
47   * @author Federico Spinazzi
48   * @author Last changed by: $Author$
49   * @version $Revision$ $Date$
50   * @since Sep 12, 2004 (pre 2.3)
51   */
52  public class CsvURLProducer implements IDataSetProducer {
53  
54      /**
55       * Logger for this class
56       */
57      private static final Logger logger = LoggerFactory.getLogger(CsvURLProducer.class);
58  
59  	/** the default consumer - does nothing */
60      private static final IDataSetConsumer EMPTY_CONSUMER = new DefaultConsumer();
61  
62      /**
63       * the consumer of the produced datasets, by default a 
64       * {@link DefaultConsumer}
65       */
66      private IDataSetConsumer _consumer = EMPTY_CONSUMER;
67      
68      /** the base url to retrieve data from */
69      private URL base;
70  
71      /** the offset from the base url where the list of tables can be found */
72      private String tableList;
73      
74      /**
75       * Create a CSV Data Set Producer which uses the base URL to retrieve 
76       * a list of tables and the data.
77       * @param base the URL where the tableList and data can be found. 
78       * @param tableList the relative location of the list of tables.
79       */
80      public CsvURLProducer(URL base, String tableList)
81      {
82      	this.base = base;
83      	this.tableList = tableList;
84      }
85      
86      /*
87  	 * @see IDataSetProducer#setConsumer(org.dbunit.dataset.stream.IDataSetConsumer)
88  	 */
89  	public void setConsumer(IDataSetConsumer consumer) throws DataSetException {
90          logger.debug("setConsumer(consumer) - start");
91  
92  		_consumer = consumer;
93  	}
94  
95  	/*
96  	 * @see IDataSetProducer#produce()
97  	 */
98  	public void produce() throws DataSetException {
99          logger.debug("produce() - start");
100 
101         _consumer.startDataSet();
102         try {
103         	List tableSpecs = CsvProducer.getTables(base, tableList);
104         	for (Iterator tableIter = tableSpecs.iterator(); tableIter.hasNext();) {
105 				String table = (String) tableIter.next();
106 	            try {
107 	                produceFromURL(new URL(base, table + ".csv"));
108 	            } catch (CsvParserException e) {
109 	                throw new DataSetException("error producing dataset for table '" + table + "'", e);
110 	            }
111 
112 			}
113             _consumer.endDataSet();
114         } catch (IOException e) {
115         	throw new DataSetException("error getting list of tables", e);
116         }
117 	}
118 
119 	/**
120 	 * Produce a dataset from a URL. 
121 	 * The URL is assumed to contain data in CSV format.
122 	 * @param url a url containing CSV data.
123 	 */
124 	private void produceFromURL(URL url) throws DataSetException {
125         logger.debug("produceFromURL(url=" + url + ") - start");
126 
127         try {
128             CsvParser parser = new CsvParserImpl();
129             List readData = parser.parse(url);
130             List readColumns = (List) readData.get(0);
131             Column[] columns = new Column[readColumns.size()];
132 
133             for (int i = 0; i < readColumns.size(); i++) {
134                 columns[i] = new Column((String) readColumns.get(i), DataType.UNKNOWN);
135             }
136 
137             String tableName = url.getFile();
138             tableName = tableName.substring(tableName.lastIndexOf("/")+1, tableName.indexOf(".csv"));
139             ITableMetaData metaData = new DefaultTableMetaData(tableName, columns);
140             _consumer.startTable(metaData);
141             for (int i = 1 ; i < readData.size(); i++) {
142                 List rowList = (List)readData.get(i);
143                 Object[] row = rowList.toArray();
144                 for(int col = 0; col < row.length; col++) {
145                 	if (CsvDataSetWriter.NULL.equals(row[col])) {
146                 		row[col] = null;
147                 	}
148                 }
149                 _consumer.row(row);
150             }
151             _consumer.endTable();
152         } catch (CsvParserException e) {
153         	throw new DataSetException("error parsing CSV for URL: '" + url + "'", e);
154 		} catch (IOException e) {
155         	throw new DataSetException("I/O error parsing CSV for URL: '" + url + "'", e);
156 		}
157 	}
158 }