aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From timothyjw...@apache.org
Subject svn commit: r1166169 [1/2] - in /aries/trunk: ejb/ejb-modeller-itest/ ejb/ejb-modeller-itest/src/test/java/org/apache/aries/ejb/container/itest/ ejb/openejb-extender-itest/ ejb/openejb-extender-itest/src/test/java/beans/integration/ ejb/openejb-extende...
Date Wed, 07 Sep 2011 13:29:16 GMT
Author: timothyjward
Date: Wed Sep  7 13:29:15 2011
New Revision: 1166169

URL: http://svn.apache.org/viewvc?rev=1166169&view=rev
Log:
ARIES-718: Integrate Aries JPA support with Modular EJBs

Added:
    aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/
    aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/Tx.java
    aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/impl/
    aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/impl/JPASingleton.java
    aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/impl/TxSingleton.java
    aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/jpa/
    aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/jpa/Laptop.java
    aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/AbstractOpenEJBTest.java
    aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/AdvancedEJBBundleTest.java
    aries/trunk/ejb/openejb-extender-itest/src/test/resources/JPA_MANIFEST.MF
    aries/trunk/ejb/openejb-extender-itest/src/test/resources/TX_MANIFEST.MF
    aries/trunk/ejb/openejb-extender-itest/src/test/resources/persistence.xml
    aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/AriesPersistenceContextIntegration.java
    aries/trunk/jpa/jpa-api/src/main/java/org/apache/aries/jpa/container/context/JTAPersistenceContextManager.java
Modified:
    aries/trunk/ejb/ejb-modeller-itest/pom.xml
    aries/trunk/ejb/ejb-modeller-itest/src/test/java/org/apache/aries/ejb/container/itest/EJBModellingTest.java
    aries/trunk/ejb/openejb-extender-itest/pom.xml
    aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/EJBBundleTest.java
    aries/trunk/ejb/openejb-extender-itest/src/test/resources/   (props changed)
    aries/trunk/ejb/openejb-extender/pom.xml
    aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/AriesProxyService.java
    aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/EJBExtender.java
    aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/OSGiTransactionManager.java
    aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/RunningApplication.java
    aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java
    aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java
    aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManagerTest.java
    aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistryTest.java
    aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/transaction/impl/TranSyncRegistryMock.java

Modified: aries/trunk/ejb/ejb-modeller-itest/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/ejb-modeller-itest/pom.xml?rev=1166169&r1=1166168&r2=1166169&view=diff
==============================================================================
--- aries/trunk/ejb/ejb-modeller-itest/pom.xml (original)
+++ aries/trunk/ejb/ejb-modeller-itest/pom.xml Wed Sep  7 13:29:15 2011
@@ -418,6 +418,11 @@
 			<type>jar</type>
 			<scope>test</scope>
 		</dependency>
+		<dependency>
+			<groupId>org.hsqldb</groupId>
+			<artifactId>hsqldb</artifactId>
+			<version>2.2.4</version>
+		</dependency>
     </dependencies>
 
     <build>

Modified: aries/trunk/ejb/ejb-modeller-itest/src/test/java/org/apache/aries/ejb/container/itest/EJBModellingTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/ejb-modeller-itest/src/test/java/org/apache/aries/ejb/container/itest/EJBModellingTest.java?rev=1166169&r1=1166168&r2=1166169&view=diff
==============================================================================
--- aries/trunk/ejb/ejb-modeller-itest/src/test/java/org/apache/aries/ejb/container/itest/EJBModellingTest.java (original)
+++ aries/trunk/ejb/ejb-modeller-itest/src/test/java/org/apache/aries/ejb/container/itest/EJBModellingTest.java Wed Sep  7 13:29:15 2011
@@ -432,6 +432,7 @@ public class EJBModellingTest extends Ab
         mavenBundle("org.apache.xbean", "xbean-finder-shaded"),
         mavenBundle("org.apache.xbean", "xbean-naming"),
         mavenBundle("org.apache.xbean", "xbean-reflect"),
+        mavenBundle("org.hsqldb", "hsqldb"),
 //        vmOption ("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5006"),
 //        waitForFrameworkStartup(),
         

Modified: aries/trunk/ejb/openejb-extender-itest/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender-itest/pom.xml?rev=1166169&r1=1166168&r2=1166169&view=diff
==============================================================================
--- aries/trunk/ejb/openejb-extender-itest/pom.xml (original)
+++ aries/trunk/ejb/openejb-extender-itest/pom.xml Wed Sep  7 13:29:15 2011
@@ -135,6 +135,24 @@
         	<scope>test</scope>
         </dependency>
         <dependency>
+        	<groupId>org.apache.aries.jpa</groupId>
+        	<artifactId>org.apache.aries.jpa.api</artifactId>
+        	<version>0.3.1-SNAPSHOT</version>
+        	<type>bundle</type>
+        	<scope>compile</scope>
+        </dependency>
+        <dependency>
+        	<groupId>org.apache.aries.jpa</groupId>
+        	<artifactId>org.apache.aries.jpa.container</artifactId>
+        	<version>0.3.1-SNAPSHOT</version>
+        	<scope>test</scope>
+        </dependency>
+        <dependency>
+        	<groupId>org.apache.aries.jpa</groupId>
+        	<artifactId>org.apache.aries.jpa.container.context</artifactId>
+        	<version>0.3.1-SNAPSHOT</version>
+        </dependency>
+        <dependency>
     		<groupId>org.apache.openejb</groupId>
     		<artifactId>openejb-core</artifactId>
     		<version>4.0.0-SNAPSHOT</version>
@@ -414,6 +432,34 @@
 			<type>jar</type>
 			<scope>test</scope>
 		</dependency>
+		<dependency>
+			<groupId>org.hsqldb</groupId>
+			<artifactId>hsqldb</artifactId>
+			<version>2.2.4</version>
+		</dependency>
+		<dependency>
+            <groupId>org.apache.openjpa</groupId>
+            <artifactId>openjpa</artifactId>
+            <version>2.0.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.servicemix.bundles</groupId>
+            <artifactId>org.apache.servicemix.bundles.serp</artifactId>
+            <version>1.13.1_2</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-pool</groupId>
+            <artifactId>commons-pool</artifactId>
+            <version>1.5.3</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.derby</groupId>
+            <artifactId>derby</artifactId>
+            <version>10.5.3.0_1</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>

Added: aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/Tx.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/Tx.java?rev=1166169&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/Tx.java (added)
+++ aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/Tx.java Wed Sep  7 13:29:15 2011
@@ -0,0 +1,11 @@
+package beans.integration;
+
+import javax.ejb.Local;
+
+@Local
+public interface Tx {
+  public Object getNoTransactionId() throws Exception;
+  public Object getMaybeTransactionId() throws Exception;
+  public Object getTransactionId() throws Exception;
+  public Object getNewTransactionId() throws Exception;
+}

Added: aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/impl/JPASingleton.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/impl/JPASingleton.java?rev=1166169&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/impl/JPASingleton.java (added)
+++ aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/impl/JPASingleton.java Wed Sep  7 13:29:15 2011
@@ -0,0 +1,22 @@
+package beans.integration.impl;
+
+import javax.ejb.Singleton;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+import beans.jpa.Laptop;
+
+@Singleton
+public class JPASingleton {
+  
+  @PersistenceContext(unitName="ejb-test")
+  private EntityManager em;
+  
+  public void editEntity(String serial) {
+    Laptop l = em.find(Laptop.class, serial);
+    
+    l.setHardDiskSize(Integer.MAX_VALUE);
+    l.setNumberOfCores(4);
+  }
+
+}

Added: aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/impl/TxSingleton.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/impl/TxSingleton.java?rev=1166169&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/impl/TxSingleton.java (added)
+++ aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/integration/impl/TxSingleton.java Wed Sep  7 13:29:15 2011
@@ -0,0 +1,42 @@
+package beans.integration.impl;
+
+import javax.ejb.Singleton;
+import javax.ejb.TransactionAttribute;
+import javax.ejb.TransactionAttributeType;
+import javax.naming.InitialContext;
+import javax.transaction.TransactionSynchronizationRegistry;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+import beans.integration.Tx;
+
+@Singleton
+public class TxSingleton implements Tx {
+
+  private TransactionSynchronizationRegistry getTSR() {
+    BundleContext ctx = FrameworkUtil.getBundle(TxSingleton.class).getBundleContext();
+    return (TransactionSynchronizationRegistry) ctx.getService(
+        ctx.getServiceReference("javax.transaction.TransactionSynchronizationRegistry"));
+  }
+  
+  @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
+  public Object getNoTransactionId() throws Exception {
+    return getTSR().getTransactionKey();
+  }
+  
+  @TransactionAttribute(TransactionAttributeType.SUPPORTS)
+  public Object getMaybeTransactionId() throws Exception {
+    return getTSR().getTransactionKey();
+  }
+  
+  @TransactionAttribute(TransactionAttributeType.REQUIRED)
+  public Object getTransactionId() throws Exception {
+    return getTSR().getTransactionKey();
+  }
+
+  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
+  public Object getNewTransactionId() throws Exception {
+    return getTSR().getTransactionKey();
+  }
+}

