You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ti...@apache.org on 2016/10/10 14:47:30 UTC

svn commit: r1764111 - in /aries/trunk/tx-control: tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/ tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ tx-control-provider-jpa...

Author: timothyjward
Date: Mon Oct 10 14:47:30 2016
New Revision: 1764111

URL: http://svn.apache.org/viewvc?rev=1764111&view=rev
Log:
ARIES-1616 Further refactoring to remove duplicate code in the JPA resource providers

Added:
    aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractJPAManagedServiceFactory.java
      - copied, changed from r1764110, aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedServiceFactoryImpl.java
    aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractManagedJPADataSourceSetup.java
      - copied, changed from r1764110, aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPADataSourceSetup.java
    aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractManagedJPAEMFLocator.java
      - copied, changed from r1764110, aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedJPAEMFLocator.java
    aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPADataSourceSetup.java
    aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPAEMFLocator.java
    aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPAManagedServiceFactory.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPADataSourceSetup.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPAEMFLocator.java
      - copied, changed from r1764110, aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPAManagedServiceFactory.java
Removed:
    aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedJPADataSourceSetup.java
    aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedJPAEMFLocator.java
    aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedServiceFactoryImpl.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPADataSourceSetup.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedServiceFactoryImpl.java
Modified:
    aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/Activator.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/Activator.java

Copied: aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractJPAManagedServiceFactory.java (from r1764110, aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedServiceFactoryImpl.java)
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractJPAManagedServiceFactory.java?p2=aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractJPAManagedServiceFactory.java&p1=aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedServiceFactoryImpl.java&r1=1764110&r2=1764111&rev=1764111&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedServiceFactoryImpl.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractJPAManagedServiceFactory.java Mon Oct 10 14:47:30 2016
@@ -16,13 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.aries.tx.control.jpa.local.impl;
+package org.apache.aries.tx.control.jpa.common.impl;
 
 import static java.lang.Integer.MAX_VALUE;
 import static java.util.Arrays.asList;
 import static java.util.function.Function.identity;
 import static java.util.stream.Collectors.toMap;
-import static javax.persistence.spi.PersistenceUnitTransactionType.RESOURCE_LOCAL;
 import static org.osgi.service.jdbc.DataSourceFactory.JDBC_DATABASE_NAME;
 import static org.osgi.service.jdbc.DataSourceFactory.JDBC_DATASOURCE_NAME;
 import static org.osgi.service.jdbc.DataSourceFactory.JDBC_DESCRIPTION;
@@ -42,6 +41,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 
+import javax.persistence.spi.PersistenceUnitTransactionType;
+
 import org.apache.aries.tx.control.resource.common.impl.ConfigurationDefinedResourceFactory;
 import org.apache.aries.tx.control.resource.common.impl.LifecycleAware;
 import org.osgi.framework.BundleContext;
