View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.configuration;
18  
19  import java.io.File;
20  import java.io.FileInputStream;
21  import java.sql.Connection;
22  
23  import javax.sql.DataSource;
24  
25  import org.apache.commons.configuration.test.HsqlDB;
26  import org.apache.commons.dbcp.BasicDataSource;
27  import org.dbunit.database.DatabaseConnection;
28  import org.dbunit.database.IDatabaseConnection;
29  import org.dbunit.dataset.IDataSet;
30  import org.dbunit.dataset.xml.XmlDataSet;
31  import org.dbunit.operation.DatabaseOperation;
32  
33  /**
34   * A helper class for performing tests for {@link DatabaseConfiguration}. This
35   * class maintains an in-process database that stores configuration data and can
36   * be accessed from a {@link DatabaseConfiguration} instance. Constants for
37   * table and column names and database connection settings are provided, too.
38   *
39   * @version $Id: DatabaseConfigurationTestHelper.java 1222447 2011-12-22 20:59:44Z oheger $
40   */
41  public class DatabaseConfigurationTestHelper
42  {
43      /** Constant for the JDBC driver class. */
44      public final String DATABASE_DRIVER = "org.hsqldb.jdbcDriver";
45  
46      /** Constant for the connection URL. */
47      public final String DATABASE_URL = "jdbc:hsqldb:mem:testdb";
48  
49      /** Constant for the DB user name. */
50      public final String DATABASE_USERNAME = "sa";
51  
52      /** Constant for the DB password. */
53      public final String DATABASE_PASSWORD = "";
54  
55      /** Constant for the configuration table. */
56      public static final String TABLE = "configuration";
57  
58      /** Constant for the multi configuration table. */
59      public static final String TABLE_MULTI = "configurations";
60  
61      /** Constant for the column with the keys. */
62      public static final String COL_KEY = "key";
63  
64      /** Constant for the column with the values. */
65      public static final String COL_VALUE = "value";
66  
67      /** Constant for the column with the configuration name. */
68      public static final String COL_NAME = "name";
69  
70      /** Constant for the name of the test configuration. */
71      public static final String CONFIG_NAME = "test";
72  
73      /** Stores the in-process database. */
74      private HsqlDB hsqlDB;
75  
76      /** The data source. */
77      private DataSource datasource;
78  
79      /**
80       * The auto-commit mode for the connections created by the managed data
81       * source.
82       */
83      private boolean autoCommit = true;
84  
85      /**
86       * Returns the auto-commit mode of the connections created by the managed
87       * data source.
88       *
89       * @return the auto-commit mode
90       */
91      public boolean isAutoCommit()
92      {
93          return autoCommit;
94      }
95  
96      /**
97       * Sets the auto-commit mode of the connections created by the managed data
98       * source.
99       *
100      * @param autoCommit the auto-commit mode
101      */
102     public void setAutoCommit(boolean autoCommit)
103     {
104         this.autoCommit = autoCommit;
105     }
106 
107     /**
108      * Initializes this helper object. This method can be called from a
109      * {@code setUp()} method of a unit test class. It creates the database
110      * instance if necessary.
111      *
112      * @throws Exception if an error occurs
113      */
114     public void setUp() throws Exception
115     {
116         File script = ConfigurationAssert.getTestFile("testdb.script");
117         hsqlDB = new HsqlDB(DATABASE_URL, DATABASE_DRIVER, script.getAbsolutePath());
118     }
119 
120     /**
121      * Frees the resources used by this helper class. This method can be called
122      * by a {@code tearDown()} method of a unit test class.
123      *
124      * @throws Exception if an error occurs
125      */
126     public void tearDown() throws Exception
127     {
128         if (datasource != null)
129         {
130             datasource.getConnection().close();
131         }
132         hsqlDB.close();
133     }
134 
135     /**
136      * Creates a database configuration with default values.
137      *
138      * @return the configuration
139      */
140     public DatabaseConfiguration setUpConfig()
141     {
142         return new DatabaseConfiguration(getDatasource(), TABLE, COL_KEY,
143                 COL_VALUE, !isAutoCommit());
144     }
145 
146     /**
147      * Creates a database configuration that supports multiple configurations in
148      * a table with default values.
149      *
150      * @return the configuration
151      */
152     public DatabaseConfiguration setUpMultiConfig()
153     {
154         return setUpMultiConfig(CONFIG_NAME);
155     }
156 
157     /**
158      * Creates a database configuration that supports multiple configurations in
159      * a table and sets the specified configuration name.
160      *
161      * @param configName the name of the configuration
162      * @return the configuration
163      */
164     public DatabaseConfiguration setUpMultiConfig(String configName)
165     {
166         return new DatabaseConfiguration(getDatasource(), TABLE_MULTI,
167                 COL_NAME, COL_KEY, COL_VALUE, configName, !isAutoCommit());
168     }
169 
170     /**
171      * Returns the {@code DataSource} managed by this class. The data
172      * source is created on first access.
173      *
174      * @return the {@code DataSource}
175      */
176     public DataSource getDatasource()
177     {
178         if (datasource == null)
179         {
180             try
181             {
182                 datasource = setUpDataSource();
183             }
184             catch (Exception ex)
185             {
186                 throw new ConfigurationRuntimeException(
187                         "Could not create data source", ex);
188             }
189         }
190         return datasource;
191     }
192 
193     /**
194      * Creates the internal data source. This method also initializes the
195      * database.
196      *
197      * @return the data source
198      * @throws Exception if an error occurs
199      */
200     private DataSource setUpDataSource() throws Exception
201     {
202         BasicDataSource ds = new BasicDataSource();
203         ds.setDriverClassName(DATABASE_DRIVER);
204         ds.setUrl(DATABASE_URL);
205         ds.setUsername(DATABASE_USERNAME);
206         ds.setPassword(DATABASE_PASSWORD);
207         ds.setDefaultAutoCommit(isAutoCommit());
208 
209         // prepare the database
210         Connection conn = ds.getConnection();
211         IDatabaseConnection connection = new DatabaseConnection(conn);
212         IDataSet dataSet = new XmlDataSet(new FileInputStream(
213                 ConfigurationAssert.getTestFile("dataset.xml")));
214 
215         try
216         {
217             DatabaseOperation.CLEAN_INSERT.execute(connection, dataSet);
218         }
219         finally
220         {
221             if (!isAutoCommit())
222             {
223                 conn.commit();
224             }
225             connection.close();
226         }
227 
228         return ds;
229     }
230 }