[ARIES-1374] EmSupplier is not unpublished when EntityManagerFactory is unpublished

git-svn-id: https://svn.apache.org/repos/asf/aries/trunk/jpa@1695124 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/jpa-support/src/main/java/org/apache/aries/jpa/support/osgi/impl/EMFTracker.java b/jpa-support/src/main/java/org/apache/aries/jpa/support/osgi/impl/EMFTracker.java
index a3435f6..0623383 100644
--- a/jpa-support/src/main/java/org/apache/aries/jpa/support/osgi/impl/EMFTracker.java
+++ b/jpa-support/src/main/java/org/apache/aries/jpa/support/osgi/impl/EMFTracker.java
@@ -61,23 +61,23 @@
         if (unitName == null) {
             return null;
         }
-        BundleContext bContext = reference.getBundle().getBundleContext();
+        BundleContext puContext = reference.getBundle().getBundleContext();
         TrackedEmf tracked = new TrackedEmf();
-        tracked.emf = (EntityManagerFactory)bContext.getService(reference);
+        tracked.emf = (EntityManagerFactory)puContext.getService(reference);
         tracked.emSupplier = new EMSupplierImpl(unitName, tracked.emf, coordinator);
-        tracked.emSupplierReg = bContext.registerService(EmSupplier.class, tracked.emSupplier,
+        tracked.emSupplierReg = puContext.registerService(EmSupplier.class, tracked.emSupplier,
                                                          getEmSupplierProps(unitName));
 
         EntityManager emProxy = createProxy(tracked.emSupplier);
-        tracked.emSupplierReg = bContext.registerService(EntityManager.class, emProxy,
+        tracked.emProxyReg = puContext.registerService(EntityManager.class, emProxy,
                                                          getEmSupplierProps(unitName));
         
         if (getTransactionType(tracked.emf) == PersistenceUnitTransactionType.RESOURCE_LOCAL) {
             JpaTemplate txManager = new ResourceLocalJpaTemplate(tracked.emSupplier, coordinator);
-            tracked.rlTxManagerReg = bContext.registerService(JpaTemplate.class, txManager,
+            tracked.rlTxManagerReg = puContext.registerService(JpaTemplate.class, txManager,
                                                           rlTxManProps(unitName));
         } else {
-            tracked.tmTracker = new TMTracker(bContext, tracked.emSupplier, unitName, coordinator);
+            tracked.tmTracker = new TMTracker(puContext, tracked.emSupplier, unitName, coordinator);
             tracked.tmTracker.open();
         }
         return tracked;
@@ -111,7 +111,6 @@
         return props;
     }
 
-    @SuppressWarnings("unchecked")
     @Override
     public void removedService(ServiceReference reference, Object trackedO) {
         TrackedEmf tracked = (TrackedEmf)trackedO;
@@ -121,9 +120,10 @@
         if (tracked.rlTxManagerReg != null) {
             tracked.rlTxManagerReg.unregister();
         }
-        tracked.emSupplier.close();
         tracked.emSupplierReg.unregister();
-        super.removedService(reference, tracked.emf);
+        tracked.emProxyReg.unregister();
+        tracked.emSupplier.close();
+        reference.getBundle().getBundleContext().ungetService(reference);
     }
     
     public static EntityManager createProxy(final EmSupplier emSupplier) {
diff --git a/jpa-support/src/test/java/org/apache/aries/jpa/support/osgi/impl/EmfTrackerTest.java b/jpa-support/src/test/java/org/apache/aries/jpa/support/osgi/impl/EmfTrackerTest.java
new file mode 100644
index 0000000..a951140
--- /dev/null
+++ b/jpa-support/src/test/java/org/apache/aries/jpa/support/osgi/impl/EmfTrackerTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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 WARRANTIESOR 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.support.osgi.impl;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.any;
+
+import java.util.Dictionary;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.spi.PersistenceUnitTransactionType;
+
+import org.apache.aries.jpa.support.osgi.impl.EMFTracker;
+import org.apache.aries.jpa.support.osgi.impl.EMFTracker.TrackedEmf;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.coordinator.Coordinator;
+import org.osgi.service.jpa.EntityManagerFactoryBuilder;
+
+public class EmfTrackerTest {
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testLifecycle() {
+        BundleContext context = mock(BundleContext.class);
+        Coordinator coordinator = mock(Coordinator.class);
+        EMFTracker tracker = new EMFTracker(context, coordinator);
+        ServiceReference<EntityManagerFactory> ref = mock(ServiceReference.class);
+        Mockito.when(ref.getProperty(EntityManagerFactoryBuilder.JPA_UNIT_NAME)).thenReturn("testunit");
+        Mockito.when(ref.getProperty(PersistenceUnitTransactionType.class.getName())).thenReturn("JTA");
+        
+        Bundle puBundle = mock(Bundle.class);
+        BundleContext puContext = mock(BundleContext.class);
+        when(puBundle.getBundleContext()).thenReturn(puContext);
+        when(ref.getBundle()).thenReturn(puBundle);
+        EntityManagerFactory emf = mock(EntityManagerFactory.class);
+        when(puContext.getService(ref)).thenReturn(emf);
+        ServiceRegistration<?> emSupplierReg = mock(ServiceRegistration.class, "emSupplierReg");
+        ServiceRegistration<?> emProxyReg = mock(ServiceRegistration.class, "emProxyReg");
+        when(puContext.registerService(any(Class.class), any(), any(Dictionary.class)))
+            .thenReturn(emSupplierReg, emProxyReg);
+
+        EMFTracker.TrackedEmf tracked = (TrackedEmf)tracker.addingService(ref);
+        Assert.assertEquals(emf, tracked.emf);
+        Assert.assertEquals(emSupplierReg, tracked.emSupplierReg);
+        Assert.assertEquals(emProxyReg, tracked.emProxyReg);
+        Assert.assertNotNull(tracked.tmTracker);
+        Assert.assertNull(tracked.rlTxManagerReg);
+        
+        tracker.removedService(ref, tracked);
+        verify(emSupplierReg, times(1)).unregister();
+        verify(emProxyReg, times(1)).unregister();
+        verify(puContext, times(1)).ungetService(ref);
+    }
+}