Export.java

  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. import java.io.File;
  23. import java.io.FileOutputStream;
  24. import java.io.IOException;
  25. import java.io.OutputStream;
  26. import java.nio.charset.Charset;
  27. import java.nio.charset.StandardCharsets;
  28. import java.sql.SQLException;
  29. import java.util.ArrayList;
  30. import java.util.Arrays;
  31. import java.util.List;

  32. import org.apache.tools.ant.Project;
  33. import org.dbunit.DatabaseUnitException;
  34. import org.dbunit.database.DatabaseSequenceFilter;
  35. import org.dbunit.database.IDatabaseConnection;
  36. import org.dbunit.dataset.FilteredDataSet;
  37. import org.dbunit.dataset.IDataSet;
  38. import org.dbunit.dataset.csv.CsvDataSetWriter;
  39. import org.dbunit.dataset.excel.XlsDataSet;
  40. import org.dbunit.dataset.filter.ITableFilter;
  41. import org.dbunit.dataset.xml.FlatDtdDataSet;
  42. import org.dbunit.dataset.xml.FlatXmlWriter;
  43. import org.dbunit.dataset.xml.XmlDataSet;
  44. import org.dbunit.dataset.yaml.YamlDataSet;
  45. import org.slf4j.Logger;
  46. import org.slf4j.LoggerFactory;

  47. /**
  48.  * The <code>Export</code> class is the step that facilitates exporting
  49.  * the contents of the database and/or it's corresponding DTD to a file.
  50.  * The export can be performed on a full dataset or a partial one if
  51.  * specific table names are identified.
  52.  *
  53.  * @author Timothy Ruppert
  54.  * @author Ben Cox
  55.  * @version $Revision$
  56.  * @since Jun 10, 2002
  57.  * @see DbUnitTaskStep
  58.  */
  59. public class Export extends AbstractStep
  60. {

  61.     /**
  62.      * Logger for this class
  63.      */
  64.     private static final Logger logger = LoggerFactory.getLogger(Export.class);

  65.     private File _dest;
  66.     private String _format = FORMAT_FLAT;
  67.     private String _doctype = null;
  68.     private Charset _encoding = StandardCharsets.UTF_8; // if no encoding set by script than the default encoding (UTF-8) of the wrietr is used
  69.     private List _tables = new ArrayList();

  70.     public Export()
  71.     {
  72.     }

  73.     private String getAbsolutePath(File filename)
  74.     {
  75.         return filename != null ? filename.getAbsolutePath() : "null";
  76.     }

  77.     public File getDest()
  78.     {
  79.         return _dest;
  80.     }

  81.     public String getFormat()
  82.     {
  83.         return _format;
  84.     }

  85.     public List getTables()
  86.     {
  87.         return _tables;
  88.     }

  89.     public void setDest(File dest)
  90.     {
  91.         logger.debug("setDest(dest={}) - start", dest);
  92.         _dest = dest;
  93.     }

  94.     public void setFormat(String format)
  95.     {
  96.         logger.debug("setFormat(format={}) - start", format);

  97.         if (format.equalsIgnoreCase(FORMAT_FLAT)
  98.                 || format.equalsIgnoreCase(FORMAT_XML)
  99.                 || format.equalsIgnoreCase(FORMAT_DTD)
  100.                 || format.equalsIgnoreCase(FORMAT_CSV)
  101.                 || format.equalsIgnoreCase(FORMAT_XLS)
  102.                 || format.equalsIgnoreCase(FORMAT_YML))
  103.         {
  104.             _format = format;
  105.         }
  106.         else
  107.         {
  108.             throw new IllegalArgumentException("Type must be one of: 'flat'(default), 'xml', 'dtd', 'xls' or 'yml' but was: " + format);
  109.         }
  110.     }

  111.     /**
  112.      * Encoding for XML-Output
  113.      * @return Returns the encoding.
  114.      */
  115.     public Charset getEncoding()
  116.     {
  117.         return this._encoding;
  118.     }

  119.     public void setEncoding(String encoding)
  120.     {
  121.         setEncoding(Charset.forName(encoding));
  122.     }

  123.     public void setEncoding(Charset encoding)
  124.     {
  125.         this._encoding = encoding;
  126.     }

  127.     public void addTable(Table table)
  128.     {
  129.         logger.debug("addTable(table={}) - start", table);
  130.         _tables.add(table);
  131.     }

  132.     public void addQuery(Query query)
  133.     {
  134.         logger.debug("addQuery(query={}) - start", query);
  135.         _tables.add(query);
  136.     }

  137.     public void addQuerySet(QuerySet querySet) {
  138.         logger.debug("addQuerySet(querySet={}) - start", querySet);
  139.         _tables.add(querySet);
  140.     }
  141.    
  142.    
  143.     public String getDoctype()
  144.     {
  145.         return _doctype;
  146.     }

  147.     public void setDoctype(String doctype)
  148.     {
  149.         logger.debug("setDoctype(doctype={}) - start", doctype);
  150.         _doctype = doctype;
  151.     }

  152.     public void execute(IDatabaseConnection connection) throws DatabaseUnitException
  153.     {
  154.         logger.debug("execute(connection={}) - start", connection);

  155.         try
  156.         {
  157.             if (_dest == null)
  158.             {
  159.                 throw new DatabaseUnitException("'_dest' is a required attribute of the <export> step.");
  160.             }

  161.             IDataSet dataset = getExportDataSet(connection);
  162.             log("dataset tables: " + Arrays.asList(dataset.getTableNames()), Project.MSG_VERBOSE);

  163.            
  164.             // Write the dataset
  165.             if (_format.equals(FORMAT_CSV))
  166.             {
  167.                 CsvDataSetWriter.write(dataset, _dest);
  168.             }
  169.             else
  170.             {
  171.                 OutputStream out = new FileOutputStream(_dest);
  172.                 try
  173.                 {
  174.                     if (_format.equalsIgnoreCase(FORMAT_FLAT))
  175.                     {
  176.                         FlatXmlWriter writer = new FlatXmlWriter(out, getEncoding());
  177.                         writer.setDocType(_doctype);
  178.                         writer.write(dataset);
  179.                     }
  180.                     else if (_format.equalsIgnoreCase(FORMAT_XML))
  181.                     {
  182.                         XmlDataSet.write(dataset, out, getEncoding());
  183.                     }
  184.                     else if (_format.equalsIgnoreCase(FORMAT_DTD))
  185.                     {
  186.                         //TODO Should DTD also support encoding? It is basically an XML file...
  187.                         FlatDtdDataSet.write(dataset, out);//, getEncoding());
  188.                     }
  189.                     else if (_format.equalsIgnoreCase(FORMAT_XLS))
  190.                     {
  191.                         XlsDataSet.write(dataset, out);
  192.                     }
  193.                     else if (_format.equalsIgnoreCase(FORMAT_YML))
  194.                     {
  195.                         YamlDataSet.write(dataset, out);
  196.                     }
  197.                     else
  198.                     {
  199.                         throw new IllegalArgumentException("The given format '"+_format+"' is not supported.");
  200.                     }
  201.                    
  202.                 }
  203.                 finally
  204.                 {
  205.                     out.close();
  206.                 }
  207.             }
  208.            
  209.             log("Successfully wrote file '" + _dest + "'", Project.MSG_INFO);
  210.            
  211.         }
  212.         catch (SQLException e)
  213.         {
  214.             throw new DatabaseUnitException(e);
  215.         }
  216.         catch (IOException e)
  217.         {
  218.             throw new DatabaseUnitException(e);
  219.         }
  220.     }

  221.     /**
  222.      * Creates the dataset that is finally used for the export
  223.      * @param connection
  224.      * @return The final dataset used for the export
  225.      * @throws DatabaseUnitException
  226.      * @throws SQLException
  227.      */
  228.     protected IDataSet getExportDataSet(IDatabaseConnection connection)
  229.     throws DatabaseUnitException, SQLException
  230.     {
  231.         IDataSet dataset = getDatabaseDataSet(connection, this._tables);
  232.         if (isOrdered())
  233.         {
  234.             // Use topologically sorted database
  235.             ITableFilter filter = new DatabaseSequenceFilter(connection);  
  236.             dataset = new FilteredDataSet(filter, dataset);
  237.         }
  238.         return dataset;
  239.     }

  240.     public String getLogMessage()
  241.     {
  242.         return "Executing export: "
  243.                 + "\n      in format: " + _format
  244.                 + " to datafile: " + getAbsolutePath(_dest);
  245.     }


  246.     public String toString()
  247.     {
  248.         final StringBuilder result = new StringBuilder();
  249.         result.append("Export: ");
  250.         result.append(" dest=" + getAbsolutePath(_dest));
  251.         result.append(", format= " + _format);
  252.         result.append(", doctype= " + _doctype);
  253.         result.append(", tables= " + _tables);

  254.         return result.toString();
  255.     }
  256. }