--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.iapi.error.StandardException\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.iapi.error;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import org.apache.derby.impl.jdbc.EmbedSQLException;\r
+import org.apache.derby.impl.jdbc.Util;\r
+import org.apache.derby.iapi.error.ExceptionSeverity;\r
+import org.apache.derby.iapi.services.i18n.MessageService;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import java.sql.SQLException;\r
+import java.sql.SQLWarning;\r
+\r
+/**\r
+ StandardException is the root of all exceptions that are handled\r
+ in a standard fashion by the database code, mainly in the language code.\r
+ <P>\r
+ This class is abstract to ensure that an implementation only throws\r
+ a specific exception (e.g. TransactionException) which is a sub-class\r
+ <P>\r
+ A method in an iterface in a protocol under com.ibm.db2j.protocol.Database must\r
+ only throw a StandardException (if it needs to throw an exception).\r
+ This indicates that the method can throw an exception and therefore its\r
+ caller must ensure that any resources it allocates will be cleaned up\r
+ in the event of an exception in the StandardException hierarchy.\r
+ <P>\r
+ Implementations of methods that throw StandardException can have throws\r
+ clause that are more specific than StandardException.\r
+*/\r
+\r
+public class StandardException extends Exception \r
+{\r
+ public static final int REPORT_DEFAULT = 0;\r
+ public static final int REPORT_NEVER = 1;\r
+ public static final int REPORT_ALWAYS = 2;\r
+\r
+ /*\r
+ * Exception State\r
+ */\r
+ private transient Object[] arguments;\r
+ private int severity;\r
+ private String textMessage;\r
+ private String sqlState;\r
+ private transient int report;\r
+\r
+ /*\r
+ ** End of constructors\r
+ */\r
+ \r
+ protected StandardException(String messageID)\r
+ {\r
+ this(messageID, (Throwable) null, (Object[]) null);\r
+\r
+ }\r
+\r
+ protected StandardException(String messageID, Object[] args)\r
+ {\r
+ this(messageID, (Throwable) null, args);\r
+ }\r
+\r
+ protected StandardException(String messageID, Throwable t, Object[] args)\r
+ {\r
+ super(messageID);\r
+\r
+ this.severity = getSeverityFromIdentifier(messageID);\r
+ this.sqlState = getSQLStateFromIdentifier(messageID);\r
+ this.arguments = args;\r
+ if (t != null) {\r
+ initCause(t);\r
+ }\r
+\r
+// if (SanityManager.DEBUG)\r
+// {\r
+// SanityManager.ASSERT(messageID != null,\r
+// "StandardException with no messageID");\r
+// }\r
+ }\r
+\r
+ /**\r
+ * This constructor is used when we already have the\r
+ * message text.\r
+ * \r
+ * @param sqlState the sql state of the message\r
+ * @param text the text of the message\r
+ */\r
+ private StandardException(String sqlState, String text)\r
+ {\r
+ this(sqlState);\r
+ textMessage = text;\r
+ }\r
+\r
+ /*\r
+ ** End of constructors\r
+ */\r
+ /**\r
+ * Sets the arguments for this exception.\r
+ */\r
+ private final void setArguments(Object[] arguments)\r
+ {\r
+ this.arguments = arguments;\r
+ }\r
+\r
+ /**\r
+ * Returns the arguments for this exception,\r
+ * if there are any.\r
+ */\r
+ public final Object[] getArguments()\r
+ {\r
+ return arguments;\r
+ }\r
+\r
+ /**\r
+ Yes, report me. Errors that need this method to return\r
+ false are in the minority.\r
+ */\r
+ public final int report() {\r
+ return report;\r
+ }\r
+\r
+ /**\r
+ Set my report type.\r
+ */\r
+ public final void setReport(int report) {\r
+ this.report = report;\r
+ }\r
+\r
+ public final void setSeverity(int severity) {\r
+ this.severity = severity;\r
+ }\r
+\r
+\r
+ public final int getSeverity() {\r
+ return severity;\r
+ }\r
+\r
+ public final int getErrorCode() {\r
+ return severity;\r
+ }\r
+\r
+ /**\r
+ Return the 5 character SQL State.\r
+ If you need teh identifier that was used to create the\r
+ message, then use getMessageId(). getMessageId() will return the\r
+ string that corresponds to the field in org.apache.derby.iapi.reference.SQLState.\r
+ */\r
+ public final String getSQLState()\r
+ {\r
+ return sqlState;\r
+ }\r
+\r
+ /**\r
+ Convert a message identifer from org.apache.derby.iapi.reference.SQLState to\r
+ a SQLState five character string.\r
+ * @param messageID - the sql state id of the message from Derby\r
+ * @return String - the 5 character code of the SQLState ID to returned to the user \r
+ */\r
+ public static String getSQLStateFromIdentifier(String messageID) {\r
+\r
+ if (messageID.length() == 5)\r
+ return messageID;\r
+ return messageID.substring(0, 5);\r
+ }\r
+\r
+ /**\r
+ Get the severity given a message identifier from org.apache.derby.iapi.reference.SQLState.\r
+ */\r
+ public static int getSeverityFromIdentifier(String messageID) {\r
+\r
+ int lseverity = ExceptionSeverity.NO_APPLICABLE_SEVERITY;\r
+\r
+ switch (messageID.length()) {\r
+ case 5:\r
+ switch (messageID.charAt(0)) {\r
+ case '0':\r
+ switch (messageID.charAt(1)) {\r
+ case '1':\r
+ lseverity = ExceptionSeverity.WARNING_SEVERITY;\r
+ break;\r
+ case 'A':\r
+ case '7':\r
+ lseverity = ExceptionSeverity.STATEMENT_SEVERITY;\r
+ break;\r
+ case '8':\r
+ lseverity = ExceptionSeverity.SESSION_SEVERITY;\r
+ break;\r
+ }\r
+ break; \r
+ case '2':\r
+ case '3':\r
+ lseverity = ExceptionSeverity.STATEMENT_SEVERITY;\r
+ break;\r
+ case '4':\r
+ switch (messageID.charAt(1)) {\r
+ case '0':\r
+ lseverity = ExceptionSeverity.TRANSACTION_SEVERITY;\r
+ break;\r
+ case '2':\r
+ lseverity = ExceptionSeverity.STATEMENT_SEVERITY;\r
+ break;\r
+ }\r
+ break; \r
+ }\r
+ break;\r
+\r
+ default:\r
+ switch (messageID.charAt(6)) {\r
+ case 'M':\r
+ lseverity = ExceptionSeverity.SYSTEM_SEVERITY;\r
+ break;\r
+ case 'D':\r
+ lseverity = ExceptionSeverity.DATABASE_SEVERITY;\r
+ break;\r
+ case 'C':\r
+ lseverity = ExceptionSeverity.SESSION_SEVERITY;\r
+ break;\r
+ case 'T':\r
+ lseverity = ExceptionSeverity.TRANSACTION_SEVERITY;\r
+ break;\r
+ case 'S':\r
+ lseverity = ExceptionSeverity.STATEMENT_SEVERITY;\r
+ break;\r
+ case 'U':\r
+ lseverity = ExceptionSeverity.NO_APPLICABLE_SEVERITY;\r
+ break;\r
+ }\r
+ break;\r
+ }\r
+\r
+ return lseverity;\r
+ }\r
+\r
+ /*\r
+ ** Set of static methods to obtain exceptions.\r
+ **\r
+ ** Possible parameters:\r
+ ** String sqlState - SQL State\r
+ ** int severity - Severity of message\r
+ ** Throwable t - exception to wrap\r
+ ** Object aN - argument to error message\r
+ **\r
+ ** Calls that can be made after the exception has been created.\r
+ **\r
+ ** setExceptionCategory()\r
+ ** setReport()\r
+ */\r
+\r
+ /* specific exceptions */\r
+\r
+ public static StandardException normalClose()\r
+ {\r
+ StandardException se = newException( SQLState.NORMAL_CLOSE );\r
+ se.report = REPORT_NEVER;\r
+ return se;\r
+ }\r
+\r
+ /* 0 arguments */\r
+\r
+ public static StandardException newException(String messageID) {\r
+ return new StandardException(messageID);\r
+ }\r
+ public static StandardException newException(String messageID, Throwable t) {\r
+ return new StandardException(messageID, t, (Object[]) null);\r
+ }\r
+\r
+ /* 1 argument */\r
+\r
+ public static StandardException newException(String messageID, Object a1) {\r
+ Object[] oa = new Object[] {a1};\r
+ return new StandardException(messageID, oa);\r
+ }\r
+ public static StandardException newException(String messageID, Throwable t, Object a1) {\r
+ Object[] oa = new Object[] {a1};\r
+ return new StandardException(messageID, t, oa);\r
+ }\r
+\r
+ /* 2 arguments */\r
+\r
+ public static StandardException newException(String messageID, Object a1, Object a2) {\r
+ Object[] oa = new Object[] {a1, a2};\r
+ return new StandardException(messageID, oa);\r
+ }\r
+\r
+ /**\r
+ * Dummy exception to catch incorrect use of\r
+ * StandardException.newException(), at compile-time. If you get a\r
+ * compilation error because this exception isn't caught, it means\r
+ * that you are using StandardException.newException(...)\r
+ * incorrectly. The nested exception should always be the second\r
+ * argument.\r
+ * @see StandardException#newException(String, Object, Throwable)\r
+ * @see StandardException#newException(String, Object, Object, Throwable)\r
+ */\r
+ public static class BadMessageArgumentException extends Throwable {}\r
+\r
+ /**\r
+ * Dummy overload which should never be called. Only used to\r
+ * detect incorrect usage, at compile time.\r
+ * @param messageID - the sql state id of the message\r
+ * @param a1 - Message arg\r
+ * @param t - Incorrectly placed exception to be nested\r
+ * @return nothing - always throws\r
+ * @throws BadMessageArgumentException - always (dummy)\r
+ */\r
+ public static StandardException newException(String messageID, \r
+ Object a1, \r
+ Throwable t) \r
+ throws BadMessageArgumentException {\r
+ throw new BadMessageArgumentException();\r
+ }\r
+\r
+ public static StandardException newException(String messageID, Throwable t, Object a1, Object a2) {\r
+ Object[] oa = new Object[] {a1, a2};\r
+ return new StandardException(messageID, t, oa);\r
+ }\r
+\r
+ /* 3 arguments */\r
+\r
+ public static StandardException newException(String messageID, Object a1, Object a2, Object a3) {\r
+ Object[] oa = new Object[] {a1, a2, a3};\r
+ return new StandardException(messageID, oa);\r
+ }\r
+ \r
+ /**\r
+ * Dummy overload which should never be called. Only used to\r
+ * detect incorrect usage, at compile time.\r
+ * @param messageID - the sql state id of the message\r
+ * @param a1 - First message arg\r
+ * @param a2 - Second message arg\r
+ * @param t - Incorrectly placed exception to be nested\r
+ * @return nothing - always throws\r
+ * @throws BadMessageArgumentException - always (dummy)\r
+ */\r
+ public static StandardException newException(String messageID, \r
+ Object a1, \r
+ Object a2,\r
+ Throwable t) \r
+ throws BadMessageArgumentException {\r
+ throw new BadMessageArgumentException(); \r
+ }\r
+\r
+ public static StandardException newException(String messageID, Throwable t, Object a1, Object a2, Object a3) {\r
+ Object[] oa = new Object[] {a1, a2, a3};\r
+ return new StandardException(messageID, t, oa);\r
+ }\r
+\r
+ /* 4 arguments */\r
+\r
+ public static StandardException newException(String messageID, Object a1, Object a2, Object a3, Object a4) {\r
+ Object[] oa = new Object[] {a1, a2, a3, a4};\r
+ return new StandardException(messageID, oa);\r
+ }\r
+ public static StandardException newException(String messageID, Throwable t, Object a1, Object a2, Object a3, Object a4) {\r
+ Object[] oa = new Object[] {a1, a2, a3, a4};\r
+ return new StandardException(messageID, t, oa);\r
+ }\r
+ \r
+ /* 5 arguments */\r
+ public static StandardException newException(String messageID, Object a1, Object a2, Object a3, Object a4, Object a5) {\r
+ Object[] oa = new Object[] {a1, a2, a3, a4, a5};\r
+ return new StandardException(messageID, oa);\r
+ }\r
+ public static StandardException newException(String messageID, Throwable t, Object a1, Object a2, Object a3, Object a4, Object a5) {\r
+ Object[] oa = new Object[] {a1, a2, a3, a4, a5};\r
+ return new StandardException(messageID, t, oa);\r
+ }\r
+\r
+ /* 6 arguments */\r
+ public static StandardException newException(String messageID, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) {\r
+ Object[] oa = new Object[] {a1, a2, a3, a4, a5, a6};\r
+ return new StandardException(messageID, oa);\r
+ }\r
+ public static StandardException newException(String messageID, Throwable t, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) {\r
+ Object[] oa = new Object[] {a1, a2, a3, a4, a5, a6};\r
+ return new StandardException(messageID, t, oa);\r
+ }\r
+\r
+ /* 7 arguments */\r
+ public static StandardException newException(String messageID, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) {\r
+ Object[] oa = new Object[] {a1, a2, a3, a4, a5, a6, a7};\r
+ return new StandardException(messageID, oa);\r
+ }\r
+ public static StandardException newException(String messageID, Throwable t, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) {\r
+ Object[] oa = new Object[] {a1, a2, a3, a4, a5, a6, a7};\r
+ return new StandardException(messageID, t, oa);\r
+ }\r
+\r
+ /* 8 arguments */\r
+ public static StandardException newException(String messageID, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) {\r
+ Object[] oa = new Object[] {a1, a2, a3, a4, a5, a6, a7, a8};\r
+ return new StandardException(messageID, oa);\r
+ }\r
+ public static StandardException newException(String messageID, Throwable t, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) {\r
+ Object[] oa = new Object[] {a1, a2, a3, a4, a5, a6, a7, a8};\r
+ return new StandardException(messageID, t, oa);\r
+ }\r
+\r
+ /**\r
+ * Creates a new StandardException using message text that has already been localized.\r
+ *\r
+ * @param MessageID The SQLState and severity are derived from the ID. However the text message is not.\r
+ * @param t The Throwable that caused this exception, null if this exception was not caused by another Throwable.\r
+ * @param localizedMessage The message associated with this exception.\r
+ * <b>It is the caller's responsibility to ensure that this message is properly localized.</b>\r
+ *\r
+ * See org.apache.derby.iapi.tools.i18n.LocalizedResource\r
+ */\r
+ public static StandardException newPreLocalizedException( String MessageID,\r
+ Throwable t,\r
+ String localizedMessage)\r
+ {\r
+ StandardException se = new StandardException( MessageID, localizedMessage);\r
+ if( t != null)\r
+ se.initCause(t);\r
+ return se;\r
+ }\r
+\r
+ public static StandardException unexpectedUserException(Throwable t)\r
+ {\r
+ // If the exception is an SQLException generated by Derby, it has an\r
+ // argument ferry which is an EmbedSQLException. Use this to check\r
+ // whether the exception was generated by Derby.\r
+ EmbedSQLException ferry = null;\r
+ if (t instanceof SQLException) {\r
+ SQLException sqle =\r
+ Util.getExceptionFactory().getArgumentFerry((SQLException) t);\r
+ if (sqle instanceof EmbedSQLException) {\r
+ ferry = (EmbedSQLException) sqle;\r
+ }\r
+ }\r
+\r
+ /*\r
+ ** If we have a SQLException that isn't an EmbedSQLException\r
+ ** (i.e. it didn't come from Derby), then we check\r
+ ** to see if it is a valid user defined exception range \r
+ ** (38001-38XXX). If so, then we convert it into a \r
+ ** StandardException without further ado.\r
+ */ \r
+ if ((t instanceof SQLException) && (ferry == null))\r
+ {\r
+ SQLException sqlex = (SQLException)t;\r
+ String state = sqlex.getSQLState();\r
+ if ((state != null) && \r
+ (state.length() == 5) &&\r
+ state.startsWith("38") &&\r
+ !state.equals("38000"))\r
+ {\r
+ StandardException se = new StandardException(state, sqlex.getMessage());\r
+ if (sqlex.getNextException() != null) \r
+ { \r
+ se.initCause(sqlex.getNextException());\r
+ }\r
+ return se;\r
+ }\r
+ }\r
+\r
+ // Look for simple wrappers for 3.0.1 - will be cleaned up in main\r
+ if (ferry != null) {\r
+ if (ferry.isSimpleWrapper()) {\r
+ Throwable wrapped = ferry.getCause();\r
+ if (wrapped instanceof StandardException)\r
+ return (StandardException) wrapped;\r
+ }\r
+ }\r
+\r
+\r
+ // no need to wrap a StandardException\r
+ if (t instanceof StandardException) \r
+ {\r
+ return (StandardException) t;\r
+ }\r
+ else\r
+ {\r
+ /*\r
+ ** \r
+ ** The exception at this point could be a:\r
+ **\r
+ ** standard java exception, e.g. NullPointerException\r
+ ** SQL Exception - from some server-side JDBC\r
+ ** 3rd party exception - from some application\r
+ ** some Derby exception that is not a standard exception.\r
+ ** \r
+ ** \r
+ ** We don't want to call t.toString() here, because the JVM is\r
+ ** inconsistent about whether it includes a detail message\r
+ ** with some exceptions (esp. NullPointerException). In those\r
+ ** cases where there is a detail message, t.toString() puts in\r
+ ** a colon character, even when the detail message is blank.\r
+ ** So, we do our own string formatting here, including the colon\r
+ ** only when there is a non-blank message.\r
+ **\r
+ ** The above is because our test canons contain the text of\r
+ ** error messages.\r
+ ** \r
+ ** In the past we didn't want to place the class name in\r
+ ** an exception because Cloudscape builds were\r
+ ** obfuscated, so the class name would change from build\r
+ ** to build. This is no longer true for Derby, but for\r
+ ** exceptions that are Derby's, i.e. EmbedSQLException,\r
+ ** we use toString(). If this returns an empty or null\r
+ ** then we use the class name to make tracking the \r
+ ** problem down easier, though the lack of a message \r
+ ** should be seen as a bug.\r
+ */\r
+ String detailMessage;\r
+ boolean derbyException = false;\r
+\r
+ if (ferry != null) {\r
+ detailMessage = ferry.toString();\r
+ derbyException = true;\r
+ }\r
+ else {\r
+ detailMessage = t.getMessage();\r
+ }\r
+\r
+ if (detailMessage == null)\r
+ {\r
+ detailMessage = "";\r
+ } else {\r
+ detailMessage = detailMessage.trim();\r
+ }\r
+\r
+ // if no message, use the class name\r
+ if (detailMessage.length() == 0) {\r
+ detailMessage = t.getClass().getName();\r
+ }\r
+ else {\r
+\r
+ if (!derbyException) {\r
+ detailMessage = t.getClass().getName() + ": " + detailMessage;\r
+ }\r
+ }\r
+\r
+ StandardException se =\r
+ newException(SQLState.LANG_UNEXPECTED_USER_EXCEPTION, t, detailMessage);\r
+ return se;\r
+ }\r
+ }\r
+\r
+ /**\r
+ Similar to unexpectedUserException but makes no assumtion about\r
+ when the execption is being called. The error is wrapped as simply\r
+ as possible.\r
+ */\r
+\r
+ public static StandardException plainWrapException(Throwable t) {\r
+\r
+ if (t instanceof StandardException)\r
+ return (StandardException) t;\r
+\r
+ if (t instanceof SQLException) {\r
+\r
+ SQLException sqle = (SQLException) t;\r
+\r
+ String sqlState = sqle.getSQLState();\r
+ if (sqlState != null) {\r
+\r
+ StandardException se = new StandardException(sqlState, "(" + sqle.getErrorCode() + ") " + sqle.getMessage());\r
+ sqle = sqle.getNextException();\r
+ if (sqle != null)\r
+ se.initCause(plainWrapException(sqle));\r
+ return se;\r
+ }\r
+ }\r
+\r
+ String detailMessage = t.getMessage();\r
+\r
+ if (detailMessage == null)\r
+ {\r
+ detailMessage = "";\r
+ } else {\r
+ detailMessage = detailMessage.trim();\r
+ }\r
+ \r
+ StandardException se =\r
+ newException(SQLState.JAVA_EXCEPTION, t, detailMessage, t.getClass().getName());\r
+ return se;\r
+ }\r
+\r
+ /**\r
+ ** A special exception to close a session.\r
+ */\r
+ public static StandardException closeException() {\r
+ StandardException se = newException(SQLState.CLOSE_REQUEST);\r
+ se.setReport(REPORT_NEVER);\r
+ return se;\r
+ }\r
+ /*\r
+ ** Message handling\r
+ */\r
+\r
+ /**\r
+ The message stored in the super class Throwable must be set\r
+ up object creation. At this time we cannot get any information\r
+ about the object itself (ie. this) in order to determine the\r
+ natural language message. Ie. we need to class of the objec in\r
+ order to look up its message, but we can't get the class of the\r
+ exception before calling the super class message.\r
+ <P>\r
+ Thus the message stored by Throwable and obtained by the\r
+ getMessage() of Throwable (ie. super.getMessage() in this\r
+ class) is the message identifier. The actual text message\r
+ is stored in this class at the first request.\r
+\r
+ */\r
+\r
+ public String getMessage() {\r
+ if (textMessage == null)\r
+ textMessage = MessageService.getCompleteMessage(getMessageId(), getArguments());\r
+\r
+ return textMessage;\r
+ }\r
+\r
+ /**\r
+ Return the message identifier that is used to look up the\r
+ error message text in the messages.properties file.\r
+ */\r
+ public final String getMessageId() {\r
+ return super.getMessage();\r
+ }\r
+\r
+\r
+ /**\r
+ Get the error code for an error given a type. The value of\r
+ the property messageId.type will be returned, e.g.\r
+ deadlock.sqlstate.\r
+ */\r
+ public String getErrorProperty(String type) {\r
+ return getErrorProperty(getMessageId(), type);\r
+ }\r
+\r
+ /**\r
+ Don't print the class name in the toString() method.\r
+ */\r
+ public String toString() {\r
+ String msg = getMessage();\r
+\r
+ return "ERROR " + getSQLState() + ": " + msg;\r
+ }\r
+\r
+ /*\r
+ ** Static methods\r
+ */\r
+\r
+ private static String getErrorProperty(String messageId, String type) {\r
+ return MessageService.getProperty(messageId, type);\r
+ }\r
+\r
+ public static StandardException interrupt(InterruptedException ie) {\r
+ StandardException se = StandardException.newException(SQLState.CONN_INTERRUPT, ie);\r
+ return se;\r
+ }\r
+ /*\r
+ ** SQL warnings\r
+ */\r
+\r
+ public static SQLWarning newWarning(String messageId) {\r
+\r
+ return newWarningCommon( messageId, (Object[]) null );\r
+\r
+ }\r
+\r
+ public static SQLWarning newWarning(String messageId, Object a1) {\r
+\r
+ Object[] oa = new Object[] {a1};\r
+\r
+ return newWarningCommon( messageId, oa );\r
+ }\r
+\r
+ public static SQLWarning newWarning(String messageId, Object a1, Object a2) {\r
+\r
+ Object[] oa = new Object[] {a1, a2};\r
+\r
+ return newWarningCommon( messageId, oa );\r
+ }\r
+\r
+ private static SQLWarning newWarningCommon( String messageId, Object[] oa )\r
+ {\r
+ String message = MessageService.getCompleteMessage(messageId, oa);\r
+ String state = StandardException.getSQLStateFromIdentifier(messageId);\r
+ SQLWarning sqlw = new SQLWarning(message, state, ExceptionSeverity.WARNING_SEVERITY);\r
+\r
+ return sqlw;\r
+ }\r
+}\r