1 16 17 package org.springframework.orm.ibatis; 18 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.io.InputStreamReader ; 22 import java.util.Properties ; 23 24 import javax.sql.DataSource ; 25 26 import com.ibatis.sqlmap.client.SqlMapClient; 27 import com.ibatis.sqlmap.client.SqlMapClientBuilder; 28 import com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient; 29 import com.ibatis.sqlmap.engine.transaction.TransactionConfig; 30 import com.ibatis.sqlmap.engine.transaction.TransactionManager; 31 import com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig; 32 33 import org.springframework.beans.factory.FactoryBean; 34 import org.springframework.beans.factory.InitializingBean; 35 import org.springframework.core.io.Resource; 36 import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; 37 import org.springframework.jdbc.support.lob.LobHandler; 38 import org.springframework.util.ClassUtils; 39 40 67 public class SqlMapClientFactoryBean implements FactoryBean, InitializingBean { 68 69 private final static boolean buildSqlMapClientWithInputStreamMethodAvailable = 72 ClassUtils.hasMethod(SqlMapClientBuilder.class, "buildSqlMapClient", 73 new Class [] {InputStream .class}); 74 75 private final static boolean buildSqlMapClientWithInputStreamAndPropertiesMethodAvailable = 78 ClassUtils.hasMethod(SqlMapClientBuilder.class, "buildSqlMapClient", 79 new Class [] {InputStream .class, Properties .class}); 80 81 82 private static final ThreadLocal configTimeLobHandlerHolder = new ThreadLocal (); 83 84 95 public static LobHandler getConfigTimeLobHandler() { 96 return (LobHandler) configTimeLobHandlerHolder.get(); 97 } 98 99 100 private Resource configLocation; 101 102 private Properties sqlMapClientProperties; 103 104 private DataSource dataSource; 105 106 private boolean useTransactionAwareDataSource = true; 107 108 private Class transactionConfigClass = ExternalTransactionConfig.class; 109 110 private Properties transactionConfigProperties; 111 112 private LobHandler lobHandler; 113 114 private SqlMapClient sqlMapClient; 115 116 117 public SqlMapClientFactoryBean() { 118 this.transactionConfigProperties = new Properties (); 119 this.transactionConfigProperties.setProperty("SetAutoCommitAllowed", "false"); 120 } 121 122 126 public void setConfigLocation(Resource configLocation) { 127 this.configLocation = configLocation; 128 } 129 130 137 public void setSqlMapClientProperties(Properties sqlMapClientProperties) { 138 this.sqlMapClientProperties = sqlMapClientProperties; 139 } 140 141 160 public void setDataSource(DataSource dataSource) { 161 this.dataSource = dataSource; 162 } 163 164 185 public void setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource) { 186 this.useTransactionAwareDataSource = useTransactionAwareDataSource; 187 } 188 189 222 public void setTransactionConfigClass(Class transactionConfigClass) { 223 if (transactionConfigClass == null || !TransactionConfig.class.isAssignableFrom(transactionConfigClass)) { 224 throw new IllegalArgumentException ("Invalid transactionConfigClass: does not implement " + 225 "com.ibatis.sqlmap.engine.transaction.TransactionConfig"); 226 } 227 this.transactionConfigClass = transactionConfigClass; 228 } 229 230 250 public void setTransactionConfigProperties(Properties transactionConfigProperties) { 251 this.transactionConfigProperties = transactionConfigProperties; 252 } 253 254 263 public void setLobHandler(LobHandler lobHandler) { 264 this.lobHandler = lobHandler; 265 } 266 267 268 public void afterPropertiesSet() throws Exception { 269 if (this.configLocation == null) { 270 throw new IllegalArgumentException ("configLocation is required"); 271 } 272 273 if (this.lobHandler != null) { 274 configTimeLobHandlerHolder.set(this.lobHandler); 277 } 278 279 try { 280 this.sqlMapClient = buildSqlMapClient(this.configLocation, this.sqlMapClientProperties); 281 282 if (this.dataSource != null) { 284 TransactionConfig transactionConfig = (TransactionConfig) this.transactionConfigClass.newInstance(); 285 DataSource dataSourceToUse = this.dataSource; 286 if (this.useTransactionAwareDataSource && !(this.dataSource instanceof TransactionAwareDataSourceProxy)) { 287 dataSourceToUse = new TransactionAwareDataSourceProxy(this.dataSource); 288 } 289 transactionConfig.setDataSource(dataSourceToUse); 290 transactionConfig.initialize(this.transactionConfigProperties); 291 applyTransactionConfig(this.sqlMapClient, transactionConfig); 292 } 293 } 294 295 finally { 296 if (this.lobHandler != null) { 297 configTimeLobHandlerHolder.set(null); 299 } 300 } 301 } 302 303 314 protected SqlMapClient buildSqlMapClient(Resource configLocation, Properties properties) throws IOException { 315 InputStream is = configLocation.getInputStream(); 316 if (properties != null) { 317 if (buildSqlMapClientWithInputStreamAndPropertiesMethodAvailable) { 318 return SqlMapClientBuilder.buildSqlMapClient(is, properties); 319 } 320 else { 321 return SqlMapClientBuilder.buildSqlMapClient(new InputStreamReader (is), properties); 322 } 323 } 324 else { 325 if (buildSqlMapClientWithInputStreamMethodAvailable) { 326 return SqlMapClientBuilder.buildSqlMapClient(is); 327 } 328 else { 329 return SqlMapClientBuilder.buildSqlMapClient(new InputStreamReader (is)); 330 } 331 } 332 } 333 334 345 protected void applyTransactionConfig(SqlMapClient sqlMapClient, TransactionConfig transactionConfig) { 346 if (!(this.sqlMapClient instanceof ExtendedSqlMapClient)) { 347 throw new IllegalArgumentException ( 348 "Cannot set TransactionConfig with DataSource for SqlMapClient if not of type " + 349 "ExtendedSqlMapClient: " + this.sqlMapClient); 350 } 351 ExtendedSqlMapClient extendedClient = (ExtendedSqlMapClient) this.sqlMapClient; 352 transactionConfig.setMaximumConcurrentTransactions(extendedClient.getDelegate().getMaxTransactions()); 353 extendedClient.getDelegate().setTxManager(new TransactionManager(transactionConfig)); 354 } 355 356 357 public Object getObject() { 358 return this.sqlMapClient; 359 } 360 361 public Class getObjectType() { 362 return (this.sqlMapClient != null ? this.sqlMapClient.getClass() : SqlMapClient.class); 363 } 364 365 public boolean isSingleton() { 366 return true; 367 } 368 369 } 370 | Popular Tags |