commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ohe...@apache.org
Subject svn commit: r707290 - in /commons/proper/configuration/branches/configuration2_experimental/src: main/java/org/apache/commons/configuration2/DatabaseConfiguration.java test/java/org/apache/commons/configuration2/TestDatabaseConfiguration.java
Date Thu, 23 Oct 2008 06:24:25 GMT
Author: oheger
Date: Wed Oct 22 23:24:25 2008
New Revision: 707290

URL: http://svn.apache.org/viewvc?rev=707290&view=rev
Log:
Refactoring of DatabaseConfiguration to simplify JDBC-related code.
Removed the deprecated getConnection() method.

Modified:
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DatabaseConfiguration.java
    commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestDatabaseConfiguration.java

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DatabaseConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DatabaseConfiguration.java?rev=707290&r1=707289&r2=707290&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DatabaseConfiguration.java
(original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DatabaseConfiguration.java
Wed Oct 22 23:24:25 2008
@@ -28,6 +28,7 @@
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+
 import javax.sql.DataSource;
 
 /**
@@ -81,6 +82,21 @@
  */
 public class DatabaseConfiguration extends AbstractConfiguration
 {
+    /** Constant for the statement used by getProperty.*/
+    private static final String SQL_GET_PROPERTY = "SELECT * FROM %s WHERE %s =?";
+
+    /** Constant for the statement used by isEmpty.*/
+    private static final String SQL_IS_EMPTY = "SELECT count(*) FROM %s WHERE 1 = 1";
+
+    /** Constant for the statement used by clearProperty.*/
+    private static final String SQL_CLEAR_PROPERTY = "DELETE FROM %s WHERE %s =?";
+
+    /** Constant for the statement used by clear.*/
+    private static final String SQL_CLEAR = "DELETE FROM %s WHERE 1 = 1";
+
+    /** Constant for the statement used by getKeys.*/
+    private static final String SQL_GET_KEYS = "SELECT DISTINCT %s FROM %s WHERE 1 = 1";
+
     /** The datasource to connect to the database. */
     private DataSource datasource;
 
@@ -145,66 +161,45 @@
      * @param key the key of the desired property
      * @return the value of this property
      */
-    public Object getProperty(String key)
+    public Object getProperty(final String key)
     {
-        Object result = null;
-
-        // build the query
-        StringBuilder query = new StringBuilder("SELECT * FROM ");
-        query.append(table).append(" WHERE ");
-        query.append(keyColumn).append("=?");
-        if (nameColumn != null)
-        {
-            query.append(" AND " + nameColumn + "=?");
-        }
-
-        Connection conn = null;
-        PreparedStatement pstmt = null;
-
-        try
+        JdbcOperation op = new JdbcOperation(EVENT_READ_PROPERTY, key, null)
         {
-            conn = getConnection();
-
-            // bind the parameters
-            pstmt = conn.prepareStatement(query.toString());
-            pstmt.setString(1, key);
-            if (nameColumn != null)
+            @Override
+            protected Object performOperation() throws SQLException
             {
-                pstmt.setString(2, name);
-            }
+                PreparedStatement pstmt = initStatement(String.format(
+                        SQL_GET_PROPERTY, table, keyColumn), true, key);
+                ResultSet rs = pstmt.executeQuery();
 
-            ResultSet rs = pstmt.executeQuery();
+                List<Object> results = new ArrayList<Object>();
+                while (rs.next())
+                {
+                    Object value = rs.getObject(valueColumn);
+                    if (isDelimiterParsingDisabled())
+                    {
+                        results.add(value);
+                    }
+                    else
+                    {
+                        // Split value if it contains the list delimiter
+                        results.addAll(PropertyConverter.flatten(value,
+                                getListDelimiter()));
+                    }
+                }
 
-            List<Object> results = new ArrayList<Object>();
-            while (rs.next())
-            {
-                Object value = rs.getObject(valueColumn);
-                if (isDelimiterParsingDisabled())
+                if (!results.isEmpty())
                 {
-                    results.add(value);
+                    return (results.size() > 1) ? results : results.get(0);
                 }
                 else
                 {
-                    // Split value if it contains the list delimiter
-                    results.addAll(PropertyConverter.flatten(value, getListDelimiter()));
+                    return null;
                 }
             }
+        };
 
-            if (!results.isEmpty())
-            {
-                result = (results.size() > 1) ? results : results.get(0);
-            }
-        }
-        catch (SQLException e)
-        {
-            fireError(EVENT_READ_PROPERTY, key, null, e);
-        }
-        finally
-        {
-            close(conn, pstmt);
-        }
-
-        return result;
+        return op.execute();
     }
 
     /**
@@ -217,47 +212,40 @@
      * @param key the property key
      * @param obj the value of the property to add
      */
-    protected void addPropertyDirect(String key, Object obj)
+    @Override
+    protected void addPropertyDirect(final String key, final Object obj)
     {
-        // build the query
-        StringBuilder query = new StringBuilder("INSERT INTO " + table);
-        if (nameColumn != null)
+        new JdbcOperation(EVENT_ADD_PROPERTY, key, obj)
         {
-            query.append(" (" + nameColumn + ", " + keyColumn + ", " + valueColumn + ") VALUES
(?, ?, ?)");
-        }
-        else
-        {
-            query.append(" (" + keyColumn + ", " + valueColumn + ") VALUES (?, ?)");
-        }
-
-        Connection conn = null;
-        PreparedStatement pstmt = null;
+            @Override
+            protected Object performOperation() throws SQLException
+            {
+                StringBuilder query = new StringBuilder("INSERT INTO ");
+                query.append(table).append(" (");
+                query.append(keyColumn).append(", ");
+                query.append(valueColumn);
+                if (nameColumn != null)
+                {
+                    query.append(", ").append(nameColumn);
+                }
+                query.append(") VALUES (?, ?");
+                if (nameColumn != null)
+                {
+                    query.append(", ?");
+                }
+                query.append(")");
 
-        try
-        {
-            conn = getConnection();
+                PreparedStatement pstmt = initStatement(query.toString(),
+                        false, key, String.valueOf(obj));
+                if (nameColumn != null)
+                {
+                    pstmt.setString(3, name);
+                }
 
-            // bind the parameters
-            pstmt = conn.prepareStatement(query.toString());
-            int index = 1;
-            if (nameColumn != null)
-            {
-                pstmt.setString(index++, name);
+                pstmt.executeUpdate();
+                return null;
             }
-            pstmt.setString(index++, key);
-            pstmt.setString(index++, String.valueOf(obj));
-
-            pstmt.executeUpdate();
-        }
-        catch (SQLException e)
-        {
-            fireError(EVENT_ADD_PROPERTY, key, obj, e);
-        }
-        finally
-        {
-            // clean up
-            close(conn, pstmt);
-        }
+        }.execute();
     }
 
     /**
@@ -272,6 +260,7 @@
      * @param key the key of the new property
      * @param value the value to be added
      */
+    @Override
     public void addProperty(String key, Object value)
     {
         boolean parsingFlag = isDelimiterParsingDisabled();
@@ -300,242 +289,127 @@
      */
     public boolean isEmpty()
     {
-        boolean empty = true;
-
-        // build the query
-        StringBuilder query = new StringBuilder("SELECT count(*) FROM " + table);
-        if (nameColumn != null)
-        {
-            query.append(" WHERE " + nameColumn + "=?");
-        }
-
-        Connection conn = null;
-        PreparedStatement pstmt = null;
-
-        try
+        JdbcOperation op = new JdbcOperation(EVENT_READ_PROPERTY, null, null)
         {
-            conn = getConnection();
-
-            // bind the parameters
-            pstmt = conn.prepareStatement(query.toString());
-            if (nameColumn != null)
+            @Override
+            protected Object performOperation() throws SQLException
             {
-                pstmt.setString(1, name);
-            }
-
-            ResultSet rs = pstmt.executeQuery();
+                PreparedStatement ps = initStatement(String.format(
+                        SQL_IS_EMPTY, table), true);
+                ResultSet rs = ps.executeQuery();
 
-            if (rs.next())
-            {
-                empty = rs.getInt(1) == 0;
+                return rs.next() ? rs.getInt(1) : null;
             }
-        }
-        catch (SQLException e)
-        {
-            fireError(EVENT_READ_PROPERTY, null, null, e);
-        }
-        finally
-        {
-            // clean up
-            close(conn, pstmt);
-        }
+        };
 
-        return empty;
+        Integer count = (Integer) op.execute();
+        return count == null || count.intValue() == 0;
     }
 
     /**
      * Checks whether this configuration contains the specified key. If this
      * causes a database error, an error event will be generated of type
-     * <code>EVENT_READ_PROPERTY</code> with the causing exception. The
-     * event's <code>propertyName</code> will be set to the passed in key, the
+     * <code>EVENT_READ_PROPERTY</code> with the causing exception. The event's
+     * <code>propertyName</code> will be set to the passed in key, the
      * <code>propertyValue</code> will be undefined.
      *
      * @param key the key to be checked
      * @return a flag whether this key is defined
      */
-    public boolean containsKey(String key)
+    public boolean containsKey(final String key)
     {
-        boolean found = false;
-
-        // build the query
-        StringBuilder query = new StringBuilder("SELECT * FROM " + table + " WHERE " + keyColumn
+ "=?");
-        if (nameColumn != null)
-        {
-            query.append(" AND " + nameColumn + "=?");
-        }
-
-        Connection conn = null;
-        PreparedStatement pstmt = null;
-
-        try
+        JdbcOperation op = new JdbcOperation(EVENT_READ_PROPERTY, key, null)
         {
-            conn = getConnection();
-
-            // bind the parameters
-            pstmt = conn.prepareStatement(query.toString());
-            pstmt.setString(1, key);
-            if (nameColumn != null)
+            @Override
+            protected Object performOperation() throws SQLException
             {
-                pstmt.setString(2, name);
-            }
-
-            ResultSet rs = pstmt.executeQuery();
+                PreparedStatement pstmt = initStatement(String.format(
+                        SQL_GET_PROPERTY, table, keyColumn), true, key);
+                ResultSet rs = pstmt.executeQuery();
 
-            found = rs.next();
-        }
-        catch (SQLException e)
-        {
-            fireError(EVENT_READ_PROPERTY, key, null, e);
-        }
-        finally
-        {
-            // clean up
-            close(conn, pstmt);
-        }
+                return rs.next();
+            }
+        };
 
-        return found;
+        Boolean result = (Boolean) op.execute();
+        return result != null && result.booleanValue();
     }
 
     /**
      * Removes the specified value from this configuration. If this causes a
      * database error, an error event will be generated of type
-     * <code>EVENT_CLEAR_PROPERTY</code> with the causing exception. The
-     * event's <code>propertyName</code> will be set to the passed in key, the
+     * <code>EVENT_CLEAR_PROPERTY</code> with the causing exception. The event's
+     * <code>propertyName</code> will be set to the passed in key, the
      * <code>propertyValue</code> will be undefined.
      *
      * @param key the key of the property to be removed
      */
