001: /*
002: * Copyright 2002-2007 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: * http://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:
017: package org.springframework.jdbc.support;
018:
019: import javax.sql.DataSource;
020:
021: import org.apache.commons.logging.Log;
022: import org.apache.commons.logging.LogFactory;
023:
024: import org.springframework.beans.factory.InitializingBean;
025:
026: /**
027: * Base class for {@link org.springframework.jdbc.core.JdbcTemplate} and
028: * other JDBC-accessing DAO helpers, defining common properties such as
029: * DataSource and exception translator.
030: *
031: * <p>Not intended to be used directly.
032: * See {@link org.springframework.jdbc.core.JdbcTemplate}.
033: *
034: * @author Juergen Hoeller
035: * @since 28.11.2003
036: * @see org.springframework.jdbc.core.JdbcTemplate
037: */
038: public abstract class JdbcAccessor implements InitializingBean {
039:
040: /** Logger available to subclasses */
041: protected final Log logger = LogFactory.getLog(getClass());
042:
043: private DataSource dataSource;
044:
045: private SQLExceptionTranslator exceptionTranslator;
046:
047: private boolean lazyInit = true;
048:
049: /**
050: * Set the JDBC DataSource to obtain connections from.
051: */
052: public void setDataSource(DataSource dataSource) {
053: this .dataSource = dataSource;
054: }
055:
056: /**
057: * Return the DataSource used by this template.
058: */
059: public DataSource getDataSource() {
060: return this .dataSource;
061: }
062:
063: /**
064: * Specify the database product name for the DataSource that this accessor uses.
065: * This allows to initialize a SQLErrorCodeSQLExceptionTranslator without
066: * obtaining a Connection from the DataSource to get the metadata.
067: * @param dbName the database product name that identifies the error codes entry
068: * @see SQLErrorCodeSQLExceptionTranslator#setDatabaseProductName
069: * @see java.sql.DatabaseMetaData#getDatabaseProductName()
070: */
071: public void setDatabaseProductName(String dbName) {
072: this .exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(
073: dbName);
074: }
075:
076: /**
077: * Set the exception translator for this instance.
078: * <p>If no custom translator is provided, a default
079: * {@link SQLErrorCodeSQLExceptionTranslator} is used
080: * which examines the SQLException's vendor-specific error code.
081: * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator
082: * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator
083: */
084: public void setExceptionTranslator(
085: SQLExceptionTranslator exceptionTranslator) {
086: this .exceptionTranslator = exceptionTranslator;
087: }
088:
089: /**
090: * Return the exception translator for this instance.
091: * <p>Creates a default {@link SQLErrorCodeSQLExceptionTranslator}
092: * for the specified DataSource if none set, or a
093: * {@link SQLStateSQLExceptionTranslator} in case of no DataSource.
094: * @see #getDataSource()
095: */
096: public synchronized SQLExceptionTranslator getExceptionTranslator() {
097: if (this .exceptionTranslator == null) {
098: DataSource dataSource = getDataSource();
099: if (dataSource != null) {
100: this .exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(
101: dataSource);
102: } else {
103: this .exceptionTranslator = new SQLStateSQLExceptionTranslator();
104: }
105: }
106: return this .exceptionTranslator;
107: }
108:
109: /**
110: * Set whether to lazily initialize the SQLExceptionTranslator for this accessor,
111: * on first encounter of a SQLException. Default is "true"; can be switched to
112: * "false" for initialization on startup.
113: * <p>Early initialization just applies if <code>afterPropertiesSet()</code> is called.
114: * @see #getExceptionTranslator()
115: * @see #afterPropertiesSet()
116: */
117: public void setLazyInit(boolean lazyInit) {
118: this .lazyInit = lazyInit;
119: }
120:
121: /**
122: * Return whether to lazily initialize the SQLExceptionTranslator for this accessor.
123: * @see #getExceptionTranslator()
124: */
125: public boolean isLazyInit() {
126: return this .lazyInit;
127: }
128:
129: /**
130: * Eagerly initialize the exception translator, if demanded,
131: * creating a default one for the specified DataSource if none set.
132: */
133: public void afterPropertiesSet() {
134: if (getDataSource() == null) {
135: throw new IllegalArgumentException(
136: "Property 'dataSource' is required");
137: }
138: if (!isLazyInit()) {
139: getExceptionTranslator();
140: }
141: }
142:
143: }
|