001/* 002 * Copyright 2002-2018 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.cci.core.support; 018 019import javax.resource.cci.Connection; 020import javax.resource.cci.ConnectionFactory; 021import javax.resource.cci.ConnectionSpec; 022 023import org.springframework.dao.support.DaoSupport; 024import org.springframework.jca.cci.CannotGetCciConnectionException; 025import org.springframework.jca.cci.connection.ConnectionFactoryUtils; 026import org.springframework.jca.cci.core.CciTemplate; 027import org.springframework.lang.Nullable; 028import org.springframework.util.Assert; 029 030/** 031 * Convenient super class for CCI-based data access objects. 032 * 033 * <p>Requires a {@link javax.resource.cci.ConnectionFactory} to be set, 034 * providing a {@link org.springframework.jca.cci.core.CciTemplate} based 035 * on it to subclasses through the {@link #getCciTemplate()} method. 036 * 037 * <p>This base class is mainly intended for CciTemplate usage but can 038 * also be used when working with a Connection directly or when using 039 * {@code org.springframework.jca.cci.object} classes. 040 * 041 * @author Thierry Templier 042 * @author Juergen Hoeller 043 * @since 1.2 044 * @see #setConnectionFactory 045 * @see #getCciTemplate 046 * @see org.springframework.jca.cci.core.CciTemplate 047 */ 048public abstract class CciDaoSupport extends DaoSupport { 049 050 @Nullable 051 private CciTemplate cciTemplate; 052 053 054 /** 055 * Set the ConnectionFactory to be used by this DAO. 056 */ 057 public final void setConnectionFactory(ConnectionFactory connectionFactory) { 058 if (this.cciTemplate == null || connectionFactory != this.cciTemplate.getConnectionFactory()) { 059 this.cciTemplate = createCciTemplate(connectionFactory); 060 } 061 } 062 063 /** 064 * Create a CciTemplate for the given ConnectionFactory. 065 * Only invoked if populating the DAO with a ConnectionFactory reference! 066 * <p>Can be overridden in subclasses to provide a CciTemplate instance 067 * with different configuration, or a custom CciTemplate subclass. 068 * @param connectionFactory the CCI ConnectionFactory to create a CciTemplate for 069 * @return the new CciTemplate instance 070 * @see #setConnectionFactory(javax.resource.cci.ConnectionFactory) 071 */ 072 protected CciTemplate createCciTemplate(ConnectionFactory connectionFactory) { 073 return new CciTemplate(connectionFactory); 074 } 075 076 /** 077 * Return the ConnectionFactory used by this DAO. 078 */ 079 @Nullable 080 public final ConnectionFactory getConnectionFactory() { 081 return (this.cciTemplate != null ? this.cciTemplate.getConnectionFactory() : null); 082 } 083 084 /** 085 * Set the CciTemplate for this DAO explicitly, 086 * as an alternative to specifying a ConnectionFactory. 087 */ 088 public final void setCciTemplate(CciTemplate cciTemplate) { 089 this.cciTemplate = cciTemplate; 090 } 091 092 /** 093 * Return the CciTemplate for this DAO, 094 * pre-initialized with the ConnectionFactory or set explicitly. 095 */ 096 @Nullable 097 public final CciTemplate getCciTemplate() { 098 return this.cciTemplate; 099 } 100 101 @Override 102 protected final void checkDaoConfig() { 103 if (this.cciTemplate == null) { 104 throw new IllegalArgumentException("'connectionFactory' or 'cciTemplate' is required"); 105 } 106 } 107 108 109 /** 110 * Obtain a CciTemplate derived from the main template instance, 111 * inheriting the ConnectionFactory and other settings but 112 * overriding the ConnectionSpec used for obtaining Connections. 113 * @param connectionSpec the CCI ConnectionSpec that the returned 114 * template instance is supposed to obtain Connections for 115 * @return the derived template instance 116 * @see org.springframework.jca.cci.core.CciTemplate#getDerivedTemplate(javax.resource.cci.ConnectionSpec) 117 */ 118 protected final CciTemplate getCciTemplate(ConnectionSpec connectionSpec) { 119 CciTemplate cciTemplate = getCciTemplate(); 120 Assert.state(cciTemplate != null, "No CciTemplate set"); 121 return cciTemplate.getDerivedTemplate(connectionSpec); 122 } 123 124 /** 125 * Get a CCI Connection, either from the current transaction or a new one. 126 * @return the CCI Connection 127 * @throws org.springframework.jca.cci.CannotGetCciConnectionException 128 * if the attempt to get a Connection failed 129 * @see org.springframework.jca.cci.connection.ConnectionFactoryUtils#getConnection(javax.resource.cci.ConnectionFactory) 130 */ 131 protected final Connection getConnection() throws CannotGetCciConnectionException { 132 ConnectionFactory connectionFactory = getConnectionFactory(); 133 Assert.state(connectionFactory != null, "No ConnectionFactory set"); 134 return ConnectionFactoryUtils.getConnection(connectionFactory); 135 } 136 137 /** 138 * Close the given CCI Connection, created via this bean's ConnectionFactory, 139 * if it isn't bound to the thread. 140 * @param con the Connection to close 141 * @see org.springframework.jca.cci.connection.ConnectionFactoryUtils#releaseConnection 142 */ 143 protected final void releaseConnection(Connection con) { 144 ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory()); 145 } 146 147}