-    public void clearProperty(String key)
+    @Override
+    public void clearProperty(final String key)
     {
-        // build the query
-        StringBuilder query = new StringBuilder("DELETE FROM " + table + " WHERE " + keyColumn
+ "=?");
-        if (nameColumn != null)
+        new JdbcOperation(EVENT_CLEAR_PROPERTY, key, null)
         {
-            query.append(" AND " + nameColumn + "=?");
-        }
-
-        Connection conn = null;
-        PreparedStatement pstmt = null;
-
-        try
-        {
-            conn = getConnection();
-
-            // bind the parameters
-            pstmt = conn.prepareStatement(query.toString());
-            pstmt.setString(1, key);
-            if (nameColumn != null)
+            @Override
+            protected Object performOperation() throws SQLException
             {
-                pstmt.setString(2, name);
+                PreparedStatement ps = initStatement(String.format(
+                        SQL_CLEAR_PROPERTY, table, keyColumn), true, key);
+                return ps.executeUpdate();
             }
-
-            pstmt.executeUpdate();
-        }
-        catch (SQLException e)
-        {
-            fireError(EVENT_CLEAR_PROPERTY, key, null, e);
-        }
-        finally
-        {
-            // clean up
-            close(conn, pstmt);
-        }
+        }.execute();
     }
 
     /**
      * Removes all entries from this configuration. If this causes a database
-     * error, an error event will be generated of type
-     * <code>EVENT_CLEAR</code> with the causing exception. Both the
-     * event's <code>propertyName</code> and the <code>propertyValue</code>
-     * will be undefined.
+     * error, an error event will be generated of type <code>EVENT_CLEAR</code>
+     * with the causing exception. Both the event's <code>propertyName</code>
+     * and the <code>propertyValue</code> will be undefined.
      */
