View Javadoc
1   package org.dbunit.dataset;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import org.dbunit.dataset.datatype.DataType;
7   
8   /**
9    * Fluent builder for creating {@link IDataSet} instances programmatically,
10   * reducing XML file dependencies in unit tests.
11   *
12   * <p>Single-table example:
13   * <pre>
14   * IDataSet ds = new DataSetBuilder()
15   *     .table("FOO")
16   *         .columns("ID", "NAME")
17   *         .row(1, "Alice")
18   *         .row(2, "Bob")
19   *     .build();
20   * </pre>
21   *
22   * <p>Multi-table example:
23   * <pre>
24   * IDataSet ds = new DataSetBuilder()
25   *     .table("FOO")
26   *         .columns("ID", "NAME")
27   *         .row(1, "Alice")
28   *     .table("BAR")
29   *         .columns("X")
30   *         .row(42)
31   *     .build();
32   * </pre>
33   *
34   * @since 3.2.0
35   */
36  public class DataSetBuilder
37  {
38      private final List<TableConfig> tableConfigs = new ArrayList<>();
39  
40      /**
41       * Starts configuring a new table with the given name.
42       *
43       * @param name the table name
44       * @return a {@link TableBuilder} for configuring columns and rows
45       */
46      public TableBuilder table(final String name)
47      {
48          final TableConfig config = new TableConfig(name);
49          tableConfigs.add(config);
50          return new TableBuilder(config);
51      }
52  
53      /**
54       * Builds and returns an {@link IDataSet} containing all configured tables.
55       *
56       * @return the dataset
57       * @throws DataSetException if any table configuration is invalid
58       */
59      public IDataSet build() throws DataSetException
60      {
61          final List<DefaultTable> tables = new ArrayList<>();
62          for (final TableConfig config : tableConfigs)
63          {
64              tables.add(config.buildTable());
65          }
66          return new DefaultDataSet(tables.toArray(new DefaultTable[0]));
67      }
68  
69      /**
70       * Fluent builder for a single table within a {@link DataSetBuilder}.
71       */
72      public class TableBuilder
73      {
74          private final TableConfig config;
75  
76          private TableBuilder(final TableConfig config)
77          {
78              this.config = config;
79          }
80  
81          /**
82           * Sets the column names for this table. Column data types are set to
83           * {@link DataType#UNKNOWN} and resolved at runtime by DbUnit.
84           *
85           * @param names the column names in order
86           * @return this builder
87           */
88          public TableBuilder columns(final String... names)
89          {
90              config.setColumnNames(names);
91              return this;
92          }
93  
94          /**
95           * Adds a row of values to this table. Values must be in the same order
96           * as the columns declared via {@link #columns(String...)}.
97           *
98           * @param values the row values
99           * @return this builder
100          */
101         public TableBuilder row(final Object... values)
102         {
103             config.addRow(values);
104             return this;
105         }
106 
107         /**
108          * Starts configuring another table, finalizing this one.
109          *
110          * @param name the next table name
111          * @return a new {@link TableBuilder} for the next table
112          */
113         public TableBuilder table(final String name)
114         {
115             return DataSetBuilder.this.table(name);
116         }
117 
118         /**
119          * Builds and returns an {@link IDataSet} containing all configured tables.
120          *
121          * @return the dataset
122          * @throws DataSetException if any table configuration is invalid
123          */
124         public IDataSet build() throws DataSetException
125         {
126             return DataSetBuilder.this.build();
127         }
128     }
129 
130     private static class TableConfig
131     {
132         private final String name;
133         private String[] columnNames = new String[0];
134         private final List<Object[]> rows = new ArrayList<>();
135 
136         TableConfig(final String name)
137         {
138             this.name = name;
139         }
140 
141         void setColumnNames(final String[] names)
142         {
143             columnNames = names;
144         }
145 
146         void addRow(final Object[] values)
147         {
148             rows.add(values);
149         }
150 
151         DefaultTable buildTable() throws DataSetException
152         {
153             final Column[] columns = new Column[columnNames.length];
154             for (int i = 0; i < columnNames.length; i++)
155             {
156                 columns[i] = new Column(columnNames[i], DataType.UNKNOWN);
157             }
158             final DefaultTable table = new DefaultTable(name, columns);
159             for (final Object[] row : rows)
160             {
161                 table.addRow(row);
162             }
163             return table;
164         }
165     }
166 }