You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by st...@apache.org on 2011/11/05 21:45:01 UTC

svn commit: r1198048 - in /myfaces/extensions/cdi/trunk/jee-modules/jpa-module: api/src/main/java/org/apache/myfaces/extensions/cdi/jpa/api/datasource/ impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/datasource/ impl/src/test/java/org/apa...

Author: struberg
Date: Sat Nov  5 20:45:00 2011
New Revision: 1198048

URL: http://svn.apache.org/viewvc?rev=1198048&view=rev
Log:
EXTCDI-236 add unit test for wrapping a JDBC Driver class.

Also fix some other Wrapper issues. tets for a wrapped JNDI DataSource
and a configured DataSource class still needs to be done

Added:
    myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/test/java/org/apache/myfaces/extensions/cdi/jpa/test/dbconfig/
    myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/test/java/org/apache/myfaces/extensions/cdi/jpa/test/dbconfig/TestDbConfig.java   (with props)
Modified:
    myfaces/extensions/cdi/trunk/jee-modules/jpa-module/api/src/main/java/org/apache/myfaces/extensions/cdi/jpa/api/datasource/DataSourceConfig.java
    myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/datasource/ConfigurableDataSource.java
    myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/test/resources/META-INF/persistence.xml

Modified: myfaces/extensions/cdi/trunk/jee-modules/jpa-module/api/src/main/java/org/apache/myfaces/extensions/cdi/jpa/api/datasource/DataSourceConfig.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jpa-module/api/src/main/java/org/apache/myfaces/extensions/cdi/jpa/api/datasource/DataSourceConfig.java?rev=1198048&r1=1198047&r2=1198048&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jpa-module/api/src/main/java/org/apache/myfaces/extensions/cdi/jpa/api/datasource/DataSourceConfig.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jpa-module/api/src/main/java/org/apache/myfaces/extensions/cdi/jpa/api/datasource/DataSourceConfig.java Sat Nov  5 20:45:00 2011
@@ -20,14 +20,14 @@ package org.apache.myfaces.extensions.cd
 
 import org.apache.myfaces.extensions.cdi.core.api.config.CodiConfig;
 
-import java.util.Map;
+import java.util.Properties;
 
 /**
  * <p>Configuration for the DataSource.
  * The <code>connectionId</code> parameter can be used to distinguish
  * between different databases.</p>
  *
- * <p>There are 2 ways to configure a DataSource
+ * <p>There are 3 ways to configure a DataSource
  *
  * <ol>
  *     <li>
@@ -35,9 +35,18 @@ import java.util.Map;
  *         {@link #getJndiResourceName(String)}
  *     </li>
  *     <li>
- *         via JDBC connecion properties - This will be used if {@link #getJndiResourceName(String)}
- *         returns <code>null</code>. In this case you must specify the {@link #getDriverClassName(String)}
- *         and {@link #getConnectionProperties(String)}.
+ *         via a DataSource class name plus properties - This will be used if {@link #getJndiResourceName(String)}
+ *         returns <code>null</code>. In this case you must specify the {@link #getConnectionClassName(String)}
+ *         to contain the class name of a DataSource, e.g.
+ *         <code>&quot";com.mchange.v2.c3p0.ComboPooledDataSource&quot";</code>
+ *         and return additional configuration via {@link #getConnectionProperties(String)}.
+ *     </li>
+ *     <li>
+ *         via a JDBC Driver class name plus properties - This will be used if {@link #getJndiResourceName(String)}
+ *         returns <code>null</code>. In this case you must specify the {@link #getConnectionClassName(String)}
+ *         to contain the class name of a javax.sql.Driver, e.g.
+ *         <code>&quot";org.hsqldb.jdbcDriver&quot";</code>
+ *         and return additional configuration via {@link #getConnectionProperties(String)}.
  *     </li>
  * </ol>
  *
@@ -52,7 +61,7 @@ public interface DataSourceConfig extend
      * Return the JNDI resource name if the DataSource should get retrieved via JNDI.
      * If a native JDBC connection should get used, this method must return <code>null</code>.
      * And the JDBC connection properties must get set via
-     * {@link #getDriverClassName(String)} and {@link #getConnectionProperties(String)}.
+     * {@link #getConnectionClassName(String)} and {@link #getConnectionProperties(String)}.
      *
      * @param connectionId used to distinguish between different databases.
      *
@@ -63,17 +72,31 @@ public interface DataSourceConfig extend
 
     /**
      * @param connectionId used to distinguish between different databases.
+     *
      * @return the fully qualified class name of the JDBC driver for the underlying connection
+     *      or <code>null</code> if {@link #getJndiResourceName(String)} is not being used
      */