+    @Override
     public void clear()
     {
-        // build the query
-        StringBuilder query = new StringBuilder("DELETE FROM " + table);
-        if (nameColumn != null)
-        {
-            query.append(" WHERE " + nameColumn + "=?");
-        }
-
-        Connection conn = null;
-        PreparedStatement pstmt = null;
-
-        try
+        new JdbcOperation(EVENT_CLEAR, null, null)
         {
-            conn = getConnection();
-
-            // bind the parameters
-            pstmt = conn.prepareStatement(query.toString());
-            if (nameColumn != null)
+            @Override
+            protected Object performOperation() throws SQLException
             {
-                pstmt.setString(1, name);
+                PreparedStatement ps = initStatement(String.format(SQL_CLEAR,
+                        table), true);
+                return ps.executeUpdate();
             }
-
-            pstmt.executeUpdate();
-        }
-        catch (SQLException e)
-        {
-            fireError(EVENT_CLEAR, null, null, e);
-        }
-        finally
-        {
-            // clean up
-            close(conn, pstmt);
-        }
+        }.execute();
     }
 
     /**
      * Returns an iterator with the names of all properties contained in this
-     * configuration. If this causes a database
-     * error, an error event will be generated of type
-     * <code>EVENT_READ_PROPERTY</code> with the causing exception. Both the
-     * event's <code>propertyName</code> and the <code>propertyValue</code>
-     * will be undefined.
-     * @return an iterator with the contained keys (an empty iterator in case
-     * of an error)
+     * configuration. If this causes a database error, an error event will be
+     * generated of type <code>EVENT_READ_PROPERTY</code> with the causing
+     * exception. Both the event's <code>propertyName</code> and the
+     * <code>propertyValue</code> will be undefined.
+     *
+     * @return an iterator with the contained keys (an empty iterator in case of
+     *         an error)
      */
     public Iterator<String> getKeys()
     {
-        Collection<String> keys = new ArrayList<String>();
+        final Collection<String> keys = new ArrayList<String>();
 
-        // build the query
-        StringBuilder query = new StringBuilder("SELECT DISTINCT " + keyColumn + " FROM "
+ table);
-        if (nameColumn != null)
+        new JdbcOperation(EVENT_READ_PROPERTY, null, null)
         {
-            query.append(" WHERE " + nameColumn + "=?");
-        }
-
-        Connection conn = null;
-        PreparedStatement pstmt = null;
-
-        try
-        {
-            conn = getConnection();
-
-            // bind the parameters
-            pstmt = conn.prepareStatement(query.toString());
-            if (nameColumn != null)
+            @Override
+            protected Object performOperation() throws SQLException
             {
-                pstmt.setString(1, name);
-            }
-
-            ResultSet rs = pstmt.executeQuery();
+                PreparedStatement ps = initStatement(String.format(
+                        SQL_GET_KEYS, keyColumn, table), true);
+                ResultSet rs = ps.executeQuery();
 
-            while (rs.next())
-            {
-                keys.add(rs.getString(1));
+                while (rs.next())
+                {
+                    keys.add(rs.getString(1));
+                }
+                return null;
             }
-        }
-        catch (SQLException e)
-        {
-            fireError(EVENT_READ_PROPERTY, null, null, e);
-        }
-        finally
-        {
-            // clean up
-            close(conn, pstmt);
-        }
+        }.execute();
 
         return keys.iterator();
     }
