001: /*
002:
003: Derby - Class org.apache.derby.impl.drda.DRDAProtocolException
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: /*
023:
024: /**
025: DRDAProtocolException is the root of all protocol exceptions that are
026: handled in a standard fashion by the DRDA AS.
027: If a protocol error message needs to send more than
028: SVRCOD, an ERRCD and CODPNT arg it should be subclassed
029:
030: @author marsden
031: */
032:
033: package org.apache.derby.impl.drda;
034:
035: import java.util.Hashtable;
036: import org.apache.derby.iapi.services.sanity.SanityManager;
037:
038: class DRDAProtocolException extends Exception {
039:
040: /* Static values, used in constructor if there is no associated
041: Error Code or the codepoint argument.
042: */
043:
044: protected static final int NO_ASSOC_ERRCD = 0;
045: protected static final int NO_CODPNT_ARG = 0;
046:
047: private DRDAConnThread agent;
048:
049: // request correlation id
050: private int correlationID;
051:
052: // correlation token
053: private byte[] crrtkn;
054:
055: //Codepoint arg
056: private int codpntArg;
057:
058: private DRDAProtocolExceptionInfo exceptionInfo;
059:
060: // CodePoint of this error
061: private int errorCodePoint;
062:
063: // Severity Code
064: private int svrcod;
065:
066: // error code (e.g. SYNERRCD)
067: private int errcd;
068:
069: // messageid for logging errors.
070: private String messageid;
071:
072: // database name
073: private String rdbnam;
074:
075: // database diagnostic information
076: private String srvdgn;
077:
078: // message arguments
079: private Object[] messageArgs;
080:
081: // A verbose error message string, will be helpful
082: // when getMessage() is called on this Exception object
083: private String msg;
084:
085: private static Hashtable errorInfoTable;
086:
087: protected static String DRDA_Proto_CMDCHKRM = "DRDA_Proto_CMDCHKRM";
088: protected static String DRDA_Proto_CMDNSPRM = "DRDA_Proto_CMDNSPRM";
089: protected static String DRDA_Proto_DTAMCHRM = "DRDA_Proto_DTAMCHRM";
090:
091: protected static String DRDA_Proto_OBJNSPRM = "DRDA_Proto_OBJNSPRM";
092: protected static String DRDA_Proto_PKGBNARM = "DRDA_Proto_PKGBNARM";
093: protected static String DRDA_Proto_PRCCNVRM = "DRDA_Proto_PRCCNVRM";
094: protected static String DRDA_Proto_PRMNSRM = "DRDA_Proto_PRMNSPRM";
095:
096: protected static String DRDA_Proto_SYNTAXRM = "DRDA_Proto_SYNTAXRM";
097: protected static String DRDA_Proto_VALNSPRM = "DRDA_Proto_VALNSPRM";
098: protected static String DRDA_Proto_MGRLVLRM = "DRDA_Proto_MGRLVLRM";
099: protected static String DRDA_Proto_RDBNFNRM = "DRDA_Proto_RDBNFNRM";
100:
101: protected static String DRDA_Disconnect = "DRDA_Disconnect";
102: protected static String DRDA_AgentError = "DRDA_AgentError";
103:
104: static {
105: /* Create the errorInfoTable
106: The Hashtable is keyed on messageid and holds
107: DRDAProtocolExceptionInfo for each of our messages.
108: */
109:
110: errorInfoTable = new Hashtable();
111:
112: errorInfoTable.put(DRDA_Proto_CMDCHKRM,
113: new DRDAProtocolExceptionInfo(CodePoint.CMDCHKRM,
114: CodePoint.SVRCOD_ERROR, NO_ASSOC_ERRCD, false));
115:
116: errorInfoTable.put(DRDA_Proto_CMDNSPRM,
117: new DRDAProtocolExceptionInfo(CodePoint.CMDNSPRM,
118: CodePoint.SVRCOD_ERROR, NO_ASSOC_ERRCD, true));
119: errorInfoTable.put(DRDA_Proto_DTAMCHRM,
120: new DRDAProtocolExceptionInfo(CodePoint.DTAMCHRM,
121: CodePoint.SVRCOD_ERROR, NO_ASSOC_ERRCD, false));
122: errorInfoTable.put(DRDA_Proto_OBJNSPRM,
123: new DRDAProtocolExceptionInfo(CodePoint.OBJNSPRM,
124: CodePoint.SVRCOD_ERROR, NO_ASSOC_ERRCD, true));
125:
126: errorInfoTable.put(DRDA_Proto_PKGBNARM,
127: new DRDAProtocolExceptionInfo(CodePoint.PKGBNARM,
128: CodePoint.SVRCOD_ERROR, NO_ASSOC_ERRCD, false));
129:
130: errorInfoTable.put(DRDA_Proto_PRCCNVRM,
131: new DRDAProtocolExceptionInfo(CodePoint.PRCCNVRM,
132: CodePoint.SVRCOD_ERROR, CodePoint.PRCCNVCD,
133: false));
134:
135: errorInfoTable.put(DRDA_Proto_SYNTAXRM,
136: new DRDAProtocolExceptionInfo(CodePoint.SYNTAXRM,
137: CodePoint.SVRCOD_ERROR, CodePoint.SYNERRCD,
138: true));
139:
140: errorInfoTable.put(DRDA_Proto_VALNSPRM,
141: new DRDAProtocolExceptionInfo(CodePoint.VALNSPRM,
142: CodePoint.SVRCOD_ERROR, NO_ASSOC_ERRCD, true));
143:
144: errorInfoTable.put(DRDA_Proto_MGRLVLRM,
145: new DRDAProtocolExceptionInfo(CodePoint.MGRLVLRM,
146: CodePoint.SVRCOD_ERROR, NO_ASSOC_ERRCD, false));
147:
148: errorInfoTable.put(DRDA_Proto_RDBNFNRM,
149: new DRDAProtocolExceptionInfo(CodePoint.RDBNFNRM,
150: CodePoint.SVRCOD_ERROR, NO_ASSOC_ERRCD, false));
151:
152: errorInfoTable.put(DRDA_Disconnect,
153: new DRDAProtocolExceptionInfo(0, 0, NO_ASSOC_ERRCD,
154: false));
155:
156: // Permanent Agent Error (AGNPRMRM) Reply Message indicates that the command
157: // requested could not be completed because of a permanent error
158: // condition detected at the target system.
159: errorInfoTable
160: .put(DRDA_AgentError, new DRDAProtocolExceptionInfo(
161: CodePoint.AGNPRMRM, CodePoint.SVRCOD_PRMDMG,
162: NO_ASSOC_ERRCD, false));
163:
164: }
165:
166: /** Create a new Protocol exception
167: *
168: * @param agent DRDAConnThread that threw this exception
169: *
170: * @param cpArg CODPNT value to pass to send
171: *
172: *
173: * @param msgid The messageid for this message. (needs to be
174: * integrated into logging mechanism)
175: *
176: * @param args Argments for the message in an Object[]
177: *
178: */
179:
180: DRDAProtocolException(String msgid, DRDAConnThread agent,
181: int cpArg, int errCdArg, Object[] args)
182:
183: {
184:
185: boolean agentError = false;
186:
187: exceptionInfo = (DRDAProtocolExceptionInfo) errorInfoTable
188: .get(msgid);
189:
190: if (agent != null) {
191: this .correlationID = agent.getCorrelationID();
192: this .crrtkn = agent.getCrrtkn();
193: }
194:
195: this .codpntArg = cpArg;
196: this .errorCodePoint = exceptionInfo.errorCodePoint;
197: this .errcd = errCdArg;
198: this .messageid = msgid;
199:
200: if (msgid.equals(DRDA_AgentError)) {
201: this .svrcod = ((Integer) args[0]).intValue();
202: this .rdbnam = (String) args[1];
203: // retrieve the server diagnostic error message
204: String srvdgn = (String) args[2];
205: msg = "Execution failed because of Permanent Agent Error: SVRCOD = "
206: + java.lang.Integer.toHexString(this .svrcod)
207: + "; RDBNAM = "
208: + rdbnam
209: + "; diagnostic msg = "
210: + srvdgn;
211: agentError = true;
212: } else if (msgid.equals(DRDA_Proto_RDBNFNRM)) {
213: this .svrcod = exceptionInfo.svrcod;
214: this .rdbnam = (String) args[0];
215: msg = "Execution failed because of Distributed Protocol Error: "
216: + messageid + "; RDBNAM = " + rdbnam;
217: } else {
218: this .svrcod = exceptionInfo.svrcod;
219: msg = "Execution failed because of a Distributed Protocol Error: "
220: + messageid
221: + "; CODPNT arg = "
222: + java.lang.Integer.toHexString(cpArg)
223: + "; Error Code Value = "
224: + java.lang.Integer.toHexString(errCdArg);
225: }
226:
227: if (!agentError && args != null) {
228: messageArgs = args;
229: for (int i = 0; i < args.length; i++) {
230: //args contain managers and manager levels display in hex
231: if (msgid.equals(DRDA_Proto_MGRLVLRM))
232: msg += ","
233: + java.lang.Integer
234: .toHexString(((Integer) args[i])
235: .intValue());
236: else
237: msg += "," + args[i];
238:
239: }
240: }
241:
242: // for now dump all errors except disconnects to console
243: // and log
244: if (!isDisconnectException()) {
245: DRDAConnThread.println2Log(agent.getDbName(), agent
246: .getSession().drdaID, msg);
247: NetworkServerControlImpl s = agent.getServer();
248: s.consoleExceptionPrintTrace(this );
249: }
250: }
251:
252: // Constructor with no additional args
253: DRDAProtocolException(String msgid, DRDAConnThread agent,
254: int cpArg, int errCdArg) {
255: this (msgid, agent, cpArg, errCdArg, (Object[]) null);
256: }
257:
258: protected static DRDAProtocolException newDisconnectException(
259: DRDAConnThread agent, Object[] args) {
260: return new DRDAProtocolException(DRDA_Disconnect, agent,
261: NO_CODPNT_ARG, NO_ASSOC_ERRCD, args);
262:
263: }
264:
265: protected static DRDAProtocolException newAgentError(
266: DRDAConnThread agent, int svrcod, String rdbnam,
267: String srvdgn) {
268: if (SanityManager.DEBUG)
269: agent.trace("agentError in " + agent);
270: Object[] oa = { new Integer(svrcod), rdbnam, srvdgn };
271: return new DRDAProtocolException(DRDA_AgentError, agent,
272: NO_CODPNT_ARG, NO_ASSOC_ERRCD, oa);
273: }
274:
275: protected final boolean isDisconnectException() {
276: return (errorCodePoint == 0);
277: }
278:
279: /** write will write the Error information to the buffer.
280: * Most errors will write only the codepoint and svrcod
281: * Where appropriate the codepoint specific error code and
282: * codePoint of origin will be written
283: *
284: * @param writer The DDMWriter for the agent.
285: */
286:
287: protected void write(DDMWriter writer) {
288: //Writing Protocol Error
289: writer.createDssReply();
290: writer.startDdm(errorCodePoint);
291: writer.writeScalar2Bytes(CodePoint.SVRCOD, svrcod);
292: if (exceptionInfo.sendsCodpntArg)
293: writer.writeScalar2Bytes(CodePoint.CODPNT, codpntArg);
294: if (exceptionInfo.errCdCodePoint != NO_ASSOC_ERRCD)
295: writer
296: .writeScalar1Byte(exceptionInfo.errCdCodePoint,
297: errcd);
298: if (rdbnam != null && agent != null) {
299: try {
300: agent.writeRDBNAM(rdbnam);
301: } catch (DRDAProtocolException e) {
302: } //ignore exceptions while processing
303: }
304: // for MGRLVLRM, need to write out the manager levels
305: if (errorCodePoint == CodePoint.MGRLVLRM) {
306: writer.startDdm(CodePoint.MGRLVLLS);
307: for (int i = 0; i < messageArgs.length; i += 2) {
308: writer.writeNetworkShort(((Integer) messageArgs[i])
309: .intValue());
310: writer.writeNetworkShort(((Integer) messageArgs[i + 1])
311: .intValue());
312: }
313: writer.endDdm();
314: }
315: writer.endDdmAndDss();
316: }
317:
318: /**
319: * Override getMessage()
320: * @return the server diagnostic error message for this exception
321: */
322: public String getMessage() {
323: return msg;
324: }
325: }
|