X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;ds=inline;f=support%2Ftest%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fsupport%2Fpersistence%2FDatabaseBuilder.java;fp=support%2Ftest%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fsupport%2Fpersistence%2FDatabaseBuilder.java;h=9c599a0a75cddf8f81203b217aeb76885827a5e4;hb=e8b7f484cbd8168c4341eee5cb020cdd080ce944;hp=0000000000000000000000000000000000000000;hpb=c6dd7d29643a8e4a6ec11088ecb5ab9f58845e0b;p=utils diff --git a/support/test/src/main/java/org/wamblee/support/persistence/DatabaseBuilder.java b/support/test/src/main/java/org/wamblee/support/persistence/DatabaseBuilder.java new file mode 100644 index 00000000..9c599a0a --- /dev/null +++ b/support/test/src/main/java/org/wamblee/support/persistence/DatabaseBuilder.java @@ -0,0 +1,116 @@ +package org.wamblee.support.persistence; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.ServiceLoader; +import java.util.logging.Logger; + +/** + * DatabaseBuilder is used from unit test to obtain a reference to a database + * from unit test. This database is either an inmemory database or represents an + * external database. Purpose of this utility is to make test code independent of the + * particular database used and specifically to be able to run database tests without + * any configuration at all (using an inmemory database). + * + * The type of database to use can be overridden by specifying either a system + * property or an environment variable ({@link #DB_CAPABILITIES_PROP}) that + * contains the comma-separated capabilities of the database. Each database type + * provides its own capabilities (see {@link DatabaseProvider} implementations}. + * + * + * There are currently two database types available: + * + * + * The DatabaseBuilder uses the {@link ServiceLoader} mechanism to find implementations + * of {@link DatabaseProvider} on the classpath. In the {@link #getDatabase(String...)} method a number of + * capabilities are passed. The database providers are then searched in (arbitrary) order and the first one that + * has all required capabilities is returned. + * + * {@link #getSupportedDatabases()} gives a list of all available databases. + */ +public class DatabaseBuilder { + + private static final Logger LOGGER = Logger.getLogger(DatabaseBuilder.class + .getName()); + + /** + * Environmment variable by which capabilities of the requested database can + * be defined + */ + private static final String DB_CAPABILITIES_PROP = "TEST_DB_CAPABILITIES"; + + private static ServiceLoader LOADER = null; + + private DatabaseBuilder() { + // Empty. + } + + private static String[] parseCapabilities(String aValue) { + return aValue.split(","); + } + + /** + * Gets the first database that has all required capabilities. + * @param aCapabilities Capabilities. + * @return Database to use. + */ + public static Database getDatabase(String... aCapabilities) { + if (aCapabilities.length == 0) { + LOGGER.info("Examining database capabilities"); + LOGGER.info(" Checking system property " + DB_CAPABILITIES_PROP); + String capabilities = System.getProperty(DB_CAPABILITIES_PROP); + if (capabilities != null) { + aCapabilities = parseCapabilities(capabilities); + } else { + LOGGER.info(" Checking environment variable " + + DB_CAPABILITIES_PROP); + capabilities = System.getenv(DB_CAPABILITIES_PROP); + if (capabilities != null) { + aCapabilities = parseCapabilities(capabilities); + } else { + LOGGER.info(" Using default capabilities"); + aCapabilities = new String[] { DatabaseProvider.CAPABILITY_IN_MEMORY }; + } + } + LOGGER.info("Using capabilities: " + aCapabilities); + } + synchronized (DatabaseBuilder.class) { + initLoader(); + for (DatabaseProvider db : LOADER) { + if (db.supportsCapabilities(aCapabilities)) { + return db.create(); + } + } + } + throw new RuntimeException( + "No database found that satisfies capabilities: " + + Arrays.asList(aCapabilities)); + } + + /** + * Gets a list of available databases. + * @return List of databases. + */ + public static List getSupportedDatabases() { + initLoader(); + List descriptions = new ArrayList(); + for (DatabaseProvider db : LOADER) { + descriptions.add(db.getDescription()); + } + return descriptions; + } + + private static void initLoader() { + if (LOADER == null) { + LOADER = ServiceLoader.load(DatabaseProvider.class); + } + } + +}