[ARIES-1520] Enable EntityManagerFactoryBuilder services to consume preconfigured datasources

git-svn-id: https://svn.apache.org/repos/asf/aries/trunk/jpa@1737986 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/container/itest/JPAContainerTest.java b/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/container/itest/JPAContainerTest.java
index b05a5da..440913f 100644
--- a/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/container/itest/JPAContainerTest.java
+++ b/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/container/itest/JPAContainerTest.java
@@ -16,10 +16,12 @@
 package org.apache.aries.jpa.container.itest;
 
 import static org.junit.Assert.assertEquals;
+import static org.osgi.service.jdbc.DataSourceFactory.OSGI_JDBC_DRIVER_CLASS;
 
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 
 import javax.inject.Inject;
 import javax.persistence.EntityManager;
@@ -33,6 +35,7 @@
 import org.junit.Test;
 import org.osgi.service.coordinator.Coordination;
 import org.osgi.service.coordinator.Coordinator;
+import org.osgi.service.jdbc.DataSourceFactory;
 import org.osgi.service.jpa.EntityManagerFactoryBuilder;
 
 public abstract class JPAContainerTest extends AbstractCarJPAITest {
@@ -140,4 +143,21 @@
         assertEquals(BLUE_CAR_PLATE, car.getNumberPlate());
     }
 
+    @Test
+    public void testCarEMFBuilderExternalDS() throws Exception {
+    	DataSourceFactory dsf = getService(DataSourceFactory.class, 
+    			"(" + OSGI_JDBC_DRIVER_CLASS + "=org.apache.derby.jdbc.EmbeddedDriver)");
+       
+    	EntityManagerFactoryBuilder emfBuilder = getService(EntityManagerFactoryBuilder.class,
+    			"(osgi.unit.name=" + EXTERNAL_TEST_UNIT + ")");
+    	
+    	Properties jdbcProps = new Properties();
+    	jdbcProps.setProperty("url", "jdbc:derby:memory:DSFTEST;create=true");
+    	
+    	Map<String, Object> props = new HashMap<String, Object>();
+    	props.put("javax.persistence.nonJtaDataSource", dsf.createDataSource(jdbcProps));
+    	
+    	EntityManagerFactory emf = emfBuilder.createEntityManagerFactory(props);
+    	carLifecycleRL(emf.createEntityManager());
+    }
 }
diff --git a/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/itest/AbstractJPAItest.java b/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/itest/AbstractJPAItest.java
index 68d56de..baed9ee 100644
--- a/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/itest/AbstractJPAItest.java
+++ b/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/itest/AbstractJPAItest.java
@@ -63,6 +63,7 @@
     protected static final String XA_TEST_UNIT = "xa-test-unit";
     protected static final String DSF_TEST_UNIT = "dsf-test-unit";
     protected static final String DSF_XA_TEST_UNIT = "dsf-xa-test-unit";
+    protected static final String EXTERNAL_TEST_UNIT = "external-test-unit";
 
     protected static final String TEST_BUNDLE_NAME = "org.apache.aries.jpa.org.apache.aries.jpa.container.itest.bundle";
     
diff --git a/itests/jpa-container-testbundle/src/main/resources/META-INF/persistence.xml b/itests/jpa-container-testbundle/src/main/resources/META-INF/persistence.xml
index d07b59a..839750d 100644
--- a/itests/jpa-container-testbundle/src/main/resources/META-INF/persistence.xml
+++ b/itests/jpa-container-testbundle/src/main/resources/META-INF/persistence.xml
@@ -86,4 +86,13 @@
       <property name="hibernate.hbm2ddl.auto" value="create-drop"/>

     </properties>

   </persistence-unit>

+  

+  <persistence-unit name="external-test-unit" transaction-type="RESOURCE_LOCAL">

+    <description>Test persistence unit for the JPA Container External DataSource iTests</description>

+    <properties>

+        <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>

+        <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>

+        <property name="hibernate.hbm2ddl.auto" value="create-drop"/>

