--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.jdbc.Util\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.jdbc;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.services.i18n.MessageService;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.services.io.StoredFormatIds;\r
+import org.apache.derby.iapi.types.TypeId;\r
+\r
+import org.apache.derby.iapi.error.ExceptionSeverity;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.reference.MessageId;\r
+import org.apache.derby.iapi.reference.JDBC30Translation;\r
+import org.apache.derby.iapi.reference.JDBC40Translation;\r
+\r
+import java.sql.SQLException;\r
+import java.sql.Types;\r
+import java.io.IOException;\r
+import java.io.PrintStream;\r
+import java.io.PrintWriter;\r
+\r
+/**\r
+ This class understands the message protocol and looks up\r
+ SQLExceptions based on keys, so that the Local JDBC driver's\r
+ messages can be localized.\r
+\r
+ REMIND: May want to investigate putting some of this in the protocol\r
+ side, for the errors that any Derby JDBC driver might return.\r
+\r
+ The ASSERT mechanism is a wrapper of the basic services,\r
+ to ensure that failed asserts at this level will behave\r
+ well in a JDBC environment.\r
+\r
+*/\r
+//In the past, this class was sent on the wire to the client and because it\r
+//has the message protcol stuff and also the detailed stack trace as one\r
+//of it's member variable, the client.jar files was really big. To get\r
+//around this problem, now we have added EmbedSQLException which is\r
+//just a java sql exception with the stack trace information variable\r
+//transient so it doesn't get transported to the client side and thus\r
+//reducing the size of client.jar The bug for this fix was 1850. The\r
+//p4 number for it will have the details of all the files impacted and\r
+//the actual changes made.\r
+public abstract class Util {\r
+\r
+\r
+ private static SQLExceptionFactory exceptionFactory = \r
+ new SQLExceptionFactory ();\r
+\r
+ /*\r
+ ** Methods of Throwable\r
+ */\r
+\r
+ // class implementation\r
+\r
+ /**\r
+ * This looks up the message and sqlstate values and calls\r
+ * the SQLExceptionFactory method to generate\r
+ * the appropriate exception off of them.\r
+ */\r
+\r
+ private static SQLException newEmbedSQLException(String messageId,\r
+ Object[] args, SQLException next, int severity, Throwable t) {\r
+ String message = MessageService.getCompleteMessage\r
+ (messageId, args);\r
+ return exceptionFactory.getSQLException (\r
+ message, messageId, next, severity, t, args);\r
+ }\r
+\r
+ public static SQLException newEmbedSQLException(String messageId,\r
+ Object[] args, int severity) {\r
+ return newEmbedSQLException(messageId, args, (SQLException) null, severity, (Throwable) null);\r
+ }\r
+\r
+ private static SQLException newEmbedSQLException(String messageId,\r
+ Object[] args, int severity, Throwable t) {\r
+ return newEmbedSQLException(messageId,args, (SQLException) null, severity, t);\r
+ }\r
+\r
+ private static SQLException newEmbedSQLException(\r
+ String messageId, int severity) {\r
+ return newEmbedSQLException(messageId, (Object[]) null, (SQLException) null, severity, (Throwable) null);\r
+ }\r
+\r
+ // class interface\r
+\r
+\r
+ /**\r
+ Mimic SanityManager.ASSERT in a JDBC-friendly way,\r
+ and providing system cleanup for JDBC failures.\r
+ We need the connection to do cleanup...\r
+\r
+ @exception SQLException the exception\r
+ */\r
+ public static void ASSERT(EmbedConnection conn, boolean mustBeTrue, String msg) throws SQLException {\r
+ if (SanityManager.DEBUG) {\r
+ try {\r
+ SanityManager.ASSERT(mustBeTrue, msg);\r
+ } catch (Throwable t) {\r
+ SQLException se = conn.handleException(t);\r
+ // get around typing constraints.\r
+ // it must be a Util, we wrapped it.\r
+ SanityManager.ASSERT(se instanceof EmbedSQLException);\r
+ throw (EmbedSQLException)se;\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ Mimic SanityManager.THROWASSERT in a JDBC-friendly way,\r
+ and providing system cleanup for JDBC failures.\r
+ We need the connection to do cleanup...\r
+ */\r
+ static void THROWASSERT(EmbedConnection conn, String msg) throws SQLException {\r
+ if (SanityManager.DEBUG) {\r
+ try {\r
+ SanityManager.THROWASSERT(msg);\r
+ } catch (Throwable t) {\r
+ SQLException se = conn.handleException(t);\r
+ // get around typing constraints.\r
+ // it must be a Util, we wrapped it.\r
+ SanityManager.ASSERT(se instanceof EmbedSQLException);\r
+ throw (EmbedSQLException)se;\r
+ }\r
+ }\r
+ }\r
+\r
+ /*\r
+ ** There is at least one static method for each message id.\r
+ ** Its parameters are specific to its message.\r
+ ** These will throw SQLException when the message repository\r
+ ** cannot be located.\r
+ ** Note that these methods call the static method newEmbedSQLException,\r
+ ** they don't directly do a new Util.\r
+ */\r
+\r
+ /* 3 arguments */\r
+ static SQLException newException(String messageID, Object a1,\r
+ Object a2, Object a3) {\r
+ return newEmbedSQLException(messageID, new Object[] {a1, a2, a3},\r
+ StandardException.getSeverityFromIdentifier(messageID));\r
+ }\r
+\r
+\r
+ public static SQLException generateCsSQLException(String error) {\r
+ return newEmbedSQLException(error,\r
+ StandardException.getSeverityFromIdentifier(error));\r
+ }\r
+\r
+ public static SQLException generateCsSQLException(String error, Object arg1) {\r
+ return newEmbedSQLException(error,\r
+ new Object[] {arg1},\r
+ StandardException.getSeverityFromIdentifier(error));\r
+ }\r
+\r
+ public static SQLException generateCsSQLException(\r
+ String error, Object arg1, Object arg2){\r
+ return newEmbedSQLException(error,\r
+ new Object[] {arg1, arg2},\r
+ StandardException.getSeverityFromIdentifier(error));\r
+ }\r
+\r
+ public static SQLException generateCsSQLException(\r
+ String error, Object arg1, Object arg2, Object arg3) {\r
+\r
+ return newEmbedSQLException(error,\r
+ new Object[] {arg1, arg2, arg3},\r
+ StandardException.getSeverityFromIdentifier(error));\r
+ }\r
+\r
+\r
+ static SQLException generateCsSQLException(\r
+ String error, Object arg1, Throwable t) {\r
+ return newEmbedSQLException(error,\r
+ new Object[] {arg1},\r
+ StandardException.getSeverityFromIdentifier(error), t);\r
+ }\r
+\r
+ public static SQLException generateCsSQLException(StandardException se) {\r
+ return exceptionFactory.getSQLException(\r
+ se.getMessage(), se.getMessageId(), (SQLException) null,\r
+ se.getSeverity(), se, se.getArguments());\r
+ }\r
+\r
+ public static SQLException noCurrentConnection() {\r
+ return newEmbedSQLException(SQLState.NO_CURRENT_CONNECTION,\r
+ StandardException.getSeverityFromIdentifier(SQLState.NO_CURRENT_CONNECTION));\r
+ }\r
+\r
+ /**\r
+ * Generate an <code>SQLException</code> which points to another\r
+ * <code>SQLException</code> nested within it with\r
+ * <code>setNextException()</code>.\r
+ *\r
+ * @param messageId message id\r
+ * @param args the arguments to the message creation\r
+ * @param next the next SQLException\r
+ * @return an SQLException wrapping another SQLException\r
+ */\r
+ static SQLException seeNextException(String messageId, Object[] args,\r
+ SQLException next) {\r
+ return newEmbedSQLException(messageId, args, next,\r
+ StandardException.getSeverityFromIdentifier(messageId), null);\r
+ }\r
+\r
+ public static SQLException javaException(Throwable t) {\r
+ String name, msg;\r
+\r
+ msg = t.getMessage();\r
+ if (msg == null) msg = "";\r
+ name = t.getClass().getName();\r
+ SQLException next = null;\r
+ Throwable cause = t.getCause();\r
+ if (cause != null) {\r
+ if (cause instanceof SQLException) {\r
+ next = (SQLException) cause;\r
+ } else if (cause instanceof StandardException) {\r
+ next = generateCsSQLException((StandardException) cause);\r
+ } else {\r
+ next = javaException(cause);\r
+ }\r
+ }\r
+ return newEmbedSQLException(SQLState.JAVA_EXCEPTION,\r
+ new Object[] {name, msg}, next,\r
+ ExceptionSeverity.NO_APPLICABLE_SEVERITY, t);\r
+ }\r
+\r
+\r
+ public static SQLException policyNotReloaded( Throwable t ) {\r
+ return newEmbedSQLException(SQLState.POLICY_NOT_RELOADED, new Object[] { t.getMessage() },\r
+ StandardException.getSeverityFromIdentifier(SQLState.POLICY_NOT_RELOADED), t);\r
+ }\r
+\r
+ public static SQLException notImplemented() {\r
+\r
+ return notImplemented( MessageService.getTextMessage(MessageId.CONN_NO_DETAILS) );\r
+ }\r
+\r
+ public static SQLException notImplemented(String feature) {\r
+\r
+ return newEmbedSQLException(SQLState.NOT_IMPLEMENTED,\r
+ new Object[] {feature},\r
+ StandardException.getSeverityFromIdentifier(SQLState.NOT_IMPLEMENTED));\r
+ }\r
+\r
+ static SQLException setStreamFailure(IOException e) {\r
+ String msg;\r
+\r
+ msg = e.getMessage();\r
+ if (msg == null) \r
+ msg = e.getClass().getName();\r
+ return newEmbedSQLException(SQLState.SET_STREAM_FAILURE,\r
+ new Object[] {msg},\r
+ StandardException.getSeverityFromIdentifier(SQLState.SET_STREAM_FAILURE));\r
+ }\r
+\r
+ static SQLException typeMisMatch(int targetSQLType) {\r
+ return newEmbedSQLException(SQLState.TYPE_MISMATCH,\r
+ new Object[] {typeName(targetSQLType)},\r
+ StandardException.getSeverityFromIdentifier(SQLState.TYPE_MISMATCH));\r
+ }\r
+\r
+ /**\r
+ * this method is called to replace the exception factory to be \r
+ * used to generate the SQLException or the subclass\r
+ */\r
+\r
+ public static void setExceptionFactory (SQLExceptionFactory factory) {\r
+ exceptionFactory = factory;\r
+ }\r
+\r
+ /**\r
+ * Get the exception factory specific to the version of JDBC which\r
+ * we are running.\r
+ */\r
+ public static SQLExceptionFactory getExceptionFactory() { return exceptionFactory; }\r
+\r
+ public static String typeName(int jdbcType) {\r
+ switch (jdbcType) {\r
+ case Types.ARRAY: return TypeId.ARRAY_NAME;\r
+ case Types.BIT : return TypeId.BIT_NAME;\r
+ case JDBC30Translation.SQL_TYPES_BOOLEAN : return TypeId.BOOLEAN_NAME;\r
+ case JDBC30Translation.DATALINK: return TypeId.DATALINK_NAME;\r
+ case Types.TINYINT : return TypeId.TINYINT_NAME;\r
+ case Types.SMALLINT : return TypeId.SMALLINT_NAME;\r
+ case Types.INTEGER : return TypeId.INTEGER_NAME;\r
+ case Types.BIGINT : return TypeId.LONGINT_NAME;\r
+\r
+ case Types.FLOAT : return TypeId.FLOAT_NAME;\r
+ case Types.REAL : return TypeId.REAL_NAME;\r
+ case Types.DOUBLE : return TypeId.DOUBLE_NAME;\r
+\r
+ case Types.NUMERIC : return TypeId.NUMERIC_NAME;\r
+ case Types.DECIMAL : return TypeId.DECIMAL_NAME;\r
+\r
+ case Types.CHAR : return TypeId.CHAR_NAME;\r
+ case Types.VARCHAR : return TypeId.VARCHAR_NAME;\r
+ case Types.LONGVARCHAR : return "LONGVARCHAR";\r
+ case Types.CLOB : return TypeId.CLOB_NAME;\r
+\r
+ case Types.DATE : return TypeId.DATE_NAME;\r
+ case Types.TIME : return TypeId.TIME_NAME;\r
+ case Types.TIMESTAMP : return TypeId.TIMESTAMP_NAME;\r
+\r
+ case Types.BINARY : return TypeId.BINARY_NAME;\r
+ case Types.VARBINARY : return TypeId.VARBINARY_NAME;\r
+ case Types.LONGVARBINARY : return TypeId.LONGVARBINARY_NAME;\r
+ case Types.BLOB : return TypeId.BLOB_NAME;\r
+\r
+ case Types.OTHER : return "OTHER";\r
+ case Types.JAVA_OBJECT : return "Types.JAVA_OBJECT";\r
+ case Types.REF : return TypeId.REF_NAME;\r
+ case JDBC40Translation.ROWID: return TypeId.ROWID_NAME;\r
+ case Types.STRUCT: return TypeId.STRUCT_NAME;\r
+ case StoredFormatIds.XML_TYPE_ID : return TypeId.XML_NAME;\r
+ case JDBC40Translation.SQLXML: return TypeId.SQLXML_NAME;\r
+ default : return String.valueOf(jdbcType);\r
+ }\r
+ }\r
+}\r