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; 029import org.springframework.lang.Nullable; 030 031/** 032 * {@link org.springframework.beans.factory.FactoryBean} that bootstraps 033 * the specified JCA 1.7 {@link javax.resource.spi.ResourceAdapter}, 034 * starting it with a local {@link javax.resource.spi.BootstrapContext} 035 * and exposing it for bean references. It will also stop the ResourceAdapter 036 * on context shutdown. This corresponds to 'non-managed' bootstrap in a 037 * local environment, according to the JCA 1.7 specification. 038 * 039 * <p>This is essentially an adapter for bean-style bootstrapping of a 040 * JCA ResourceAdapter, allowing the BootstrapContext or its elements 041 * (such as the JCA WorkManager) to be specified through bean properties. 042 * 043 * @author Juergen Hoeller 044 * @since 2.0.3 045 * @see #setResourceAdapter 046 * @see #setBootstrapContext 047 * @see #setWorkManager 048 * @see javax.resource.spi.ResourceAdapter#start(javax.resource.spi.BootstrapContext) 049 * @see javax.resource.spi.ResourceAdapter#stop() 050 */ 051public class ResourceAdapterFactoryBean implements FactoryBean<ResourceAdapter>, InitializingBean, DisposableBean { 052 053 @Nullable 054 private ResourceAdapter resourceAdapter; 055 056 @Nullable 057 private BootstrapContext bootstrapContext; 058 059 @Nullable 060 private WorkManager workManager; 061 062 @Nullable 063 private XATerminator xaTerminator; 064 065 066 /** 067 * Specify the target JCA ResourceAdapter as class, to be instantiated 068 * with its default configuration. 069 * <p>Alternatively, specify a pre-configured ResourceAdapter instance 070 * through the "resourceAdapter" property. 071 * @see #setResourceAdapter 072 */ 073 public void setResourceAdapterClass(Class<? extends ResourceAdapter> resourceAdapterClass) { 074 this.resourceAdapter = BeanUtils.instantiateClass(resourceAdapterClass); 075 } 076 077 /** 078 * Specify the target JCA ResourceAdapter, passed in as configured instance 079 * which hasn't been started yet. This will typically happen as an 080 * inner bean definition, configuring the ResourceAdapter instance 081 * through its vendor-specific bean properties. 082 */ 083 public void setResourceAdapter(ResourceAdapter resourceAdapter) { 084 this.resourceAdapter = resourceAdapter; 085 } 086 087 /** 088 * Specify the JCA BootstrapContext to use for starting the ResourceAdapter. 089 * <p>Alternatively, you can specify the individual parts (such as the 090 * JCA WorkManager) as individual references. 091 * @see #setWorkManager 092 * @see #setXaTerminator 093 */ 094 public void setBootstrapContext(BootstrapContext bootstrapContext) { 095 this.bootstrapContext = bootstrapContext; 096 } 097 098 /** 099 * Specify the JCA WorkManager to use for bootstrapping the ResourceAdapter. 100 * @see #setBootstrapContext 101 */ 102 public void setWorkManager(WorkManager workManager) { 103 this.workManager = workManager; 104 } 105 106 /** 107 * Specify the JCA XATerminator to use for bootstrapping the ResourceAdapter. 108 * @see #setBootstrapContext 109 */ 110 public void setXaTerminator(XATerminator xaTerminator) { 111 this.xaTerminator = xaTerminator; 112 } 113 114 115 /** 116 * Builds the BootstrapContext and starts the ResourceAdapter with it. 117 * @see javax.resource.spi.ResourceAdapter#start(javax.resource.spi.BootstrapContext) 118 */ 119 @Override 120 public void afterPropertiesSet() throws ResourceException { 121 if (this.resourceAdapter == null) { 122 throw new IllegalArgumentException("'resourceAdapter' or 'resourceAdapterClass' is required"); 123 } 124 if (this.bootstrapContext == null) { 125 this.bootstrapContext = new SimpleBootstrapContext(this.workManager, this.xaTerminator); 126 } 127 this.resourceAdapter.start(this.bootstrapContext); 128 } 129 130 131 @Override 132 @Nullable 133 public ResourceAdapter getObject() { 134 return this.resourceAdapter; 135 } 136 137 @Override 138 public Class<? extends ResourceAdapter> getObjectType() { 139 return (this.resourceAdapter != null ? this.resourceAdapter.getClass() : ResourceAdapter.class); 140 } 141 142 @Override 143 public boolean isSingleton() { 144 return true; 145 } 146 147 148 /** 149 * Stops the ResourceAdapter. 150 * @see javax.resource.spi.ResourceAdapter#stop() 151 */ 152 @Override 153 public void destroy() { 154 if (this.resourceAdapter != null) { 155 this.resourceAdapter.stop(); 156 } 157 } 158 159}