2 * Copyright 2005-2010 the original author or authors.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.wamblee.support.persistence;
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.List;
21 import java.util.ServiceLoader;
22 import java.util.logging.Logger;
25 * DatabaseBuilder is used from unit test to obtain a reference to a database
26 * from unit test. This database is either an inmemory database or represents an
27 * external database. Purpose of this utility is to make test code independent
28 * of the particular database used and specifically to be able to run database
29 * tests without any configuration at all (using an inmemory database).
31 * The type of database to use can be overridden by specifying either a system
32 * property or an environment variable ({@link #DB_CAPABILITIES_PROP}) that
33 * contains the comma-separated capabilities of the database. Each database type
34 * provides its own capabilities (see {@link DatabaseProvider} implementations}.
37 * There are currently two database types available:
39 * <li>Derby: AN inmemory derby. Provided by {@link DerbyDatabaseProvider}. This
40 * is the default.</li>
41 * <li>External: An arbitrary external database configured using system
42 * properties or environment variables in the usual way using a JDBC URL,
43 * username, and password.</li>
46 * The <code>DatabaseBuilder</code> uses the {@link ServiceLoader} mechanism to
47 * find implementations of {@link DatabaseProvider} on the classpath. In the
48 * {@link #getDatabase(String...)} method a number of capabilities are passed.
49 * The database providers are then searched in (arbitrary) order and the first
50 * one that has all required capabilities is returned.
52 * {@link #getSupportedDatabases()} gives a list of all available databases.
54 public class DatabaseBuilder {
56 private static final Logger LOGGER = Logger.getLogger(DatabaseBuilder.class
60 * Environmment variable by which capabilities of the requested database can
63 private static final String DB_CAPABILITIES_PROP = "TEST_DB_CAPABILITIES";
65 private static ServiceLoader<DatabaseProvider> LOADER =
66 ServiceLoader.load(DatabaseProvider.class);
68 private DatabaseBuilder() {
72 private static String[] parseCapabilities(String aValue) {
73 return aValue.split(",");
77 * Gets the first database that has all required capabilities.
79 * @param aCapabilities
81 * @return Database to use.
83 public static Database getDatabase(String... aCapabilities) {
84 if (aCapabilities.length == 0) {
85 LOGGER.info("Examining database capabilities");
86 LOGGER.info(" Checking system property " + DB_CAPABILITIES_PROP);
87 String capabilities = System.getProperty(DB_CAPABILITIES_PROP);
88 if (capabilities != null) {
89 aCapabilities = parseCapabilities(capabilities);
91 LOGGER.info(" Checking environment variable " +
92 DB_CAPABILITIES_PROP);
93 capabilities = System.getenv(DB_CAPABILITIES_PROP);
94 if (capabilities != null) {
95 aCapabilities = parseCapabilities(capabilities);
97 LOGGER.info(" Using default capabilities");
98 aCapabilities = new String[] { DatabaseProvider.CAPABILITY_IN_MEMORY };
101 LOGGER.info("Using capabilities: " + Arrays.asList(aCapabilities));
103 synchronized (DatabaseBuilder.class) {
104 for (DatabaseProvider db : LOADER) {
105 if (db.supportsCapabilities(aCapabilities)) {
110 throw new RuntimeException(
111 "No database found that satisfies capabilities: " +
112 Arrays.asList(aCapabilities));
116 * Gets a list of available databases.
118 * @return List of databases.
120 public static List<DatabaseDescription> getSupportedDatabases() {
121 List<DatabaseDescription> descriptions = new ArrayList<DatabaseDescription>();
122 for (DatabaseProvider db : LOADER) {
123 descriptions.add(db.getDescription());