Added: aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/jpa/Laptop.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/jpa/Laptop.java?rev=1166169&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/jpa/Laptop.java (added)
+++ aries/trunk/ejb/openejb-extender-itest/src/test/java/beans/jpa/Laptop.java Wed Sep  7 13:29:15 2011
@@ -0,0 +1,42 @@
+package beans.jpa;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class Laptop {
+
+  @Id
+  private String serialNumber;
+  
+  private int numberOfCores;
+  
+  private int hardDiskSize;
+
+  public String getSerialNumber() {
+    return serialNumber;
+  }
+
+  public void setSerialNumber(String serialNumber) {
+    this.serialNumber = serialNumber;
+  }
+
+  public int getNumberOfCores() {
+    return numberOfCores;
+  }
+
+  public void setNumberOfCores(int numberOfCores) {
+    this.numberOfCores = numberOfCores;
+  }
+
+  public int getHardDiskSize() {
+    return hardDiskSize;
+  }
+
+  public void setHardDiskSize(int hardDiskSize) {
+    this.hardDiskSize = hardDiskSize;
+  }
+  
+  
+  
+}

Added: aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/AbstractOpenEJBTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/AbstractOpenEJBTest.java?rev=1166169&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/AbstractOpenEJBTest.java (added)
+++ aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/AbstractOpenEJBTest.java Wed Sep  7 13:29:15 2011
@@ -0,0 +1,103 @@
+package org.apache.aries.ejb.openejb.extender.itest;
+
+import static org.apache.aries.itest.ExtraOptions.mavenBundle;
+import static org.apache.aries.itest.ExtraOptions.paxLogging;
+import static org.apache.aries.itest.ExtraOptions.testOptions;
+import static org.apache.aries.itest.ExtraOptions.transactionBootDelegation;
+import static org.ops4j.pax.exam.CoreOptions.equinox;
+import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption;
+
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.aries.itest.AbstractIntegrationTest;
+import org.apache.aries.util.io.IOUtils;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.container.def.PaxRunnerOptions;
+
+public abstract class AbstractOpenEJBTest extends AbstractIntegrationTest{
+  @org.ops4j.pax.exam.junit.Configuration
+  public static Option[] configuration() {
+    return testOptions(
+        paxLogging("DEBUG"),
+        transactionBootDelegation(),
+        vmOption("-Dorg.osgi.framework.system.packages.extra=sun.misc,javax.xml.namespace;version=1.1"),
+        // Bundles
+        mavenBundle("org.apache.aries", "org.apache.aries.util"),
+        mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint"),
+        mavenBundle("asm", "asm-all"),
+        mavenBundle("org.apache.aries.proxy", "org.apache.aries.proxy"),
+        mavenBundle("org.apache.aries.transaction", "org.apache.aries.transaction.manager"),
+        mavenBundle("org.osgi", "org.osgi.compendium"),
+        mavenBundle("org.apache.aries.ejb", "org.apache.aries.ejb.openejb.extender"),
+        mavenBundle("org.apache.openejb", "openejb-core"),
+        mavenBundle("org.apache.openejb", "openejb-api"),
+        mavenBundle("org.apache.openejb", "openejb-javaagent"),
+        mavenBundle("org.apache.openejb", "openejb-jee"),
+        mavenBundle("org.apache.openejb", "openejb-loader"),
+        mavenBundle("org.apache.openwebbeans", "openwebbeans-impl"),
+        mavenBundle("org.apache.openwebbeans", "openwebbeans-spi"),
+        mavenBundle("org.apache.openwebbeans", "openwebbeans-ee"),
+        mavenBundle("org.apache.openwebbeans", "openwebbeans-ejb"),
+        mavenBundle("org.apache.openwebbeans", "openwebbeans-web"),
+        mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.javassist"),
+        mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.wsdl4j-1.6.1"),
+        mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.jaxb-impl"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-annotation_1.1_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-ejb_3.1_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-jcdi_1.0_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-el_2.2_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-jta_1.1_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-jaxrpc_1.1_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-atinject_1.0_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-servlet_3.0_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-jsp_2.2_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-interceptor_1.1_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-saaj_1.3_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-activation_1.1_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-j2ee-management_1.1_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-jpa_2.0_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-j2ee-connector_1.6_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-jacc_1.4_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-validation_1.0_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-jaxrs_1.1_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-ws-metadata_2.0_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-jaspic_1.0_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-jaxb_2.2_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-stax-api_1.2_spec"),
+        mavenBundle("org.apache.geronimo.specs", "geronimo-jaxws_2.2_spec"),
+        //JMS is non optional if *any* EJBs are going to work, not just ones that use it :/
+        mavenBundle("org.apache.geronimo.specs", "geronimo-jms_1.1_spec"),
+        mavenBundle("commons-cli", "commons-cli"),
+        mavenBundle("commons-lang", "commons-lang"),
+        mavenBundle("commons-beanutils", "commons-beanutils"),
+        mavenBundle("commons-collections", "commons-collections"),
+        mavenBundle("org.apache.geronimo.components", "geronimo-connector"),
+        mavenBundle("org.apache.geronimo.components", "geronimo-transaction"),
+        mavenBundle("org.apache.geronimo.bundles", "scannotation"),
+        mavenBundle("org.apache.xbean", "xbean-asm-shaded"),
+        mavenBundle("org.apache.xbean", "xbean-finder-shaded"),
+        mavenBundle("org.apache.xbean", "xbean-naming"),
+        mavenBundle("org.apache.xbean", "xbean-reflect"),
+        mavenBundle("org.hsqldb", "hsqldb"),
+//        vmOption ("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5006"),
+//        waitForFrameworkStartup(),
+        
+
+        PaxRunnerOptions.rawPaxRunnerOption("config", "classpath:ss-runner.properties"),
+        equinox().version("3.7.0.v20110613"));
+  }
+
+  protected void addToZip(ZipOutputStream zos, String src) throws IOException {
+    addToZip(zos, src, src);
+  }
+
+  protected void addToZip(ZipOutputStream zos, String src, String outLocation)
+      throws IOException {
+        zos.putNextEntry(new ZipEntry(outLocation));
+        IOUtils.copy(getClass().getClassLoader().
+            getResourceAsStream(src), zos);
+        zos.closeEntry();
+      }
+}