@@ -50,28 +51,23 @@ import org.osgi.service.cm.Configuration
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class ManagedServiceFactoryImpl extends ConfigurationDefinedResourceFactory {
+public abstract class AbstractJPAManagedServiceFactory extends ConfigurationDefinedResourceFactory {
 
-	static final Logger LOG = LoggerFactory.getLogger(ManagedServiceFactoryImpl.class);
+	private static final Logger LOG = LoggerFactory.getLogger(AbstractJPAManagedServiceFactory.class);
 	
-	static final String DSF_TARGET_FILTER = "aries.dsf.target.filter";
-	static final String EMF_BUILDER_TARGET_FILTER = "aries.emf.builder.target.filter";
-	static final String JDBC_PROP_NAMES = "aries.jdbc.property.names";
-	static final List<String> JDBC_PROPERTIES = asList(JDBC_DATABASE_NAME, JDBC_DATASOURCE_NAME,
+	public static final String DSF_TARGET_FILTER = "aries.dsf.target.filter";
+	public static final String EMF_BUILDER_TARGET_FILTER = "aries.emf.builder.target.filter";
+	public static final String JDBC_PROP_NAMES = "aries.jdbc.property.names";
+	public static final List<String> JDBC_PROPERTIES = asList(JDBC_DATABASE_NAME, JDBC_DATASOURCE_NAME,
 			JDBC_DESCRIPTION, JDBC_NETWORK_PROTOCOL, JDBC_PASSWORD, JDBC_PORT_NUMBER, JDBC_ROLE_NAME, JDBC_SERVER_NAME,
 			JDBC_URL, JDBC_USER);
-	static final String JPA_PROP_NAMES = "aries.jpa.property.names";
+	public static final String JPA_PROP_NAMES = "aries.jpa.property.names";
 
-	public ManagedServiceFactoryImpl(BundleContext context) {
+	public AbstractJPAManagedServiceFactory(BundleContext context) {
 		super(context);
 	}
 
 	@Override
-	public String getName() {
-		return "Aries JPAEntityManagerProvider (Local only) service";
-	}
-
-	@Override
 	protected LifecycleAware getConfigurationDrivenResource(BundleContext context, String pid,
 			Map<String, Object> properties) throws Exception {
 
@@ -82,13 +78,13 @@ public class ManagedServiceFactoryImpl e
 			LifecycleAware worker;
 			if(properties.containsKey(OSGI_JDBC_DRIVER_CLASS) ||
 					properties.containsKey(DSF_TARGET_FILTER)) {
-				worker = new ManagedJPADataSourceSetup(context, pid, jdbcProps, jpaProps, properties);
+				worker = dataSourceTracking(context, pid, properties, jdbcProps, jpaProps);
 			} else {
 				if(!jdbcProps.isEmpty()) {
 					LOG.warn("The configuration {} contains raw JDBC configuration, but no osgi.jdbc.driver.class or aries.dsf.target.filter properties. No DataSourceFactory will be used byt this bundle, so the JPA provider must be able to directly create the datasource, and these configuration properties will likely be ignored. {}",
 								pid, jdbcProps.stringPropertyNames());
 				}
-				worker = new ManagedJPAEMFLocator(context, pid, jpaProps, properties, null);
+				worker = emfTracking(context, pid, properties, jpaProps);
 			}
 			return worker;
 		} catch (InvalidSyntaxException e) {
@@ -97,6 +93,13 @@ public class ManagedServiceFactoryImpl e
 		}
 	}
 
+	protected abstract LifecycleAware dataSourceTracking(BundleContext context, String pid,
+			Map<String, Object> properties, Properties jdbcProps, Map<String, Object> jpaProps)
+			throws InvalidSyntaxException, ConfigurationException;
+
+	protected abstract LifecycleAware emfTracking(BundleContext context, String pid, Map<String, Object> properties,
+			Map<String, Object> jpaProps) throws InvalidSyntaxException, ConfigurationException;
+
 	@SuppressWarnings("unchecked")
 	private Properties getJdbcProps(String pid, Map<String, Object> properties) throws ConfigurationException {
 
@@ -143,11 +146,13 @@ public class ManagedServiceFactoryImpl e
 			.filter(propnames::contains)
 			.collect(toMap(identity(), properties::get));
 		
-		result.putIfAbsent("javax.persistence.transactionType", RESOURCE_LOCAL.name());
+		result.putIfAbsent("javax.persistence.transactionType", getTransactionType().name());
 		
 		return result;
 	}
 
+	protected abstract PersistenceUnitTransactionType getTransactionType();
+	
 	private static class AllCollection implements Collection<String> {
 
 		@Override

Copied: aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractManagedJPADataSourceSetup.java (from r1764110, aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPADataSourceSetup.java)
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractManagedJPADataSourceSetup.java?p2=aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractManagedJPADataSourceSetup.java&p1=aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPADataSourceSetup.java&r1=1764110&r2=1764111&rev=1764111&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPADataSourceSetup.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractManagedJPADataSourceSetup.java Mon Oct 10 14:47:30 2016
@@ -16,8 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.aries.tx.control.jpa.xa.impl;
+package org.apache.aries.tx.control.jpa.common.impl;
 
+import static java.util.Collections.unmodifiableMap;
 import static java.util.Optional.ofNullable;
 import static java.util.concurrent.TimeUnit.HOURS;
 import static java.util.concurrent.TimeUnit.SECONDS;
@@ -29,9 +30,7 @@ import static org.osgi.service.transacti
 import static org.osgi.service.transaction.control.jdbc.JDBCConnectionProviderFactory.IDLE_TIMEOUT;
 import static org.osgi.service.transaction.control.jdbc.JDBCConnectionProviderFactory.MAX_CONNECTIONS;
 import static org.osgi.service.transaction.control.jdbc.JDBCConnectionProviderFactory.MIN_CONNECTIONS;
-import static org.osgi.service.transaction.control.jdbc.JDBCConnectionProviderFactory.USE_DRIVER;
 
-import java.sql.SQLException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -41,24 +40,24 @@ import java.util.concurrent.atomic.Atomi
 
 import javax.sql.DataSource;
 
-import org.apache.aries.tx.control.jdbc.xa.connection.impl.XADataSourceMapper;
 import org.apache.aries.tx.control.resource.common.impl.LifecycleAware;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.cm.ConfigurationException;
 import org.osgi.service.jdbc.DataSourceFactory;
-import org.osgi.service.transaction.control.TransactionException;
 import org.osgi.util.tracker.ServiceTracker;
 import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.zaxxer.hikari.HikariConfig;
 import com.zaxxer.hikari.HikariDataSource;
 
-public class ManagedJPADataSourceSetup implements LifecycleAware,
-		ServiceTrackerCustomizer<DataSourceFactory, ManagedJPAEMFLocator> {
+public abstract class AbstractManagedJPADataSourceSetup implements LifecycleAware,
+		ServiceTrackerCustomizer<DataSourceFactory, AbstractManagedJPAEMFLocator> {
 
-	private static final String JAVAX_PERSISTENCE_NON_JTA_DATA_SOURCE = "javax.persistence.nonJtaDataSource";
+	private static final Logger LOG = LoggerFactory.getLogger(AbstractManagedJPADataSourceSetup.class);
 	
 	private final BundleContext context;
 	private final String pid;
@@ -66,10 +65,10 @@ public class ManagedJPADataSourceSetup i
 	private final Map<String, Object> baseJPAProperties;
 	private final Map<String, Object> providerProperties;
 	
-	private final ServiceTracker<DataSourceFactory, ManagedJPAEMFLocator> dsfTracker;
+	private final ServiceTracker<DataSourceFactory, AbstractManagedJPAEMFLocator> dsfTracker;
 	private final AtomicReference<ServiceReference<DataSourceFactory>> activeDsf = new AtomicReference<>();
 
-	public ManagedJPADataSourceSetup(BundleContext context, String pid, Properties jdbcProperties,
+	public AbstractManagedJPADataSourceSetup(BundleContext context, String pid, Properties jdbcProperties,
 			Map<String, Object> baseJPAProperties, Map<String, Object> providerProperties) throws InvalidSyntaxException, ConfigurationException {
 		this.context = context;
 		this.pid = pid;
@@ -77,11 +76,11 @@ public class ManagedJPADataSourceSetup i
 		this.baseJPAProperties = baseJPAProperties;
 		this.providerProperties = providerProperties;
 
-		String targetFilter = (String) providerProperties.get(ManagedServiceFactoryImpl.DSF_TARGET_FILTER);
+		String targetFilter = (String) providerProperties.get(AbstractJPAManagedServiceFactory.DSF_TARGET_FILTER);
 		if (targetFilter == null) {
 			String driver = (String) providerProperties.get(OSGI_JDBC_DRIVER_CLASS);
 			if (driver == null) {
-				ManagedServiceFactoryImpl.LOG.error("The configuration {} must specify a target filter or a JDBC driver class", pid);
+				LOG.error("The configuration {} must specify a target filter or a JDBC driver class", pid);
 				throw new ConfigurationException(OSGI_JDBC_DRIVER_CLASS,
 						"The configuration must specify either a target filter or a JDBC driver class");
 			}
@@ -102,20 +101,17 @@ public class ManagedJPADataSourceSetup i
 	}
 
 	@Override
-	public ManagedJPAEMFLocator addingService(ServiceReference<DataSourceFactory> reference) {
+	public AbstractManagedJPAEMFLocator addingService(ServiceReference<DataSourceFactory> reference) {
 		DataSourceFactory service = context.getService(reference);
-		ManagedJPAEMFLocator toReturn;
+		AbstractManagedJPAEMFLocator toReturn;
 		try {
-			toReturn = new ManagedJPAEMFLocator(context, pid, 
-					getJPAProperties(service), providerProperties, () -> {
-						Object o = providerProperties.get(JAVAX_PERSISTENCE_NON_JTA_DATA_SOURCE);
-						if (o instanceof HikariDataSource) {
-							((HikariDataSource)o).close();
-						}
-					});
+			Map<String, Object> jpaProps = decorateJPAProperties(service, 
+					unmodifiableMap(providerProperties), (Properties) jdbcProperties.clone(), 
+					new HashMap<>(baseJPAProperties));
+			toReturn = getManagedJPAEMFLocator(context, pid, jpaProps, providerProperties, 
+					() -> cleanupOnClose(jpaProps));
 		} catch (Exception e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+			LOG.error("An error occured creating the Resource provider for pid {}", pid, e);
 			return null;
 		}
 		updateService(reference, toReturn);
@@ -123,7 +119,16 @@ public class ManagedJPADataSourceSetup i
 		return toReturn;
 	}
 
-	private void updateService(ServiceReference<DataSourceFactory> reference, ManagedJPAEMFLocator locator) {
+	protected abstract Map<String, Object> decorateJPAProperties(DataSourceFactory dsf, 
+			Map<String, Object> providerProperties, Properties jdbcProperties,
+			Map<String, Object> jpaProperties) throws Exception;
+	
+	protected abstract void cleanupOnClose(Map<String, Object> jpaProperties);
+
+	protected abstract AbstractManagedJPAEMFLocator getManagedJPAEMFLocator(BundleContext context, String pid, 
+			Map<String, Object> jpaProps, Map<String, Object> providerProperties, Runnable onClose) throws Exception;
+
+	private void updateService(ServiceReference<DataSourceFactory> reference, AbstractManagedJPAEMFLocator locator) {
 		boolean setDsf;
 		synchronized (this) {
 			setDsf = activeDsf.compareAndSet(null, reference);
@@ -133,51 +138,30 @@ public class ManagedJPADataSourceSetup i
 				locator.start();
 			}
 		} catch (Exception e) {
-			ManagedServiceFactoryImpl.LOG.error("An error occurred when creating the connection provider for {}.", pid, e);
+			LOG.error("An error occurred when creating the connection provider for {}.", pid, e);
 			activeDsf.compareAndSet(reference, null);
 			throw new IllegalStateException("An error occurred when creating the connection provider", e);
 		}
 	}
 
-	private Map<String, Object> getJPAProperties(DataSourceFactory dsf) {
-		Map<String, Object> props = new HashMap<>(baseJPAProperties);
-		
-		DataSource unpooled;
-		try {
-			if (toBoolean(providerProperties, USE_DRIVER, false)) {
-				throw new TransactionException("The Database must use an XA connection");
-			} else {
-				unpooled = new XADataSourceMapper(dsf.createXADataSource(jdbcProperties));
-			}
-		} catch (SQLException sqle) {
-			throw new TransactionException("Unable to create the JDBC resource provider", sqle);
-		}
-
-		DataSource toUse = poolIfNecessary(providerProperties, unpooled);
-		
-		props.put("javax.persistence.jtaDataSource", toUse);
-		
-		return props;
-	}
-	
 	@Override
-	public void modifiedService(ServiceReference<DataSourceFactory> reference, ManagedJPAEMFLocator service) {
+	public void modifiedService(ServiceReference<DataSourceFactory> reference, AbstractManagedJPAEMFLocator service) {
 	}
 
 	@Override
-	public void removedService(ServiceReference<DataSourceFactory> reference, ManagedJPAEMFLocator service) {
+	public void removedService(ServiceReference<DataSourceFactory> reference, AbstractManagedJPAEMFLocator service) {
 		service.stop();
 
 		if (activeDsf.compareAndSet(reference, null)) {
-			Map<ServiceReference<DataSourceFactory>,ManagedJPAEMFLocator> tracked = dsfTracker.getTracked();
+			Map<ServiceReference<DataSourceFactory>,AbstractManagedJPAEMFLocator> tracked = dsfTracker.getTracked();
 			if (!tracked.isEmpty()) {
-				Entry<ServiceReference<DataSourceFactory>, ManagedJPAEMFLocator> e = tracked.entrySet().iterator().next();
+				Entry<ServiceReference<DataSourceFactory>, AbstractManagedJPAEMFLocator> e = tracked.entrySet().iterator().next();
 				updateService(e.getKey(), e.getValue());
 			}
 		}
 	}
 	
-	private DataSource poolIfNecessary(Map<String, Object> resourceProviderProperties, DataSource unpooled) {
+	protected DataSource poolIfNecessary(Map<String, Object> resourceProviderProperties, DataSource unpooled) {
 		DataSource toUse;
 
 		if (toBoolean(resourceProviderProperties, CONNECTION_POOLING_ENABLED, true)) {
@@ -201,7 +185,7 @@ public class ManagedJPADataSourceSetup i
 		return toUse;
 	}
 
-	private boolean toBoolean(Map<String, Object> props, String key, boolean defaultValue) {
+	protected boolean toBoolean(Map<String, Object> props, String key, boolean defaultValue) {
 		Object o =  ofNullable(props)
 			.map(m -> m.get(key))
 			.orElse(defaultValue);
@@ -215,7 +199,7 @@ public class ManagedJPADataSourceSetup i
 		}
 	}
 
-	private int toInt(Map<String, Object> props, String key, int defaultValue) {
+	protected int toInt(Map<String, Object> props, String key, int defaultValue) {
 		
 		Object o =  ofNullable(props)
 				.map(m -> m.get(key))

Copied: aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractManagedJPAEMFLocator.java (from r1764110, aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedJPAEMFLocator.java)
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractManagedJPAEMFLocator.java?p2=aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractManagedJPAEMFLocator.java&p1=aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedJPAEMFLocator.java&r1=1764110&r2=1764111&rev=1764111&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedJPAEMFLocator.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/AbstractManagedJPAEMFLocator.java Mon Oct 10 14:47:30 2016
@@ -16,9 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.aries.tx.control.jpa.local.impl;
+package org.apache.aries.tx.control.jpa.common.impl;
 
-import static org.apache.aries.tx.control.jpa.local.impl.ManagedServiceFactoryImpl.EMF_BUILDER_TARGET_FILTER;
+import static org.apache.aries.tx.control.jpa.common.impl.AbstractJPAManagedServiceFactory.EMF_BUILDER_TARGET_FILTER;
 import static org.osgi.framework.Constants.OBJECTCLASS;
 import static org.osgi.service.jdbc.DataSourceFactory.JDBC_PASSWORD;
 import static org.osgi.service.jpa.EntityManagerFactoryBuilder.JPA_UNIT_NAME;
@@ -39,10 +39,14 @@ import org.osgi.service.jpa.EntityManage
 import org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;
 import org.osgi.util.tracker.ServiceTracker;
 import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-public class ManagedJPAEMFLocator implements LifecycleAware,
+public abstract class AbstractManagedJPAEMFLocator implements LifecycleAware,
 	ServiceTrackerCustomizer<EntityManagerFactoryBuilder, EntityManagerFactoryBuilder> {
 
+	private static final Logger LOG = LoggerFactory.getLogger(AbstractJPAEntityManagerProvider.class);
+	
 	private final BundleContext context;
 	private final String pid;
 	private final Map<String, Object> jpaProperties;
@@ -55,7 +59,7 @@ public class ManagedJPAEMFLocator implem
 	
 	private final AtomicReference<ServiceRegistration<JPAEntityManagerProvider>> serviceReg = new AtomicReference<>();
 
-	public ManagedJPAEMFLocator(BundleContext context, String pid, Map<String, Object> jpaProperties,
+	public AbstractManagedJPAEMFLocator(BundleContext context, String pid, Map<String, Object> jpaProperties,
 			Map<String, Object> providerProperties, Runnable onClose) throws InvalidSyntaxException, ConfigurationException {
 		this.context = context;
 		this.pid = pid;
@@ -65,7 +69,7 @@ public class ManagedJPAEMFLocator implem
 
 		String unitName = (String) providerProperties.get(JPA_UNIT_NAME);
 		if (unitName == null) {
-			ManagedServiceFactoryImpl.LOG.error("The configuration {} must specify a persistence unit name", pid);
+			LOG.error("The configuration {} must specify a persistence unit name", pid);
 			throw new ConfigurationException(JPA_UNIT_NAME,
 					"The configuration must specify a persistence unit name");
 		}
@@ -92,11 +96,11 @@ public class ManagedJPAEMFLocator implem
 	public EntityManagerFactoryBuilder addingService(ServiceReference<EntityManagerFactoryBuilder> reference) {
 		EntityManagerFactoryBuilder service = context.getService(reference);
 
-		updateService(service);
+		updateService(reference, service);
 		return service;
 	}
 
-	private void updateService(EntityManagerFactoryBuilder service) {
+	private void updateService(ServiceReference<EntityManagerFactoryBuilder> reference, EntityManagerFactoryBuilder service) {
 		boolean setEMFB;
 		synchronized (this) {
 			setEMFB = activeEMFB.compareAndSet(null, service);
@@ -105,8 +109,7 @@ public class ManagedJPAEMFLocator implem
 		if (setEMFB) {
 			AbstractJPAEntityManagerProvider provider = null;
 			try {
-				provider = new JPAEntityManagerProviderFactoryImpl().getProviderFor(service,
-						jpaProperties, providerProperties, onClose);
+				provider = getResourceProvider(context, service, reference, jpaProperties, providerProperties, onClose);
 				providerObject.set(provider);
 				ServiceRegistration<JPAEntityManagerProvider> reg = context
 						.registerService(JPAEntityManagerProvider.class, provider, getServiceProperties());
@@ -114,7 +117,7 @@ public class ManagedJPAEMFLocator implem
 					throw new IllegalStateException("Unable to set the JDBC connection provider registration");
 				}
 			} catch (Exception e) {
-				ManagedServiceFactoryImpl.LOG.error("An error occurred when creating the connection provider for {}.", pid, e);
+				LOG.error("An error occurred when creating the resource provider for {}.", pid, e);
 				activeEMFB.compareAndSet(service, null);
 				if(provider != null) {
 					provider.close();
@@ -124,6 +127,10 @@ public class ManagedJPAEMFLocator implem
 		}
 	}
 
+	protected abstract AbstractJPAEntityManagerProvider getResourceProvider(BundleContext context, 
+			EntityManagerFactoryBuilder service, ServiceReference<EntityManagerFactoryBuilder> reference, 
+			Map<String, Object> jpaProperties, Map<String, Object> providerProperties, Runnable onClose);
+
 	private Dictionary<String, ?> getServiceProperties() {
 		Hashtable<String, Object> props = new Hashtable<>();
 		providerProperties.keySet().stream().filter(s -> !JDBC_PASSWORD.equals(s))
@@ -152,7 +159,7 @@ public class ManagedJPAEMFLocator implem
 			try {
 				oldReg.unregister();
 			} catch (IllegalStateException ise) {
-				ManagedServiceFactoryImpl.LOG.debug("An exception occurred when unregistering a service for {}", pid);
+				LOG.debug("An exception occurred when unregistering a service for {}", pid);
 			}
 		}
 		
@@ -160,20 +167,24 @@ public class ManagedJPAEMFLocator implem
 			try {
 				toClose.close();
 			} catch (Exception e) {
-				ManagedServiceFactoryImpl.LOG.debug("An Exception occured when closing the Resource provider for {}", pid, e);
+				LOG.debug("An Exception occured when closing the Resource provider for {}", pid, e);
 			}
 		}
 		
 		try {
 			context.ungetService(reference);
 		} catch (IllegalStateException ise) {
-			ManagedServiceFactoryImpl.LOG.debug("An exception occurred when ungetting the service for {}", reference);
+			LOG.debug("An exception occurred when ungetting the service for {}", reference);
 		}
 
 		if (emfbLeft) {
-			EntityManagerFactoryBuilder newEMFBuilder = emfBuilderTracker.getService();
-			if (newEMFBuilder != null) {
-				updateService(newEMFBuilder);
+			ServiceReference<EntityManagerFactoryBuilder> newEMFBuilderRef = emfBuilderTracker
+					.getServiceReference();
+			if (newEMFBuilderRef != null) {
+				EntityManagerFactoryBuilder newEMFBuilder = emfBuilderTracker.getService(newEMFBuilderRef);
+				if(newEMFBuilder != null) {
+					updateService(newEMFBuilderRef, newEMFBuilder);
+				}
 			}
 		}
 	}

Modified: aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/Activator.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/Activator.java?rev=1764111&r1=1764110&r2=1764111&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/Activator.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/Activator.java Mon Oct 10 14:47:30 2016
@@ -55,7 +55,7 @@ public class Activator extends JPAResour
 
 	@Override
 	protected ConfigurationDefinedResourceFactory getConfigurationDefinedResourceFactory(BundleContext context) {
-		return new ManagedServiceFactoryImpl(context);
+		return new LocalJPAManagedServiceFactory(context);
 	}
 
 	@Override

Added: aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPADataSourceSetup.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPADataSourceSetup.java?rev=1764111&view=auto
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPADataSourceSetup.java (added)
+++ aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPADataSourceSetup.java Mon Oct 10 14:47:30 2016
@@ -0,0 +1,86 @@
+/*
+ * 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.tx.control.jpa.local.impl;
+
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_URL;
+import static org.osgi.service.transaction.control.jdbc.JDBCConnectionProviderFactory.USE_DRIVER;
+
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.sql.DataSource;
+
+import org.apache.aries.tx.control.jpa.common.impl.AbstractManagedJPADataSourceSetup;
+import org.apache.aries.tx.control.jpa.common.impl.AbstractManagedJPAEMFLocator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.jdbc.DataSourceFactory;
+import org.osgi.service.transaction.control.TransactionException;
+
+import com.zaxxer.hikari.HikariDataSource;
+
+public class LocalJPADataSourceSetup extends AbstractManagedJPADataSourceSetup {
+
+	private static final String JAVAX_PERSISTENCE_NON_JTA_DATA_SOURCE = "javax.persistence.nonJtaDataSource";
+
+	public LocalJPADataSourceSetup(BundleContext context, String pid, Properties jdbcProperties,
+			Map<String, Object> baseJPAProperties, Map<String, Object> providerProperties) throws InvalidSyntaxException, ConfigurationException {
+		super(context, pid, jdbcProperties, baseJPAProperties, providerProperties);
+	}
+
+	@Override
+	protected Map<String, Object> decorateJPAProperties(DataSourceFactory dsf, 
+			Map<String, Object> providerProperties, Properties jdbcProperties, 
+			Map<String, Object> jpaProperties) {
+		DataSource unpooled;
+		try {
+			if (toBoolean(providerProperties, USE_DRIVER, false)) {
+				unpooled = new DriverDataSource(dsf.createDriver(null), jdbcProperties.getProperty(JDBC_URL),
+						jdbcProperties);
+			} else {
+				unpooled = dsf.createDataSource(jdbcProperties);
+			}
+		} catch (SQLException sqle) {
+			throw new TransactionException("Unable to create the JDBC resource provider", sqle);
+		}
+
+		DataSource toUse = poolIfNecessary(providerProperties, unpooled);
+		
+		jpaProperties.put(JAVAX_PERSISTENCE_NON_JTA_DATA_SOURCE, toUse);
+		
+		return jpaProperties;
+	}
+
+	@Override
+	protected void cleanupOnClose(Map<String, Object> jpaProperties) {
+		Object o = jpaProperties.get(JAVAX_PERSISTENCE_NON_JTA_DATA_SOURCE);
+		if (o instanceof HikariDataSource) {
+			((HikariDataSource)o).close();
+		}
+	}
+
+	@Override
+	protected AbstractManagedJPAEMFLocator getManagedJPAEMFLocator(BundleContext context, String pid,
+			Map<String, Object> jpaProps, Map<String, Object> providerProperties, Runnable onClose) 
+					throws InvalidSyntaxException, ConfigurationException {
+		return new LocalJPAEMFLocator(context, pid, jpaProps, providerProperties, onClose);
+	}
+}
\ No newline at end of file

Added: aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPAEMFLocator.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPAEMFLocator.java?rev=1764111&view=auto
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPAEMFLocator.java (added)
+++ aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPAEMFLocator.java Mon Oct 10 14:47:30 2016
@@ -0,0 +1,45 @@
+/*
+ * 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.tx.control.jpa.local.impl;
+
+import java.util.Map;
+
+import org.apache.aries.tx.control.jpa.common.impl.AbstractJPAEntityManagerProvider;
+import org.apache.aries.tx.control.jpa.common.impl.AbstractManagedJPAEMFLocator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.jpa.EntityManagerFactoryBuilder;
+
+public class LocalJPAEMFLocator extends AbstractManagedJPAEMFLocator {
+
+	public LocalJPAEMFLocator(BundleContext context, String pid, Map<String, Object> jpaProperties,
+			Map<String, Object> providerProperties, Runnable onClose) throws InvalidSyntaxException, ConfigurationException {
+		super(context, pid, jpaProperties, providerProperties, onClose);
+	}
+
+	@Override
+	protected AbstractJPAEntityManagerProvider getResourceProvider(BundleContext context,
+			EntityManagerFactoryBuilder service, ServiceReference<EntityManagerFactoryBuilder> reference,
+			Map<String, Object> jpaProperties, Map<String, Object> providerProperties, Runnable onClose) {
+		return new JPAEntityManagerProviderFactoryImpl().getProviderFor(service,
+				jpaProperties, providerProperties, onClose);
+	}
+}
\ No newline at end of file

Added: aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPAManagedServiceFactory.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPAManagedServiceFactory.java?rev=1764111&view=auto
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPAManagedServiceFactory.java (added)
+++ aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/LocalJPAManagedServiceFactory.java Mon Oct 10 14:47:30 2016
@@ -0,0 +1,61 @@
+/*
+ * 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.tx.control.jpa.local.impl;
+
+import java.util.Map;
+import java.util.Properties;
+
+import javax.persistence.spi.PersistenceUnitTransactionType;
+
+import org.apache.aries.tx.control.jpa.common.impl.AbstractJPAManagedServiceFactory;
+import org.apache.aries.tx.control.jpa.common.impl.AbstractManagedJPADataSourceSetup;
+import org.apache.aries.tx.control.jpa.common.impl.AbstractManagedJPAEMFLocator;
+import org.apache.aries.tx.control.resource.common.impl.LifecycleAware;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.ConfigurationException;
+
+public class LocalJPAManagedServiceFactory extends AbstractJPAManagedServiceFactory {
+
+	public LocalJPAManagedServiceFactory(BundleContext context) {
+		super(context);
+	}
+
+	@Override
+	public String getName() {
+		return "Aries JPAEntityManagerProvider (Local only) service";
+	}
+
+	@Override
+	protected AbstractManagedJPADataSourceSetup dataSourceTracking(BundleContext context, String pid, Map<String, Object> properties,
+			Properties jdbcProps, Map<String, Object> jpaProps) throws InvalidSyntaxException, ConfigurationException {
+		return new LocalJPADataSourceSetup(context, pid, jdbcProps, jpaProps, properties);
+	}
+
+	@Override
+	protected AbstractManagedJPAEMFLocator emfTracking(BundleContext context, String pid, Map<String, Object> properties,
+			Map<String, Object> jpaProps) throws InvalidSyntaxException, ConfigurationException {
+		return new LocalJPAEMFLocator(context, pid, jpaProps, properties, null);
+	}
+
+	@Override
+	protected PersistenceUnitTransactionType getTransactionType() {
+		return PersistenceUnitTransactionType.RESOURCE_LOCAL;
+	}
+}

Modified: aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/Activator.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/Activator.java?rev=1764111&r1=1764110&r2=1764111&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/Activator.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/Activator.java Mon Oct 10 14:47:30 2016
@@ -55,7 +55,7 @@ public class Activator extends JPAResour
 
 	@Override
 	protected ConfigurationDefinedResourceFactory getConfigurationDefinedResourceFactory(BundleContext context) {
-		return new ManagedServiceFactoryImpl(context);
+		return new XAJPAManagedServiceFactory(context);
 	}
 
 	@Override

Added: aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPADataSourceSetup.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPADataSourceSetup.java?rev=1764111&view=auto
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPADataSourceSetup.java (added)
+++ aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPADataSourceSetup.java Mon Oct 10 14:47:30 2016
@@ -0,0 +1,83 @@
+/*
+ * 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.tx.control.jpa.xa.impl;
+
+import static org.osgi.service.transaction.control.jdbc.JDBCConnectionProviderFactory.USE_DRIVER;
+
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.sql.DataSource;
+
+import org.apache.aries.tx.control.jdbc.xa.connection.impl.XADataSourceMapper;
+import org.apache.aries.tx.control.jpa.common.impl.AbstractManagedJPADataSourceSetup;
+import org.apache.aries.tx.control.jpa.common.impl.AbstractManagedJPAEMFLocator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.jdbc.DataSourceFactory;
+import org.osgi.service.transaction.control.TransactionException;
+
+import com.zaxxer.hikari.HikariDataSource;
+
+public class XAJPADataSourceSetup extends AbstractManagedJPADataSourceSetup {
+
+	private static final String JAVAX_PERSISTENCE_NON_JTA_DATA_SOURCE = "javax.persistence.nonJtaDataSource";
+	
+	public XAJPADataSourceSetup(BundleContext context, String pid, Properties jdbcProperties,
+			Map<String, Object> baseJPAProperties, Map<String, Object> providerProperties) throws InvalidSyntaxException, ConfigurationException {
+		super(context, pid, jdbcProperties, baseJPAProperties, providerProperties);
+	}
+
+	@Override
+	protected Map<String, Object> decorateJPAProperties(DataSourceFactory dsf, Map<String, Object> providerProperties,
+			Properties jdbcProperties, Map<String, Object> jpaProperties) throws Exception {
+		DataSource unpooled;
+		try {
+			if (toBoolean(providerProperties, USE_DRIVER, false)) {
+				throw new TransactionException("The Database must use an XA connection");
+			} else {
+				unpooled = new XADataSourceMapper(dsf.createXADataSource(jdbcProperties));
+			}
+		} catch (SQLException sqle) {
+			throw new TransactionException("Unable to create the JDBC resource provider", sqle);
+		}
+
+		DataSource toUse = poolIfNecessary(providerProperties, unpooled);
+		
+		jpaProperties.put("javax.persistence.jtaDataSource", toUse);
+		
+		return jpaProperties;
+	}
+
+	@Override
+	protected void cleanupOnClose(Map<String, Object> jpaProperties) {
+		Object o = jpaProperties.get(JAVAX_PERSISTENCE_NON_JTA_DATA_SOURCE);
+		if (o instanceof HikariDataSource) {
+			((HikariDataSource)o).close();
+		}
+	}
+
+	@Override
+	protected AbstractManagedJPAEMFLocator getManagedJPAEMFLocator(BundleContext context, String pid,
+			Map<String, Object> jpaProps, Map<String, Object> providerProperties, Runnable onClose) throws Exception {
+		return new XAJPAEMFLocator(context, pid, jpaProps, providerProperties, onClose);
+	}
+}
\ No newline at end of file

Copied: aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPAEMFLocator.java (from r1764110, aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java)
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPAEMFLocator.java?p2=aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPAEMFLocator.java&p1=aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java&r1=1764110&r2=1764111&rev=1764111&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPAEMFLocator.java Mon Oct 10 14:47:30 2016
@@ -18,137 +18,58 @@
  */
 package org.apache.aries.tx.control.jpa.xa.impl;
 
-import static org.apache.aries.tx.control.jpa.xa.impl.ManagedServiceFactoryImpl.EMF_BUILDER_TARGET_FILTER;
-import static org.osgi.framework.Constants.OBJECTCLASS;
-import static org.osgi.service.jdbc.DataSourceFactory.JDBC_PASSWORD;
-import static org.osgi.service.jpa.EntityManagerFactoryBuilder.JPA_UNIT_NAME;
 import static org.osgi.service.jpa.EntityManagerFactoryBuilder.JPA_UNIT_PROVIDER;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.Dictionary;
 import java.util.HashMap;
-import java.util.Hashtable;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicReference;
 
 import javax.persistence.spi.PersistenceProvider;
 
 import org.apache.aries.tx.control.jpa.common.impl.AbstractJPAEntityManagerProvider;
-import org.apache.aries.tx.control.resource.common.impl.LifecycleAware;
+import org.apache.aries.tx.control.jpa.common.impl.AbstractManagedJPAEMFLocator;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.wiring.BundleWire;
 import org.osgi.framework.wiring.BundleWiring;
 import org.osgi.service.cm.ConfigurationException;
 import org.osgi.service.jpa.EntityManagerFactoryBuilder;
 import org.osgi.service.transaction.control.TransactionControl;
-import org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-
-public class ManagedJPAEMFLocator implements LifecycleAware,
-	ServiceTrackerCustomizer<EntityManagerFactoryBuilder, EntityManagerFactoryBuilder> {
-
-	private final BundleContext context;
-	private final String pid;
-	private final Map<String, Object> jpaProperties;
-	private final Map<String, Object> providerProperties;
-	private final Runnable onClose;
-	private final ServiceTracker<EntityManagerFactoryBuilder, EntityManagerFactoryBuilder> emfBuilderTracker;
-
-	private final AtomicReference<EntityManagerFactoryBuilder> activeEMFB = new AtomicReference<>();
-	private final AtomicReference<AbstractJPAEntityManagerProvider> providerObject = new AtomicReference<>();
-	
-	private final AtomicReference<ServiceRegistration<JPAEntityManagerProvider>> serviceReg = new AtomicReference<>();
 
-	public ManagedJPAEMFLocator(BundleContext context, String pid, Map<String, Object> jpaProperties,
-			Map<String, Object> providerProperties, Runnable onClose) throws InvalidSyntaxException, ConfigurationException {
-		this.context = context;
-		this.pid = pid;
-		this.jpaProperties = jpaProperties;
-		this.providerProperties = providerProperties;
-		this.onClose = onClose;
-
-		String unitName = (String) providerProperties.get(JPA_UNIT_NAME);
-		if (unitName == null) {
-			ManagedServiceFactoryImpl.LOG.error("The configuration {} must specify a persistence unit name", pid);
-			throw new ConfigurationException(JPA_UNIT_NAME,
-					"The configuration must specify a persistence unit name");
-		}
-		
-		String targetFilter = (String) providerProperties.get(EMF_BUILDER_TARGET_FILTER);
-		if (targetFilter == null) {
-			targetFilter = "(" + JPA_UNIT_NAME + "=" + unitName + ")";
-		}
-
-		targetFilter = "(&(" + OBJECTCLASS + "=" + EntityManagerFactoryBuilder.class.getName() + ")" + targetFilter + ")";
-
-		this.emfBuilderTracker = new ServiceTracker<>(context, context.createFilter(targetFilter), this);
-	}
-
-	public void start() {
-		emfBuilderTracker.open();
-	}
+public class XAJPAEMFLocator extends AbstractManagedJPAEMFLocator {
 
-	public void stop() {
-		emfBuilderTracker.close();
+	public XAJPAEMFLocator(BundleContext context, String pid, Map<String, Object> jpaProperties,
+			Map<String, Object> providerProperties, Runnable onClose) throws InvalidSyntaxException, ConfigurationException {
+		super(context, pid, jpaProperties, providerProperties, onClose);
 	}
 
 	@Override
-	public EntityManagerFactoryBuilder addingService(ServiceReference<EntityManagerFactoryBuilder> reference) {
-		EntityManagerFactoryBuilder service = context.getService(reference);
-
-		updateService(reference, service);
-		return service;
-	}
-
-	private void updateService(ServiceReference<EntityManagerFactoryBuilder> reference, EntityManagerFactoryBuilder service) {
-		boolean setEMFB;
-		synchronized (this) {
-			setEMFB = activeEMFB.compareAndSet(null, service);
-		}
-
-		if (setEMFB) {
-			AbstractJPAEntityManagerProvider jpaEM = null;
-			try {
-				jpaEM = new DelayedJPAEntityManagerProvider(t -> {
-					
-					Map<String, Object> jpaProps = new HashMap<String, Object>(jpaProperties);
-					Map<String, Object> providerProps = new HashMap<String, Object>(providerProperties);
-					
-					setupTransactionManager(jpaProps, providerProps, t, reference);
-					
-					return new JPAEntityManagerProviderFactoryImpl().getProviderFor(service,
-							jpaProps, providerProps, t, onClose);
-				});
-				providerObject.set(jpaEM);
-				ServiceRegistration<JPAEntityManagerProvider> reg = context
-						.registerService(JPAEntityManagerProvider.class, jpaEM, getServiceProperties());
-				if (!serviceReg.compareAndSet(null, reg)) {
-					throw new IllegalStateException("Unable to set the JDBC connection provider registration");
-				}
-			} catch (Exception e) {
-				ManagedServiceFactoryImpl.LOG.error("An error occurred when creating the connection provider for {}.", pid, e);
-				activeEMFB.compareAndSet(service, null);
-				if(jpaEM != null) {
-					jpaEM.close();
-				}
-			}
-		}
+	protected AbstractJPAEntityManagerProvider getResourceProvider(BundleContext context,
+			EntityManagerFactoryBuilder service, ServiceReference<EntityManagerFactoryBuilder> reference,
+			Map<String, Object> jpaProperties, Map<String, Object> providerProperties, Runnable onClose) {
+		return new DelayedJPAEntityManagerProvider(t -> {
+			
+			Map<String, Object> jpaProps = new HashMap<String, Object>(jpaProperties);
+			Map<String, Object> providerProps = new HashMap<String, Object>(providerProperties);
+			
+			setupTransactionManager(context, jpaProps, providerProps, t, reference);
+			
+			return new JPAEntityManagerProviderFactoryImpl().getProviderFor(service,
+					jpaProps, providerProps, t, onClose);
+		});
 	}
 
-	private void setupTransactionManager(Map<String, Object> props, Map<String, Object> providerProps, 
-			ThreadLocal<TransactionControl> t, ServiceReference<EntityManagerFactoryBuilder> reference) {
+	private void setupTransactionManager(BundleContext context, Map<String, Object> props, 
+			Map<String, Object> providerProps, ThreadLocal<TransactionControl> t, ServiceReference<EntityManagerFactoryBuilder> reference) {
 		String provider = (String) reference.getProperty(JPA_UNIT_PROVIDER);
 		
-		ServiceReference<PersistenceProvider> providerRef = getPersistenceProvider(provider);
+		ServiceReference<PersistenceProvider> providerRef = getPersistenceProvider(provider, context);
 		
 		if(providerRef == null) {
 			// TODO log a warning and give up
@@ -245,7 +166,7 @@ public class ManagedJPAEMFLocator implem
 						}
 						byte[] clazzBytes = baos.toByteArray();
 						c = defineClass(name, clazzBytes, 0, clazzBytes.length, 
-								ManagedJPAEMFLocator.class.getProtectionDomain());
+								XAJPAEMFLocator.class.getProtectionDomain());
 						loaded.putIfAbsent(name, c);
 						return c;
 					} catch (IOException e) {
@@ -262,7 +183,7 @@ public class ManagedJPAEMFLocator implem
 		};
 	}
 
-	private ServiceReference<PersistenceProvider> getPersistenceProvider(String provider) {
+	private ServiceReference<PersistenceProvider> getPersistenceProvider(String provider, BundleContext context) {
 		if(provider == null) {
 			return null;
 		}
@@ -276,58 +197,4 @@ public class ManagedJPAEMFLocator implem
 			return null;
 		} 
 	}
-
-	private Dictionary<String, ?> getServiceProperties() {
-		Hashtable<String, Object> props = new Hashtable<>();
-		providerProperties.keySet().stream().filter(s -> !JDBC_PASSWORD.equals(s))
-				.forEach(s -> props.put(s, providerProperties.get(s)));
-		return props;
-	}
-
-	@Override
-	public void modifiedService(ServiceReference<EntityManagerFactoryBuilder> reference, EntityManagerFactoryBuilder service) {
-	}
-
-	@Override
-	public void removedService(ServiceReference<EntityManagerFactoryBuilder> reference, EntityManagerFactoryBuilder service) {
-		boolean emfbLeft;
-		ServiceRegistration<JPAEntityManagerProvider> oldReg = null;
-		AbstractJPAEntityManagerProvider toClose = null;
-		synchronized (this) {
-			emfbLeft = activeEMFB.compareAndSet(service, null);
-			if (emfbLeft) {
-				toClose = providerObject.get();
-				oldReg = serviceReg.getAndSet(null);
-			}
-		}
-
-		if (oldReg != null) {
-			try {
-				oldReg.unregister();
-			} catch (IllegalStateException ise) {
-				ManagedServiceFactoryImpl.LOG.debug("An exception occurred when unregistering a service for {}", pid);
-			}
-		}
-		
-		if(toClose != null) {
-			try {
-				toClose.close();
-			} catch (Exception e) {
-				ManagedServiceFactoryImpl.LOG.debug("An Exception occured when closing the Resource provider for {}", pid, e);
-			}
-		}
-		
-		try {
-			context.ungetService(reference);
-		} catch (IllegalStateException ise) {
-			ManagedServiceFactoryImpl.LOG.debug("An exception occurred when ungetting the service for {}", reference);
-		}
-
-		if (emfbLeft) {
-			EntityManagerFactoryBuilder newEMFBuilder = emfBuilderTracker.getService();
-			if (newEMFBuilder != null) {
-				updateService(reference, newEMFBuilder);
-			}
-		}
-	}
 }
\ No newline at end of file

Added: aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPAManagedServiceFactory.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPAManagedServiceFactory.java?rev=1764111&view=auto
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPAManagedServiceFactory.java (added)
+++ aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPAManagedServiceFactory.java Mon Oct 10 14:47:30 2016
@@ -0,0 +1,60 @@
+/*
+ * 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.tx.control.jpa.xa.impl;
+
+import java.util.Map;
+import java.util.Properties;
+
+import javax.persistence.spi.PersistenceUnitTransactionType;
+
+import org.apache.aries.tx.control.jpa.common.impl.AbstractJPAManagedServiceFactory;
+import org.apache.aries.tx.control.jpa.common.impl.AbstractManagedJPADataSourceSetup;
+import org.apache.aries.tx.control.jpa.common.impl.AbstractManagedJPAEMFLocator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.ConfigurationException;
+
+public class XAJPAManagedServiceFactory extends AbstractJPAManagedServiceFactory {
+
+	public XAJPAManagedServiceFactory(BundleContext context) {
+		super(context);
+	}
+
+	@Override
+	public String getName() {
+		return "Aries JPAEntityManagerProvider (XA only) service";
+	}
+
+	@Override
+	protected AbstractManagedJPADataSourceSetup dataSourceTracking(BundleContext context, String pid, Map<String, Object> properties,
+			Properties jdbcProps, Map<String, Object> jpaProps) throws InvalidSyntaxException, ConfigurationException {
+		return new XAJPADataSourceSetup(context, pid, jdbcProps, jpaProps, properties);
+	}
+
+	@Override
+	protected AbstractManagedJPAEMFLocator emfTracking(BundleContext context, String pid, Map<String, Object> properties,
+			Map<String, Object> jpaProps) throws InvalidSyntaxException, ConfigurationException {
+		return new XAJPAEMFLocator(context, pid, jpaProps, properties, null);
+	}
+
+	@Override
+	protected PersistenceUnitTransactionType getTransactionType() {
+		return PersistenceUnitTransactionType.JTA;
+	}
+}