private void setupTransactionManager()

in tx-control-providers/jpa/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl.java [248:347]


	private void setupTransactionManager(BundleContext context, Map<String, Object> props, 
			ThreadLocal<TransactionControl> t, EntityManagerFactoryBuilder builder) {
		String provider = builder.getPersistenceProviderName();
		Bundle providerBundle = builder.getPersistenceProviderBundle();
		
		if(providerBundle == null) {
			LOGGER.warn("Unable to find a Persistence Provider for the provider named {}, so no XA plugin can be registered. XA transactions are unlikely to function properly.", provider);
			return;
		}
	
		Bundle txControlProviderBundle = context.getBundle();
		
		try {
			if("org.hibernate.jpa.HibernatePersistenceProvider".equals(provider)) {
				
				if(props.containsKey("hibernate.transaction.coordinator_class")) {
					LOGGER.warn("The JPA configuration properties already define a Hibernate transaction coordinator. This resource provider will not install its own plugin.");
					return;
				}
				
				String pluginClass;
				
				Bundle toUse = findSource(providerBundle, "org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder");
				
				if(toUse != null) {
					
					try {
						toUse.loadClass("org.hibernate.resource.transaction.spi.DdlTransactionIsolator");
						LOGGER.debug("Detected Hibernate 5.2.2 or above when attempting to install the XA plugin.");
						pluginClass = "org.apache.aries.tx.control.jpa.xa.plugin.hibernate.impl.Hibernate522TxControlPlatform";
					} catch (Exception e) {
						LOGGER.debug("Detected Hibernate 5.2.0 or 5.2.1 when attempting to install the XA plugin.");
						pluginClass = "org.apache.aries.tx.control.jpa.xa.plugin.hibernate.impl.Hibernate520TxControlPlatform";
					}
				} else {
					toUse = findSource(providerBundle, "org.hibernate.resource.transaction.TransactionCoordinatorBuilder");
					if(toUse != null) {
						LOGGER.debug("Detected Hibernate 5.0.x or 5.1.x or above when attempting to install the XA plugin.");
						pluginClass = "org.apache.aries.tx.control.jpa.xa.plugin.hibernate.impl.HibernateTxControlPlatform";
					} else {
						LOGGER.warn("Detected a Hibernate provider, but we were unable to load an appropriate XA plugin");
						return;
					}
				}
				
				ClassLoader pluginLoader = getPluginLoader(toUse, txControlProviderBundle);
				
				Class<?> pluginClazz = pluginLoader.loadClass(pluginClass);
				Object plugin = pluginClazz.getConstructor(ThreadLocal.class)
					.newInstance(t);
				
				props.put("hibernate.transaction.coordinator_class", plugin);
				
			} else if("org.apache.openjpa.persistence.PersistenceProviderImpl".equals(provider)) {
				
				if(props.containsKey("openjpa.ManagedRuntime")) {
					LOGGER.warn("The JPA configuration properties already define an OpenJPA transaction runtime. This resource provider will not install its own plugin.");
					return;
				}
				
				ClassLoader pluginLoader = getPluginLoader(providerBundle, txControlProviderBundle);
					
				Class<?> pluginClazz = pluginLoader.loadClass("org.apache.aries.tx.control.jpa.xa.plugin.openjpa.impl.OpenJPATxControlPlatform");
				Object plugin = pluginClazz.getConstructor(ThreadLocal.class)
						.newInstance(t);
					
				props.put("openjpa.ManagedRuntime", plugin);
				props.put("openjpa.ConnectionFactoryMode", "managed");
				props.put("openjpa.TransactionMode", "managed");
					
			} else if("org.eclipse.persistence.jpa.PersistenceProvider".equals(provider)) {
				
				if(props.containsKey("eclipselink.target-server")) {
					LOGGER.warn("The JPA configuration properties already define an EclipseLink transaction target. This resource provider will not install its own plugin.");
					return;
				}
				
				ClassLoader pluginLoader = getPluginLoader(providerBundle, txControlProviderBundle);
				
				Class<?> pluginClazz = pluginLoader.loadClass("org.apache.aries.tx.control.jpa.xa.plugin.eclipse.impl.EclipseTxControlPlatform");
				
				pluginClazz.getMethod("setTransactionControl", ThreadLocal.class)
						.invoke(null, t);
				
				props.put("eclipselink.target-server", pluginClazz.getName());
				props.put("org.apache.aries.jpa.eclipselink.plugin.types", pluginClazz);
				// This is needed to ensure that sequences can be generated in nested
				// transactions without blowing up.
				if(!props.containsKey("eclipselink.jdbc.sequence-connection-pool")) {
					props.put("eclipselink.jdbc.sequence-connection-pool", "true");
				}
				
			} else {
				LOGGER.warn("The persistence provider {} is not recognised, so no adapter plugin can be registered with it. XA transactions are unlikely to work properly", provider);
				return;
			} 
		} catch (Exception e) {
			LOGGER.error("There was a problem trying to install a transaction integration plugin for the JPA provider {}.", provider, e);
		}
	}