Added: aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/AdvancedEJBBundleTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/AdvancedEJBBundleTest.java?rev=1166169&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/AdvancedEJBBundleTest.java (added)
+++ aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/AdvancedEJBBundleTest.java Wed Sep  7 13:29:15 2011
@@ -0,0 +1,174 @@
+/*  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.aries.ejb.openejb.extender.itest;
+
+import static org.apache.aries.itest.ExtraOptions.mavenBundle;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.zip.ZipOutputStream;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceContextType;
+import javax.transaction.TransactionSynchronizationRegistry;
+import javax.transaction.UserTransaction;
+
+import org.apache.aries.jpa.container.PersistenceUnitConstants;
+import org.apache.aries.jpa.container.context.PersistenceContextProvider;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.Bundle;
+
+import beans.integration.Tx;
+import beans.integration.impl.JPASingleton;
+import beans.jpa.Laptop;
+
+@RunWith(JUnit4TestRunner.class)
+public class AdvancedEJBBundleTest extends AbstractOpenEJBTest {
+
+  @org.ops4j.pax.exam.junit.Configuration
+  public static Option[] jpaConfig() {
+    return options( 
+        vmOption ("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5006"),
+        mavenBundle("org.apache.aries.jpa", "org.apache.aries.jpa.api"),
+        mavenBundle("org.apache.aries.jpa", "org.apache.aries.jpa.container"),
+        mavenBundle("org.apache.aries.jpa", "org.apache.aries.jpa.container.context"),
+        mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.serp"),
+        mavenBundle("org.apache.openjpa", "openjpa"),
+        mavenBundle("commons-pool", "commons-pool"),
+        mavenBundle("org.apache.derby", "derby")
+    );
+  }
+  
+  @Test
+  public void testTransactionalEJB() throws Exception {
+    
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    ZipOutputStream zos = new ZipOutputStream(baos);
+    addToZip(zos, "TX_MANIFEST.MF", "META-INF/MANIFEST.MF");
+    addToZip(zos, "beans/integration/impl/TxSingleton.class");
+    addToZip(zos, "beans/integration/Tx.class");
+    zos.close();
+    
+    Bundle test = context().installBundle("", new ByteArrayInputStream(baos.toByteArray()));
+
+    try {
+      test.start();
+      
+      Object bean = context().getService(context().getServiceReference(Tx.class.getName()));
+      UserTransaction ut = context().getService(UserTransaction.class);
+      
+      Method no = bean.getClass().getMethod("getNoTransactionId");
+      Method maybe = bean.getClass().getMethod("getMaybeTransactionId");
+      Method tx = bean.getClass().getMethod("getTransactionId");
+      Method newTx = bean.getClass().getMethod("getNewTransactionId");
+      
+      assertNull(no.invoke(bean));
+      assertNull(maybe.invoke(bean));
+      assertNotNull(tx.invoke(bean));
+      assertNotNull(newTx.invoke(bean));
+      
+      ut.begin();
+      try {
+        Object key = context().getService(TransactionSynchronizationRegistry.class).
+            getTransactionKey();
+        
+        assertNotNull(key);
+        assertNull(no.invoke(bean));
+        assertSame(key, maybe.invoke(bean));
+        assertSame(key, tx.invoke(bean));
+        Object o = newTx.invoke(bean);
+        assertNotNull(o);
+        assertNotSame(key, o);
+      } finally {
+        ut.commit();
+      }
+      test.stop();
+    } finally {
+      test.uninstall();
+    }
+  }
+  
+  @Test
+  public void testJPAContextSharing() throws Exception {
+  
+    System.setProperty("openejb.validation.output.level", "VERBOSE");
+    
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    ZipOutputStream zos = new ZipOutputStream(baos);
+    addToZip(zos, "JPA_MANIFEST.MF", "META-INF/MANIFEST.MF");
+    addToZip(zos, "persistence.xml", "META-INF/persistence.xml");
+    addToZip(zos, "beans/integration/impl/JPASingleton.class");
+    addToZip(zos, "beans/jpa/Laptop.class");
+    zos.close();
+    
+    Bundle test = context().installBundle("", new ByteArrayInputStream(baos.toByteArray()));
+
+    try {
+      test.start();
+      
+      PersistenceContextProvider provider = context().getService(PersistenceContextProvider.class);
+      
+      HashMap<String, Object> props = new HashMap<String, Object>();
+      props.put(PersistenceContextProvider.PERSISTENCE_CONTEXT_TYPE, PersistenceContextType.TRANSACTION);
+      provider.registerContext("ejb-test", context().getBundle(), props);
+      
+      
+      Object bean = context().getService(context().getServiceReference(JPASingleton.class.getName()));
+      UserTransaction ut = context().getService(UserTransaction.class);
+      
+      Method m = bean.getClass().getMethod("editEntity", String.class);
+      
+      EntityManager em = context().getService(EntityManagerFactory.class, "(&(osgi.unit.name=ejb-test)(" 
+          + PersistenceUnitConstants.CONTAINER_MANAGED_PERSISTENCE_UNIT + "=true)" +
+        "(" + PersistenceContextProvider.PROXY_FACTORY_EMF_ATTRIBUTE + "=*))").createEntityManager();
+      
+      ut.begin();
+      try {
+        
+        Object e = test.loadClass(Laptop.class.getName()).newInstance();
+        
+        e.getClass().getMethod("setSerialNumber", String.class).invoke(e, "ABC123");
+        e.getClass().getMethod("setNumberOfCores", int.class).invoke(e, 1);
+        
+        em.persist(e);
+        
+        m.invoke(bean, "ABC123");
+        
+        assertEquals(4, e.getClass().getMethod("getNumberOfCores").invoke(e));
+        assertEquals(Integer.MAX_VALUE, e.getClass().getMethod("getHardDiskSize").invoke(e));
+        
+      } finally {
+        ut.commit();
+      }
+      test.stop();
+    } finally {
+      test.uninstall();
+    }
+  }
+}

Modified: aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/EJBBundleTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/EJBBundleTest.java?rev=1166169&r1=1166168&r2=1166169&view=diff
==============================================================================
--- aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/EJBBundleTest.java (original)
+++ aries/trunk/ejb/openejb-extender-itest/src/test/java/org/apache/aries/ejb/openejb/extender/itest/EJBBundleTest.java Wed Sep  7 13:29:15 2011
@@ -15,38 +15,33 @@
  */
 package org.apache.aries.ejb.openejb.extender.itest;
 
-import static org.apache.aries.itest.ExtraOptions.mavenBundle;
-import static org.apache.aries.itest.ExtraOptions.paxLogging;
-import static org.apache.aries.itest.ExtraOptions.testOptions;
-import static org.apache.aries.itest.ExtraOptions.transactionBootDelegation;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertNull;
-import static org.ops4j.pax.exam.CoreOptions.equinox;
-import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption;
+import static org.junit.Assert.assertSame;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.zip.ZipEntry;
+import java.lang.reflect.Method;
 import java.util.zip.ZipOutputStream;
 
-import org.apache.aries.itest.AbstractIntegrationTest;
-import org.apache.aries.util.io.IOUtils;
+import javax.transaction.TransactionSynchronizationRegistry;
+import javax.transaction.UserTransaction;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.container.def.PaxRunnerOptions;
 import org.ops4j.pax.exam.junit.JUnit4TestRunner;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceReference;
 
 import beans.StatelessSessionBean;
+import beans.integration.Tx;
 import beans.xml.LocalIface;
 import beans.xml.RemoteIface;
 
 @RunWith(JUnit4TestRunner.class)
-public class EJBBundleTest extends AbstractIntegrationTest {
+public class EJBBundleTest extends AbstractOpenEJBTest {
 
   private void assertXML(Bundle test, boolean exists) throws Exception {
     ServiceReference[] local = context().getAllServiceReferences(LocalIface.class.getName(), 
@@ -397,87 +392,4 @@ public class EJBBundleTest extends Abstr
       test.uninstall();
     }
   }
-  
-  private void addToZip(ZipOutputStream zos, String src) throws IOException {
-    addToZip(zos, src, src);
-  }
-  
-  private void addToZip(ZipOutputStream zos, String src, String outLocation) throws IOException {
-    zos.putNextEntry(new ZipEntry(outLocation));
-    IOUtils.copy(getClass().getClassLoader().
-        getResourceAsStream(src), zos);
-    zos.closeEntry();
-  }
-
-  @org.ops4j.pax.exam.junit.Configuration
-  public static Option[] configuration() {
-    return testOptions(
-        paxLogging("DEBUG"),
-        transactionBootDelegation(),
-        vmOption("-Dorg.osgi.framework.system.packages.extra=sun.misc,javax.xml.namespace;version=1.1"),
-        // Bundles
-        mavenBundle("org.apache.aries", "org.apache.aries.util"),
-        mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint"),
-        mavenBundle("asm", "asm-all"),
-        mavenBundle("org.apache.aries.proxy", "org.apache.aries.proxy"),
-        mavenBundle("org.apache.aries.transaction", "org.apache.aries.transaction.manager"),
-        mavenBundle("org.osgi", "org.osgi.compendium"),
-        mavenBundle("org.apache.aries.ejb", "org.apache.aries.ejb.openejb.extender"),
-        mavenBundle("org.apache.openejb", "openejb-core"),
-        mavenBundle("org.apache.openejb", "openejb-api"),
-        mavenBundle("org.apache.openejb", "openejb-javaagent"),
-        mavenBundle("org.apache.openejb", "openejb-jee"),
-        mavenBundle("org.apache.openejb", "openejb-loader"),
-        mavenBundle("org.apache.openwebbeans", "openwebbeans-impl"),
-        mavenBundle("org.apache.openwebbeans", "openwebbeans-spi"),
-        mavenBundle("org.apache.openwebbeans", "openwebbeans-ee"),
-        mavenBundle("org.apache.openwebbeans", "openwebbeans-ejb"),
-        mavenBundle("org.apache.openwebbeans", "openwebbeans-web"),
-        mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.javassist"),
-        mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.wsdl4j-1.6.1"),
-        mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.jaxb-impl"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-annotation_1.1_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-ejb_3.1_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-jcdi_1.0_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-el_2.2_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-jta_1.1_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-jaxrpc_1.1_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-atinject_1.0_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-servlet_3.0_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-jsp_2.2_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-interceptor_1.1_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-saaj_1.3_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-activation_1.1_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-j2ee-management_1.1_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-jpa_2.0_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-j2ee-connector_1.6_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-jacc_1.4_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-validation_1.0_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-jaxrs_1.1_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-ws-metadata_2.0_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-jaspic_1.0_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-jaxb_2.2_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-stax-api_1.2_spec"),
-        mavenBundle("org.apache.geronimo.specs", "geronimo-jaxws_2.2_spec"),
-        //JMS is non optional if *any* EJBs are going to work, not just ones that use it :/
-        mavenBundle("org.apache.geronimo.specs", "geronimo-jms_1.1_spec"),
-        mavenBundle("commons-cli", "commons-cli"),
-        mavenBundle("commons-lang", "commons-lang"),
-        mavenBundle("commons-beanutils", "commons-beanutils"),
-        mavenBundle("commons-collections", "commons-collections"),
-        mavenBundle("org.apache.geronimo.components", "geronimo-connector"),
-        mavenBundle("org.apache.geronimo.components", "geronimo-transaction"),
-        mavenBundle("org.apache.geronimo.bundles", "scannotation"),
-        mavenBundle("org.apache.xbean", "xbean-asm-shaded"),
-        mavenBundle("org.apache.xbean", "xbean-finder-shaded"),
-        mavenBundle("org.apache.xbean", "xbean-naming"),
-        mavenBundle("org.apache.xbean", "xbean-reflect"),
-//        vmOption ("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5006"),
-//        waitForFrameworkStartup(),
-        
-
-        PaxRunnerOptions.rawPaxRunnerOption("config", "classpath:ss-runner.properties"),
-        equinox().version("3.7.0.v20110613"));
-  }
-
 }

