Removed DOCUMENT ME comments that were generated and applied source code
[utils] / test / enterprise / src / main / java / org / wamblee / support / persistence / DatabaseBuilder.java
1 package org.wamblee.support.persistence;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.List;
6 import java.util.ServiceLoader;
7 import java.util.logging.Logger;
8
9 /**
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
13  * of the particular database used and specifically to be able to run database
14  * tests without any configuration at all (using an inmemory database).
15  * 
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}.
20  * 
21  * 
22  * There are currently two database types available:
23  * <ul>
24  * <li>Derby: AN inmemory derby. Provided by {@link DerbyDatabaseProvider}. This
25  * is the default.</li>
26  * <li>External: An arbitrary external database configured using system
27  * properties or environment variables in the usual way using a JDBC URL,
28  * username, and password.</li>
29  * </ul>
30  * 
31  * The <code>DatabaseBuilder</code> uses the {@link ServiceLoader} mechanism to
32  * find implementations of {@link DatabaseProvider} on the classpath. In the
33  * {@link #getDatabase(String...)} method a number of capabilities are passed.
34  * The database providers are then searched in (arbitrary) order and the first
35  * one that has all required capabilities is returned.
36  * 
37  * {@link #getSupportedDatabases()} gives a list of all available databases.
38  */
39 public class DatabaseBuilder {
40
41     private static final Logger LOGGER = Logger.getLogger(DatabaseBuilder.class
42         .getName());
43
44     /**
45      * Environmment variable by which capabilities of the requested database can
46      * be defined
47      */
48     private static final String DB_CAPABILITIES_PROP = "TEST_DB_CAPABILITIES";
49
50     private static ServiceLoader<DatabaseProvider> LOADER = null;
51
52     private DatabaseBuilder() {
53         // Empty.
54     }
55
56     private static String[] parseCapabilities(String aValue) {
57         return aValue.split(",");
58     }
59
60     /**
61      * Gets the first database that has all required capabilities.
62      * 
63      * @param aCapabilities
64      *            Capabilities.
65      * @return Database to use.
66      */
67     public static Database getDatabase(String... aCapabilities) {
68         if (aCapabilities.length == 0) {
69             LOGGER.info("Examining database capabilities");
70             LOGGER.info("  Checking system property " + DB_CAPABILITIES_PROP);
71             String capabilities = System.getProperty(DB_CAPABILITIES_PROP);
72             if (capabilities != null) {
73                 aCapabilities = parseCapabilities(capabilities);
74             } else {
75                 LOGGER.info("  Checking environment variable " +
76                     DB_CAPABILITIES_PROP);
77                 capabilities = System.getenv(DB_CAPABILITIES_PROP);
78                 if (capabilities != null) {
79                     aCapabilities = parseCapabilities(capabilities);
80                 } else {
81                     LOGGER.info("  Using default capabilities");
82                     aCapabilities = new String[] { DatabaseProvider.CAPABILITY_IN_MEMORY };
83                 }
84             }
85             LOGGER.info("Using capabilities: " + aCapabilities);
86         }
87         synchronized (DatabaseBuilder.class) {
88             initLoader();
89             for (DatabaseProvider db : LOADER) {
90                 if (db.supportsCapabilities(aCapabilities)) {
91                     return db.create();
92                 }
93             }
94         }
95         throw new RuntimeException(
96             "No database found that satisfies capabilities: " +
97                 Arrays.asList(aCapabilities));
98     }
99
100     /**
101      * Gets a list of available databases.
102      * 
103      * @return List of databases.
104      */
105     public static List<DatabaseDescription> getSupportedDatabases() {
106         initLoader();
107         List<DatabaseDescription> descriptions = new ArrayList<DatabaseDescription>();
108         for (DatabaseProvider db : LOADER) {
109             descriptions.add(db.getDescription());
110         }
111         return descriptions;
112     }
113
114     private static void initLoader() {
115         if (LOADER == null) {
116             LOADER = ServiceLoader.load(DatabaseProvider.class);
117         }
118     }
119
120 }