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.ant;
22  
23  import java.io.File;
24  import java.io.IOException;
25  import java.net.MalformedURLException;
26  import java.sql.SQLException;
27  import java.util.ArrayList;
28  import java.util.Iterator;
29  import java.util.List;
30  
31  import org.apache.tools.ant.ProjectComponent;
32  import org.dbunit.DatabaseUnitException;
33  import org.dbunit.database.DatabaseConfig;
34  import org.dbunit.database.IDatabaseConnection;
35  import org.dbunit.database.QueryDataSet;
36  import org.dbunit.dataset.CachedDataSet;
37  import org.dbunit.dataset.CompositeDataSet;
38  import org.dbunit.dataset.DataSetException;
39  import org.dbunit.dataset.ForwardOnlyDataSet;
40  import org.dbunit.dataset.IDataSet;
41  import org.dbunit.dataset.csv.CsvProducer;
42  import org.dbunit.dataset.excel.XlsDataSet;
43  import org.dbunit.dataset.stream.IDataSetProducer;
44  import org.dbunit.dataset.stream.StreamingDataSet;
45  import org.dbunit.dataset.xml.FlatDtdProducer;
46  import org.dbunit.dataset.xml.FlatXmlProducer;
47  import org.dbunit.dataset.xml.XmlProducer;
48  import org.dbunit.util.FileHelper;
49  import org.slf4j.Logger;
50  import org.slf4j.LoggerFactory;
51  import org.xml.sax.InputSource;
52  
53  /**
54   * @author Manuel Laflamme
55   * @author Last changed by: $Author$
56   * @version $Revision$ $Date$
57   * @since 2.1 (Apr 3, 2004)
58   */
59  public abstract class AbstractStep extends ProjectComponent implements DbUnitTaskStep
60  {
61  
62      /**
63       * Logger for this class
64       */
65      private static final Logger logger = LoggerFactory.getLogger(AbstractStep.class);
66  
67      public static final String FORMAT_FLAT = "flat";
68      public static final String FORMAT_XML = "xml";
69      public static final String FORMAT_DTD = "dtd";
70      public static final String FORMAT_CSV = "csv";
71      public static final String FORMAT_XLS = "xls";
72  
73      private boolean ordered = false;
74  
75      
76      protected IDataSet getDatabaseDataSet(IDatabaseConnection connection,
77              List tables) throws DatabaseUnitException
78      {
79      	if (logger.isDebugEnabled())
80      	{
81              logger.debug("getDatabaseDataSet(connection={}, tables={}) - start",
82              		new Object[] { connection, tables});
83      	}
84  
85          try
86          {
87              DatabaseConfig config = connection.getConfig();
88  
89              // Retrieve the complete database if no tables or queries specified.
90              if (tables.size() == 0)
91              {
92              	logger.debug("Retrieving the whole database because tables/queries have not been specified");
93                  return connection.createDataSet();
94              }
95  
96              List queryDataSets = createQueryDataSet(tables, connection);
97  
98              IDataSet[] dataSetsArray = null;
99              if (config.getProperty(DatabaseConfig.PROPERTY_RESULTSET_TABLE_FACTORY)
100                     .getClass().getName().equals("org.dbunit.database.ForwardOnlyResultSetTableFactory")) {
101                 dataSetsArray = (IDataSet[]) createForwardOnlyDataSetArray(queryDataSets);
102             } else {
103                 dataSetsArray = (IDataSet[]) queryDataSets.toArray(new IDataSet[queryDataSets.size()]);
104             }
105             return new CompositeDataSet(dataSetsArray);
106         }
107         catch (SQLException e)
108         {
109             throw new DatabaseUnitException(e);
110         }
111     }
112 
113 
114     private ForwardOnlyDataSet[] createForwardOnlyDataSetArray(List<QueryDataSet> dataSets) throws DataSetException, SQLException {
115         ForwardOnlyDataSet[] forwardOnlyDataSets = new ForwardOnlyDataSet[dataSets.size()];
116 
117         for (int i = 0; i < dataSets.size(); i++) {
118             forwardOnlyDataSets[i] = new ForwardOnlyDataSet(dataSets.get(i));
119         }
120 
121         return forwardOnlyDataSets;
122     }
123    
124 	private List createQueryDataSet(List tables, IDatabaseConnection connection) 
125 	throws DataSetException, SQLException 
126 	{
127 		logger.debug("createQueryDataSet(tables={}, connection={})", tables, connection);
128 		
129 		List queryDataSets = new ArrayList();
130 		
131         QueryDataSet queryDataSet = new QueryDataSet(connection);
132         
133         for (Iterator it = tables.iterator(); it.hasNext();)
134         {
135             Object item = it.next();
136             
137             if(item instanceof QuerySet) {
138 				if(queryDataSet.getTableNames().length > 0) 
139             		queryDataSets.add(queryDataSet);
140 				
141 				QueryDataSet newQueryDataSet = (((QuerySet)item).getQueryDataSet(connection));
142 				queryDataSets.add(newQueryDataSet);
143 				queryDataSet = new QueryDataSet(connection);
144             }
145             else if (item instanceof Query)
146             {
147                 Query queryItem = (Query)item;
148                 queryDataSet.addTable(queryItem.getName(), queryItem.getSql());
149             }
150             else if (item instanceof Table)
151             {
152                 Table tableItem = (Table)item;
153                 queryDataSet.addTable(tableItem.getName());
154             }
155             else
156             {
157             	throw new IllegalArgumentException("Unsupported element type " + item.getClass().getName() + ".");
158             }
159         }
160         
161         if(queryDataSet.getTableNames().length > 0) 
162         	queryDataSets.add(queryDataSet);
163         
164         return queryDataSets;
165 	}
166 
167 
168 	protected IDataSet getSrcDataSet(File src, String format,
169             boolean forwardonly) throws DatabaseUnitException
170     {
171 		if (logger.isDebugEnabled())
172 		{
173 			logger.debug("getSrcDataSet(src={}, format={}, forwardonly={}) - start",
174 					new Object[]{ src, format, String.valueOf(forwardonly) });
175 		}
176 
177         try
178         {
179             IDataSetProducer producer = null;
180             if (format.equalsIgnoreCase(FORMAT_XML))
181             {
182                 producer = new XmlProducer(getInputSource(src));
183             }
184             else if (format.equalsIgnoreCase(FORMAT_CSV))
185             {
186                 producer = new CsvProducer(src);
187             }
188             else if (format.equalsIgnoreCase(FORMAT_FLAT))
189             {
190                 producer = new FlatXmlProducer(getInputSource(src), true, true);
191             }
192             else if (format.equalsIgnoreCase(FORMAT_DTD))
193             {
194                 producer = new FlatDtdProducer(getInputSource(src));
195             }
196             else if (format.equalsIgnoreCase(FORMAT_XLS))
197             {
198                 return new CachedDataSet(new XlsDataSet(src));
199             }
200             else
201             {
202                 throw new IllegalArgumentException("Type must be either 'flat'(default), 'xml', 'csv', 'xls' or 'dtd' but was: " + format);
203             }
204 
205             if (forwardonly)
206             {
207                 return new StreamingDataSet(producer);
208             }
209             return new CachedDataSet(producer);
210         }
211         catch (IOException e)
212         {
213             throw new DatabaseUnitException(e);
214         }
215     }
216     
217 
218     /**
219 	 * Checks if the given format is a format which contains tabular data.
220 	 * @param format The format to check
221 	 * @return <code>true</code> if the given format is a data format. A data
222 	 * format is a format which holds tabular data that can be loaded via dbunit.
223 	 * An example for a data format is "xml" or "flat". A non-data format is "dtd" which
224 	 * holds only metadata information.
225 	 * @since 2.4
226 	 */
227 	public boolean isDataFormat(String format)
228 	{
229         logger.debug("isDataFormat(format={}) - start", format);
230 
231         if (format.equalsIgnoreCase(FORMAT_FLAT)
232                 || format.equalsIgnoreCase(FORMAT_XML)
233                 || format.equalsIgnoreCase(FORMAT_CSV)
234                 || format.equalsIgnoreCase(FORMAT_XLS)
235         )
236         {
237             return true;
238         }
239         else
240         {
241             return false;
242         }
243 	}
244 	
245     /**
246      * Checks if the given data format is a valid one according to
247      * the method {@link #isDataFormat(String)}. If it is not an
248      * {@link IllegalArgumentException} is thrown.
249      * @param format The format to check
250      * @throws IllegalArgumentException If the given format is not
251      * a valid data format
252      * @since 2.4
253      */
254     protected void checkDataFormat(String format) 
255     {
256         logger.debug("checkDataFormat(format={}) - start", format);
257 
258         if (!isDataFormat(format))
259         {
260             throw new IllegalArgumentException("format must be either 'flat'(default), 'xml', 'csv' or 'xls' but was: " + format);
261         }
262     }
263 
264 	
265 	/**
266 	 * Creates and returns an {@link InputSource}
267 	 * @param file The file for which an {@link InputSource} should be created
268 	 * @return The input source for the given file
269 	 * @throws MalformedURLException
270 	 */
271 	public static InputSource getInputSource(File file) throws MalformedURLException
272 	{
273         InputSource source = FileHelper.createInputSource(file);
274         return source;
275 	}
276 	
277     public boolean isOrdered() 
278     {
279         return ordered;
280     }
281 
282     public void setOrdered(boolean ordered) 
283     {
284         this.ordered = ordered;
285     }
286     
287     public String toString()
288     {
289         StringBuffer result = new StringBuffer();
290         result.append("AbstractStep: ");
291         result.append("ordered=").append(this.ordered);
292         return result.toString();
293     }
294 
295 }