1 /*
2 * Copyright 2002-2012 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.springframework.jdbc.support;
18
19 import javax.sql.DataSource;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23
24 import org.springframework.beans.factory.InitializingBean;
25
26 /**
27 * Base class for {@link org.springframework.jdbc.core.JdbcTemplate} and
28 * other JDBC-accessing DAO helpers, defining common properties such as
29 * DataSource and exception translator.
30 *
31 * <p>Not intended to be used directly.
32 * See {@link org.springframework.jdbc.core.JdbcTemplate}.
33 *
34 * @author Juergen Hoeller
35 * @since 28.11.2003
36 * @see org.springframework.jdbc.core.JdbcTemplate
37 */
38 public abstract class JdbcAccessor implements InitializingBean {
39
40 /** Logger available to subclasses */
41 protected final Log logger = LogFactory.getLog(getClass());
42
43 private DataSource dataSource;
44
45 private SQLExceptionTranslator exceptionTranslator;
46
47 private boolean lazyInit = true;
48
49
50 /**
51 * Set the JDBC DataSource to obtain connections from.
52 */
53 public void setDataSource(DataSource dataSource) {
54 this.dataSource = dataSource;
55 }
56
57 /**
58 * Return the DataSource used by this template.
59 */
60 public DataSource getDataSource() {
61 return this.dataSource;
62 }
63
64 /**
65 * Specify the database product name for the DataSource that this accessor uses.
66 * This allows to initialize a SQLErrorCodeSQLExceptionTranslator without
67 * obtaining a Connection from the DataSource to get the metadata.
68 * @param dbName the database product name that identifies the error codes entry
69 * @see SQLErrorCodeSQLExceptionTranslator#setDatabaseProductName
70 * @see java.sql.DatabaseMetaData#getDatabaseProductName()
71 */
72 public void setDatabaseProductName(String dbName) {
73 this.exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dbName);
74 }
75
76 /**
77 * Set the exception translator for this instance.
78 * <p>If no custom translator is provided, a default
79 * {@link SQLErrorCodeSQLExceptionTranslator} is used
80 * which examines the SQLException's vendor-specific error code.
81 * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator
82 * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator
83 */
84 public void setExceptionTranslator(SQLExceptionTranslator exceptionTranslator) {
85 this.exceptionTranslator = exceptionTranslator;
86 }
87
88 /**
89 * Return the exception translator for this instance.
90 * <p>Creates a default {@link SQLErrorCodeSQLExceptionTranslator}
91 * for the specified DataSource if none set, or a
92 * {@link SQLStateSQLExceptionTranslator} in case of no DataSource.
93 * @see #getDataSource()
94 */
95 public synchronized SQLExceptionTranslator getExceptionTranslator() {
96 if (this.exceptionTranslator == null) {
97 DataSource dataSource = getDataSource();
98 if (dataSource != null) {
99 this.exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);
100 }
101 else {
102 this.exceptionTranslator = new SQLStateSQLExceptionTranslator();
103 }
104 }
105 return this.exceptionTranslator;
106 }
107
108 /**
109 * Set whether to lazily initialize the SQLExceptionTranslator for this accessor,
110 * on first encounter of a SQLException. Default is "true"; can be switched to
111 * "false" for initialization on startup.
112 * <p>Early initialization just applies if {@code afterPropertiesSet()} is called.
113 * @see #getExceptionTranslator()
114 * @see #afterPropertiesSet()
115 */
116 public void setLazyInit(boolean lazyInit) {
117 this.lazyInit = lazyInit;
118 }
119
120 /**
121 * Return whether to lazily initialize the SQLExceptionTranslator for this accessor.
122 * @see #getExceptionTranslator()
123 */
124 public boolean isLazyInit() {
125 return this.lazyInit;
126 }
127
128 /**
129 * Eagerly initialize the exception translator, if demanded,
130 * creating a default one for the specified DataSource if none set.
131 */
132 @Override
133 public void afterPropertiesSet() {
134 if (getDataSource() == null) {
135 throw new IllegalArgumentException("Property 'dataSource' is required");
136 }
137 if (!isLazyInit()) {
138 getExceptionTranslator();
139 }
140 }
141
142 }