Propchange: aries/trunk/ejb/openejb-extender-itest/src/test/resources/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Sep  7 13:29:15 2011
@@ -0,0 +1 @@
+JPA_MANIFEST.MF

Added: aries/trunk/ejb/openejb-extender-itest/src/test/resources/JPA_MANIFEST.MF
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender-itest/src/test/resources/JPA_MANIFEST.MF?rev=1166169&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender-itest/src/test/resources/JPA_MANIFEST.MF (added)
+++ aries/trunk/ejb/openejb-extender-itest/src/test/resources/JPA_MANIFEST.MF Wed Sep  7 13:29:15 2011
@@ -0,0 +1,6 @@
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: foo
+Export-EJB: ALL
+Meta-Persistence: 
+Import-Package: javax.ejb, javax.persistence, org.apache.derby.jdbc
+

Added: aries/trunk/ejb/openejb-extender-itest/src/test/resources/TX_MANIFEST.MF
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender-itest/src/test/resources/TX_MANIFEST.MF?rev=1166169&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender-itest/src/test/resources/TX_MANIFEST.MF (added)
+++ aries/trunk/ejb/openejb-extender-itest/src/test/resources/TX_MANIFEST.MF Wed Sep  7 13:29:15 2011
@@ -0,0 +1,5 @@
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: foo
+Export-EJB: ALL
+Import-Package: javax.ejb, javax.transaction, javax.naming, org.osgi.framework
+

Added: aries/trunk/ejb/openejb-extender-itest/src/test/resources/persistence.xml
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender-itest/src/test/resources/persistence.xml?rev=1166169&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender-itest/src/test/resources/persistence.xml (added)
+++ aries/trunk/ejb/openejb-extender-itest/src/test/resources/persistence.xml Wed Sep  7 13:29:15 2011
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
+   version="1.0">
+  
+  <persistence-unit name="ejb-test" transaction-type="JTA">
+    <description>Test persistence unit for the JPA Container advanced iTests</description>
+    <properties>
+      <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
+      <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
+      <property name="javax.persistence.jdbc.url" value="jdbc:derby:memory:TEST;create=true"/>
+    </properties>
+  </persistence-unit>
+  
+</persistence>

Modified: aries/trunk/ejb/openejb-extender/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender/pom.xml?rev=1166169&r1=1166168&r2=1166169&view=diff
==============================================================================
--- aries/trunk/ejb/openejb-extender/pom.xml (original)
+++ aries/trunk/ejb/openejb-extender/pom.xml Wed Sep  7 13:29:15 2011
@@ -39,6 +39,10 @@
 
     <properties>
 		<aries.osgi.export/>
+		<aries.osgi.import>
+		  org.apache.aries.jpa.container.context;resolution:=optional,
+		  *
+		</aries.osgi.import>
         <aries.osgi.private.pkg>
           org.apache.aries.ejb.*
         </aries.osgi.private.pkg>
@@ -106,6 +110,13 @@
         	<type>jar</type>
         	<scope>compile</scope>
         </dependency>
+        <dependency>
+        	<groupId>org.apache.aries.jpa</groupId>
+        	<artifactId>org.apache.aries.jpa.api</artifactId>
+        	<version>0.3.1-SNAPSHOT</version>
+        	<type>bundle</type>
+        	<scope>compile</scope>
+        </dependency>
     </dependencies>
 
 </project>

Added: aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/AriesPersistenceContextIntegration.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/AriesPersistenceContextIntegration.java?rev=1166169&view=auto
==============================================================================
--- aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/AriesPersistenceContextIntegration.java (added)
+++ aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/AriesPersistenceContextIntegration.java Wed Sep  7 13:29:15 2011
@@ -0,0 +1,100 @@
+package org.apache.aries.ejb.openejb.extender;
+
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+import org.apache.aries.jpa.container.context.JTAPersistenceContextManager;
+import org.apache.aries.util.tracker.SingleServiceTracker;
+import org.apache.aries.util.tracker.SingleServiceTracker.SingleServiceListener;
+import org.apache.openejb.persistence.EntityManagerTxKey;
+import org.apache.openejb.persistence.JtaEntityManagerRegistry;
+import org.osgi.framework.BundleContext;
+
+public class AriesPersistenceContextIntegration extends
+    JtaEntityManagerRegistry {
+  
+  private static final AtomicReference<AriesPersistenceContextIntegration> INSTANCE =
+    new AtomicReference<AriesPersistenceContextIntegration>();
+  
+  private final SingleServiceTracker<JTAPersistenceContextManager> ariesJTARegistry;
+  
+  private AriesPersistenceContextIntegration(BundleContext ctx) {
+    super(OSGiTransactionManager.get());
+    ariesJTARegistry = new SingleServiceTracker<JTAPersistenceContextManager>
+        (ctx, JTAPersistenceContextManager.class, new DummySingleServiceListener());
+    ariesJTARegistry.open();
+  }
+  
+  public static void init(BundleContext ctx) {
+    AriesPersistenceContextIntegration apci = new AriesPersistenceContextIntegration(ctx);
+    if(!!!INSTANCE.compareAndSet(null, apci))
+      apci.destroy();
+  }
+  
+  public static AriesPersistenceContextIntegration get() {
+    return INSTANCE.get();
+  }
+  
+  public void destroy() {
+    INSTANCE.set(null);
+    ariesJTARegistry.close();
+  }
+  
+  @Override
+  public EntityManager getEntityManager(EntityManagerFactory emf, Map props,
+      boolean extended, String unitName) throws IllegalStateException {
+
+    if(!!!isTransactionActive())
+      return super.getEntityManager(emf, props, extended, unitName);
+    
+    JTAPersistenceContextManager mgr = ariesJTARegistry.getService();
+    
+    if(mgr == null)
+      throw new IllegalStateException("No JTAPersistenceContextManager service available");
+    
+    //Check if we, or OpenEJB, already have a context
+    EntityManager ariesEM = mgr.getExistingPersistenceContext(emf);
+    EntityManager openEjbEM = (EntityManager) OSGiTransactionManager.get().
+                                  getResource(new EntityManagerTxKey(emf));
+    
+    if(ariesEM == null) {
+      if(openEjbEM == null) {
+        //If both are null then it's easier to let OpenEJB win and push the PC into Aries
+        openEjbEM = super.getEntityManager(emf, props, extended, unitName);
+      }
+      mgr.manageExistingPersistenceContext(emf, openEjbEM);
+      ariesEM = openEjbEM;
+    } else {
+      //We have an Aries EM, if OpenEJB doesn't then sort it out, if it does they should be the same
+      if(openEjbEM == null){
+        if(extended) {
+          throw new IllegalStateException("We already have an active TX scope PersistenceContext, so we can't" +
+            "create an extended one");
+        } else {
+          OSGiTransactionManager.get().putResource(new EntityManagerTxKey(emf), ariesEM);
+          openEjbEM = ariesEM;
+        }
+      } else {
+        //If both non null and not equal then something bad has happened
+        if(openEjbEM != ariesEM) {
+          throw new IllegalStateException("OpenEJB has been cheating. They have a different EntityManager to Aries");
+        }
+      }
+    }
+    
+    //We could return either ariesEM or openEjbEM at this point
+    return ariesEM;
+  }
+
+  private static final class DummySingleServiceListener implements SingleServiceListener {
+
+    public void serviceFound() {}
+
+    public void serviceLost() {}
+
+    public void serviceReplaced() {}
+  }
+}

Modified: aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/AriesProxyService.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/AriesProxyService.java?rev=1166169&r1=1166168&r2=1166169&view=diff
==============================================================================
--- aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/AriesProxyService.java (original)
+++ aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/AriesProxyService.java Wed Sep  7 13:29:15 2011
@@ -152,6 +152,7 @@ public class AriesProxyService implement
   }
   
   public void destroy() {
+    INSTANCE.set(null);
     proxyTracker.close();
   }
   

Modified: aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/EJBExtender.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/EJBExtender.java?rev=1166169&r1=1166168&r2=1166169&view=diff
==============================================================================
--- aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/EJBExtender.java (original)
+++ aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/EJBExtender.java Wed Sep  7 13:29:15 2011
@@ -17,8 +17,10 @@
 package org.apache.aries.ejb.openejb.extender;
 
 import java.io.IOException;
+import java.lang.reflect.Field;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Dictionary;
@@ -50,7 +52,11 @@ import org.apache.openejb.assembler.clas
 import org.apache.openejb.assembler.dynamic.PassthroughFactory;
 import org.apache.openejb.config.ConfigurationFactory;
 import org.apache.openejb.config.EjbModule;