-    public String getDriverClassName(String connectionId);
+    public String getConnectionClassName(String connectionId);
 
     /**
      * @param connectionId used to distinguish between different databases.
      *
      * @return allows to configure additional connection properties which will
-     *      get applied to the underlying JDBC driver.
+     *      get applied to the underlying JDBC driver or <code>null</code>
+     *      if {@link #getJndiResourceName(String)} is not being used
      */
-    public Map<String, String> getConnectionProperties(String connectionId);
+    public Properties getConnectionProperties(String connectionId);
 
+    /**
+     * This will only get used if {@link #getConnectionClassName(String)} is a javax.sql.Driver.
+     * Foor Datasources, the underlying connection url must get configured via
+     * {@link #getConnectionProperties(String)}.
+     *
+     * @param connectionId used to distinguish between different databases.
+     *
+     * @return the connection url, e.g. &quot;jdbc://...&quot;
+     *      or <code>null</code> if {@link #getJndiResourceName(String)} is not being used
+     */
+    public String getJdbcConnectionUrl(String connectionId);
 
 }

Modified: myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/datasource/ConfigurableDataSource.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/datasource/ConfigurableDataSource.java?rev=1198048&r1=1198047&r2=1198048&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/datasource/ConfigurableDataSource.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/datasource/ConfigurableDataSource.java Sat Nov  5 20:45:00 2011
@@ -27,9 +27,11 @@ import java.io.PrintWriter;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.sql.Connection;
+import java.sql.Driver;
 import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
 import java.util.Map;
+import java.util.Properties;
 import java.util.logging.Logger;
 
 /**
@@ -47,7 +49,7 @@ public class ConfigurableDataSource impl
     /**
      * config and settings are loaded only once.
      */
-    private boolean loaded;
+    private volatile boolean loaded;
 
     /**
      * The connectionId allows to configure multiple databases.
@@ -62,9 +64,26 @@ public class ConfigurableDataSource impl
     private DataSourceConfig dataSourceConfig;
 
     /**
-     *  The underlying 'real' DataSource
+     * In case of an underlying JDBC connection, we need to provide the connection URL;
      */
-    private volatile DataSource wrappedDataSource;
+    private String jdbcConnectionURL;
+
+    /**
+     * In case of an underlying JDBC connection, we need to provide some configured properties
+     */
+    private Properties connectionProperties;
+
+    /**
+     *  The underlying 'real' DataSource if we got a DataSource either via JNDI
+     *  or as class name.
+     */
+    private DataSource wrappedDataSource = null;
+
+    /**
+     *  The underlying jdbcDriver if configured.
+     */
+    private Driver wrappedJdbcDriver = null;
+
 
     public ConfigurableDataSource()
     {
@@ -88,16 +107,27 @@ public class ConfigurableDataSource impl
 
     public Connection getConnection(String userName, String password) throws SQLException
     {
-        if (wrappedDataSource == null)
+        if (!loaded)
         {
             initDataSource();
         }
 
-        if (userName == null && password == null)
+        if (wrappedDataSource != null)
+        {
+            // if we got a DataSource as underlying connector
+            if (userName == null && password == null )
+            {
+                return wrappedDataSource.getConnection();
+            }
+            return wrappedDataSource.getConnection(userName, password);
+        }
+        else if (wrappedJdbcDriver != null)
         {
-            return wrappedDataSource.getConnection();
+            // if we got a native JDBC Driver class as underlying connector
+            return wrappedJdbcDriver.connect(jdbcConnectionURL, connectionProperties);
         }
-        return wrappedDataSource.getConnection(userName, password);
+
+        return null;
     }
 
 
@@ -147,15 +177,17 @@ public class ConfigurableDataSource impl
     }
 
     /**
-     *
+     *  Initialize the DataSource either from JNDI or via JDBC Driver.
+     *  This method does not actually create a connection yet.
      */
     protected synchronized void initDataSource() throws SQLException
     {
         // double check lock idiom on volatile member is ok as of Java5
-        if (wrappedDataSource != null)
+        if (loaded)
         {
             return;
         }
+        loaded = true;
 
         String jndiLookupName = dataSourceConfig.getJndiResourceName(connectionId);
         if (jndiLookupName != null && jndiLookupName.length() > 0)
@@ -165,30 +197,48 @@ public class ConfigurableDataSource impl
         }
 
         // no JNDI, so we take the direct JDBC route.
-        String jdbcDriverClass = dataSourceConfig.getDriverClassName(connectionId);
-        if (jdbcDriverClass == null && jdbcDriverClass.length() == 0)
+        String dataSourceClass = dataSourceConfig.getConnectionClassName(connectionId);
+        if (dataSourceClass == null && dataSourceClass.length() == 0)
         {
             throw new SQLException("Neither a JNDI location nor a JDBC driver class name is configured!");
         }
 
