YamlProducer.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.dataset.yaml;

  22. import org.dbunit.database.AmbiguousTableNameException;
  23. import org.dbunit.dataset.Column;
  24. import org.dbunit.dataset.DataSetException;
  25. import org.dbunit.dataset.DefaultTableMetaData;
  26. import org.dbunit.dataset.ITableMetaData;
  27. import org.dbunit.dataset.datatype.DataType;
  28. import org.dbunit.dataset.stream.DefaultConsumer;
  29. import org.dbunit.dataset.stream.IDataSetConsumer;
  30. import org.dbunit.dataset.stream.IDataSetProducer;
  31. import org.yaml.snakeyaml.LoaderOptions;
  32. import org.yaml.snakeyaml.Yaml;
  33. import org.yaml.snakeyaml.constructor.DuplicateKeyException;

  34. import java.io.File;
  35. import java.io.FileInputStream;
  36. import java.io.IOException;
  37. import java.io.InputStream;
  38. import java.util.ArrayList;
  39. import java.util.LinkedHashMap;
  40. import java.util.LinkedHashSet;
  41. import java.util.List;
  42. import java.util.Map;
  43. import java.util.Set;

  44. /**
  45.  * @author Björn Beskow
  46.  * @version $Revision$ $Date$
  47.  */

  48. public class YamlProducer implements IDataSetProducer
  49. {

  50.     private static final IDataSetConsumer EMPTY_CONSUMER = new DefaultConsumer();

  51.     /**
  52.      * The consumer which is responsible for creating the datasets and tables
  53.      */
  54.     private IDataSetConsumer _consumer = EMPTY_CONSUMER;

  55.     private InputStream _inputStream;

  56.     private Yaml _yaml;

  57.     public YamlProducer(File file) throws IOException
  58.     {
  59.         this(new FileInputStream(file));
  60.     }

  61.     public YamlProducer(InputStream inputStream)
  62.     {
  63.         this._inputStream = inputStream;
  64.         LoaderOptions options = new LoaderOptions();
  65.         options.setAllowDuplicateKeys(false);
  66.         _yaml = new Yaml(options);
  67.     }

  68.     ////////////////////////////////////////////////////////////////////////////
  69.     // IDataSetProducer interface

  70.     public void setConsumer(IDataSetConsumer consumer)
  71.     {
  72.         _consumer = consumer;
  73.     }

  74.     public void produce() throws DataSetException
  75.     {
  76.         _consumer.startDataSet();
  77.         LinkedHashMap<String, Object> dataset;
  78.         // get the base object tree from the stream
  79.         try
  80.         {
  81.             dataset = (LinkedHashMap<String, Object>) _yaml.load(_inputStream);
  82.         }
  83.         catch (DuplicateKeyException e)
  84.         {
  85.             String problem = e.getProblem();
  86.             String duplicateTable = problem.replace("found duplicate key ", "");
  87.             throw new AmbiguousTableNameException(duplicateTable, e);
  88.         }
  89.         // iterate over the tables in the object tree
  90.         for (String tableName : dataset.keySet())
  91.         {
  92.             // get the rows for the table
  93.             List<Map<String, Object>> rows = (List<Map<String, Object>>) dataset.get(tableName);
  94.             ITableMetaData meta = getMetaData(tableName, rows);
  95.             _consumer.startTable(meta);
  96.             if (rows != null)
  97.             {
  98.                 for (Map<String, Object> row : rows)
  99.                 {
  100.                     _consumer.row(getRow(meta, row));
  101.                 }
  102.             }
  103.             _consumer.endTable();
  104.         }
  105.     }


  106.     private ITableMetaData getMetaData(String tableName, List<Map<String, Object>> rows)
  107.     {
  108.         Set<String> columns = new LinkedHashSet<String>();
  109.         if (rows != null)
  110.         {
  111.             // iterate through the dataset and add the column names to a set
  112.             for (Map<String, Object> row : rows)
  113.             {
  114.                 for (Map.Entry<String, Object> column : row.entrySet())
  115.                 {
  116.                     columns.add(column.getKey());
  117.                 }
  118.             }
  119.             List<Column> list = new ArrayList<Column>(columns.size());
  120.             // create a list of DBUnit columns based on the column name set
  121.             for (String s : columns)
  122.             {
  123.                 list.add(new Column(s, DataType.UNKNOWN));
  124.             }
  125.             return new DefaultTableMetaData(tableName, list.toArray(new Column[list.size()]));
  126.         } else
  127.         {
  128.             return new DefaultTableMetaData(tableName, new Column[0]);
  129.         }
  130.     }

  131.     private Object[] getRow(ITableMetaData meta, Map<String, Object> row) throws DataSetException
  132.     {
  133.         Object[] result = new Object[meta.getColumns().length];
  134.         for (int i = 0; i < meta.getColumns().length; i++)
  135.         {
  136.             result[i] = row.get(meta.getColumns()[i].getColumnName());
  137.         }
  138.         return result;
  139.     }

  140. }