AbstractStep.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.IOException;
  24. import java.net.MalformedURLException;
  25. import java.sql.SQLException;
  26. import java.util.ArrayList;
  27. import java.util.Iterator;
  28. import java.util.List;

  29. import org.apache.tools.ant.ProjectComponent;
  30. import org.dbunit.DatabaseUnitException;
  31. import org.dbunit.database.DatabaseConfig;
  32. import org.dbunit.database.IDatabaseConnection;
  33. import org.dbunit.database.QueryDataSet;
  34. import org.dbunit.dataset.CachedDataSet;
  35. import org.dbunit.dataset.CompositeDataSet;
  36. import org.dbunit.dataset.DataSetException;
  37. import org.dbunit.dataset.ForwardOnlyDataSet;
  38. import org.dbunit.dataset.IDataSet;
  39. import org.dbunit.dataset.csv.CsvProducer;
  40. import org.dbunit.dataset.excel.XlsDataSet;
  41. import org.dbunit.dataset.stream.IDataSetProducer;
  42. import org.dbunit.dataset.stream.StreamingDataSet;
  43. import org.dbunit.dataset.xml.FlatDtdProducer;
  44. import org.dbunit.dataset.xml.FlatXmlProducer;
  45. import org.dbunit.dataset.xml.XmlProducer;
  46. import org.dbunit.dataset.yaml.YamlProducer;
  47. import org.dbunit.util.FileHelper;
  48. import org.slf4j.Logger;
  49. import org.slf4j.LoggerFactory;
  50. import org.xml.sax.InputSource;

  51. /**
  52.  * @author Manuel Laflamme
  53.  * @author Last changed by: $Author$
  54.  * @version $Revision$ $Date$
  55.  * @since 2.1 (Apr 3, 2004)
  56.  */
  57. public abstract class AbstractStep extends ProjectComponent implements DbUnitTaskStep
  58. {

  59.     /**
  60.      * Logger for this class
  61.      */
  62.     private static final Logger logger = LoggerFactory.getLogger(AbstractStep.class);

  63.     public static final String FORMAT_FLAT = "flat";
  64.     public static final String FORMAT_XML = "xml";
  65.     public static final String FORMAT_DTD = "dtd";
  66.     public static final String FORMAT_CSV = "csv";
  67.     public static final String FORMAT_XLS = "xls";
  68.     public static final String FORMAT_YML = "yml";

  69.     private boolean ordered = false;

  70.    
  71.     protected IDataSet getDatabaseDataSet(IDatabaseConnection connection,
  72.             List tables) throws DatabaseUnitException
  73.     {
  74.         if (logger.isDebugEnabled())
  75.         {
  76.             logger.debug("getDatabaseDataSet(connection={}, tables={}) - start",
  77.                  connection, tables);
  78.         }

  79.         try
  80.         {
  81.             DatabaseConfig config = connection.getConfig();

  82.             // Retrieve the complete database if no tables or queries specified.
  83.             if (tables.size() == 0)
  84.             {
  85.                 logger.debug("Retrieving the whole database because tables/queries have not been specified");
  86.                 return connection.createDataSet();
  87.             }

  88.             List queryDataSets = createQueryDataSet(tables, connection);

  89.             IDataSet[] dataSetsArray = null;
  90.             if (config.getProperty(DatabaseConfig.PROPERTY_RESULTSET_TABLE_FACTORY)
  91.                     .getClass().getName().equals("org.dbunit.database.ForwardOnlyResultSetTableFactory")) {
  92.                 dataSetsArray = createForwardOnlyDataSetArray(queryDataSets);
  93.             } else {
  94.                 dataSetsArray = (IDataSet[]) queryDataSets.toArray(new IDataSet[queryDataSets.size()]);
  95.             }
  96.             return new CompositeDataSet(dataSetsArray);
  97.         }
  98.         catch (SQLException e)
  99.         {
  100.             throw new DatabaseUnitException(e);
  101.         }
  102.     }


  103.     private ForwardOnlyDataSet[] createForwardOnlyDataSetArray(List<QueryDataSet> dataSets) throws DataSetException, SQLException {
  104.         ForwardOnlyDataSet[] forwardOnlyDataSets = new ForwardOnlyDataSet[dataSets.size()];

  105.         for (int i = 0; i < dataSets.size(); i++) {
  106.             forwardOnlyDataSets[i] = new ForwardOnlyDataSet(dataSets.get(i));
  107.         }

  108.         return forwardOnlyDataSets;
  109.     }
  110.    
  111.     private List createQueryDataSet(List tables, IDatabaseConnection connection)
  112.     throws DataSetException, SQLException
  113.     {
  114.         logger.debug("createQueryDataSet(tables={}, connection={})", tables, connection);
  115.        
  116.         List queryDataSets = new ArrayList();
  117.        
  118.         QueryDataSet queryDataSet = new QueryDataSet(connection);
  119.        
  120.         for (Iterator it = tables.iterator(); it.hasNext();)
  121.         {
  122.             Object item = it.next();
  123.            
  124.             if(item instanceof QuerySet) {
  125.                 if(queryDataSet.getTableNames().length > 0)
  126.                     queryDataSets.add(queryDataSet);
  127.                
  128.                 QueryDataSet newQueryDataSet = (((QuerySet)item).getQueryDataSet(connection));
  129.                 queryDataSets.add(newQueryDataSet);
  130.                 queryDataSet = new QueryDataSet(connection);
  131.             }
  132.             else if (item instanceof Query)
  133.             {
  134.                 Query queryItem = (Query)item;
  135.                 queryDataSet.addTable(queryItem.getName(), queryItem.getSql());
  136.             }
  137.             else if (item instanceof Table)
  138.             {
  139.                 Table tableItem = (Table)item;
  140.                 queryDataSet.addTable(tableItem.getName());
  141.             }
  142.             else
  143.             {
  144.                 throw new IllegalArgumentException("Unsupported element type " + item.getClass().getName() + ".");
  145.             }
  146.         }
  147.        
  148.         if(queryDataSet.getTableNames().length > 0)
  149.             queryDataSets.add(queryDataSet);
  150.        
  151.         return queryDataSets;
  152.     }


  153.     protected IDataSet getSrcDataSet(File src, String format,
  154.             boolean forwardonly) throws DatabaseUnitException
  155.     {
  156.         if (logger.isDebugEnabled())
  157.         {
  158.             logger.debug("getSrcDataSet(src={}, format={}, forwardonly={}) - start",
  159.                      src, format, forwardonly);
  160.         }

  161.         try
  162.         {
  163.             IDataSetProducer producer = null;
  164.             if (format.equalsIgnoreCase(FORMAT_XML))
  165.             {
  166.                 producer = new XmlProducer(getInputSource(src));
  167.             }
  168.             else if (format.equalsIgnoreCase(FORMAT_CSV))
  169.             {
  170.                 producer = new CsvProducer(src);
  171.             }
  172.             else if (format.equalsIgnoreCase(FORMAT_FLAT))
  173.             {
  174.                 producer = new FlatXmlProducer(getInputSource(src), true, true);
  175.             }
  176.             else if (format.equalsIgnoreCase(FORMAT_DTD))
  177.             {
  178.                 producer = new FlatDtdProducer(getInputSource(src));
  179.             }
  180.             else if (format.equalsIgnoreCase(FORMAT_XLS))
  181.             {
  182.                 return new CachedDataSet(new XlsDataSet(src));
  183.             }
  184.             else if (format.equalsIgnoreCase(FORMAT_YML))
  185.             {
  186.                 return new CachedDataSet(new YamlProducer(src), true);
  187.             }
  188.             else
  189.             {
  190.                 throw new IllegalArgumentException("Type must be either 'flat'(default), 'xml', 'csv', 'xls', 'yml' or 'dtd' but was: " + format);
  191.             }

  192.             if (forwardonly)
  193.             {
  194.                 return new StreamingDataSet(producer);
  195.             }
  196.             return new CachedDataSet(producer);
  197.         }
  198.         catch (IOException e)
  199.         {
  200.             throw new DatabaseUnitException(e);
  201.         }
  202.     }
  203.    

  204.     /**
  205.      * Checks if the given format is a format which contains tabular data.
  206.      * @param format The format to check
  207.      * @return <code>true</code> if the given format is a data format. A data
  208.      * format is a format which holds tabular data that can be loaded via dbunit.
  209.      * An example for a data format is "xml" or "flat". A non-data format is "dtd" which
  210.      * holds only metadata information.
  211.      * @since 2.4
  212.      */
  213.     public boolean isDataFormat(String format)
  214.     {
  215.         logger.debug("isDataFormat(format={}) - start", format);

  216.         return format.equalsIgnoreCase(FORMAT_FLAT)
  217.                 || format.equalsIgnoreCase(FORMAT_XML)
  218.                 || format.equalsIgnoreCase(FORMAT_CSV)
  219.                 || format.equalsIgnoreCase(FORMAT_XLS)
  220.                 || format.equalsIgnoreCase(FORMAT_YML);
  221.     }

  222.     /**
  223.      * Checks if the given data format is a valid one according to
  224.      * the method {@link #isDataFormat(String)}. If it is not an
  225.      * {@link IllegalArgumentException} is thrown.
  226.      * @param format The format to check
  227.      * @throws IllegalArgumentException If the given format is not
  228.      * a valid data format
  229.      * @since 2.4
  230.      */
  231.     protected void checkDataFormat(String format)
  232.     {
  233.         logger.debug("checkDataFormat(format={}) - start", format);

  234.         if (!isDataFormat(format))
  235.         {
  236.             throw new IllegalArgumentException("format must be either 'flat'(default), 'xml', 'csv', 'xls' or 'yml' but was: " + format);
  237.         }
  238.     }

  239.    
  240.     /**
  241.      * Creates and returns an {@link InputSource}
  242.      * @param file The file for which an {@link InputSource} should be created
  243.      * @return The input source for the given file
  244.      * @throws MalformedURLException
  245.      */
  246.     public static InputSource getInputSource(File file) throws MalformedURLException
  247.     {
  248.         InputSource source = FileHelper.createInputSource(file);
  249.         return source;
  250.     }
  251.    
  252.     public boolean isOrdered()
  253.     {
  254.         return ordered;
  255.     }

  256.     public void setOrdered(boolean ordered)
  257.     {
  258.         this.ordered = ordered;
  259.     }
  260.    
  261.     public String toString()
  262.     {
  263.         final StringBuilder result = new StringBuilder();
  264.         result.append("AbstractStep: ");
  265.         result.append("ordered=").append(this.ordered);
  266.         return result.toString();
  267.     }

  268. }