KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > client > net > NetLogWriter


1 /*
2
3    Derby - Class org.apache.derby.client.net.NetLogWriter
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20 */

21
22 package org.apache.derby.client.net;
23
24 // network traffic tracer.
25
// This class traces communication buffers for both sends and receives.
26
// The value of the hex bytes are traced along with the ascii and ebcdic translations.
27

28 public class NetLogWriter extends org.apache.derby.client.am.LogWriter {
29
30     // The recevie constant is used to indicate that the bytes were read to a Stream.
31
// It indicates to this class that a receive header should be used.
32
public static final int TYPE_TRACE_RECEIVE = 2;
33
34     // The send constant is used to indicate that the bytes were written to
35
// a Stream. It indicates to this class that a send header should be used.
36
public static final int TYPE_TRACE_SEND = 1;
37
38     //------------------------------ internal constants --------------------------
39

40     // This class was implemented using character arrays to translate bytes
41
// into ascii and ebcdic. The goal was to be able to quickly index into the
42
// arrays to find the characters. Char arrays instead of strings were used as
43
// much as possible in an attempt to help speed up performance.
44

45     // An array of characters used to translate bytes to ascii.
46
// The position in the array corresponds to the hex value of the character.
47
private static final char asciiChar__ [] = {
48         // 0 1 2 3 4 5 6 7 8 9 A B C D E F
49
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', //0
50
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', //1
51
' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', //2
52
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', //3
53
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', //4
54
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', //5
55
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', //6
56
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '.', //7
57
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', //8
58
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', //9
59
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', //A
60
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', //B
61
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', //C
62
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', //D
63
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', //E
64
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' //F
65
};
66
67     // This column position header is used to mark offsets into the trace.
68
private static final String JavaDoc colPosHeader__ =
69             " 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF 0123456789ABCDEF";
70
71     // An array of characters used to translate bytes to ebcdic.
72
// The position in the array corresponds to the hex value of the
73
// character.
74
private static final char ebcdicChar__[] = {
75         // 0 1 2 3 4 5 6 7 8 9 A B C D E F
76
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', //0
77
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', //1
78
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', //2
79
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', //3
80
' ', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '<', '(', '+', '|', //4
81
'&', '.', '.', '.', '.', '.', '.', '.', '.', '.', '!', '$', '*', ')', ';', '.', //5
82
'-', '/', '.', '.', '.', '.', '.', '.', '.', '.', '|', ',', '%', '_', '>', '?', //6
83
'.', '.', '.', '.', '.', '.', '.', '.', '.', '`', ':', '#', '@', '\'', '=', '"', //7
84
'.', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', '.', '.', '.', '.', '.', '.', //8
85
'.', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', '.', '.', '.', '.', '.', '.', //9
86
'.', '~', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '.', '.', '.', '.', '.', '.', //A
87
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', //B
88
'{', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', '.', '.', '.', '.', '.', '.', //C
89
'}', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', '.', '.', '.', '.', '.', '.', //D
90
'\\', '.', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '.', '.', '.', '.', '.', '.', //E
91
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '.', '.', '.', '.', '.' //F
92
};
93
94     // An array of characters representing hex numbers.
95
private static final char hexDigit__ [] = {
96         '0', '1', '2', '3', '4', '5', '6', '7',
97         '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
98     };
99
100     // The receive header comes befor bytes which would be read from a stream.
101
private static final String JavaDoc receiveHeader__ =
102             " RECEIVE BUFFER: (ASCII) (EBCDIC)";
103
104     // The send header comes before bytes which would be written to a stream.
105
private static final String JavaDoc sendHeader__ =
106             " SEND BUFFER: (ASCII) (EBCDIC)";
107
108     private static final char spaceChar__ = ' ';
109
110     private static final char zeroChar__ = '0';
111
112     // This mapping table associates a codepoint to a String describing the codepoint.
113
// This is needed because the trace prints the first codepoint in send and receive buffers.
114
// This is created lazily because there is no need to create the mapping if tracing isn't used.
115
// So this array will only be created when the com buffer trace is started.
116
private static CodePointNameTable codePointNameTable__ = null;
117
118     //-----------------------------internal state---------------------------------
119

120     //-----------------------------constructors/finalizer-------------------------
121

122     // One NetLogWriter object is created per data source, iff tracing is enabled.
123
public NetLogWriter(java.io.PrintWriter JavaDoc printWriter, int traceLevel) {
124         super(printWriter, traceLevel);
125
126         // Initialize the codepoint name table if not previously initialized.
127
// This is done lazily so that it is not created if the trace isn't used (save some init time).
128
if (codePointNameTable__ == null) {
129             codePointNameTable__ = new CodePointNameTable();
130         }
131     }
132
133     //------------------------------entry points----------------------------------
134

135     // Specialization of LogWriter.traceConnectsExit()
136
public void traceConnectsExit(org.apache.derby.client.am.Connection connection) {
137         if (traceSuspended()) {
138             return;
139         }
140         NetConnection c = (NetConnection) connection;
141         synchronized (printWriter_) {
142             super.traceConnectsExit(c);
143             dncnetprint(" PROTOCOL manager levels: { ");
144             printWriter_.print("SQLAM=" + c.getSQLAM() + ", ");
145             printWriter_.print("AGENT=" + c.getAGENT() + ", ");
146             printWriter_.print("CMNTCPIP=" + c.getCMNTCPIP() + ", ");
147             printWriter_.print("RDB=" + c.getRDB() + ", ");
148             printWriter_.print("SECMGR=" + c.getSECMGR() + ", ");
149             printWriter_.print("XAMGR=" + c.getXAMGR() + ", ");
150             printWriter_.print("SYNCPTMGR=" + c.getSYNCPTMGR() + ", ");
151             printWriter_.print("RSYNCMGR=" + c.getRSYNCMGR());
152             printWriter_.println(" }");
153             printWriter_.flush();
154         }
155     }
156
157     public void traceConnectsResetExit(org.apache.derby.client.am.Connection connection) {
158         if (traceSuspended()) {
159             return;
160         }
161         NetConnection c = (NetConnection) connection;
162         synchronized (printWriter_) {
163             super.traceConnectsResetExit(c);
164             dncnetprint(" PROTOCOL manager levels: { ");
165             printWriter_.print("SQLAM=" + c.getSQLAM() + ", ");
166             printWriter_.print("AGENT=" + c.getAGENT() + ", ");
167             printWriter_.print("CMNTCPIP=" + c.getCMNTCPIP() + ", ");
168             printWriter_.print("RDB=" + c.getRDB() + ", ");
169             printWriter_.print("SECMGR=" + c.getSECMGR() + ", ");
170             printWriter_.print("XAMGR=" + c.getXAMGR() + ", ");
171             printWriter_.print("SYNCPTMGR=" + c.getSYNCPTMGR() + ", ");
172             printWriter_.print("RSYNCMGR=" + c.getRSYNCMGR());
173             printWriter_.println(" }");
174             printWriter_.flush();
175         }
176     }
177
178     // Pass the connection handle and print it in the header
179
// What exactly is supposed to be passed, assume one complete DSS packet
180
// Write the communication buffer data to the trace.
181
// The data is passed in via a byte array. The start and length of the data is given.
182
// The type is needed to indicate if the data is part of the send or receive buffer.
183
// The class name, method name, and trcPt number are also written to the trace.
184
// Not much checking is performed on the parameters. This is done to help performance.
185
synchronized public void traceProtocolFlow(byte[] buff,
186                                                int offset,
187                                                int len,
188                                                int type,
189                                                String JavaDoc className,
190                                                String JavaDoc methodName,
191                                                int tracepoint) {
192         if (traceSuspended()) {
193             return;
194         }
195         if (!loggingEnabled(org.apache.derby.jdbc.ClientDataSource.TRACE_PROTOCOL_FLOWS)) {
196             return;
197         }
198         synchronized (printWriter_) {
199             super.tracepoint("[net]", tracepoint, className, methodName);
200
201             int fullLen = len;
202             boolean printColPos = true;
203             while (fullLen >= 2) { // format each DssHdr seperately
204
// get the length of this DssHdr
205
len = ((buff[offset] & 0xff) << 8) + ((buff[offset + 1] & 0xff) << 0);
206
207                 // check for valid dss header or not all of dss block
208
if ((len < 10) || (len > fullLen)) {
209                     len = fullLen;
210                 }
211
212                 // subtract that length from the full length
213
fullLen -= len;
214                 // The data will only be written if there is a non-zero positive length.
215
if (len != 0) {
216                     String JavaDoc codePointName = null;
217                     // If the length <= 10, lookup the first codepoint so it's name can be printed
218
if (len >= 10) {
219                         // Get the int value of the two byte unsigned codepoint.
220
int codePoint = getCodePoint(buff, offset + 8);
221                         codePointName = codePointNameTable__.lookup(codePoint);
222
223                         // if this is not a valid codepoint then format the entire buffer
224
// as one block.
225
if (codePointName == null) {
226                             len += fullLen;
227                             fullLen = 0;
228                         }
229                     }
230
231                     if (!printColPos) { // not 1st Dss header of this buffer, write seperator
232
dncnetprintln("");
233                     }
234
235                     if (codePointName == null) {
236                         // codePointName was still null so either < 10 bytes were given or
237
// the codepoint wasn't found in the table. Just print the plain send header.
238
dncnetprintln(getHeader(type));
239                     } else {
240                         // codePointName isn't null so the name of the codepoint will be printed.
241
printHeaderWithCodePointName(codePointName, type);
242                     }
243
244                     // Print the col position header in the trace.
245
if (printColPos) { // first Dss header of buffer, need column position header
246
dncnetprintln(colPosHeader__);
247                         printColPos = false;
248                     }
249
250                     // A char array will be used to translate the bytes to their character
251
// representations along with ascii and ebcdic representations.
252
char trcDump[] = new char[77];
253
254                     // bCounter, aCounter, eCounter are offsets used to help position the characters
255
short bCounter = 7;
256                     short aCounter = 43;
257                     short eCounter = 61;
258
259                     // The lines will be counted starting at zero.
260
// This is hard coded since we are at the beginning.
261
trcDump[0] = zeroChar__;
262                     trcDump[1] = zeroChar__;
263                     trcDump[2] = zeroChar__;
264                     trcDump[3] = zeroChar__;
265
266                     // The 0's are already in the trace so bump the line counter up a row.
267
int lineCounter = 0x10;
268
269                     // Make sure the character array has all blanks in it.
270
// Some of these blanks will be replaced later with values.
271
// The 0's were not wrote over.
272
for (int j = 4; j < 77; j++) {
273                         trcDump[j] = spaceChar__;
274                     }
275
276                     // i will maintain the position in the byte array to be traced.
277
int i = 0;
278
279                     do {
280                         // Get the unsigned value of the byte.
281
// int num = b[off++] & 0xff;
282
int num = (buff[offset] < 0) ? buff[offset] + 256 : buff[offset];
283                         offset++;
284                         i++;
285                         // Place the characters representing the bytes in the array.
286
trcDump[bCounter++] = hexDigit__[((num >>> 4) & 0xf)];
287                         trcDump[bCounter++] = hexDigit__[(num & 0xf)];
288
289                         // Place the ascii and ebcdc representations in the array.
290
trcDump[aCounter++] = asciiChar__[num];
291                         trcDump[eCounter++] = ebcdicChar__[num];
292
293                         if (((i % 8) == 0)) {
294                             if (((i % 16) == 0)) {
295                                 // Print the array each time 16 bytes are processed.
296
dncnetprintln(trcDump);
297                                 if (i != len) {
298                                     // Not yet at the end of the byte array.
299
if ((len - i) < 16) {
300                                         // This is the last line so blank it all out.
301
// This keeps the last line looking pretty in case
302
// < 16 bytes remain.
303
for (int j = 0; j < trcDump.length; j++) {
304                                             trcDump[j] = spaceChar__;
305                                         }
306                                     }
307                                     // Reset the counters.
308
bCounter = 0;
309                                     aCounter = 43;
310                                     eCounter = 61;
311                                     // Reset the lineCounter if it starts to get too large.
312
if (lineCounter == 0x100000) {
313                                         lineCounter = 0;
314                                     }
315                                     // Place the characters representing the line counter in the array.
316
trcDump[bCounter++] = hexDigit__[((lineCounter >>> 12) & 0xf)];
317                                     trcDump[bCounter++] = hexDigit__[((lineCounter >>> 8) & 0xf)];
318                                     trcDump[bCounter++] = hexDigit__[((lineCounter >>> 4) & 0xf)];
319                                     trcDump[bCounter++] = hexDigit__[(lineCounter & 0xf)];
320                                     bCounter += 3;
321                                     // Bump up the line counter.
322
lineCounter += 0x10;
323                                 }
324                             } else {
325                                 // 8 bytes were processed so move the counter to adjust for
326
// spaces between the columns of bytes.
327
bCounter += 2;
328                             }
329                         }
330                         // do this until we all the data has been traced.
331
} while (i < len);
332
333                     // print the last line and add some blank lines to make it easier to read.
334
if (len % 16 != 0) {
335                         dncnetprintln(trcDump);
336                     }
337                 }
338             }
339             dncnetprintln("");
340         }
341     }
342
343     // Gets the int value of the two byte unsigned codepoint.
344
private static int getCodePoint(byte[] buff, int offset) {
345         return ((buff[offset++] & 0xff) << 8) +
346                 ((buff[offset] & 0xff) << 0);
347     }
348
349     private static String JavaDoc getHeader(int type) {
350         switch (type) {
351         case TYPE_TRACE_SEND:
352             return sendHeader__;
353         case TYPE_TRACE_RECEIVE:
354             return receiveHeader__;
355         default:
356             return null;
357         }
358     }
359
360     private static int getStartPosition(int type) {
361         switch (type) {
362         case TYPE_TRACE_SEND:
363             return 20; // This is right after 'SEND BUFFER: '.
364
case TYPE_TRACE_RECEIVE:
365             return 23; // This is right after 'RECEIVE BUFFER: '.
366
default:
367             return 0;
368         }
369     }
370
371     private void printHeaderWithCodePointName(String JavaDoc codePointName, int type) {
372         // Create a char array so some of the characters
373
// can be replaced with the name of the codepoint.
374
char headerArray[] = getHeader(type).toCharArray();
375
376         // At most, 16 character name will be used. This is so
377
// the headers on top of the ascii and ebcdic rows aren't shifted.
378
int replaceLen = (codePointName.length() < 17) ? codePointName.length() : 16;
379
380         int offset = getStartPosition(type);
381         for (int i = 0; i < replaceLen; i++) {
382             headerArray[offset++] = codePointName.charAt(i);
383         }
384         dncnetprintln(headerArray);
385     }
386
387     private void dncnetprint(String JavaDoc s) {
388         synchronized (printWriter_) {
389             printWriter_.print("[derby] " + s);
390             printWriter_.flush();
391         }
392     }
393
394     private void dncnetprintln(String JavaDoc s) {
395         synchronized (printWriter_) {
396             printWriter_.println("[derby] " + s);
397             printWriter_.flush();
398         }
399     }
400
401     private void dncnetprintln(char[] s) {
402         synchronized (printWriter_) {
403             printWriter_.print("[derby] ");
404             printWriter_.println(s);
405             printWriter_.flush();
406         }
407     }
408 }
409
Popular Tags