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  
22  package org.dbunit.ant;
23  
24  import java.io.File;
25  import java.io.FileOutputStream;
26  import java.io.IOException;
27  import java.io.OutputStream;
28  import java.sql.SQLException;
29  import java.util.ArrayList;
30  import java.util.Arrays;
31  import java.util.List;
32  
33  import org.apache.tools.ant.Project;
34  import org.dbunit.DatabaseUnitException;
35  import org.dbunit.database.DatabaseSequenceFilter;
36  import org.dbunit.database.IDatabaseConnection;
37  import org.dbunit.dataset.FilteredDataSet;
38  import org.dbunit.dataset.IDataSet;
39  import org.dbunit.dataset.csv.CsvDataSetWriter;
40  import org.dbunit.dataset.excel.XlsDataSet;
41  import org.dbunit.dataset.filter.ITableFilter;
42  import org.dbunit.dataset.xml.FlatDtdDataSet;
43  import org.dbunit.dataset.xml.FlatXmlWriter;
44  import org.dbunit.dataset.xml.XmlDataSet;
45  import org.slf4j.Logger;
46  import org.slf4j.LoggerFactory;
47  
48  /**
49   * The <code>Export</code> class is the step that facilitates exporting
50   * the contents of the database and/or it's corresponding DTD to a file.
51   * The export can be performed on a full dataset or a partial one if
52   * specific table names are identified.
53   *
54   * @author Timothy Ruppert
55   * @author Ben Cox
56   * @version $Revision$
57   * @since Jun 10, 2002
58   * @see DbUnitTaskStep
59   */
60  public class Export extends AbstractStep
61  {
62  
63      /**
64       * Logger for this class
65       */
66      private static final Logger logger = LoggerFactory.getLogger(Export.class);
67  
68      private File _dest;
69      private String _format = FORMAT_FLAT;
70      private String _doctype = null;
71      private String _encoding = null; // if no encoding set by script than the default encoding (UTF-8) of the wrietr is used
72      private List _tables = new ArrayList();
73  
74      public Export()
75      {
76      }
77  
78      private String getAbsolutePath(File filename)
79      {
80          return filename != null ? filename.getAbsolutePath() : "null";
81      }
82  
83      public File getDest()
84      {
85          return _dest;
86      }
87  
88      public String getFormat()
89      {
90          return _format;
91      }
92  
93      public List getTables()
94      {
95          return _tables;
96      }
97  
98      public void setDest(File dest)
99      {
100         logger.debug("setDest(dest={}) - start", dest);
101         _dest = dest;
102     }
103 
104     public void setFormat(String format)
105     {
106         logger.debug("setFormat(format={}) - start", format);
107 
108         if (format.equalsIgnoreCase(FORMAT_FLAT)
109                 || format.equalsIgnoreCase(FORMAT_XML)
110                 || format.equalsIgnoreCase(FORMAT_DTD)
111                 || format.equalsIgnoreCase(FORMAT_CSV)
112                 || format.equalsIgnoreCase(FORMAT_XLS))
113         {
114             _format = format;
115         }
116         else
117         {
118             throw new IllegalArgumentException("Type must be one of: 'flat'(default), 'xml', 'dtd' or 'xls' but was: " + format);
119         }
120     }
121 
122     /**
123      * Encoding for XML-Output
124      * @return Returns the encoding.
125      */
126     public String getEncoding() 
127     {
128         return this._encoding;
129     }
130 
131     public void setEncoding(String encoding) 
132     { 
133         this._encoding = encoding;
134     }
135 
136     public void addTable(Table table)
137     {
138         logger.debug("addTable(table={}) - start", table);
139         _tables.add(table);
140     }
141 
142     public void addQuery(Query query)
143     {
144         logger.debug("addQuery(query={}) - start", query);
145         _tables.add(query);
146     }
147 
148 	public void addQuerySet(QuerySet querySet) {
149         logger.debug("addQuerySet(querySet={}) - start", querySet);
150         _tables.add(querySet);
151 	}
152 	
153     
154 	public String getDoctype()
155     {
156         return _doctype;
157     }
158 
159     public void setDoctype(String doctype)
160     {
161         logger.debug("setDoctype(doctype={}) - start", doctype);
162         _doctype = doctype;
163     }
164 
165     public void execute(IDatabaseConnection connection) throws DatabaseUnitException
166     {
167         logger.debug("execute(connection={}) - start", connection);
168 
169         try
170         {
171             if (_dest == null)
172             {
173                 throw new DatabaseUnitException("'_dest' is a required attribute of the <export> step.");
174             }
175 
176             IDataSet dataset = getExportDataSet(connection);
177 			log("dataset tables: " + Arrays.asList(dataset.getTableNames()), Project.MSG_VERBOSE);
178 
179 			
180             // Write the dataset
181             if (_format.equals(FORMAT_CSV))
182             {
183                 CsvDataSetWriter.write(dataset, _dest);
184             }
185             else
186             {
187                 OutputStream out = new FileOutputStream(_dest);
188                 try
189                 {
190                     if (_format.equalsIgnoreCase(FORMAT_FLAT))
191                     {
192                         FlatXmlWriter writer = new FlatXmlWriter(out, getEncoding());
193                         writer.setDocType(_doctype);
194                         writer.write(dataset);
195                     }
196                     else if (_format.equalsIgnoreCase(FORMAT_XML))
197                     {
198                         XmlDataSet.write(dataset, out, getEncoding());
199                     }
200                     else if (_format.equalsIgnoreCase(FORMAT_DTD))
201                     {
202                         //TODO Should DTD also support encoding? It is basically an XML file...
203                         FlatDtdDataSet.write(dataset, out);//, getEncoding());
204                     }
205                     else if (_format.equalsIgnoreCase(FORMAT_XLS))
206                     {
207                         XlsDataSet.write(dataset, out);
208                     }
209                     else
210                     {
211                         throw new IllegalArgumentException("The given format '"+_format+"' is not supported.");
212                     }
213                     
214                 }
215                 finally
216                 {
217                     out.close();
218                 }
219             }
220             
221             log("Successfully wrote file '" + _dest + "'", Project.MSG_INFO);
222             
223         }
224         catch (SQLException e)
225         {
226         	throw new DatabaseUnitException(e);
227         }
228         catch (IOException e)
229         {
230             throw new DatabaseUnitException(e);
231         }
232     }
233 
234     /**
235      * Creates the dataset that is finally used for the export
236      * @param connection
237      * @return The final dataset used for the export
238      * @throws DatabaseUnitException
239      * @throws SQLException
240      */
241     protected IDataSet getExportDataSet(IDatabaseConnection connection) 
242     throws DatabaseUnitException, SQLException 
243     {
244         IDataSet dataset = getDatabaseDataSet(connection, this._tables);
245         if (isOrdered()) 
246         {
247         	// Use topologically sorted database
248         	ITableFilter filter = new DatabaseSequenceFilter(connection);  
249         	dataset = new FilteredDataSet(filter, dataset);
250         }
251         return dataset;
252 	}
253 
254 	public String getLogMessage()
255     {
256         return "Executing export: "
257                 + "\n      in format: " + _format
258                 + " to datafile: " + getAbsolutePath(_dest);
259     }
260 
261 
262     public String toString()
263     {
264         StringBuffer result = new StringBuffer();
265         result.append("Export: ");
266         result.append(" dest=" + getAbsolutePath(_dest));
267         result.append(", format= " + _format);
268         result.append(", doctype= " + _doctype);
269         result.append(", tables= " + _tables);
270 
271         return result.toString();
272     }
273 }