--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.drda.DRDAProtocolException\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
+/*\r
+\r
+/**\r
+ DRDAProtocolException is the root of all protocol exceptions that are \r
+ handled in a standard fashion by the DRDA AS.\r
+ If a protocol error message needs to send more than \r
+ SVRCOD, an ERRCD and CODPNT arg it should be subclassed\r
+\r
+*/\r
+\r
+package org.apache.derby.impl.drda;\r
+import java.util.Hashtable;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+class DRDAProtocolException extends Exception\r
+{\r
+ \r
+ /* Static values, used in constructor if there is no associated \r
+ Error Code or the codepoint argument.\r
+ */\r
+ \r
+ protected static final int NO_ASSOC_ERRCD = 0;\r
+ protected static final int NO_CODPNT_ARG = 0;\r
+\r
+ \r
+ private DRDAConnThread agent;\r
+\r
+ // request correlation id\r
+ private int correlationID;\r
+ \r
+ // correlation token\r
+ private byte[] crrtkn;\r
+\r
+ //Codepoint arg\r
+ private int codpntArg;\r
+\r
+ private DRDAProtocolExceptionInfo exceptionInfo;\r
+\r
+ // CodePoint of this error\r
+ private int errorCodePoint;\r
+ \r
+ // Severity Code\r
+ private int svrcod;\r
+ \r
+ // error code (e.g. SYNERRCD)\r
+ private int errcd;\r
+ \r
+ // messageid for logging errors.\r
+ private String messageid;\r
+\r
+ // database name\r
+ private String rdbnam;\r
+ \r
+ // database diagnostic information\r
+ private String srvdgn;\r
+\r
+ // message arguments\r
+ private Object [] messageArgs;\r
+ \r
+ // A verbose error message string, will be helpful\r
+ // when getMessage() is called on this Exception object\r
+ private String msg;\r
+ \r
+ private static Hashtable errorInfoTable;\r
+ \r
+ protected static String DRDA_Proto_CMDCHKRM= "DRDA_Proto_CMDCHKRM";\r
+ protected static String DRDA_Proto_CMDNSPRM= "DRDA_Proto_CMDNSPRM";\r
+ protected static String DRDA_Proto_DTAMCHRM= "DRDA_Proto_DTAMCHRM";\r
+\r
+ protected static String DRDA_Proto_OBJNSPRM = "DRDA_Proto_OBJNSPRM";\r
+ protected static String DRDA_Proto_PKGBNARM= "DRDA_Proto_PKGBNARM";\r
+ protected static String DRDA_Proto_PRCCNVRM= "DRDA_Proto_PRCCNVRM";\r
+ protected static String DRDA_Proto_PRMNSRM = "DRDA_Proto_PRMNSPRM";\r
+\r
+ protected static String DRDA_Proto_SYNTAXRM= "DRDA_Proto_SYNTAXRM";\r
+ protected static String DRDA_Proto_VALNSPRM= "DRDA_Proto_VALNSPRM";\r
+ protected static String DRDA_Proto_MGRLVLRM= "DRDA_Proto_MGRLVLRM";\r
+ protected static String DRDA_Proto_RDBNFNRM= "DRDA_Proto_RDBNFNRM";\r
+\r
+ protected static String DRDA_Disconnect= "DRDA_Disconnect";\r
+ protected static String DRDA_AgentError= "DRDA_AgentError";\r
+ protected static String DRDA_Timeout= "DRDA_Timeout";\r
+\r
+ static {\r
+ /* Create the errorInfoTable\r
+ The Hashtable is keyed on messageid and holds \r
+ DRDAProtocolExceptionInfo for each of our messages.\r
+ */\r
+ \r
+ errorInfoTable = new Hashtable();\r
+ \r
+ errorInfoTable.put(\r
+ DRDA_Proto_CMDCHKRM,\r
+ new DRDAProtocolExceptionInfo(\r
+ CodePoint.CMDCHKRM,\r
+ CodePoint.SVRCOD_ERROR,\r
+ NO_ASSOC_ERRCD,\r
+ false));\r
+\r
+ errorInfoTable.put(\r
+ DRDA_Proto_CMDNSPRM,\r
+ new DRDAProtocolExceptionInfo(\r
+ CodePoint.CMDNSPRM,\r
+ CodePoint.SVRCOD_ERROR,\r
+ NO_ASSOC_ERRCD,\r
+ true));\r
+ errorInfoTable.put(\r
+ DRDA_Proto_DTAMCHRM,\r
+ new DRDAProtocolExceptionInfo(\r
+ CodePoint.DTAMCHRM,\r
+ CodePoint.SVRCOD_ERROR,\r
+ NO_ASSOC_ERRCD,\r
+ false));\r
+ errorInfoTable.put(\r
+ DRDA_Proto_OBJNSPRM,\r
+ new DRDAProtocolExceptionInfo(\r
+ CodePoint.OBJNSPRM,\r
+ CodePoint.SVRCOD_ERROR,\r
+ NO_ASSOC_ERRCD,\r
+ true));\r
+ \r
+ errorInfoTable.put(\r
+ DRDA_Proto_PKGBNARM,\r
+ new DRDAProtocolExceptionInfo(\r
+ CodePoint.PKGBNARM,\r
+ CodePoint.SVRCOD_ERROR,\r
+ NO_ASSOC_ERRCD,\r
+ false));\r
+ \r
+ errorInfoTable.put(DRDA_Proto_PRCCNVRM,\r
+ new DRDAProtocolExceptionInfo(\r
+ CodePoint.PRCCNVRM,\r
+ CodePoint.SVRCOD_ERROR,\r
+ CodePoint.PRCCNVCD,\r
+ false));\r
+\r
+ errorInfoTable.put(DRDA_Proto_SYNTAXRM,\r
+ new DRDAProtocolExceptionInfo(\r
+ CodePoint.SYNTAXRM,\r
+ CodePoint.SVRCOD_ERROR,\r
+ CodePoint.SYNERRCD,\r
+ true));\r
+\r
+ errorInfoTable.put(DRDA_Proto_VALNSPRM,\r
+ new DRDAProtocolExceptionInfo(\r
+ CodePoint.VALNSPRM,\r
+ CodePoint.SVRCOD_ERROR,\r
+ NO_ASSOC_ERRCD,\r
+ true));\r
+\r
+ errorInfoTable.put(DRDA_Proto_MGRLVLRM,\r
+ new DRDAProtocolExceptionInfo(\r
+ CodePoint.MGRLVLRM,\r
+ CodePoint.SVRCOD_ERROR,\r
+ NO_ASSOC_ERRCD,\r
+ false));\r
+\r
+ errorInfoTable.put(DRDA_Proto_RDBNFNRM,\r
+ new DRDAProtocolExceptionInfo(\r
+ CodePoint.RDBNFNRM,\r
+ CodePoint.SVRCOD_ERROR,\r
+ NO_ASSOC_ERRCD,\r
+ false));\r
+\r
+ \r
+ errorInfoTable.put(DRDA_Disconnect,\r
+ new DRDAProtocolExceptionInfo(\r
+ 0,\r
+ 0,\r
+ NO_ASSOC_ERRCD,\r
+ false));\r
+\r
+ // Permanent Agent Error (AGNPRMRM) Reply Message indicates that the command\r
+ // requested could not be completed because of a permanent error\r
+ // condition detected at the target system.\r
+ errorInfoTable.put(DRDA_AgentError,\r
+ new DRDAProtocolExceptionInfo(\r
+ CodePoint.AGNPRMRM,\r
+ CodePoint.SVRCOD_PRMDMG,\r
+ NO_ASSOC_ERRCD,\r
+ false));\r
+\r
+\r
+ errorInfoTable.put(DRDA_Timeout,\r
+ new DRDAProtocolExceptionInfo(\r
+ 0,\r
+ 0,\r
+ NO_ASSOC_ERRCD,\r
+ false));\r
+\r
+ }\r
+ \r
+ \r
+ /** Create a new Protocol exception \r
+ *\r
+ * @param agent DRDAConnThread that threw this exception\r
+ *\r
+ * @param cpArg CODPNT value to pass to send\r
+ *\r
+ *\r
+ * @param msgid The messageid for this message. (needs to be\r
+ * integrated into logging mechanism)\r
+ *\r
+ * @param args Argments for the message in an Object[]\r
+ *\r
+ */\r
+ \r
+ DRDAProtocolException(String msgid,\r
+ DRDAConnThread agent, \r
+ int cpArg, \r
+ int errCdArg, Object []args)\r
+ \r
+ {\r
+ \r
+ boolean agentError = false;\r
+\r
+ exceptionInfo = \r
+ (DRDAProtocolExceptionInfo) errorInfoTable.get(msgid);\r
+ \r
+ if (agent != null)\r
+ {\r
+ this.correlationID = agent.getCorrelationID();\r
+ this.crrtkn = agent.getCrrtkn();\r
+ }\r
+\r
+ this.codpntArg= cpArg;\r
+ this.errorCodePoint = exceptionInfo.errorCodePoint;\r
+ this.errcd = errCdArg;\r
+ this.messageid = msgid;\r
+\r
+ if (msgid.equals(DRDA_AgentError))\r
+ {\r
+ this.svrcod = ((Integer)args[0]).intValue();\r
+ this.rdbnam = (String)args[1];\r
+ // retrieve the server diagnostic error message \r
+ String srvdgn = (String)args[2];\r
+ msg = "Execution failed because of Permanent Agent Error: SVRCOD = " +\r
+ java.lang.Integer.toHexString(this.svrcod) +\r
+ "; RDBNAM = "+ rdbnam +"; diagnostic msg = "+ srvdgn;\r
+ agentError = true;\r
+ }\r
+ else if (msgid.equals(DRDA_Proto_RDBNFNRM))\r
+ {\r
+ this.svrcod = exceptionInfo.svrcod;\r
+ this.rdbnam = (String)args[0];\r
+ msg = "Execution failed because of Distributed Protocol Error: " \r
+ + messageid +\r
+ "; RDBNAM = "+ rdbnam;\r
+ }\r
+ else\r
+ {\r
+ this.svrcod = exceptionInfo.svrcod;\r
+ msg = "Execution failed because of a Distributed Protocol Error: " \r
+ + messageid +\r
+ "; CODPNT arg = " + java.lang.Integer.toHexString(cpArg) +\r
+ "; Error Code Value = " + java.lang.Integer.toHexString(errCdArg);\r
+ if (msgid.equals(DRDA_Proto_SYNTAXRM)) {\r
+ msg += ". Plaintext connection attempt from an SSL enabled client?";\r
+ }\r
+ }\r
+ \r
+ \r
+ if (!agentError && args != null)\r
+ {\r
+ messageArgs = args;\r
+ for (int i = 0; i < args.length; i++)\r
+ {\r
+ //args contain managers and manager levels display in hex\r
+ if (msgid.equals(DRDA_Proto_MGRLVLRM))\r
+ msg += "," + \r
+ java.lang.Integer.toHexString(((Integer)args[i]).intValue());\r
+ else\r
+ msg += "," + args[i];\r
+ \r
+ }\r
+ }\r
+\r
+\r
+ // for now dump all errors except disconnects to console \r
+ // and log\r
+ if (!isDisconnectException())\r
+ {\r
+ DRDAConnThread.println2Log(agent.getDbName(),\r
+ agent.getSession().drdaID, \r
+ msg);\r
+ NetworkServerControlImpl s = agent.getServer();\r
+ s.consoleExceptionPrintTrace(this);\r
+ }\r
+ }\r
+ \r
+ // Constructor with no additional args\r
+ DRDAProtocolException(String msgid,\r
+ DRDAConnThread agent, \r
+ int cpArg, \r
+ int errCdArg)\r
+ {\r
+ this(msgid,agent, cpArg, errCdArg, (Object []) null);\r
+ }\r
+\r
+\r
+ protected static DRDAProtocolException newDisconnectException(DRDAConnThread\r
+ agent,Object[] args)\r
+ {\r
+ return new DRDAProtocolException(DRDA_Disconnect,\r
+ agent,\r
+ NO_CODPNT_ARG,\r
+ NO_ASSOC_ERRCD,\r
+ args);\r
+ \r
+ }\r
+ \r
+ protected static DRDAProtocolException newAgentError(DRDAConnThread agent,\r
+ int svrcod, String rdbnam, String srvdgn)\r
+ {\r
+ if ( SanityManager.DEBUG )\r
+ agent.trace("agentError in " + agent);\r
+ Object[] oa = {new Integer(svrcod), rdbnam, srvdgn};\r
+ return new DRDAProtocolException(DRDA_AgentError,\r
+ agent,\r
+ NO_CODPNT_ARG,\r
+ NO_ASSOC_ERRCD,\r
+ oa);\r
+ }\r
+ \r
+ protected final boolean isDisconnectException()\r
+ {\r
+ return (errorCodePoint == 0);\r
+ }\r
+ \r
+ /** write will write the Error information to the buffer.\r
+ * Most errors will write only the codepoint and svrcod \r
+ * Where appropriate the codepoint specific error code and\r
+ * codePoint of origin will be written\r
+ *\r
+ * @param writer The DDMWriter for the agent.\r
+ */\r
+ \r
+ protected void write(DDMWriter writer)\r
+ {\r
+ //Writing Protocol Error\r
+ writer.createDssReply();\r
+ writer.startDdm(errorCodePoint);\r
+ writer.writeScalar2Bytes(CodePoint.SVRCOD,svrcod);\r
+ if (exceptionInfo.sendsCodpntArg)\r
+ writer.writeScalar2Bytes(CodePoint.CODPNT,codpntArg);\r
+ if (exceptionInfo.errCdCodePoint != NO_ASSOC_ERRCD)\r
+ writer.writeScalar1Byte(exceptionInfo.errCdCodePoint,\r
+ errcd);\r
+ if (rdbnam != null && agent != null)\r
+ {\r
+ try {\r
+ agent.writeRDBNAM(rdbnam);\r
+ } catch (DRDAProtocolException e) {} //ignore exceptions while processing\r
+ }\r
+ // for MGRLVLRM, need to write out the manager levels\r
+ if (errorCodePoint == CodePoint.MGRLVLRM)\r
+ {\r
+ writer.startDdm(CodePoint.MGRLVLLS);\r
+ for (int i = 0; i < messageArgs.length ; i += 2)\r
+ {\r
+ writer.writeNetworkShort(((Integer)messageArgs[i]).intValue());\r
+ writer.writeNetworkShort(((Integer)messageArgs[i+1]).intValue());\r
+ }\r
+ writer.endDdm();\r
+ }\r
+ writer.endDdmAndDss();\r
+ }\r
+ \r
+ /**\r
+ * Override getMessage() \r
+ * @return the server diagnostic error message for this exception\r
+ */\r
+ public String getMessage()\r
+ {\r
+ return msg;\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ * Class used to transport that fact that we had a timeout and should\r
+ * *NOT* disconnect the connection.\r
+ * See DRDAConnThread.run()\r
+ */\r
+class DRDASocketTimeoutException extends DRDAProtocolException {\r
+ DRDASocketTimeoutException(DRDAConnThread t) {\r
+ super(DRDA_Timeout,t,0,0);\r
+ }\r
+}\r