/* * Copyright 2005-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.wamblee.test.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 */ public static final String DB_CAPABILITIES_PROP = "TEST_DB_CAPABILITIES"; private static ServiceLoader LOADER = ServiceLoader.load(DatabaseProvider.class); /** * Constructs the database builder. */ 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: " + Arrays.asList(aCapabilities)); } synchronized (DatabaseBuilder.class) { 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() { List descriptions = new ArrayList(); for (DatabaseProvider db : LOADER) { descriptions.add(db.getDescription()); } return descriptions; } }