+import org.apache.openejb.config.ValidationContext;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.oejb3.OpenejbJar;
 import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.persistence.JtaEntityManagerRegistry;
 import org.apache.openejb.ri.sp.PseudoSecurityService;
 import org.apache.openejb.util.OpenEjbVersion;
 import org.osgi.framework.Bundle;
@@ -66,8 +72,6 @@ public class EJBExtender implements Bund
   
   private static final Object PROCESSING_OBJECT = new Object();
   private static final Object REMOVING_OBJECT = new Object();
-  private static final String NONE = "NONE";
-  private static final String ALL = "ALL";
   
   private RecursiveBundleTracker tracker;
   
@@ -82,7 +86,11 @@ public class EJBExtender implements Bund
     //Internal setup
     OSGiTransactionManager.init(context);
     AriesProxyService.init(context);
-    
+    try {
+      AriesPersistenceContextIntegration.init(context);
+    } catch (NoClassDefFoundError ncdfe) {
+      //TODO log that no JPA Context integration is available
+    }
     
     //Setup OpenEJB with our own extensions
     setupOpenEJB();
@@ -116,6 +124,16 @@ public class EJBExtender implements Bund
       Thread.currentThread().setContextClassLoader(cl);
     }
     
+    try {
+      //Overwrite existing, default JPA integration with an Aries JPA integrated one
+      Assembler.getContext().put(JtaEntityManagerRegistry.class.getName(), 
+          AriesPersistenceContextIntegration.get());
+      SystemInstance.get().setComponent(JtaEntityManagerRegistry.class, 
+          AriesPersistenceContextIntegration.get());
+    } catch (NoClassDefFoundError ncdfe) {
+      //TODO log that no JPA Context integration is available
+    }
+    
     SecurityServiceInfo ssi = new SecurityServiceInfo();
     ssi.service = "SecurityService";
     ssi.id = "Pseudo Security Service";
@@ -146,6 +164,11 @@ public class EJBExtender implements Bund
     tracker.close();
     AriesProxyService.get().destroy();
     OSGiTransactionManager.get().destroy();
+    try {
+      AriesPersistenceContextIntegration.get().destroy();
+    } catch (NoClassDefFoundError ncdfe) {
+      //TODO log that no JPA Context integration is available
+    }
   }
 
   public Object addingBundle(Bundle bundle, BundleEvent event) {
@@ -185,9 +208,15 @@ public class EJBExtender implements Bund
       if(runningApps.get(bundle) != null)
         return;
       
-      EjbModule ejbModule = new EjbModule(AriesFrameworkUtil.getClassLoaderForced(bundle),
-          null, null, null);
-      
+      //Broken validation for persistence :(
+      EjbModule ejbModule = new EjbModule(AriesFrameworkUtil.getClassLoaderForced(bundle), null, null, null);
+      try {
+        Field f = EjbModule.class.getDeclaredField("validation");
+        f.setAccessible(true);
+        f.set(ejbModule, new ValidationProofValidationContext(ejbModule));
+      } catch (Exception e) {
+        // Hmmm
+      }
       addAltDDs(ejbModule, bundle);
       //We build our own because we can't trust anyone to get the classpath right otherwise!
       ejbModule.setFinder(new OSGiFinder(bundle));
@@ -225,7 +254,7 @@ public class EJBExtender implements Bund
         try {
           Thread.currentThread().setContextClassLoader(OpenEjbVersion.class.getClassLoader());
           app = new RunningApplication(assembler.createApplication(ejbInfo, 
-              new AppClassLoader(ejbModule.getClassLoader())));
+              new AppClassLoader(ejbModule.getClassLoader())), bundle, ejbInfo.enterpriseBeans);
         } finally {
           Thread.currentThread().setContextClassLoader(cl);
         }
@@ -234,7 +263,8 @@ public class EJBExtender implements Bund
       }
       runningApps.put(bundle, app);
       
-      app.addRegs(registerEJBs(app.getCtx(), bundle));
+      app.init();
+      
       
     } catch (OpenEJBException oee) {
       // TODO Auto-generated catch block
@@ -269,97 +299,9 @@ public class EJBExtender implements Bund
         
       altDDs.put(urlString, u);
     }
-    //Persistence descriptors are handled by Aries JPA
-    altDDs.remove("persistence.xml");
-  }
-
-  private Collection<ServiceRegistration<?>> registerEJBs(AppContext appCtx, Bundle bundle) {
-    
-    Collection<ServiceRegistration<?>> regs = new ArrayList<ServiceRegistration<?>>();
-    
-    Collection<String> names = new HashSet<String>();
-    
-    Dictionary<String, String> d = bundle.getHeaders();
-    String valueOfExportEJBHeader = d.get("Export-EJB");
-    
-    if((valueOfExportEJBHeader == null)||(valueOfExportEJBHeader.equals(""))){
-      return Collections.emptyList();
-    }
-    
-    List<NameValuePair> contentsOfExportEJBHeader = ManifestHeaderProcessor.parseExportString(valueOfExportEJBHeader);
-    for(NameValuePair nvp:contentsOfExportEJBHeader){
-      names.add(nvp.getName());
-    }
-    
-    if(names.contains(NONE)){
-      return Collections.emptyList();
-    }
-    
-    if(names.contains(ALL)){
-      names = new AllCollection<String>();
-    }
-    
-    //Register our session beans
-    for (BeanContext beanContext : appCtx.getDeployments()) {
-      String ejbName = beanContext.getEjbName();
-      //Skip if not a Singleton or stateless bean
-      ContainerType type = beanContext.getContainer().getContainerType();
-      boolean register = type == ContainerType.SINGLETON || type == ContainerType.STATELESS;
-      
-      //Skip if not allowed name
-      register &= names.contains(ejbName);
-      
-      if(!register) {
-        continue;
-      }
-      
-      if (beanContext.isLocalbean()) {
-
-        BeanContext.BusinessLocalBeanHome home = beanContext.getBusinessLocalBeanHome();
-    
-        Dictionary<String, Object> props = new Hashtable<String, Object>(); 
-        
-        props.put("ejb.name", ejbName);
-        props.put("ejb.type", getCasedType(type));
-        regs.add(bundle.getBundleContext().registerService(beanContext.getBeanClass().getName(), 
-            new EJBServiceFactory(home), props));
-      }
-
-  
-      for (Class<?> interfce : beanContext.getBusinessLocalInterfaces()) {
-
-        BeanContext.BusinessLocalHome home = beanContext.getBusinessLocalHome(interfce);
-        
-        Dictionary<String, Object> props = new Hashtable<String, Object>(); 
-        
-        props.put("ejb.name", ejbName);
-        props.put("ejb.type", getCasedType(type));
-        regs.add(bundle.getBundleContext().registerService(interfce.getName(), 
-            new EJBServiceFactory(home), props));
-      }
-      
-      for (Class<?> interfce : beanContext.getBusinessRemoteInterfaces()) {
-
-        List<Class> interfaces = ProxyInterfaceResolver.getInterfaces(beanContext.getBeanClass(), 
-            interfce, beanContext.getBusinessRemoteInterfaces());
-        BeanContext.BusinessRemoteHome home = beanContext.getBusinessRemoteHome(interfaces, interfce);
-        
-        Dictionary<String, Object> props = new Hashtable<String, Object>(); 
-        
-        props.put("sevice.exported.interfaces", interfce.getName());
-        props.put("ejb.name", ejbName);
-        props.put("ejb.type", getCasedType(type));
-        regs.add(bundle.getBundleContext().registerService(interfce.getName(), 
-            new EJBServiceFactory(home), props));
-      }
-    }
-    return regs;
-  }
-
-  private String getCasedType(ContainerType type) {
-    String s = type.toString().substring(0,1).toUpperCase();
-    s += type.toString().substring(1).toLowerCase();
-    return s;
+    //Persistence descriptors are handled by Aries JPA, but OpenEJB fails validation
+    //if we hide them. As a result we switch it off.
+    //altDDs.remove("persistence.xml");
   }
 
   private void stopEJBs(Bundle bundle) {
@@ -369,9 +311,7 @@ public class EJBExtender implements Bund
       try {
         RunningApplication app = runningApps.remove(bundle);
         if(app != null) {
-          for(ServiceRegistration<?> reg : app.getRegs()) {
-            AriesFrameworkUtil.safeUnregisterService(reg);
-          }
+          app.destroy();
           Assembler assembler = (Assembler) SystemInstance.get().getComponent(Assembler.class);
           assembler.destroyApplication(app.getCtx());
         }
@@ -391,6 +331,29 @@ public class EJBExtender implements Bund
     }
   }
   
