Author: rmannibucau
Date: Sun May 13 23:15:11 2012
New Revision: 1338005

URL: http://svn.apache.org/viewvc?rev=1338005&view=rev
Log:
TOMEE-171 better resource resolution, managing app and global names for 
datasourcedefinition

Added:
    
openejb/trunk/openejb/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/DataSourceDefinitionGlobalJPATest.java
Modified:
    
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ReloadableEntityManagerFactory.java
    
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java

Modified: 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ReloadableEntityManagerFactory.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ReloadableEntityManagerFactory.java?rev=1338005&r1=1338004&r2=1338005&view=diff
==============================================================================
--- 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ReloadableEntityManagerFactory.java
 (original)
+++ 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ReloadableEntityManagerFactory.java
 Sun May 13 23:15:11 2012
@@ -17,6 +17,7 @@
 
 package org.apache.openejb.assembler.classic;
 
+import javax.persistence.spi.*;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.api.internal.Internal;
 import org.apache.openejb.jee.JAXBContextFactory;
@@ -53,7 +54,6 @@ import javax.persistence.SharedCacheMode
 import javax.persistence.ValidationMode;
 import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.metamodel.Metamodel;
-import javax.persistence.spi.PersistenceUnitTransactionType;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Marshaller;
 import java.io.File;
@@ -321,6 +321,10 @@ public class ReloadableEntityManagerFact
         
entityManagerFactoryCallable.getUnitInfo().getManagedClassNames().remove(clazz);
     }
 
+    public javax.persistence.spi.PersistenceUnitInfo info() {
+        return entityManagerFactoryCallable.getUnitInfo();
+    }
+
     @MBean
     @Internal
     @Description("represents a persistence unit managed by OpenEJB")

Modified: 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java?rev=1338005&r1=1338004&r2=1338005&view=diff
==============================================================================
--- 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java
 (original)
+++ 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java
 Sun May 13 23:15:11 2012
@@ -1218,10 +1218,10 @@ public class AutoConfig implements Dynam
             }
 
             required.put("JtaManaged", "true");
-            String jtaDataSourceId = findResourceId(unit.getJtaDataSource(), 
"DataSource", required, null);
+            String jtaDataSourceId = 
findResourceId(replaceJavaAndSlash(unit.getJtaDataSource()), "DataSource", 
required, null);
 
             required.put("JtaManaged", "false");