@@ -552,22 +426,6 @@
     }
 
     /**
-     * Returns a <code>Connection</code> object. This method is called when
-     * ever the database is to be accessed. This implementation returns a
-     * connection from the current <code>DataSource</code>.
-     *
-     * @return the <code>Connection</code> object to be used
-     * @throws SQLException if an error occurs
-     * @since 1.4
-     * @deprecated Use a custom data source to change the connection used by the
-     * class. To be removed in Commons Configuration 2.0
-     */
-    protected Connection getConnection() throws SQLException
-    {
-        return getDatasource().getConnection();
-    }
-
-    /**
      * Close a <code>Connection</code> and, <code>Statement</code>.
      * Avoid closing if null and hide any SQLExceptions that occur.
      *
@@ -600,4 +458,156 @@
             getLogger().log(Level.SEVERE, "An error occured on closing the connection", e);
         }
     }
+
+    /**
+     * An internally used helper class for simplifying database access through
+     * plain JDBC. This class provides a simple framework for creating and
+     * executing a JDBC statement. It especially takes care of proper handling
+     * of JDBC resources even in case of an error.
+     */
+    private abstract class JdbcOperation
+    {
+        /** Stores the connection. */
+        private Connection conn;
+
+        /** Stores the statement. */
+        private PreparedStatement pstmt;
+
+        /** The type of the event to send in case of an error. */
+        private final int errorEventType;
+
+        /** The property name for an error event. */
+        private final String errorPropertyName;
+
+        /** The property value for an error event. */
+        private final Object errorPropertyValue;
+
+        /**
+         * Creates a new instance of <code>JdbcOperation</code> and initializes
+         * the properties related to the error event.
+         *
+         * @param errEvType the type of the error event
+         * @param errPropName the property name for the error event
+         * @param errPropVal the property value for the error event
+         */
+        protected JdbcOperation(int errEvType, String errPropName,
+                Object errPropVal)
+        {
+            errorEventType = errEvType;
+            errorPropertyName = errPropName;
+            errorPropertyValue = errPropVal;
+        }
+
+        /**
+         * Executes this operation. This method obtains a database connection
+         * and then delegates to <code>performOperation()</code>. Afterwards
it
+         * performs the necessary clean up. Exceptions that are thrown during
+         * the JDBC operation are caught and transformed into configuration
+         * error events.
+         *
+         * @return the result of the operation
+         */
+        public Object execute()
+        {
+            Object result = null;
+
+            try
+            {
+                conn = getDatasource().getConnection();
+                result = performOperation();
+            }
+            catch (SQLException e)
+            {
+                fireError(errorEventType, errorPropertyName,
+                        errorPropertyValue, e);
+            }
+            finally
+            {
+                close(conn, pstmt);
+            }
+
+            return result;
+        }
+
+        /**
+         * Returns the current connection. This method can be called while
+         * <code>execute()</code> is running. It returns <b>null</b>
otherwise.
+         *
+         * @return the current connection
+         */
+        protected Connection getConnection()
+        {
+            return conn;
+        }
+
+        /**
+         * Creates a <code>PreparedStatement</code> object for executing the
+         * specified SQL statement.
+         *
+         * @param sql the statement to be executed
+         * @param nameCol a flag whether the name column should be taken into
+         *        account
+         * @return the prepared statement object
+         * @throws SQLException if an SQL error occurs
+         */
+        protected PreparedStatement createStatement(String sql, boolean nameCol)
+                throws SQLException
+        {
+            String statement;
+            if (nameCol && nameColumn != null)
+            {
+                StringBuilder buf = new StringBuilder(sql);
+                buf.append(" AND ").append(nameColumn).append("=?");
+                statement = buf.toString();
+            }
+            else
+            {
+                statement = sql;
+            }
+
+            pstmt = getConnection().prepareStatement(statement);
+            return pstmt;
+        }
+
+        /**
+         * Creates an initializes a <code>PreparedStatement</code> object for
+         * executing an SQL statement. This method first calls
+         * <code>createStatement()</code> for creating the statement and then
+         * initializes the statement's parameters.
+         *
+         * @param sql the statement to be executed
+         * @param nameCol a flag whether the name column should be taken into
+         *        account
+         * @param params the parameters for the statement
+         * @return the initialized statement object
+         * @throws SQLException if an SQL error occurs
+         */
+        protected PreparedStatement initStatement(String sql, boolean nameCol,
+                Object... params) throws SQLException
+        {
+            PreparedStatement ps = createStatement(sql, nameCol);
+
+            int idx = 1;
+            for (Object param : params)
+            {
+                ps.setObject(idx++, param);
+            }
+            if (nameCol && nameColumn != null)
+            {
+                ps.setString(idx, name);
+            }
+
+            return ps;
+        }
+
+        /**
+         * Performs the JDBC operation. This method is called by
+         * <code>execute()</code> after this object has been fully initialized.
+         * Here the actual JDBC logic has to be placed.
+         *
+         * @return the result of the operation
+         * @throws SQLException if an SQL error occurs
+         */
+        protected abstract Object performOperation() throws SQLException;
+    }
 }

Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestDatabaseConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestDatabaseConfiguration.java?rev=707290&r1=707289&r2=707290&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestDatabaseConfiguration.java
(original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestDatabaseConfiguration.java
Wed Oct 22 23:24:25 2008
@@ -24,16 +24,17 @@
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
+
 import javax.naming.Context;
 import javax.naming.NamingException;
 import javax.naming.spi.InitialContextFactory;
 import javax.sql.DataSource;
 
+import junit.framework.TestCase;
+
 import org.apache.commons.configuration2.event.ConfigurationErrorListener;
 import org.apache.commons.configuration2.test.HsqlDB;
 import org.apache.commons.dbcp.BasicDataSource;
-
-import junit.framework.TestCase;
 import org.codehaus.spice.jndikit.DefaultNameParser;
 import org.codehaus.spice.jndikit.DefaultNamespace;
 import org.codehaus.spice.jndikit.memory.MemoryContext;
@@ -53,7 +54,7 @@
 public class TestDatabaseConfiguration extends TestCase
 {
     public final String DATABASE_DRIVER = "org.hsqldb.jdbcDriver";
-    public final String DATABASE_URL = "jdbc:hsqldb:target/test-classes/testdb";
+    public final String DATABASE_URL = "jdbc:hsqldb:mem:testdb";
     public final String DATABASE_USERNAME = "sa";
     public final String DATABASE_PASSWORD = "";
 
@@ -77,11 +78,12 @@
 
     private static HsqlDB hsqlDB = null;
 
-    private DataSource datasource;
+    private PotentialErrorDataSource datasource;
 
     /** An error listener for testing whether internal errors occurred.*/
     private ConfigurationErrorListenerImpl listener;
 
+    @Override
     protected void setUp() throws Exception
     {
         /*
@@ -98,7 +100,7 @@
             hsqlDB = new HsqlDB(DATABASE_URL, DATABASE_DRIVER, script.getAbsolutePath());
         }
 
-        BasicDataSource datasource = new BasicDataSource();
+        PotentialErrorDataSource datasource = new PotentialErrorDataSource();
         datasource.setDriverClassName(DATABASE_DRIVER);
         datasource.setUrl(DATABASE_URL);
         datasource.setUsername(DATABASE_USERNAME);
@@ -120,6 +122,7 @@
         }
     }
 
+    @Override
     protected void tearDown() throws Exception{
         datasource.getConnection().commit();
         datasource.getConnection().close();
@@ -137,9 +140,9 @@
      *
      * @return the configuration
      */
-    private PotentialErrorDatabaseConfiguration setUpConfig()
+    private DatabaseConfiguration setUpConfig()
     {
-        return new PotentialErrorDatabaseConfiguration(datasource, TABLE, COL_KEY, COL_VALUE);
+        return new DatabaseConfiguration(datasource, TABLE, COL_KEY, COL_VALUE);
     }
 
     /**
@@ -158,13 +161,13 @@
      *
      * @param config the configuration
      */
-    private void setUpErrorListener(PotentialErrorDatabaseConfiguration config)
+    private void setUpErrorListener(DatabaseConfiguration config)
     {
         // remove log listener to avoid exception longs
         config.removeErrorListener((ConfigurationErrorListener) config.getErrorListeners().iterator().next());
         listener = new ConfigurationErrorListenerImpl();
         config.addErrorListener(listener);
-        config.failOnConnect = true;
+        datasource.failOnConnect = true;
     }
 
     /**
@@ -173,9 +176,9 @@
      *
      * @return the initialized configuration
      */
-    private PotentialErrorDatabaseConfiguration setUpErrorConfig()
+    private DatabaseConfiguration setUpErrorConfig()
     {
-        PotentialErrorDatabaseConfiguration config = setUpConfig();
+        DatabaseConfiguration config = setUpConfig();
         setUpErrorListener(config);
         return config;
     }
@@ -491,10 +494,10 @@
     {
         public static DataSource datasource;
 
-        public Context getInitialContext(Hashtable environment) throws NamingException
+        public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException
         {
             DefaultNamespace namespace = new DefaultNamespace(new DefaultNameParser());
-            MemoryContext context = new MemoryContext(namespace, new Hashtable(), null);
+            MemoryContext context = new MemoryContext(namespace, new Hashtable<Object,
Object>(), null);
             context.createSubcontext("java:comp").createSubcontext("env").createSubcontext("jdbc").bind("configuration",
datasource);
 
             return context;
@@ -502,25 +505,21 @@
     }
 
     /**
-     * A specialized database configuration implementation that can be
-     * configured to throw an exception when obtaining a connection. This way
-     * database exceptions can be simulated.
+     * A specialized DataSource implementation that can be configured to throw
+     * an exception when obtaining a connection. This way database exceptions
+     * can be simulated.
      */
-    static class PotentialErrorDatabaseConfiguration extends DatabaseConfiguration
+    private static class PotentialErrorDataSource extends BasicDataSource
     {
         /** A flag whether a getConnection() call should fail. */
         boolean failOnConnect;
 
-        public PotentialErrorDatabaseConfiguration(DataSource datasource,
-                String table, String keyColumn, String valueColumn)
-        {
-            super(datasource, table, keyColumn, valueColumn);
-        }
-
-        protected Connection getConnection() throws SQLException
+        @Override
+        public Connection getConnection() throws SQLException
         {
             if (failOnConnect)
             {
+                failOnConnect = false; // fail only once
                 throw new SQLException("Simulated DB error");
             }
             return super.getConnection();



Mime
View raw message