001/*
002 * Copyright 2002-2016 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.jdbc.support;
018
019import org.springframework.util.StringUtils;
020
021/**
022 * JavaBean for holding JDBC error codes for a particular database.
023 * Instances of this class are normally loaded through a bean factory.
024 *
025 * <p>Used by Spring's {@link SQLErrorCodeSQLExceptionTranslator}.
026 * The file "sql-error-codes.xml" in this package contains default
027 * {@code SQLErrorCodes} instances for various databases.
028 *
029 * @author Thomas Risberg
030 * @author Juergen Hoeller
031 * @see SQLErrorCodesFactory
032 * @see SQLErrorCodeSQLExceptionTranslator
033 */
034public class SQLErrorCodes {
035
036        private String[] databaseProductNames;
037
038        private boolean useSqlStateForTranslation = false;
039
040        private String[] badSqlGrammarCodes = new String[0];
041
042        private String[] invalidResultSetAccessCodes = new String[0];
043
044        private String[] duplicateKeyCodes = new String[0];
045
046        private String[] dataIntegrityViolationCodes = new String[0];
047
048        private String[] permissionDeniedCodes = new String[0];
049
050        private String[] dataAccessResourceFailureCodes = new String[0];
051
052        private String[] transientDataAccessResourceCodes = new String[0];
053
054        private String[] cannotAcquireLockCodes = new String[0];
055
056        private String[] deadlockLoserCodes = new String[0];
057
058        private String[] cannotSerializeTransactionCodes = new String[0];
059
060        private CustomSQLErrorCodesTranslation[] customTranslations;
061
062        private SQLExceptionTranslator customSqlExceptionTranslator;
063
064
065        /**
066         * Set this property if the database name contains spaces,
067         * in which case we can not use the bean name for lookup.
068         */
069        public void setDatabaseProductName(String databaseProductName) {
070                this.databaseProductNames = new String[] {databaseProductName};
071        }
072
073        public String getDatabaseProductName() {
074                return (this.databaseProductNames != null && this.databaseProductNames.length > 0 ?
075                                this.databaseProductNames[0] : null);
076        }
077
078        /**
079         * Set this property to specify multiple database names that contains spaces,
080         * in which case we can not use bean names for lookup.
081         */
082        public void setDatabaseProductNames(String... databaseProductNames) {
083                this.databaseProductNames = databaseProductNames;
084        }
085
086        public String[] getDatabaseProductNames() {
087                return this.databaseProductNames;
088        }
089
090        /**
091         * Set this property to true for databases that do not provide an error code
092         * but that do provide SQL State (this includes PostgreSQL).
093         */
094        public void setUseSqlStateForTranslation(boolean useStateCodeForTranslation) {
095                this.useSqlStateForTranslation = useStateCodeForTranslation;
096        }
097
098        public boolean isUseSqlStateForTranslation() {
099                return this.useSqlStateForTranslation;
100        }
101
102        public void setBadSqlGrammarCodes(String... badSqlGrammarCodes) {
103                this.badSqlGrammarCodes = StringUtils.sortStringArray(badSqlGrammarCodes);
104        }
105
106        public String[] getBadSqlGrammarCodes() {
107                return this.badSqlGrammarCodes;
108        }
109
110        public void setInvalidResultSetAccessCodes(String... invalidResultSetAccessCodes) {
111                this.invalidResultSetAccessCodes = StringUtils.sortStringArray(invalidResultSetAccessCodes);
112        }
113
114        public String[] getInvalidResultSetAccessCodes() {
115                return this.invalidResultSetAccessCodes;
116        }
117
118        public String[] getDuplicateKeyCodes() {
119                return duplicateKeyCodes;
120        }
121
122        public void setDuplicateKeyCodes(String... duplicateKeyCodes) {
123                this.duplicateKeyCodes = duplicateKeyCodes;
124        }
125
126        public void setDataIntegrityViolationCodes(String... dataIntegrityViolationCodes) {
127                this.dataIntegrityViolationCodes = StringUtils.sortStringArray(dataIntegrityViolationCodes);
128        }
129
130        public String[] getDataIntegrityViolationCodes() {
131                return this.dataIntegrityViolationCodes;
132        }
133
134        public void setPermissionDeniedCodes(String... permissionDeniedCodes) {
135                this.permissionDeniedCodes = StringUtils.sortStringArray(permissionDeniedCodes);
136        }
137
138        public String[] getPermissionDeniedCodes() {
139                return this.permissionDeniedCodes;
140        }
141
142        public void setDataAccessResourceFailureCodes(String... dataAccessResourceFailureCodes) {
143                this.dataAccessResourceFailureCodes = StringUtils.sortStringArray(dataAccessResourceFailureCodes);
144        }
145
146        public String[] getDataAccessResourceFailureCodes() {
147                return this.dataAccessResourceFailureCodes;
148        }
149
150        public void setTransientDataAccessResourceCodes(String... transientDataAccessResourceCodes) {
151                this.transientDataAccessResourceCodes = StringUtils.sortStringArray(transientDataAccessResourceCodes);
152        }
153
154        public String[] getTransientDataAccessResourceCodes() {
155                return this.transientDataAccessResourceCodes;
156        }
157
158        public void setCannotAcquireLockCodes(String... cannotAcquireLockCodes) {
159                this.cannotAcquireLockCodes = StringUtils.sortStringArray(cannotAcquireLockCodes);
160        }
161
162        public String[] getCannotAcquireLockCodes() {
163                return this.cannotAcquireLockCodes;
164        }
165
166        public void setDeadlockLoserCodes(String... deadlockLoserCodes) {
167                this.deadlockLoserCodes = StringUtils.sortStringArray(deadlockLoserCodes);
168        }
169
170        public String[] getDeadlockLoserCodes() {
171                return this.deadlockLoserCodes;
172        }
173
174        public void setCannotSerializeTransactionCodes(String... cannotSerializeTransactionCodes) {
175                this.cannotSerializeTransactionCodes = StringUtils.sortStringArray(cannotSerializeTransactionCodes);
176        }
177
178        public String[] getCannotSerializeTransactionCodes() {
179                return this.cannotSerializeTransactionCodes;
180        }
181
182        public void setCustomTranslations(CustomSQLErrorCodesTranslation... customTranslations) {
183                this.customTranslations = customTranslations;
184        }
185
186        public CustomSQLErrorCodesTranslation[] getCustomTranslations() {
187                return this.customTranslations;
188        }
189
190        public void setCustomSqlExceptionTranslatorClass(Class<? extends SQLExceptionTranslator> customTranslatorClass) {
191                if (customTranslatorClass != null) {
192                        try {
193                                this.customSqlExceptionTranslator = customTranslatorClass.newInstance();
194                        }
195                        catch (Throwable ex) {
196                                throw new IllegalStateException("Unable to instantiate custom translator", ex);
197                        }
198                }
199                else {
200                        this.customSqlExceptionTranslator = null;
201                }
202        }
203
204        public void setCustomSqlExceptionTranslator(SQLExceptionTranslator customSqlExceptionTranslator) {
205                this.customSqlExceptionTranslator = customSqlExceptionTranslator;
206        }
207
208        public SQLExceptionTranslator getCustomSqlExceptionTranslator() {
209                return this.customSqlExceptionTranslator;
210        }
211
212}