1 package org.wamblee.support.persistence;
3 import java.util.ArrayList;
4 import java.util.Arrays;
6 import java.util.ServiceLoader;
7 import java.util.logging.Logger;
10 * DatabaseBuilder is used from unit test to obtain a reference to a database
11 * from unit test. This database is either an inmemory database or represents an
12 * external database. Purpose of this utility is to make test code independent of the
13 * particular database used and specifically to be able to run database tests without
14 * any configuration at all (using an inmemory database).
16 * The type of database to use can be overridden by specifying either a system
17 * property or an environment variable ({@link #DB_CAPABILITIES_PROP}) that
18 * contains the comma-separated capabilities of the database. Each database type
19 * provides its own capabilities (see {@link DatabaseProvider} implementations}.
22 * There are currently two database types available:
24 * <li> Derby: AN inmemory derby. Provided by {@link DerbyDatabaseProvider}. This is the default.
26 * <li> External: An arbitrary external database configured using system properties or environment variables
27 * in the usual way using a JDBC URL, username, and password.
31 * The <code>DatabaseBuilder</code> uses the {@link ServiceLoader} mechanism to find implementations
32 * of {@link DatabaseProvider} on the classpath. In the {@link #getDatabase(String...)} method a number of
33 * capabilities are passed. The database providers are then searched in (arbitrary) order and the first one that
34 * has all required capabilities is returned.
36 * {@link #getSupportedDatabases()} gives a list of all available databases.
38 public class DatabaseBuilder {
40 private static final Logger LOGGER = Logger.getLogger(DatabaseBuilder.class
44 * Environmment variable by which capabilities of the requested database can
47 private static final String DB_CAPABILITIES_PROP = "TEST_DB_CAPABILITIES";
49 private static ServiceLoader<DatabaseProvider> LOADER = null;
51 private DatabaseBuilder() {
55 private static String[] parseCapabilities(String aValue) {
56 return aValue.split(",");
60 * Gets the first database that has all required capabilities.
61 * @param aCapabilities Capabilities.
62 * @return Database to use.
64 public static Database getDatabase(String... aCapabilities) {
65 if (aCapabilities.length == 0) {
66 LOGGER.info("Examining database capabilities");
67 LOGGER.info(" Checking system property " + DB_CAPABILITIES_PROP);
68 String capabilities = System.getProperty(DB_CAPABILITIES_PROP);
69 if (capabilities != null) {
70 aCapabilities = parseCapabilities(capabilities);
72 LOGGER.info(" Checking environment variable "
73 + DB_CAPABILITIES_PROP);
74 capabilities = System.getenv(DB_CAPABILITIES_PROP);
75 if (capabilities != null) {
76 aCapabilities = parseCapabilities(capabilities);
78 LOGGER.info(" Using default capabilities");
79 aCapabilities = new String[] { DatabaseProvider.CAPABILITY_IN_MEMORY };
82 LOGGER.info("Using capabilities: " + aCapabilities);
84 synchronized (DatabaseBuilder.class) {
86 for (DatabaseProvider db : LOADER) {
87 if (db.supportsCapabilities(aCapabilities)) {
92 throw new RuntimeException(
93 "No database found that satisfies capabilities: "
94 + Arrays.asList(aCapabilities));
98 * Gets a list of available databases.
99 * @return List of databases.
101 public static List<DatabaseDescription> getSupportedDatabases() {
103 List<DatabaseDescription> descriptions = new ArrayList<DatabaseDescription>();
104 for (DatabaseProvider db : LOADER) {
105 descriptions.add(db.getDescription());
110 private static void initLoader() {
111 if (LOADER == null) {
112 LOADER = ServiceLoader.load(DatabaseProvider.class);