+
+        connectionProperties = dataSourceConfig.getConnectionProperties(connectionId);
+
         try
         {
             // we explicitely use class.forName and NOT the ThreadContextClassLoader!
-            Class clazz =  Class.forName(jdbcDriverClass);
+            Class clazz =  Class.forName(dataSourceClass);
 
             // the given driver classname must be a DataSource
-            if (!DataSource.class.isAssignableFrom(clazz))
+            if (DataSource.class.isAssignableFrom(clazz))
             {
-                throw new SQLException("Configured DriverClassName is not a javax.sql.DataSource: "
-                                       + jdbcDriverClass);
-            }
+                wrappedDataSource = (DataSource) clazz.newInstance();
 
-            wrappedDataSource = (DataSource) clazz.newInstance();
+                for (Map.Entry configOption : connectionProperties.entrySet())
+                {
+                    String name = (String) configOption.getKey();
+                    String value = (String) configOption.getValue();
+                    setProperty(wrappedDataSource, name, value);
+                }
+            }
+            else if(Driver.class.isAssignableFrom(clazz))
+            {
+                // if we have a javax.sql.Driver then we also need an explicite connection URL
+                jdbcConnectionURL = dataSourceConfig.getJdbcConnectionUrl(connectionId);
+                if (jdbcConnectionURL == null)
+                {
+                    throw new SQLException("Neither a JNDI location nor a JDBC connection URL is configured!");
+                }
 
-            Map<String, String> config = dataSourceConfig.getConnectionProperties(connectionId);
-            for (Map.Entry<String, String> configOption : config.entrySet())
+                wrappedJdbcDriver = (Driver) clazz.newInstance();
+            }
+            else
             {
-                setProperty(wrappedDataSource, configOption.getKey(), configOption.getValue());
+                throw new SQLException("Configured DriverClassName is not a javax.sql.DataSource "
+                                       + "nor a javax.sql.Driver: "
+                                       + dataSourceClass);
             }
         }
         catch (Exception e)
@@ -227,7 +277,8 @@ public class ConfigurableDataSource impl
             {
                 //X TODO probably search for fields to set
 
-                throw new IllegalArgumentException("Cannot set property with name " + setterName);
+                //
+
             }
         }
 

Added: myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/test/java/org/apache/myfaces/extensions/cdi/jpa/test/dbconfig/TestDbConfig.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/test/java/org/apache/myfaces/extensions/cdi/jpa/test/dbconfig/TestDbConfig.java?rev=1198048&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/test/java/org/apache/myfaces/extensions/cdi/jpa/test/dbconfig/TestDbConfig.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/test/java/org/apache/myfaces/extensions/cdi/jpa/test/dbconfig/TestDbConfig.java Sat Nov  5 20:45:00 2011
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.myfaces.extensions.cdi.jpa.test.dbconfig;
+
+import org.apache.myfaces.extensions.cdi.jpa.api.datasource.DataSourceConfig;
+
+import javax.enterprise.context.ApplicationScoped;
+import java.util.Properties;
+
+/**
+ * {@link DataSourceConfig} for our test database.
+ */
+@ApplicationScoped
+public class TestDbConfig implements DataSourceConfig
+{
+    public String getJndiResourceName(String connectionId)
+    {
+        return null;
+    }
+
+    public String getConnectionClassName(String connectionId)
+    {
+        return "org.hsqldb.jdbcDriver";
+    }
+
+    public String getJdbcConnectionUrl(String connectionId)
+    {
+        return "jdbc:hsqldb:mem:test";
+    }
+
+    public Properties getConnectionProperties(String connectionId)
+    {
+        Properties props = new Properties();
+
+        props.put("userName", "sa");
+        props.put("", "");
+
+        return props;
+    }
+
+}

Propchange: myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/test/java/org/apache/myfaces/extensions/cdi/jpa/test/dbconfig/TestDbConfig.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/test/resources/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/test/resources/META-INF/persistence.xml?rev=1198048&r1=1198047&r2=1198048&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/test/resources/META-INF/persistence.xml (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jpa-module/impl/src/test/resources/META-INF/persistence.xml Sat Nov  5 20:45:00 2011
@@ -28,11 +28,9 @@
 
         <properties>
             <property name="openjpa.jdbc.DBDictionary" value="hsql" />
-            <property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver" />
-            <property name="openjpa.ConnectionURL" value="jdbc:hsqldb:mem:test" />
-            <property name="openjpa.ConnectionUserName" value="sa" />
-            <property name="openjpa.ConnectionPassword" value="" />
-            <property name="openjpa.Log" value="DefaultLevel=TRACE"/>
+            <property name="openjpa.ConnectionDriverName" value="org.apache.myfaces.extensions.cdi.jpa.impl.datasource.ConfigurableDataSource"/>
+            <property name="openjpa.ConnectionProperties" value="connectionId=core"/>
+
             <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
 
             <!-- Enhancement via subclassing. This is not suggested for production! -->