+    </properties>

+  </persistence-unit>

 </persistence>

diff --git a/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/AriesEntityManagerFactoryBuilder.java b/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/AriesEntityManagerFactoryBuilder.java
index 4a47b19..71b4dd4 100644
--- a/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/AriesEntityManagerFactoryBuilder.java
+++ b/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/AriesEntityManagerFactoryBuilder.java
@@ -18,12 +18,14 @@
  */
 package org.apache.aries.jpa.container.impl;
 
+import java.util.HashMap;
 import java.util.Map;
 
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.spi.PersistenceProvider;
-import javax.persistence.spi.PersistenceUnitInfo;
+import javax.sql.DataSource;
 
+import org.apache.aries.jpa.container.parser.impl.PersistenceUnit;
 import org.osgi.service.jpa.EntityManagerFactoryBuilder;
 
 /**
@@ -33,12 +35,15 @@
  */
 public class AriesEntityManagerFactoryBuilder implements EntityManagerFactoryBuilder {
     private static final String JAVAX_PERSISTENCE_JDBC_DRIVER = "javax.persistence.jdbc.driver";
+    private static final String JAVAX_PERSISTENCE_JTA_DATASOURCE = "javax.persistence.jtaDataSource";
+    private static final String JAVAX_PERSISTENCE_NON_JTA_DATASOURCE = "javax.persistence.nonJtaDataSource";
 
     private PersistenceProvider provider;
-    private PersistenceUnitInfo persistenceUnit;
+    private PersistenceUnit persistenceUnit;
     private String driver;
+    
 
-    public AriesEntityManagerFactoryBuilder(PersistenceProvider provider, PersistenceUnitInfo persistenceUnit) {
+    public AriesEntityManagerFactoryBuilder(PersistenceProvider provider, PersistenceUnit persistenceUnit) {
         this.provider = provider;
         this.persistenceUnit = persistenceUnit;
         this.driver = (String)persistenceUnit.getProperties().get(JAVAX_PERSISTENCE_JDBC_DRIVER);
@@ -46,12 +51,30 @@
 
     @Override
     public EntityManagerFactory createEntityManagerFactory(Map<String, Object> props) {
-        String newDriver = (String)props.get(JAVAX_PERSISTENCE_JDBC_DRIVER);
+        props = new HashMap<String, Object>(props);
+    	
+    	String newDriver = (String)props.get(JAVAX_PERSISTENCE_JDBC_DRIVER);
         if (driver == null) {
             driver = newDriver;
         } else if (newDriver != null && !newDriver.equals(driver)){
             throw new IllegalArgumentException("Can not rebind to a different database driver");
         }
+        
+        // Handle overridden datasources in a provider agnostic way
+        // This isn't necessary for EclipseLink, but Hibernate and 
+        // OpenJPA both need some extra help.
+        Object o = props.get(JAVAX_PERSISTENCE_JTA_DATASOURCE);
+        if(o instanceof DataSource) {
+        	persistenceUnit.setJtaDataSource((DataSource) o);
+        	props.remove(JAVAX_PERSISTENCE_JTA_DATASOURCE);
+        }
+
+        o = props.get(JAVAX_PERSISTENCE_NON_JTA_DATASOURCE);
+        if(o instanceof DataSource) {
+        	persistenceUnit.setNonJtaDataSource((DataSource) o);
+        	props.remove(JAVAX_PERSISTENCE_NON_JTA_DATASOURCE);
+        }
+        
         return provider.createContainerEntityManagerFactory(persistenceUnit, props);
     }
 
diff --git a/jpa-parent/pom.xml b/jpa-parent/pom.xml
index fdb054f..a9711dd 100644
--- a/jpa-parent/pom.xml
+++ b/jpa-parent/pom.xml
@@ -34,7 +34,7 @@
     <packaging>pom</packaging>
     
     <properties>
-        <baseline>2.1.0</baseline>
+        <baseline>2.3.0</baseline>
         <baseline.skip>false</baseline.skip>
     </properties>