FlatXmlDataSetBuilder.java

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

  22. import java.io.File;
  23. import java.io.IOException;
  24. import java.io.InputStream;
  25. import java.io.Reader;
  26. import java.net.MalformedURLException;
  27. import java.net.URL;

  28. import org.dbunit.dataset.DataSetException;
  29. import org.dbunit.dataset.IDataSet;
  30. import org.slf4j.Logger;
  31. import org.slf4j.LoggerFactory;
  32. import org.xml.sax.InputSource;

  33. /**
  34.  * Builder for the creation of {@link FlatXmlDataSet} instances.
  35.  *
  36.  * @see FlatXmlDataSet
  37.  * @author gommma (gommma AT users.sourceforge.net)
  38.  * @author Last changed by: $Author$
  39.  * @version $Revision$ $Date$
  40.  * @since 2.4.7
  41.  */
  42. public final class FlatXmlDataSetBuilder
  43. {
  44.     /**
  45.      * Logger for this class
  46.      */
  47.     private static final Logger logger = LoggerFactory.getLogger(FlatXmlDataSetBuilder.class);

  48.     /**
  49.      * The metadata (column information etc.) for the flat XML to be built.
  50.      * If this is set the builder properties
  51.      * <ul>
  52.      * <li>{@link #columnSensing}</li>
  53.      * <li>{@link #caseSensitiveTableNames}</li>
  54.      * <li>{@link #dtdMetadata}</li>
  55.      * </ul>
  56.      * are <b>not</b> regarded.
  57.      */
  58.     private IDataSet metaDataSet = null;
  59.    
  60.     /**
  61.      * Whether or not DTD metadata is available to parse via a DTD handler. Defaults to {@value}
  62.      */
  63.     private boolean dtdMetadata = true;
  64.    
  65. //TODO Think about this: should we use "columnSensing=true" by default if no DTD is specified? To avoid e.g. bug reports like #2812985 https://sourceforge.net/tracker/?func=detail&atid=449491&aid=2812985&group_id=47439
  66.     /**
  67.      * Since DBUnit 2.3.0 there is a functionality called "column sensing" which basically
  68.      * reads in the whole XML into a buffer and dynamically adds new columns as they appear.
  69.      * Defaults to {@value}
  70.      */
  71.     private boolean columnSensing = false;
  72.     /**
  73.     * Whether or not the created dataset should use case sensitive table names
  74.     * Defaults to {@value}
  75.     */
  76.     private boolean caseSensitiveTableNames = false;
  77.    
  78.    
  79.     /**
  80.      * Default constructor
  81.      */
  82.     public FlatXmlDataSetBuilder()
  83.     {
  84.     }
  85.    
  86.     /**
  87.      * Sets the flat XML input source from which the {@link FlatXmlDataSet} is to be built
  88.      * @param inputSource The flat XML input as {@link InputSource}
  89.      * @return The created {@link FlatXmlDataSet}
  90.      * @throws DataSetException
  91.      */
  92.     public FlatXmlDataSet build(InputSource inputSource) throws DataSetException
  93.     {
  94.         return buildInternal(inputSource);
  95.     }

  96.     /**
  97.      * Sets the flat XML input source from which the {@link FlatXmlDataSet} is to be built
  98.      * @param xmlInputFile The flat XML input as {@link File}
  99.      * @return The created {@link FlatXmlDataSet}
  100.      * @throws DataSetException
  101.      */
  102.     public FlatXmlDataSet build(File xmlInputFile) throws MalformedURLException, DataSetException
  103.     {
  104.         URL xmlInputUrl = xmlInputFile.toURL();
  105.         InputSource inputSource = createInputSourceFromUrl(xmlInputUrl);
  106.         return buildInternal(inputSource);
  107.     }
  108.    
  109.     /**
  110.      * Sets the flat XML input source from which the {@link FlatXmlDataSet} is to be built
  111.      * @param xmlInputUrl The flat XML input as {@link URL}
  112.      * @return The created {@link FlatXmlDataSet}
  113.      * @throws DataSetException
  114.      */
  115.     public FlatXmlDataSet build(URL xmlInputUrl) throws DataSetException
  116.     {
  117.         InputSource inputSource = createInputSourceFromUrl(xmlInputUrl);
  118.         return buildInternal(inputSource);
  119.     }
  120.    
  121.     /**
  122.      * Sets the flat XML input source from which the {@link FlatXmlDataSet} is to be built
  123.      * @param xmlReader The flat XML input as {@link Reader}
  124.      * @return The created {@link FlatXmlDataSet}
  125.      * @throws DataSetException
  126.      */
  127.     public FlatXmlDataSet build(Reader xmlReader) throws DataSetException
  128.     {
  129.         InputSource inputSource = new InputSource(xmlReader);
  130.         return buildInternal(inputSource);
  131.     }

  132.     /**
  133.      * Sets the flat XML input source from which the {@link FlatXmlDataSet} is to be built
  134.      * @param xmlInputStream The flat XML input as {@link InputStream}
  135.      * @return The created {@link FlatXmlDataSet}
  136.      * @throws DataSetException
  137.      */
  138.     public FlatXmlDataSet build(InputStream xmlInputStream) throws DataSetException
  139.     {
  140.         InputSource inputSource = new InputSource(xmlInputStream);
  141.         return buildInternal(inputSource);
  142.     }
  143.    
  144.     /**
  145.      * Utility method to create an {@link InputSource} object from a URL
  146.      * @param xmlInputUrl
  147.      * @return
  148.      */
  149.     private InputSource createInputSourceFromUrl(URL xmlInputUrl)
  150.     {
  151.         String stringUrl = xmlInputUrl.toString();
  152.         return new InputSource(stringUrl);
  153.     }
  154.    
  155.     /**
  156.      * Set the metadata information (column info etc.) to be used. May come from a DTD.
  157.      * This has precedence to the other builder's properties.
  158.      * @param metaDataSet
  159.      * @return this
  160.      */
  161.     public FlatXmlDataSetBuilder setMetaDataSet(IDataSet metaDataSet)
  162.     {
  163.         this.metaDataSet = metaDataSet;
  164.         return this;
  165.     }

  166.     /**
  167.      * Set the metadata information (column info etc.) to be used from the given DTD input.
  168.      * This has precedence to the other builder's properties.
  169.      * @param dtdReader A reader that provides the DTD content
  170.      * @throws DataSetException
  171.      * @throws IOException
  172.      * @return this
  173.      */
  174.     public FlatXmlDataSetBuilder setMetaDataSetFromDtd(Reader dtdReader) throws DataSetException, IOException
  175.     {
  176.         this.metaDataSet = new FlatDtdDataSet(dtdReader);
  177.         return this;
  178.     }
  179.    
  180.     /**
  181.      * Set the metadata information (column info etc.) to be used from the given DTD input.
  182.      * This has precedence to the other builder's properties.
  183.      * @param dtdStream
  184.      * @throws DataSetException
  185.      * @throws IOException
  186.      * @return this
  187.      */
  188.     public FlatXmlDataSetBuilder setMetaDataSetFromDtd(InputStream dtdStream) throws DataSetException, IOException
  189.     {
  190.         this.metaDataSet = new FlatDtdDataSet(dtdStream);
  191.         return this;
  192.     }
  193.    
  194.     public boolean isDtdMetadata() {
  195.         return dtdMetadata;
  196.     }

  197.     /**
  198.      * Whether or not DTD metadata is available to parse via a DTD handler.
  199.      * @param dtdMetadata
  200.      * @return this
  201.      */
  202.     public FlatXmlDataSetBuilder setDtdMetadata(boolean dtdMetadata) {
  203.         this.dtdMetadata = dtdMetadata;
  204.         return this;
  205.     }

  206.     public boolean isColumnSensing() {
  207.         return columnSensing;
  208.     }

  209.     /**
  210.      * Since DBUnit 2.3.0 there is a functionality called "column sensing" which basically
  211.      * reads in the whole XML into a buffer and dynamically adds new columns as they appear.
  212.      * @param columnSensing
  213.      * @return this
  214.      */
  215.     public FlatXmlDataSetBuilder setColumnSensing(boolean columnSensing) {
  216.         this.columnSensing = columnSensing;
  217.         return this;
  218.     }

  219.     public boolean isCaseSensitiveTableNames() {
  220.         return caseSensitiveTableNames;
  221.     }

  222.     /**
  223.      * Whether or not the created dataset should use case sensitive table names
  224.      * @param caseSensitiveTableNames
  225.      * @return this
  226.      */
  227.     public FlatXmlDataSetBuilder setCaseSensitiveTableNames(boolean caseSensitiveTableNames) {
  228.         this.caseSensitiveTableNames = caseSensitiveTableNames;
  229.         return this;
  230.     }


  231.     /**
  232.      * Builds the {@link FlatXmlDataSet} from the parameters that are currently set on this builder
  233.      * @param inputSource The XML input to be built
  234.      * @return The {@link FlatXmlDataSet} built from the configuration of this builder.
  235.      * @throws DataSetException
  236.      */
  237.     private FlatXmlDataSet buildInternal(InputSource inputSource) throws DataSetException
  238.     {
  239.         logger.trace("build(inputSource={}) - start", inputSource);
  240.        
  241.         // Validate required parameters
  242.         if(inputSource==null)
  243.         {
  244.             throw new NullPointerException("The parameter 'inputSource' must not be null");
  245.         }
  246.        
  247.         // Create the flat XML IDataSet
  248.         logger.debug("Creating FlatXmlDataSet with builder parameters: {}", this);
  249.         FlatXmlProducer producer = createProducer(inputSource);
  250.         return new FlatXmlDataSet(producer);
  251.     }

  252.     /**
  253.      * @param inputSource The XML input to be built
  254.      * @return The producer which is used to create the {@link FlatXmlDataSet}
  255.      */
  256.     protected FlatXmlProducer createProducer(InputSource inputSource)
  257.     {
  258.         logger.trace("createProducer(inputSource={}) - start", inputSource);
  259.        
  260.         FlatXmlProducer producer = null;
  261.         if(this.metaDataSet!=null)
  262.         {
  263.             logger.debug("Creating FlatXmlProducer using the following metaDataSet: {}", this.metaDataSet);
  264.             producer = new FlatXmlProducer(inputSource, this.metaDataSet);
  265.         }
  266.         else
  267.         {
  268.             logger.debug("Creating FlatXmlProducer using the properties of this builder: {}", this);
  269.             producer = new FlatXmlProducer(
  270.                     inputSource, this.dtdMetadata, this.columnSensing, this.caseSensitiveTableNames);
  271.         }
  272.         return producer;
  273.     }
  274.    
  275.     public String toString()
  276.     {
  277.         final StringBuilder sb = new StringBuilder();
  278.         sb.append(getClass().getName()).append("[");
  279.         sb.append("dtdMetadata=").append(dtdMetadata);
  280.         sb.append(", columnSensing=").append(columnSensing);
  281.         sb.append(", caseSensitiveTableNames=").append(caseSensitiveTableNames);
  282.         sb.append(", metaDataSet=").append(metaDataSet);
  283.         sb.append("]");
  284.         return sb.toString();
  285.     }
  286. }