001: package net.sourceforge.squirrel_sql.plugins.db2;
002:
003: /*
004: * Copyright (C) 2007 Christoph Schmitz
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020: import java.lang.reflect.Method;
021:
022: import net.sourceforge.squirrel_sql.fw.util.ExceptionFormatter;
023:
024: /**
025: * Formats an exception of the new DB2 JCC driver, where the human-readable
026: * error message needs to be obtained from a DB2SqlCa object.
027: *
028: * Invokes DB2 specific methods via reflection in order to avoid the need for
029: * the proprietary DB2 class files for compilation.
030: *
031: * @author Christoph Schmitz <schm4704@users.sourceforge.net>
032: */
033: public class DB2JCCExceptionFormatter implements ExceptionFormatter {
034:
035: /*
036: * As the JCC driver code is obfuscated, we do not check the full class
037: * name, but resort to checking a prefix and suffix instead.
038: *
039: * In my version, the full class name is "com.ibm.db2.jcc.c.SqlException"
040: */
041:
042: // Prefix for the JCC SqlException class name
043: private static final String JCC_EXCEPTION_PREFIX = "com.ibm.db2.jcc";
044:
045: // Class name for the JCC SqlException class
046: private static final String JCC_EXCEPTION_CLASS = "SqlException";
047:
048: // Names of the various methods we need to invoke
049: private static final String METHOD_GET_SQLCA = "getSqlca";
050:
051: private static final String METHOD_GET_SQL_STATE = "getSqlState";
052:
053: private static final String METHOD_GET_SQL_CODE = "getSqlCode";
054:
055: private static final String METHOD_GET_MESSAGE = "getMessage";
056:
057: /**
058: * Checks if this {@link Throwable} is a DB2 JCC SqlException
059: * (com.ibm.db2.jcc.*.SqlException) by testing for the proper prefix and
060: * suffix of the class name
061: *
062: * @see net.sourceforge.squirrel_sql.fw.util.ExceptionFormatter#formatsException(Throwable)
063: */
064: public boolean formatsException(Throwable t) {
065: if (t == null) {
066: return false;
067: } else {
068: String className = t.getClass().getName();
069: return className.startsWith(JCC_EXCEPTION_PREFIX)
070: && className.endsWith(JCC_EXCEPTION_CLASS);
071: }
072: }
073:
074: /**
075: * @see net.sourceforge.squirrel_sql.fw.util.ExceptionFormatter#format(Throwable)
076: */
077: public String format(Throwable t) throws Exception {
078: StringBuilder builder = new StringBuilder();
079: // DB2Sqlca sqlca = ((DB2Diagnosable) t).getSqlca();
080: Method getSqlca = t.getClass().getMethod(METHOD_GET_SQLCA,
081: (Class[]) null);
082: Object sqlca = getSqlca.invoke(t, (Object[]) null);
083:
084: // String msg = sqlca.getMessage();
085: Method getMessage = sqlca.getClass().getMethod(
086: METHOD_GET_MESSAGE, (Class[]) null);
087: String msg = getMessage.invoke(sqlca, (Object[]) null)
088: .toString();
089:
090: // int sqlCode = sqlca.getSqlCode();
091: Method getSqlCode = sqlca.getClass().getMethod(
092: METHOD_GET_SQL_CODE, (Class[]) null);
093: int sqlCode = (Integer) getSqlCode.invoke(sqlca,
094: (Object[]) null);
095:
096: // int sqlstate = sqlca.getSqlState();
097: Method getSqlState = sqlca.getClass().getMethod(
098: METHOD_GET_SQL_STATE, (Class[]) null);
099: String sqlState = getSqlState.invoke(sqlca, (Object[]) null)
100: .toString();
101:
102: builder.append(msg).append(" SQL Code: ").append(sqlCode)
103: .append(", SQL State: ").append(sqlState);
104: return builder.toString();
105: }
106: }
|