-            String nonJtaDataSourceId = 
findResourceId(unit.getNonJtaDataSource(), "DataSource", required, null);
+            String nonJtaDataSourceId = 
findResourceId(replaceJavaAndSlash(unit.getNonJtaDataSource()), "DataSource", 
required, null);
 
             if (jtaDataSourceId != null && nonJtaDataSourceId != null){
                 // Both DataSources were explicitly configured.
@@ -1232,11 +1232,15 @@ public class AutoConfig implements Dynam
 
             // another try prefixing datasource name with app moduleid, case 
of datasourcedefinition for instance
             final String prefix = app.getModuleId() + "/";
-            required.put("JtaManaged", "true");
-            jtaDataSourceId = findResourceId(prefix + unit.getJtaDataSource(), 
"DataSource", required, null);
+            if (jtaDataSourceId == null) {
+                required.put("JtaManaged", "true");
+                jtaDataSourceId = findResourceId(prefix + 
replaceJavaAndSlash(unit.getJtaDataSource()), "DataSource", required, null);
+            }
 
-            required.put("JtaManaged", "false");
-            nonJtaDataSourceId = findResourceId(prefix + 
unit.getNonJtaDataSource(), "DataSource", required, null);
+            if (nonJtaDataSourceId == null) {
+                required.put("JtaManaged", "false");
+                nonJtaDataSourceId = findResourceId(prefix + 
replaceJavaAndSlash(unit.getNonJtaDataSource()), "DataSource", required, null);
+            }
 
             if (jtaDataSourceId != null && nonJtaDataSourceId != null){
                 // Both DataSources were explicitly configured.
@@ -1285,8 +1289,8 @@ public class AutoConfig implements Dynam
             //
 
             required.put("JtaManaged", ANY);
-            String possibleJta = findResourceId(unit.getJtaDataSource(), 
"DataSource", required, null);
-            String possibleNonJta = findResourceId(unit.getNonJtaDataSource(), 
"DataSource", required, null);
+            String possibleJta = 
findResourceId(replaceJavaAndSlash(unit.getJtaDataSource()), "DataSource", 
required, null);
+            String possibleNonJta = 
findResourceId(replaceJavaAndSlash(unit.getNonJtaDataSource()), "DataSource", 
required, null);
             if (possibleJta != null && possibleJta == possibleNonJta){
                 ResourceInfo dataSource = 
configFactory.getResourceInfo(possibleJta);
 
@@ -1546,6 +1550,20 @@ public class AutoConfig implements Dynam
         }
     }
 
+    private String replaceJavaAndSlash(final String name) {
+        if (name == null) {
+            return null;
+        }
+
+        if (name.startsWith("java:")) {
+            return replaceJavaAndSlash(name.substring("java:".length()));
+        }
+        if (name.startsWith("/")) {
+            return name.substring(1);
+        }
+        return name;
+    }
+
     private void setNonJtaDataSource(PersistenceUnit unit, String current) {
 
 

Added: 
openejb/trunk/openejb/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/DataSourceDefinitionGlobalJPATest.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/DataSourceDefinitionGlobalJPATest.java?rev=1338005&view=auto
==============================================================================
--- 
openejb/trunk/openejb/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/DataSourceDefinitionGlobalJPATest.java
 (added)
+++ 
openejb/trunk/openejb/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/DataSourceDefinitionGlobalJPATest.java
 Sun May 13 23:15:11 2012
@@ -0,0 +1,139 @@
+/*
+ * 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.openejb.assembler.classic;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+import javax.annotation.sql.DataSourceDefinition;
+import javax.ejb.EJB;
+import javax.ejb.Stateless;
+import javax.persistence.Entity;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.PersistenceUnit;
+import javax.sql.DataSource;
+import org.apache.commons.dbcp.DelegatingConnection;
+import org.apache.commons.dbcp.managed.ManagedConnection;
+import org.apache.openejb.jee.jpa.unit.Persistence;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.junit.Configuration;
+import org.apache.openejb.junit.Module;
+import org.apache.openejb.resource.jdbc.BasicManagedDataSource;
+import org.apache.openejb.resource.jdbc.DataSourceFactory;
+import org.hsqldb.jdbc.JDBCConnection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static junit.framework.Assert.assertEquals;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.junit.Assert.assertThat;
+
+@RunWith(ApplicationComposer.class)
+public class DataSourceDefinitionGlobalJPATest {
+
+    @EJB
+    private EmfHolder holder;
+
+    @Module
+    public Class<?>[] app() throws Exception {
+        return new Class<?>[]{EmfHolder.class};
+    }
+
+    @Configuration // useless but add another datasource so resolution should 
be more tricky, name before d
+    public Properties config() {
+        final Properties p = new Properties();
+        p.put("cczczcz", "new://Resource?type=DataSource");
+        p.put("cczczcz.JdbcDriver", "org.hsqldb.jdbcDriver");
+        p.put("cczczcz.JdbcUrl", "jdbc:hsqldb:mem:cczczcz");
+        return p;
+    }
+
+    @Module
+    public Persistence persistence() {
+        org.apache.openejb.jee.jpa.unit.PersistenceUnit unit = new 
org.apache.openejb.jee.jpa.unit.PersistenceUnit("jpa-global-dsdef-unit");
+        unit.addClass(IdEntity.class);
+        unit.setProperty("openjpa.jdbc.SynchronizeMappings", 
"buildSchema(ForeignKeys=true)");
+        unit.getProperties().setProperty("openjpa.RuntimeUnenhancedClasses", 
"supported");
+        unit.setJtaDataSource("java:app/foo");
+        unit.setExcludeUnlistedClasses(true);
+
+        Persistence persistence = new Persistence(unit);
+        persistence.setVersion("2.0");
+        return persistence;
+    }
+
+    @DataSourceDefinition(
+            name = "java:app/foo",
+            className = "org.hsqldb.jdbc.JDBCDataSource",
+            user = "sa",
+            password = "",
+            url = "jdbc:hsqldb:mem:dsdjpa"
+    )
+    @Stateless
+    public static class EmfHolder {
+        @PersistenceUnit
+        private EntityManagerFactory emf;
+
+        public EntityManagerFactory getEmf() {
+            return emf;
+        }
+    }
+
+    @Entity
+    public static class IdEntity {
+        @Id
+        @GeneratedValue
+        private long id;
+
+        public long getId() {
+            return id;
+        }
+
+        public void setId(long id) {
+            this.id = id;
+        }
+    }
+
+    @Test
+    public void check() throws Exception {
+        final EntityManagerFactory emf = holder.getEmf();
+        assertThat(emf, instanceOf(ReloadableEntityManagerFactory.class));
+        final ReloadableEntityManagerFactory remf = 
(ReloadableEntityManagerFactory) emf;
+        final DataSource ds = remf.info().getJtaDataSource();
+        check(ds, "dsdjpa");
+    }
+
+    private void check(final DataSource ds, final String name) throws 
SQLException, NoSuchMethodException, InvocationTargetException, 
IllegalAccessException {
+        // the first "cast part" is not important, we just want to check the 
jdbc url is ok
+        assertThat(ds, instanceOf(BasicManagedDataSource.class));
+        final BasicManagedDataSource dbcp = (BasicManagedDataSource) ds;
+        final Connection connection = dbcp.getConnection();
+        assertThat(connection, instanceOf(ManagedConnection.class));
+        final ManagedConnection mc = (ManagedConnection) connection;
+        final Method getInnermostDelegateInternal = 
DelegatingConnection.class.getDeclaredMethod("getInnermostDelegateInternal");
+        getInnermostDelegateInternal.setAccessible(true);
+        final Connection delegate = (Connection) 
getInnermostDelegateInternal.invoke(mc);
+        assertThat(delegate, instanceOf(JDBCConnection.class));
+        final Method getURL = JDBCConnection.class.getDeclaredMethod("getURL");
+        getURL.setAccessible(true);
+        assertEquals("jdbc:hsqldb:mem:" + name, getURL.invoke(delegate));
+    }
+}


Reply via email to