001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.jca.support; 018 019import javax.resource.ResourceException; 020import javax.resource.spi.BootstrapContext; 021import javax.resource.spi.ResourceAdapter; 022import javax.resource.spi.XATerminator; 023import javax.resource.spi.work.WorkManager; 024 025import org.springframework.beans.BeanUtils; 026import org.springframework.beans.factory.DisposableBean; 027import org.springframework.beans.factory.FactoryBean; 028import org.springframework.beans.factory.InitializingBean; 029 030/** 031 * {@link org.springframework.beans.factory.FactoryBean} that bootstraps 032 * the specified JCA 1.7 {@link javax.resource.spi.ResourceAdapter}, 033 * starting it with a local {@link javax.resource.spi.BootstrapContext} 034 * and exposing it for bean references. It will also stop the ResourceAdapter 035 * on context shutdown. This corresponds to 'non-managed' bootstrap in a 036 * local environment, according to the JCA 1.7 specification. 037 * 038 * <p>This is essentially an adapter for bean-style bootstrapping of a 039 * JCA ResourceAdapter, allowing the BootstrapContext or its elements 040 * (such as the JCA WorkManager) to be specified through bean properties. 041 * 042 * @author Juergen Hoeller 043 * @since 2.0.3 044 * @see #setResourceAdapter 045 * @see #setBootstrapContext 046 * @see #setWorkManager 047 * @see javax.resource.spi.ResourceAdapter#start(javax.resource.spi.BootstrapContext) 048 * @see javax.resource.spi.ResourceAdapter#stop() 049 */ 050public class ResourceAdapterFactoryBean implements FactoryBean<ResourceAdapter>, InitializingBean, DisposableBean { 051 052 private ResourceAdapter resourceAdapter; 053 054 private BootstrapContext bootstrapContext; 055 056 private WorkManager workManager; 057 058 private XATerminator xaTerminator; 059 060 061 /** 062 * Specify the target JCA ResourceAdapter as class, to be instantiated 063 * with its default configuration. 064 * <p>Alternatively, specify a pre-configured ResourceAdapter instance 065 * through the "resourceAdapter" property. 066 * @see #setResourceAdapter 067 */ 068 public void setResourceAdapterClass(Class<? extends ResourceAdapter> resourceAdapterClass) { 069 this.resourceAdapter = BeanUtils.instantiateClass(resourceAdapterClass); 070 } 071 072 /** 073 * Specify the target JCA ResourceAdapter, passed in as configured instance 074 * which hasn't been started yet. This will typically happen as an 075 * inner bean definition, configuring the ResourceAdapter instance 076 * through its vendor-specific bean properties. 077 */ 078 public void setResourceAdapter(ResourceAdapter resourceAdapter) { 079 this.resourceAdapter = resourceAdapter; 080 } 081 082 /** 083 * Specify the JCA BootstrapContext to use for starting the ResourceAdapter. 084 * <p>Alternatively, you can specify the individual parts (such as the 085 * JCA WorkManager) as individual references. 086 * @see #setWorkManager 087 * @see #setXaTerminator 088 */ 089 public void setBootstrapContext(BootstrapContext bootstrapContext) { 090 this.bootstrapContext = bootstrapContext; 091 } 092 093 /** 094 * Specify the JCA WorkManager to use for bootstrapping the ResourceAdapter. 095 * @see #setBootstrapContext 096 */ 097 public void setWorkManager(WorkManager workManager) { 098 this.workManager = workManager; 099 } 100 101 /** 102 * Specify the JCA XATerminator to use for bootstrapping the ResourceAdapter. 103 * @see #setBootstrapContext 104 */ 105 public void setXaTerminator(XATerminator xaTerminator) { 106 this.xaTerminator = xaTerminator; 107 } 108 109 110 /** 111 * Builds the BootstrapContext and starts the ResourceAdapter with it. 112 * @see javax.resource.spi.ResourceAdapter#start(javax.resource.spi.BootstrapContext) 113 */ 114 @Override 115 public void afterPropertiesSet() throws ResourceException { 116 if (this.resourceAdapter == null) { 117 throw new IllegalArgumentException("'resourceAdapter' or 'resourceAdapterClass' is required"); 118 } 119 if (this.bootstrapContext == null) { 120 this.bootstrapContext = new SimpleBootstrapContext(this.workManager, this.xaTerminator); 121 } 122 this.resourceAdapter.start(this.bootstrapContext); 123 } 124 125 126 @Override 127 public ResourceAdapter getObject() { 128 return this.resourceAdapter; 129 } 130 131 @Override 132 public Class<? extends ResourceAdapter> getObjectType() { 133 return (this.resourceAdapter != null ? this.resourceAdapter.getClass() : ResourceAdapter.class); 134 } 135 136 @Override 137 public boolean isSingleton() { 138 return true; 139 } 140 141 142 /** 143 * Stops the ResourceAdapter. 144 * @see javax.resource.spi.ResourceAdapter#stop() 145 */ 146 @Override 147 public void destroy() { 148 this.resourceAdapter.stop(); 149 } 150 151}