+  private static final class ValidationProofValidationContext extends ValidationContext {
+    private ValidationProofValidationContext(EjbModule mod) {
+      super(mod);
+    }
+
+    @Override
+    public boolean hasErrors() {
+      return false;
+    }
+
+    @Override
+    public boolean hasFailures() {
+      return false;
+    }
+
+    @Override
+    public boolean hasWarnings() {
+      return false;
+    }
+
+    
+  }
+
   private static final class AppClassLoader extends ClassLoader {
     private AppClassLoader(ClassLoader parentLoader) {
       super(parentLoader);

Modified: aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/OSGiTransactionManager.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/OSGiTransactionManager.java?rev=1166169&r1=1166168&r2=1166169&view=diff
==============================================================================
--- aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/OSGiTransactionManager.java (original)
+++ aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/OSGiTransactionManager.java Wed Sep  7 13:29:15 2011
@@ -98,6 +98,7 @@ public class OSGiTransactionManager impl
   }
   
   public void destroy() {
+    INSTANCE.set(null);
     tmTracker.close();
     tsrTracker.close();
   }

Modified: aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/RunningApplication.java
URL: http://svn.apache.org/viewvc/aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/RunningApplication.java?rev=1166169&r1=1166168&r2=1166169&view=diff
==============================================================================
--- aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/RunningApplication.java (original)
+++ aries/trunk/ejb/openejb-extender/src/main/java/org/apache/aries/ejb/openejb/extender/RunningApplication.java Wed Sep  7 13:29:15 2011
@@ -18,30 +18,296 @@ package org.apache.aries.ejb.openejb.ext
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.persistence.EntityManagerFactory;
+
+import org.apache.aries.jpa.container.PersistenceUnitConstants;
+import org.apache.aries.jpa.container.context.PersistenceContextProvider;
+import org.apache.aries.util.AriesFrameworkUtil;
+import org.apache.aries.util.manifest.ManifestHeaderProcessor;
+import org.apache.aries.util.manifest.ManifestHeaderProcessor.NameValuePair;
 import org.apache.openejb.AppContext;
+import org.apache.openejb.BeanContext;
+import org.apache.openejb.ContainerType;
+import org.apache.openejb.assembler.classic.EnterpriseBeanInfo;
+import org.apache.openejb.assembler.classic.PersistenceContextReferenceInfo;
+import org.apache.openejb.assembler.classic.PersistenceUnitReferenceInfo;
+import org.apache.openejb.assembler.classic.ProxyInterfaceResolver;
+import org.apache.openejb.jee.EnterpriseBean;
+import org.apache.openejb.persistence.JtaEntityManager;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 
-public class RunningApplication {
+public class RunningApplication implements ServiceTrackerCustomizer {
 
+  private static final String NONE = "NONE";
+  private static final String ALL = "ALL";
+  
   private final AppContext ctx;
+  private final Bundle bundle;
   private final Collection<ServiceRegistration<?>> regs = 
-    Collections.synchronizedCollection(new ArrayList<ServiceRegistration<?>>());
+    new ArrayList<ServiceRegistration<?>>();
+  
+  private ServiceTracker tracker;
+  
+  private final ConcurrentMap<String, ConcurrentMap<Context, String>> unitRegistrations = 
+    new ConcurrentHashMap<String, ConcurrentMap<Context, String>>();
   
-  public RunningApplication(AppContext context) {
+  private final ConcurrentMap<String, ConcurrentMap<Context, PersistenceContextReferenceInfo>> 
+    contextRegistrations = new ConcurrentHashMap<String, ConcurrentMap<Context, PersistenceContextReferenceInfo>>();
+  
+  public RunningApplication(AppContext context, Bundle bundle, List<EnterpriseBeanInfo> enterpriseBeans) {
     this.ctx = context;
+    this.bundle = bundle;
+    
+    for(EnterpriseBeanInfo bean : enterpriseBeans) {
+      for(PersistenceUnitReferenceInfo pui : bean.jndiEnc.persistenceUnitRefs) {
+        ConcurrentMap<Context, String> map = unitRegistrations.get(pui.persistenceUnitName);
+        
+        if(map == null) {
+          map = new ConcurrentHashMap<Context, String>();
+          unitRegistrations.put(pui.persistenceUnitName, map);
+        }
+        
+        for(BeanContext eb : ctx.getBeanContexts()) {
+          if(eb.getEjbName().equals(bean.ejbName)){
+            map.put(eb.getJndiContext(), pui.referenceName);
+            continue;
+          }
+        }
+      }
+      
+      for(PersistenceContextReferenceInfo pci : bean.jndiEnc.persistenceContextRefs) {
+        ConcurrentMap<Context, PersistenceContextReferenceInfo> map = contextRegistrations.
+            get(pci.persistenceUnitName);
+        
+        if(map == null) {
+          map = new ConcurrentHashMap<Context, PersistenceContextReferenceInfo>();
+          contextRegistrations.put(pci.persistenceUnitName, map);
+        }
+        
+        for(BeanContext eb : ctx.getBeanContexts()) {
+          if(eb.getEjbName().equals(bean.ejbName)){
+            map.put(eb.getJndiContext(), pci);
+            continue;
+          }
+        }
+      }
+    }
   }
 
   public AppContext getCtx() {
     return ctx;
   }
 
-  public Collection<ServiceRegistration<?>> getRegs() {
-    return regs;
+  public void init() {
+    
+    tracker = new ServiceTracker(bundle.getBundleContext(), 
+        EntityManagerFactory.class.getName(), this);
+    tracker.open();
+    
+    registerEJBs();
+  }
+  
+  public void destroy() {
+    tracker.close();
+    for(ServiceRegistration<?> reg : regs) {
+      AriesFrameworkUtil.safeUnregisterService(reg);
+    }
   }
   
-  public void addRegs(Collection<ServiceRegistration<?>> toAdd) {
-    regs.addAll(toAdd);
+
+  
+  private void registerEJBs() {
+    
+    Collection<String> names = new HashSet<String>();
+    
+    Dictionary<String, String> d = bundle.getHeaders();
+    String valueOfExportEJBHeader = d.get("Export-EJB");
+    
+    if((valueOfExportEJBHeader == null)||(valueOfExportEJBHeader.equals(""))){
+      return;
+    }
+    
+    List<NameValuePair> contentsOfExportEJBHeader = ManifestHeaderProcessor.parseExportString(valueOfExportEJBHeader);
+    for(NameValuePair nvp:contentsOfExportEJBHeader){
+      names.add(nvp.getName());
+    }
+    
+    if(names.contains(NONE)){
+      return;
+    }
+    
+    if(names.contains(ALL)){
+      names = new AllCollection<String>();
+    }
+    
+    //Register our session beans
+    for (BeanContext beanContext : ctx.getDeployments()) {
+      String ejbName = beanContext.getEjbName();
+      //Skip if not a Singleton or stateless bean
+      ContainerType type = beanContext.getContainer().getContainerType();
+      boolean register = type == ContainerType.SINGLETON || type == ContainerType.STATELESS;
+      
+      //Skip if not allowed name
+      register &= names.contains(ejbName);
+      
+      if(!register) {
+        continue;
+      }
+      
+      if (beanContext.isLocalbean()) {
+
+        BeanContext.BusinessLocalBeanHome home = beanContext.getBusinessLocalBeanHome();
+    
+        Dictionary<String, Object> props = new Hashtable<String, Object>(); 
+        
+        props.put("ejb.name", ejbName);
+        props.put("ejb.type", getCasedType(type));
+        regs.add(bundle.getBundleContext().registerService(beanContext.getBeanClass().getName(), 
+            new EJBServiceFactory(home), props));
+      }
+
+  
+      for (Class<?> interfce : beanContext.getBusinessLocalInterfaces()) {
+
+        BeanContext.BusinessLocalHome home = beanContext.getBusinessLocalHome(interfce);
+        
+        Dictionary<String, Object> props = new Hashtable<String, Object>(); 
+        
+        props.put("ejb.name", ejbName);
+        props.put("ejb.type", getCasedType(type));
+        regs.add(bundle.getBundleContext().registerService(interfce.getName(), 
+            new EJBServiceFactory(home), props));
+      }
+      
+      for (Class<?> interfce : beanContext.getBusinessRemoteInterfaces()) {
+
+        List<Class> interfaces = ProxyInterfaceResolver.getInterfaces(beanContext.getBeanClass(), 
+            interfce, beanContext.getBusinessRemoteInterfaces());
+        BeanContext.BusinessRemoteHome home = beanContext.getBusinessRemoteHome(interfaces, interfce);
+        
+        Dictionary<String, Object> props = new Hashtable<String, Object>(); 
+        
+        props.put("sevice.exported.interfaces", interfce.getName());
+        props.put("ejb.name", ejbName);
+        props.put("ejb.type", getCasedType(type));
+        regs.add(bundle.getBundleContext().registerService(interfce.getName(), 
+            new EJBServiceFactory(home), props));
+      }
+    }
+  }
+  
+  private String getCasedType(ContainerType type) {
+    String s = type.toString().substring(0,1).toUpperCase();
+    s += type.toString().substring(1).toLowerCase();
+    return s;
+  }
+
+  public Object addingService(ServiceReference reference) {
+    
+    if(isTrue(reference, PersistenceUnitConstants.CONTAINER_MANAGED_PERSISTENCE_UNIT) &&
+       !!!isTrue(reference, PersistenceContextProvider.PROXY_FACTORY_EMF_ATTRIBUTE)) {
+      
+      Map<Context, String> pUnitRefs = unitRegistrations.
+             get(reference.getProperty(PersistenceUnitConstants.OSGI_UNIT_NAME));
+      Map<Context, PersistenceContextReferenceInfo> pCtxRefs = contextRegistrations.
+             get(reference.getProperty(PersistenceUnitConstants.OSGI_UNIT_NAME));
+      
+      if(pUnitRefs == null) {
+        pUnitRefs = new HashMap<Context, String>();
+      }
+      if(pCtxRefs == null) {
+        pCtxRefs = new HashMap<Context, PersistenceContextReferenceInfo>();
+      }      
+      
+      if(pUnitRefs.size() > 0 || pCtxRefs.size() > 0) {
+      
+        EntityManagerFactory emf = (EntityManagerFactory)bundle.getBundleContext().getService(reference);
+        
+        for(Entry<Context, String> e : pUnitRefs.entrySet()) {
+          try {
+            e.getKey().bind(e.getValue(), emf);
+          } catch (NamingException ex) {
+            // TODO Auto-generated catch block
+            ex.printStackTrace();
+          }
+        }
+        
+        for(Entry<Context, PersistenceContextReferenceInfo> e : pCtxRefs.entrySet()) {
+          PersistenceContextReferenceInfo pci = e.getValue();
+          try {
+            e.getKey().bind(pci.referenceName, new JtaEntityManager((String)reference.getProperty(
+                PersistenceUnitConstants.OSGI_UNIT_NAME), AriesPersistenceContextIntegration.get(),
+                emf, pci.properties, pci.extended));
+          } catch (NamingException ex) {
+            // TODO Auto-generated catch block
+            ex.printStackTrace();
+          }
+        }
+        return emf;
+      }
+    }
+    return null;
+  }
+
+  private boolean isTrue(ServiceReference reference,
+      String key) {
+    return Boolean.parseBoolean(String.valueOf(reference.getProperty(key)));
+  }
+
+  public void modifiedService(ServiceReference reference, Object service) {
+    //No op
+  }
+
+  public void removedService(ServiceReference reference, Object service) {
+    
+    Map<Context, String> pUnitRefs = unitRegistrations.
+        get(reference.getProperty(PersistenceUnitConstants.OSGI_UNIT_NAME));
+    Map<Context, PersistenceContextReferenceInfo> pCtxRefs = contextRegistrations.
+        get(reference.getProperty(PersistenceUnitConstants.OSGI_UNIT_NAME));
+
+    if(pUnitRefs == null) {
+      pUnitRefs = new HashMap<Context, String>();
+    }
+    if(pCtxRefs == null) {
+      pCtxRefs = new HashMap<Context, PersistenceContextReferenceInfo>();
+    }      
+    
+    if(pUnitRefs.size() > 0 || pCtxRefs.size() > 0) {
+    
+      for(Entry<Context, String> e : pUnitRefs.entrySet()) {
+        try {
+          e.getKey().unbind(e.getValue());
+        } catch (NamingException ex) {
+          // TODO Auto-generated catch block
+          ex.printStackTrace();
+        }
+      }
+    
+      for(Entry<Context, PersistenceContextReferenceInfo> e : pCtxRefs.entrySet()) {
+        PersistenceContextReferenceInfo pci = e.getValue();
+        try {
+          e.getKey().unbind(pci.referenceName);
+        } catch (NamingException ex) {
+          // TODO Auto-generated catch block
+          ex.printStackTrace();
+        }
+      }
+    }
   }
 }

Added: aries/trunk/jpa/jpa-api/src/main/java/org/apache/aries/jpa/container/context/JTAPersistenceContextManager.java
URL: http://svn.apache.org/viewvc/aries/trunk/jpa/jpa-api/src/main/java/org/apache/aries/jpa/container/context/JTAPersistenceContextManager.java?rev=1166169&view=auto
==============================================================================
--- aries/trunk/jpa/jpa-api/src/main/java/org/apache/aries/jpa/container/context/JTAPersistenceContextManager.java (added)
+++ aries/trunk/jpa/jpa-api/src/main/java/org/apache/aries/jpa/container/context/JTAPersistenceContextManager.java Wed Sep  7 13:29:15 2011
@@ -0,0 +1,55 @@
+/**
+ * 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.aries.jpa.container.context;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.TransactionRequiredException;
+
+
+public interface JTAPersistenceContextManager {
+
+  /**
+   * Get the existing Transaction scoped PersistenceContext for this transaction and persistence unit
+   * @param emf The PersistenceUnit to get a PersistenceContext for
+   * @return An existing transaction scoped PersistenceContext, or null if none already exists 
+   * @throws TransactionRequiredException if there is no current transaction
+   */
+  public EntityManager getExistingPersistenceContext(EntityManagerFactory emf) throws TransactionRequiredException;
+ 
+  /**
+   * Make the supplied {@link EntityManager} the current persistence context for this transaction.
+   * The {@link JTAPersistenceContextManager} will call {@link EntityManager#joinTransaction()} 
+   * but will not close the EntityManager when the transaction commits.
+   * After a successful call to this method, {@link #getExistingPersistenceContext(EntityManagerFactory)}
+   * will return the {@link EntityManager} em
+   * @param emf The persistence unit
+   * @param em The persistence context that will be the "managed" persistence context for the current
+   * transaction
+   * @throws TransactionRequiredException if there is no active transaction
+   * @throws IllegalStateException if there is already a persistence context associated with this transaction
+   */
+  public void manageExistingPersistenceContext(EntityManagerFactory emf, EntityManager em) 
+  throws TransactionRequiredException, IllegalStateException;
+  
+  /**
+   * Determine whether there is an active transaction
+   */
+  public boolean isTransactionActive();
+}

Modified: aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java
URL: http://svn.apache.org/viewvc/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java?rev=1166169&r1=1166168&r2=1166169&view=diff
==============================================================================
--- aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java (original)
+++ aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java Wed Sep  7 13:29:15 2011
@@ -26,6 +26,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.Map.Entry;
 
+import org.apache.aries.jpa.container.context.JTAPersistenceContextManager;
 import org.apache.aries.jpa.container.context.PersistenceContextProvider;
 import org.apache.aries.jpa.container.context.transaction.impl.DestroyCallback;
 import org.apache.aries.jpa.container.context.transaction.impl.JTAPersistenceContextRegistry;
@@ -50,6 +51,7 @@ public class GlobalPersistenceManager im
   private static final Logger _logger = LoggerFactory.getLogger("org.apache.aries.jpa.container.context");
   
   private JTAPersistenceContextRegistry registry;
+  private ServiceRegistration registryReg;
   
   /** 
    *    The list of persistence context managers. Each is valid for exactly one framework
@@ -240,7 +242,7 @@ public class GlobalPersistenceManager im
     
     //Register our service
     pcpReg = context.registerService(PersistenceContextProvider.class.getName(), this, null);
-    
+    registryReg = context.registerService(JTAPersistenceContextManager.class.getName(), registry, null);
     try{
       context.getBundle().loadClass(QUIESCE_PARTICIPANT_CLASS);
       //Class was loaded, register
@@ -255,6 +257,7 @@ public class GlobalPersistenceManager im
   public void stop(BundleContext context) throws Exception {
     //Clean up
     AriesFrameworkUtil.safeUnregisterService(pcpReg);
+    AriesFrameworkUtil.safeUnregisterService(registryReg);
     AriesFrameworkUtil.safeUnregisterService(quiesceReg);
     if(quiesceTidyUp != null)
       quiesceTidyUp.callback();

Modified: aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java
URL: http://svn.apache.org/viewvc/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java?rev=1166169&r1=1166168&r2=1166169&view=diff
==============================================================================
--- aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java (original)
+++ aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java Wed Sep  7 13:29:15 2011
@@ -29,6 +29,7 @@ import javax.persistence.TransactionRequ
 import javax.transaction.Synchronization;
 import javax.transaction.TransactionSynchronizationRegistry;
 
+import org.apache.aries.jpa.container.context.JTAPersistenceContextManager;
 import org.apache.aries.jpa.container.context.impl.NLS;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -39,7 +40,7 @@ import org.slf4j.LoggerFactory;
 /**
  * This class is used to manage the lifecycle of JTA peristence contexts
  */
-public final class JTAPersistenceContextRegistry extends ServiceTracker {
+public final class JTAPersistenceContextRegistry extends ServiceTracker implements JTAPersistenceContextManager {
   /** Logger */
   private static final Logger _logger = LoggerFactory.getLogger("org.apache.aries.jpa.container.context");
   /** The unique key we use to find our Map */
@@ -76,9 +77,48 @@ public final class JTAPersistenceContext
     open();
   }
 
+  public final EntityManager getExistingPersistenceContext(EntityManagerFactory emf) {
+    
+    ensureTransaction();
+    
+    Map<EntityManagerFactory, EntityManager> contextsForTransaction = getContextsForTransaction(tranRegistry.get());
+    
+    return contextsForTransaction.get(emf);
+  }
+  
+  public final void manageExistingPersistenceContext(EntityManagerFactory emf, EntityManager em) 
+  throws TransactionRequiredException {
+    //Throw the error on to the client
+    ensureTransaction();
+    
+    Map<EntityManagerFactory, EntityManager> contextsForTransaction = getContextsForTransaction(tranRegistry.get());
+
+    if(contextsForTransaction.containsKey(emf))
+      throw new IllegalStateException(NLS.MESSAGES.getMessage("existing.persistence.context"));
+    
+    em.joinTransaction();
+    contextsForTransaction.put(emf, em);
+  }
+
+  /**
+   * Throw a {@link TransactionRequiredException} if there is no active transaction
+   * @throws TransactionRequiredException
+   */
+  private void ensureTransaction() throws TransactionRequiredException{
+    if(!!!isTransactionActive()) {
+      if(jtaIntegrationAvailable())
+        throw new TransactionRequiredException(NLS.MESSAGES.getMessage("no.active.transaction"));
+      else {
+        throw new TransactionRequiredException(NLS.MESSAGES.getMessage("no.transaction.manager"));
+      }
+    }
+  }
+  
   /**
    * Get a PersistenceContext for the current transaction. The persistence context will 
-   * automatically be closed when the transaction completes.
+   * automatically be closed when the transaction completes. This method will create
+   * a new PersistenceContext if none exists for the current transaction, or will 
+   * return any existing PersistenceContext for this transaction.
    * 
    * @param persistenceUnit The peristence unit to create the persitence context from
    * @param properties  Any properties that should be passed on the call to {@code createEntityManager()}. 
@@ -95,28 +135,55 @@ public final class JTAPersistenceContext
       EntityManagerFactory persistenceUnit, Map<?,?> properties, AtomicLong activeCount,
       DestroyCallback cbk) throws TransactionRequiredException
   {
-    //There will only ever be one thread associated with a transaction at a given time
-    //As a result, it is only the outer map that needs to be thread safe.
     
-    //Throw the error on to the client
-    if(!!!isTransactionActive()) {
-      if(jtaIntegrationAvailable())
-        throw new TransactionRequiredException(NLS.MESSAGES.getMessage("no.active.transaction"));
-      else {
-        throw new TransactionRequiredException(NLS.MESSAGES.getMessage("no.transaction.manager"));
-      }
+    EntityManager toReturn = getExistingPersistenceContext(persistenceUnit);
+    
+    if(toReturn != null) {
+      if(_logger.isDebugEnabled())
+        _logger.debug("Re-using a persistence context for transaction " + tranRegistry.get().getTransactionKey());
+      return toReturn;
     }
-    EntityManager toReturn = null;
+    
     TransactionSynchronizationRegistry tsr = tranRegistry.get();
-    //Get hold of the Map. If there is no Map already registered then add one.
-    //We don't need to worry about a race condition, as no other thread will
-    //share our transaction and be able to access our Map
-    Map<EntityManagerFactory, EntityManager> contextsForTransaction = (Map<EntityManagerFactory, EntityManager>) tsr.getResource(EMF_MAP_KEY);
     
-    //If we have a map then find an EntityManager, else create a new Map add it to the registry, and register for cleanup
-    if(contextsForTransaction != null) {
-      toReturn = contextsForTransaction.get(persistenceUnit);
-    } else {
+    Map<EntityManagerFactory, EntityManager> contextsForTransaction = getContextsForTransaction(tsr);
+    
+    //Create an EntityManager
+    toReturn = (properties == null) ? persistenceUnit.createEntityManager() : persistenceUnit.createEntityManager(properties);
+    
+    if(_logger.isDebugEnabled())
+      _logger.debug("Created a new persistence context {} for transaction {}.", new Object[] {toReturn, tsr.getTransactionKey()});
+    
+    try {
+      tsr.registerInterposedSynchronization(new EntityManagerClearUp(toReturn, activeCount, cbk));
+    } catch (IllegalStateException e) {
+      String message = NLS.MESSAGES.getMessage("unable.to.register.synchronization", tsr.getTransactionKey());
+      _logger.warn(message);
+      toReturn.close();
+      throw new TransactionRequiredException(message);
+    }
+    contextsForTransaction.put(persistenceUnit, toReturn);
+    activeCount.incrementAndGet();
+
+    return toReturn;
+  }
+
+  /**
+   * Get the map of contexts for the current transaction
+   * @param tsr
+   * @return
+   */
+  private Map<EntityManagerFactory, EntityManager> getContextsForTransaction(
+      TransactionSynchronizationRegistry tsr) {
+    
+    Map<EntityManagerFactory, EntityManager> contextsForTransaction = 
+        (Map<EntityManagerFactory, EntityManager>) tsr.getResource(EMF_MAP_KEY);
+    
+    //There will only ever be one thread associated with a transaction at a given time
+    //As a result, it is only the outer map that needs to be thread safe.
+    //Also we don't need to worry about a race condition, as no other thread will
+    //share our transaction and be able to access our Map
+    if(contextsForTransaction == null) {
       contextsForTransaction = new IdentityHashMap<EntityManagerFactory, EntityManager>();
       try {
         tsr.putResource(EMF_MAP_KEY, contextsForTransaction);
@@ -126,33 +193,9 @@ public final class JTAPersistenceContext
         throw new TransactionRequiredException(message);
       }
     }
-    
-    //If we have no previously created EntityManager
-    if(toReturn == null) {
-      toReturn = (properties == null) ? persistenceUnit.createEntityManager() : persistenceUnit.createEntityManager(properties);
-      if(_logger.isDebugEnabled())
-        _logger.debug("Created a new persistence context {} for transaction {}.", new Object[] {toReturn, tsr.getTransactionKey()});
-      try {
-        tsr.registerInterposedSynchronization(new EntityManagerClearUp(toReturn, activeCount, cbk));
-      } catch (IllegalStateException e) {
-        String message = NLS.MESSAGES.getMessage("unable.to.register.synchronization", tsr.getTransactionKey());
-        _logger.warn(message);
-        toReturn.close();
-        throw new TransactionRequiredException(message);
-      }
-      contextsForTransaction.put(persistenceUnit, toReturn);
-      activeCount.incrementAndGet();
-    } else {
-      if(_logger.isDebugEnabled())
-        _logger.debug("Re-using a persistence context for transaction " + tsr.getTransactionKey());
-    }
-    return toReturn;
+    return contextsForTransaction;
   }
   
-  /**
-   * Determine whether there is an active transaction on the thread
-   * @return
-   */
   public final boolean isTransactionActive()
   {
     TransactionSynchronizationRegistry tsr = tranRegistry.get();

Modified: aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManagerTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManagerTest.java?rev=1166169&r1=1166168&r2=1166169&view=diff
==============================================================================
--- aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManagerTest.java (original)
+++ aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManagerTest.java Wed Sep  7 13:29:15 2011
@@ -26,8 +26,12 @@ import java.util.Hashtable;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.aries.jpa.container.context.JTAPersistenceContextManager;
+import org.apache.aries.jpa.container.context.PersistenceContextProvider;
 import org.apache.aries.jpa.container.context.transaction.impl.JTAPersistenceContextRegistry;
+import org.apache.aries.mocks.BundleContextMock;
 import org.apache.aries.mocks.BundleMock;
+import org.apache.aries.quiesce.participant.QuiesceParticipant;
 import org.apache.aries.unittest.mocks.MethodCall;
 import org.apache.aries.unittest.mocks.Skeleton;
 import org.junit.Before;
@@ -65,6 +69,29 @@ public class GlobalPersistenceManagerTes
     }
     
     @Test
+    public void testServices() throws Exception {
+      BundleContext bc = Skeleton.newMock(new BundleContextMock(), BundleContext.class);
+      
+      GlobalPersistenceManager gpm = new GlobalPersistenceManager();
+      
+      BundleContextMock.assertNoServiceExists(PersistenceContextProvider.class.getName());
+      BundleContextMock.assertNoServiceExists(JTAPersistenceContextManager.class.getName());
+      BundleContextMock.assertNoServiceExists(QuiesceParticipant.class.getName());
+      
+      gpm.start(bc);
+      
+      BundleContextMock.assertServiceExists(PersistenceContextProvider.class.getName());
+      BundleContextMock.assertServiceExists(JTAPersistenceContextManager.class.getName());
+      BundleContextMock.assertServiceExists(QuiesceParticipant.class.getName());
+      
+      gpm.stop(bc);
+      
+      BundleContextMock.assertNoServiceExists(PersistenceContextProvider.class.getName());
+      BundleContextMock.assertNoServiceExists(JTAPersistenceContextManager.class.getName());
+      BundleContextMock.assertNoServiceExists(QuiesceParticipant.class.getName());
+    }
+    
+    @Test
     public void testRegister() throws Exception {
         sut.registerContext("name", client, new HashMap<String, Object>());
         sut.registerContext("otherName", otherClient, new HashMap<String, Object>());



Mime
View raw message