001: //** Copyright Statement ***************************************************
002: //The Salmon Open Framework for Internet Applications (SOFIA)
003: //Copyright (C) 1999 - 2002, Salmon LLC
004: //
005: //This program is free software; you can redistribute it and/or
006: //modify it under the terms of the GNU General Public License version 2
007: //as published by the Free Software Foundation;
008: //
009: //This program is distributed in the hope that it will be useful,
010: //but WITHOUT ANY WARRANTY; without even the implied warranty of
011: //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: //GNU General Public License for more details.
013: //
014: //You should have received a copy of the GNU General Public License
015: //along with this program; if not, write to the Free Software
016: //Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: //
018: //For more information please visit http://www.salmonllc.com
019: //** End Copyright Statement ***************************************************
020: package com.salmonllc.sql;
021:
022: import java.lang.reflect.Method;
023:
024: /**
025: * Thin wrapper for DB2 "SqlException" and "DB2Sqlca", to make it look like a real Exception with
026: * a working getMessage() that presents the almost-human-readable string hidden in the Sqlca
027: * (what does "CA" stand for, anyway?) instead of the normal random garbage that you get from a DB2
028: * SQLException, like "SQLCode -321, SqlState 32891, SqlErrMc null".
029: * <p>Example usage:
030: * <pre>try {
031: * .....
032: * } catch (SQLException ex) {
033: * if (e.getClass().getName().equals("com.ibm.db2.jcc.c.SqlException")) {
034: * throw new DB2SalvageException(e);
035: * }
036: * throw new JspException(e.getMessage());
037: * }</pre>
038: * <p>
039: * This Exception has been rewritten to use dynamic loading (from class Class) so that it should work fine whether you
040: * have DB2 on your classpath or not; the DB2 drivers are definitely NOT needed to compile this (obviously, the SOFIA
041: * framework could not be allowed to require DB2 drivers in order to compile...).
042: * @author Ian Darwin.
043: */
044: public final class DB2SalvageException extends RuntimeException {
045: private static Class ibmSqlExceptionClass;
046: private static Class ibmSqlCaClass;
047: private static Method method_getMessage; // SqlException.getSqlca();
048: private static Method method_getSqlca; // DB2Sqlca.getMessage();
049: private Exception boringOldException;
050: private Object ibmSqlEx;
051: private Object ca;
052:
053: static {
054: try {
055: ibmSqlExceptionClass = Class
056: .forName("com.ibm.db2.jcc.c.SqlException");
057: ibmSqlCaClass = Class.forName("com.ibm.db2.jcc.DB2Sqlca");
058: method_getSqlca = ibmSqlExceptionClass.getMethod(
059: "getSqlca", new Class[0]);
060: method_getMessage = ibmSqlCaClass.getMethod("getMessage",
061: new Class[0]);
062: } catch (ClassNotFoundException e) {
063: // This nattering omitted for the benefit of those who don't have to put up with DB2 :-)
064: // System.err.println("IBM DB2 Driver Classes not on ClassPath");
065: } catch (SecurityException e) {
066: // "Can't Happen"
067: } catch (NoSuchMethodException e) {
068: System.err
069: .println("DB2SalvageException.<clinit>: Problem finding getMethod(): "
070: + e);
071: }
072: }
073:
074: /** Construct a DB2SalvageException around what is expected to be DB2 exception
075: * @param ex The SQLException you caught from the DB2 driver.
076: */
077: public DB2SalvageException(Exception ex) {
078: // this.ex = (SqlException)ex;
079: // ca = this.ex.getSqlca();
080:
081: if (ibmSqlExceptionClass == null) {
082: boringOldException = ex;
083: }
084:
085: if (!(ibmSqlExceptionClass.isAssignableFrom(ex.getClass()))) {
086: throw new IllegalArgumentException(
087: "Can only salvage a DB2 SqlException");
088: }
089: ibmSqlEx = ex;
090: try {
091: ca = method_getSqlca.invoke(ibmSqlEx, null);
092:
093: } catch (Exception e) {
094: System.err.println("Unable to invoke method: " + e);
095: }
096: }
097:
098: /** Present this Exception object as a String.
099: * @see java.lang.Object#toString()
100: */
101: public String toString() {
102: return "DB2SalvageException: " + getMessage();
103: }
104:
105: /** Get the almost-human-readable message contained in the nested DB2Sqlca object.
106: * @see java.lang.Throwable#getMessage()
107: */
108: public String getMessage() {
109: if (boringOldException != null) {
110: return boringOldException.getMessage();
111: }
112: try {
113: //return ca.getMessage();
114: String result = (String) method_getMessage.invoke(ca, null);
115: if (result == null) {
116: return ibmSqlEx.toString();
117: }
118: return result;
119: } catch (NullPointerException npe) {
120: return "The DB2 sqlca getMessage() threw a NPE; original was "
121: + ibmSqlEx.toString();
122: } catch (Exception e) {
123: return "The DB2 sqlca getMessage() threw " + e
124: + "; original was " + ibmSqlEx.toString();
125: }
126: }
127: }
|