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 org.apache.commons.logging.Log;
020: import org.apache.commons.logging.LogFactory;
021: import org.springframework.dao.*;
022: import org.springframework.jdbc.BadSqlGrammarException;
023: import org.springframework.util.Assert;
024:
025: import java.sql.*;
026:
027: /**
028: * {@link org.springframework.jdbc.support.SQLExceptionTranslator} implementation that analyzes the {@link java.sql.SQLException}
029: * subclass that was returned. This is only available with JDBC 4.0 and later drivers when using Java 6 or later.
030: *
031: * @author Thomas Risberg
032: * @since 2.5
033: * @see java.sql.SQLException
034: */
035: public class SQLExceptionSubclassTranslator implements
036: SQLExceptionTranslator {
037:
038: /** Logger available to subclasses */
039: protected final Log logger = LogFactory.getLog(getClass());
040:
041: public DataAccessException translate(String task, String sql,
042: SQLException ex) {
043: Assert.notNull(ex, "Cannot translate a null SQLException.");
044: if (task == null) {
045: task = "";
046: }
047: if (sql == null) {
048: sql = "";
049: }
050: if (ex instanceof SQLTransientException) {
051: if (ex instanceof SQLTransactionRollbackException) {
052: return new ConcurrencyFailureException(buildMessage(
053: task, sql, ex), ex);
054: }
055: if (ex instanceof SQLTransientConnectionException) {
056: return new TransientDataAccessResourceException(
057: buildMessage(task, sql, ex), ex);
058: }
059: if (ex instanceof SQLTimeoutException) {
060: return new TransientDataAccessResourceException(
061: buildMessage(task, sql, ex), ex);
062: }
063: } else if (ex instanceof SQLNonTransientException) {
064: if (ex instanceof SQLDataException) {
065: return new DataIntegrityViolationException(
066: buildMessage(task, sql, ex), ex);
067: } else if (ex instanceof SQLFeatureNotSupportedException) {
068: return new BadSqlGrammarException(task, sql, ex);
069: } else if (ex instanceof SQLIntegrityConstraintViolationException) {
070: return new DataIntegrityViolationException(
071: buildMessage(task, sql, ex), ex);
072: } else if (ex instanceof SQLInvalidAuthorizationSpecException) {
073: return new PermissionDeniedDataAccessException(
074: buildMessage(task, sql, ex), ex);
075: } else if (ex instanceof SQLNonTransientConnectionException) {
076: return new DataAccessResourceFailureException(
077: buildMessage(task, sql, ex), ex);
078: } else if (ex instanceof SQLSyntaxErrorException) {
079: return new BadSqlGrammarException(task, sql, ex);
080: }
081: } else if (ex instanceof SQLRecoverableException) {
082: return new RecoverableDataAccessException(buildMessage(
083: task, sql, ex), ex);
084: }
085: // We couldn't identify it more precisely - let's allow other translation strategies to kick in.
086: return null;
087: }
088:
089: /**
090: * Build a message <code>String</code> for the given {@link java.sql.SQLException}.
091: * <p>Called when creating an instance of a generic
092: * {@link org.springframework.dao.DataAccessException} class.
093: * @param task readable text describing the task being attempted
094: * @param sql the SQL statement that caused the problem. May be <code>null</code>.
095: * @param ex the offending <code>SQLException</code>
096: * @return the message <code>String</code> to use
097: */
098: protected String buildMessage(String task, String sql,
099: SQLException ex) {
100: return task + "; SQL [" + sql + "]; " + ex.getMessage();
101: }
102:
103: }
|