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