SqlLoaderControlProducer.java

  1. /*
  2.  *
  3.  * The DbUnit Database Testing Framework
  4.  * Copyright (C)2002-2008, 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.sqlloader;

  22. import java.io.File;
  23. import java.io.IOException;
  24. import java.util.Iterator;
  25. import java.util.List;

  26. import org.dbunit.dataset.Column;
  27. import org.dbunit.dataset.DataSetException;
  28. import org.dbunit.dataset.DefaultTableMetaData;
  29. import org.dbunit.dataset.IDataSet;
  30. import org.dbunit.dataset.ITableMetaData;
  31. import org.dbunit.dataset.common.handlers.IllegalInputCharacterException;
  32. import org.dbunit.dataset.common.handlers.PipelineException;
  33. import org.dbunit.dataset.datatype.DataType;
  34. import org.dbunit.dataset.stream.DefaultConsumer;
  35. import org.dbunit.dataset.stream.IDataSetConsumer;
  36. import org.dbunit.dataset.stream.IDataSetProducer;
  37. import org.dbunit.util.FileHelper;
  38. import org.slf4j.Logger;
  39. import org.slf4j.LoggerFactory;

  40. /**
  41.  * Producer that creates an {@link IDataSet} using SQLLoader style '.ctl' files.
  42.  *
  43.  * @author Stephan Strittmatter (stritti AT users.sourceforge.net), gommma (gommma AT users.sourceforge.net)
  44.  * @author Last changed by: $Author$
  45.  * @version $Revision$ $Date$
  46.  * @since 2.4.0
  47.  */
  48. public class SqlLoaderControlProducer implements IDataSetProducer {

  49.     /**
  50.      * Logger for this class
  51.      */
  52.     private static final Logger logger = LoggerFactory.getLogger(SqlLoaderControlProducer.class);

  53.     private static final String TMP_TABLE_LIST_FILENAME = "table-list.txt";


  54.     /** The Constant NULL. */
  55.     public static final String NULL = "null";

  56.     /** The Constant EMPTY_CONSUMER. */
  57.     private static final IDataSetConsumer EMPTY_CONSUMER = new DefaultConsumer();

  58.     /** The consumer. */
  59.     private IDataSetConsumer consumer = EMPTY_CONSUMER;

  60.     /** The control files directory */
  61.     private final File controlFilesDir;

  62.     /**
  63.      * String list of the ordered table names
  64.      */
  65.     private List orderedTableNames;


  66.     /**
  67.      * The Constructor.
  68.      *
  69.      * @param controlFilesDir the control files directory
  70.      * @param tableOrderFile the table order file
  71.      * @throws DataSetException
  72.      */
  73.     public SqlLoaderControlProducer(String controlFilesDir, String tableOrderFile)
  74.     throws DataSetException
  75.     {
  76.         this(new File(controlFilesDir), new File(tableOrderFile));
  77.     }

  78.     /**
  79.      * The Constructor.
  80.      *
  81.      * @param controlFilesDir the control files directory
  82.      * @param tableOrderFile the table order file
  83.      * @throws DataSetException
  84.      */
  85.     public SqlLoaderControlProducer(File controlFilesDir, File tableOrderFile)
  86.     throws DataSetException
  87.     {
  88.         this.controlFilesDir = controlFilesDir;
  89.        
  90.         try {
  91.             this.orderedTableNames = SqlLoaderControlProducer.getTables(controlFilesDir, tableOrderFile);
  92.         }
  93.         catch (IOException e) {
  94.             throw new DataSetException("error getting list of tables from file '" + tableOrderFile + "'", e);
  95.         }
  96.     }

  97.     /**
  98.      * The Constructor.
  99.      *
  100.      * @param controlFilesDir the control files directory
  101.      * @param orderedTableNames a list of strings that contains the ordered table names
  102.      */
  103.     public SqlLoaderControlProducer(File controlFilesDir, List orderedTableNames) {
  104.         this.controlFilesDir = controlFilesDir;
  105.         this.orderedTableNames = orderedTableNames;
  106.     }

  107.     /**
  108.      * @see org.dbunit.dataset.stream.IDataSetProducer#setConsumer(org.dbunit.dataset.stream.IDataSetConsumer)
  109.      */
  110.     public void setConsumer(IDataSetConsumer consumer) throws DataSetException {
  111.         this.consumer = consumer;
  112.     }

  113.     /**
  114.      * @see org.dbunit.dataset.stream.IDataSetProducer#produce()
  115.      */
  116.     public void produce() throws DataSetException {
  117.         logger.debug("produce() - start");

  118.         File dir = this.controlFilesDir;

  119.         if (!this.controlFilesDir.isDirectory()) {
  120.             throw new DataSetException("'"
  121.                     + this.controlFilesDir + "' should be a directory of the control files");
  122.         }

  123.         this.consumer.startDataSet();
  124.        
  125.         for (Iterator tableIter = this.orderedTableNames.iterator(); tableIter.hasNext();) {
  126.             String table = (String) tableIter.next();
  127.             try {
  128.                 File ctlFile = new File(dir, table + ".ctl");
  129.                 produceFromControlFile(ctlFile);
  130.             }
  131.             catch (SqlLoaderControlParserException e) {
  132.                 throw new DataSetException("error producing dataset for table '" + table + "'", e);
  133.             }
  134.             catch (DataSetException e) {
  135.                 throw new DataSetException("error producing dataset for table '" + table + "'", e);
  136.             }

  137.         }
  138.         this.consumer.endDataSet();
  139.     }

  140.     /**
  141.      * Produce from control file.
  142.      *
  143.      * @param controlFile the control file
  144.      *
  145.      * @throws DataSetException the data set exception
  146.      * @throws SqlLoaderControlParserException the oracle control parser exception
  147.      */
  148.     private void produceFromControlFile(File controlFile) throws DataSetException,
  149.     SqlLoaderControlParserException
  150.     {
  151.         logger.debug("produceFromControlFile(controlFile={}) - start", controlFile);

  152.         try {
  153.             SqlLoaderControlParser parser = new SqlLoaderControlParserImpl();
  154.             List readData = parser.parse(controlFile);
  155.             List readColumns = ((List) readData.get(0));
  156.             Column[] columns = new Column[readColumns.size()];

  157.             for (int i = 0; i < readColumns.size(); i++) {
  158.                 columns[i] = new Column((String) readColumns.get(i), DataType.UNKNOWN);
  159.             }

  160.             String tableName = parser.getTableName();
  161.             ITableMetaData metaData = new DefaultTableMetaData(tableName, columns);
  162.             this.consumer.startTable(metaData);
  163.             for (int i = 1; i < readData.size(); i++) {
  164.                 List rowList = (List) readData.get(i);
  165.                 Object[] row = rowList.toArray();
  166.                 for (int col = 0; col < row.length; col++) {
  167.                     row[col] = row[col].equals(NULL) ? null : row[col];
  168.                 }
  169.                 this.consumer.row(row);
  170.             }
  171.             this.consumer.endTable();
  172.         }
  173.         catch (PipelineException e) {
  174.             throw new DataSetException(e);
  175.         }
  176.         catch (IllegalInputCharacterException e) {
  177.             throw new DataSetException(e);
  178.         }
  179.         catch (IOException e) {
  180.             throw new DataSetException(e);
  181.         }
  182.     }

  183.     /**
  184.      * Get a list of tables that this producer will create.
  185.      *
  186.      * @param controlFilesDir the base directory
  187.      * @param tableList the table list
  188.      *
  189.      * @return a list of Strings, where each item is a CSV file relative to the base URL
  190.      *
  191.      * @throws IOException when IO on the base URL has issues.
  192.      */
  193.     public static List getTables(File controlFilesDir, File tableList) throws IOException
  194.     {
  195.         logger.debug("getTables(controlFilesDir={}, tableList={}) - start", controlFilesDir, tableList);

  196.         // Copy file into the control directory
  197.         File tmpTableList = new File(controlFilesDir, TMP_TABLE_LIST_FILENAME);
  198.         FileHelper.copyFile(tableList, tmpTableList);

  199.         List orderedNames;
  200.         try {
  201.             orderedNames = FileHelper.readLines(tmpTableList);
  202.         }
  203.         finally {
  204.             boolean success = tmpTableList.delete();
  205.             if (!success) {
  206.                 throw new IOException("Deletion of temorary file failed: " + tmpTableList);
  207.             }
  208.         }
  209.         return orderedNames;
  210.     }

  211. }