Biblioteca Java - Blame information for rev 6
Subversion Repositories:
Rev | Author | Line No. | Line |
---|---|---|---|
6 | mihai | 1 | /* |
2 | * To change this template, choose Tools | Templates | ||
3 | * and open the template in the editor. | ||
4 | */ | ||
5 | |||
6 | package mqdemo; | ||
7 | |||
8 | /* | ||
9 | * @(#)QBrowser.java 1.7 09/15/04 | ||
10 | * | ||
11 | * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved | ||
12 | * SUN PROPRIETARY/CONFIDENTIAL | ||
13 | * Use is subject to license terms. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | import java.awt.*; | ||
18 | import java.util.*; | ||
19 | import java.text.*; | ||
20 | import java.awt.event.*; | ||
21 | import javax.swing.*; | ||
22 | import javax.swing.event.*; | ||
23 | import javax.swing.table.*; | ||
24 | |||
25 | import javax.jms.ConnectionFactory; | ||
26 | import javax.jms.Connection; | ||
27 | import javax.jms.Session; | ||
28 | import javax.jms.Destination; | ||
29 | import javax.jms.Queue; | ||
30 | import javax.jms.Topic; | ||
31 | import javax.jms.MessageConsumer; | ||
32 | import javax.jms.Message; | ||
33 | import javax.jms.QueueBrowser; | ||
34 | import javax.jms.DeliveryMode; | ||
35 | import javax.jms.StreamMessage; | ||
36 | import javax.jms.MapMessage; | ||
37 | import javax.jms.ObjectMessage; | ||
38 | import javax.jms.BytesMessage; | ||
39 | import javax.jms.TextMessage; | ||
40 | import javax.jms.JMSException; | ||
41 | |||
42 | |||
43 | /** | ||
44 | * The QBrowser example is a GUI application that lets you visually | ||
45 | * examine the contents of a JMS Queue. It is written using javax.swing. | ||
46 | * | ||
47 | * By default QBrowser will connect to the imqbrokerd running | ||
48 | * on localhost:7676. You can use the -b and -p options to change | ||
49 | * the host and port: | ||
50 | * | ||
51 | * java QBrowser -b myserver -p7677 | ||
52 | * | ||
53 | * Once QBrowser is up, enter the name of a queue and click Browse. | ||
54 | * A list of messages on the queue will appear in the main window. | ||
55 | * Select a message and click "Details" to see the contents of the message. | ||
56 | * | ||
57 | * QBrowser consists of the following classes: | ||
58 | * | ||
59 | * QBrowser main(), the base GUI frame, and the JMS code | ||
60 | * MsgTable A TableModel for handling the display of messages on a queue | ||
61 | * PropertyPanel A JPanel with a scrolling text area for displaying | ||
62 | * simple text, or the contents of a HashMap. | ||
63 | * A number of minor event handling classes. | ||
64 | * | ||
65 | */ | ||
66 | public class QBrowser extends JPanel implements javax.jms.MessageListener { | ||
67 | |||
68 | JMenuItem exit_item = null; | ||
69 | JLabel qLabel = null; | ||
70 | JComboBox qBox = null; | ||
71 | JButton qBrowse = null; | ||
72 | JTable msgTable = null; | ||
73 | JLabel footerLabel = null; | ||
74 | JPanel footerPanel = null; | ||
75 | QueueBrowser qb = null; | ||
76 | Session session = null; | ||
77 | Connection connection = null; | ||
78 | Topic metricTopic = null; | ||
79 | MessageConsumer metricSubscriber = null; | ||
80 | JFrame detailsFrame = null; | ||
81 | PropertyPanel headerPanel = null, propertyPanel = null, bodyPanel = null; | ||
82 | |||
83 | static final String DEFAULT_BROKER_HOST = "localhost"; | ||
84 | static final int DEFAULT_BROKER_PORT = 7676; | ||
85 | static final String DEST_LIST_TOPIC_NAME = "mq.metrics.destination_list"; | ||
86 | public static String version = "1.0"; | ||
87 | public static String title = "QBrowser " + version; | ||
88 | |||
89 | public static String serverHost = DEFAULT_BROKER_HOST; | ||
90 | public static int serverPort = DEFAULT_BROKER_PORT; | ||
91 | public static String[] pad = {"", "0", "00", "000", "0000"}; | ||
92 | |||
93 | QBrowser() { | ||
94 | super(true); | ||
95 | |||
96 | setBorder(BorderFactory.createEtchedBorder()); | ||
97 | setLayout(new BorderLayout()); | ||
98 | |||
99 | // Create menu bar | ||
100 | JMenuBar menubar = new JMenuBar(); | ||
101 | JMenu menu = new JMenu("File"); | ||
102 | exit_item = new JMenuItem("Exit"); | ||
103 | exit_item.addActionListener(new ExitListener()); | ||
104 | menu.add(exit_item); | ||
105 | menubar.add(menu); | ||
106 | |||
107 | // Create panel to hold input area for Q name and Browse button | ||
108 | JPanel qPanel = new JPanel(); | ||
109 | qPanel.setLayout(new BorderLayout()); | ||
110 | qPanel.add(BorderLayout.NORTH, menubar); | ||
111 | |||
112 | qLabel = new JLabel("Queue Name: "); | ||
113 | qPanel.add(BorderLayout.WEST, qLabel); | ||
114 | |||
115 | qBox = new JComboBox(); | ||
116 | Dimension d = qBox.getPreferredSize(); | ||
117 | d.setSize(10 * d.getWidth(), d.getHeight()); | ||
118 | qBox.setPreferredSize(d); | ||
119 | qBox.setEditable(true); | ||
120 | //qBox.addActionListener(new BrowseListener()); | ||
121 | qPanel.add(BorderLayout.CENTER, qBox); | ||
122 | qBrowse = new JButton("Browse"); | ||
123 | qBrowse.addActionListener(new BrowseListener() ); | ||
124 | qPanel.add(BorderLayout.EAST, qBrowse); | ||
125 | |||
126 | qPanel.updateUI(); | ||
127 | //qPanel.setBackground(Color.YELLOW); | ||
128 | |||
129 | add(BorderLayout.NORTH, qPanel); | ||
130 | |||
131 | // Create panel to hold table of messages | ||
132 | JPanel tPanel = new JPanel(); | ||
133 | tPanel.setLayout(new BorderLayout()); | ||
134 | |||
135 | msgTable = new JTable(new MsgTable()); | ||
136 | msgTable.addMouseListener(new TableMouseListener()); | ||
137 | |||
138 | TableColumn column = msgTable.getColumnModel().getColumn(1); | ||
139 | column.setPreferredWidth(190); | ||
140 | column = msgTable.getColumnModel().getColumn(2); | ||
141 | column.setPreferredWidth(130); | ||
142 | |||
143 | JScrollPane tablePane = new JScrollPane(msgTable); | ||
144 | tablePane.setPreferredSize(new Dimension(100, 300)); | ||
145 | //tablePane.setMinimumSize(new Dimension(100, 100)); | ||
146 | tPanel.add(BorderLayout.CENTER, tablePane); | ||
147 | |||
148 | add(BorderLayout.CENTER, tPanel); | ||
149 | |||
150 | // Create footer | ||
151 | footerPanel = new JPanel(); | ||
152 | footerPanel.setLayout(new BorderLayout()); | ||
153 | footerLabel = new JLabel(""); | ||
154 | footerPanel.add(BorderLayout.WEST, footerLabel); | ||
155 | |||
156 | JButton details = new JButton("Details..."); | ||
157 | details.addActionListener(new DetailsListener() ); | ||
158 | footerPanel.add(BorderLayout.EAST, details); | ||
159 | |||
160 | add(BorderLayout.SOUTH, footerPanel); | ||
161 | |||
162 | setFooter("Enter a Queue Name and click Browse"); | ||
163 | |||
164 | try { | ||
165 | connect(); | ||
166 | } catch (JMSException ex) { | ||
167 | System.err.println("Could not initialize JMS: " + ex); | ||
168 | System.err.println( | ||
169 | "Are you sure there is an imqbrokerd running on " + | ||
170 | serverHost + ":" + serverPort + "?" ); | ||
171 | usage(); | ||
172 | } | ||
173 | |||
174 | } | ||
175 | |||
176 | private void shutdownJMS() { | ||
177 | try { | ||
178 | connection.close(); | ||
179 | } catch (JMSException e) { | ||
180 | System.out.println("Exception closing JMS connection: " + e); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | /** | ||
185 | * Initialize JMS by creating Connection and Session. | ||
186 | */ | ||
187 | private void initJMS() throws JMSException { | ||
188 | ConnectionFactory cf = null; | ||
189 | |||
190 | cf = new com.sun.messaging.ConnectionFactory(); | ||
191 | |||
192 | ((com.sun.messaging.ConnectionFactory)cf).setProperty( | ||
193 | com.sun.messaging.ConnectionConfiguration.imqBrokerHostName, | ||
194 | serverHost); | ||
195 | ((com.sun.messaging.ConnectionFactory)cf).setProperty( | ||
196 | com.sun.messaging.ConnectionConfiguration.imqBrokerHostPort, | ||
197 | String.valueOf(serverPort)); | ||
198 | |||
199 | connection = cf.createConnection(); | ||
200 | session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); | ||
201 | } | ||
202 | |||
203 | /** | ||
204 | * Setup a consumer that listens on the Message Queue monitoring topic | ||
205 | * that sends out lists of destinations. | ||
206 | */ | ||
207 | private void initDestListConsumer() throws JMSException { | ||
208 | metricTopic = session.createTopic(DEST_LIST_TOPIC_NAME); | ||
209 | metricSubscriber = session.createConsumer(metricTopic); | ||
210 | metricSubscriber.setMessageListener(this); | ||
211 | } | ||
212 | |||
213 | |||
214 | |||
215 | /** | ||
216 | * Set text on footer | ||
217 | */ | ||
218 | private void setFooter(String s) { | ||
219 | footerLabel.setText(s); | ||
220 | footerLabel.paintImmediately(footerLabel.getBounds()); | ||
221 | } | ||
222 | |||
223 | /** | ||
224 | * Show the contents of a message in a seperate popup window | ||
225 | */ | ||
226 | private void showDetails(Message msg, int msgno) { | ||
227 | if (detailsFrame == null) { | ||
228 | // Create popup | ||
229 | detailsFrame = new JFrame(); | ||
230 | detailsFrame.setTitle(QBrowser.title + " - Message Details"); | ||
231 | detailsFrame.setBackground(Color.white); | ||
232 | detailsFrame.getContentPane().setLayout(new BorderLayout()); | ||
233 | |||
234 | headerPanel = new PropertyPanel(); | ||
235 | headerPanel.setTitle("JMS Headers"); | ||
236 | detailsFrame.getContentPane().add(BorderLayout.NORTH, headerPanel); | ||
237 | |||
238 | propertyPanel = new PropertyPanel(); | ||
239 | propertyPanel.setTitle("Message Properties"); | ||
240 | detailsFrame.getContentPane().add(BorderLayout.CENTER, propertyPanel); | ||
241 | |||
242 | bodyPanel = new PropertyPanel(); | ||
243 | bodyPanel.setTitle("Message body"); | ||
244 | detailsFrame.getContentPane().add(BorderLayout.SOUTH, bodyPanel); | ||
245 | detailsFrame.pack(); | ||
246 | } | ||
247 | |||
248 | // Load JMS headers from message | ||
249 | try { | ||
250 | HashMap hdrs = jmsHeadersToHashMap(msg); | ||
251 | headerPanel.setTitle("JMS Headers: Message #" + msgno); | ||
252 | headerPanel.load(hdrs); | ||
253 | } catch (JMSException ex) { | ||
254 | setFooter("Error: " + ex.getMessage()); | ||
255 | } | ||
256 | |||
257 | // Load message properties | ||
258 | HashMap props = new HashMap(); | ||
259 | // Get all message properties and stuff into a hash table | ||
260 | try { | ||
261 | for (Enumeration enu = msg.getPropertyNames(); | ||
262 | enu.hasMoreElements();) { | ||
263 | |||
264 | String name = (enu.nextElement()).toString(); | ||
265 | props.put(name, (msg.getObjectProperty(name)).toString()); | ||
266 | } | ||
267 | } catch (JMSException ex) { | ||
268 | setFooter("Error: " + ex.getMessage()); | ||
269 | } | ||
270 | propertyPanel.load(props); | ||
271 | |||
272 | // Load message body | ||
273 | bodyPanel.setTitle("Message Body: (" + QBrowser.messageType(msg) + ")"); | ||
274 | bodyPanel.load(jmsMsgBodyAsString(msg)); | ||
275 | |||
276 | detailsFrame.show(); | ||
277 | } | ||
278 | |||
279 | private void connect() throws JMSException { | ||
280 | if (connection == null) { | ||
281 | setFooter("Connecting to " + serverHost + ":" + | ||
282 | serverPort + "..."); | ||
283 | initJMS(); | ||
284 | |||
285 | try { | ||
286 | initDestListConsumer(); | ||
287 | } catch (JMSException e) { | ||
288 | // If we can't subscribe to the mq.metrics topic then we | ||
289 | // are probably not running against an EE broker. That's | ||
290 | // OK. It just means we can't populate the Destination | ||
291 | // combo-box on the GUI. | ||
292 | //System.out.println("Could not subscribe to " + | ||
293 | // DEST_LIST_TOPIC_NAME); | ||
294 | } | ||
295 | connection.start(); | ||
296 | setFooter("Connected to " + serverHost + ":" + serverPort); | ||
297 | } | ||
298 | } | ||
299 | |||
300 | |||
301 | /** | ||
302 | * Browse the queue | ||
303 | */ | ||
304 | private void doBrowse() { | ||
305 | |||
306 | ComboBoxEditor editor = qBox.getEditor(); | ||
307 | String name = (String)editor.getItem(); | ||
308 | setFooter("Browsing " + name + "..."); | ||
309 | |||
310 | // Browse queue | ||
311 | try { | ||
312 | String selector = null; | ||
313 | Queue q = session.createQueue(name); | ||
314 | QueueBrowser qb; | ||
315 | if (selector == null) { | ||
316 | qb = session.createBrowser(q); | ||
317 | } else { | ||
318 | qb = session.createBrowser(q, selector); | ||
319 | } | ||
320 | // Load messages into table | ||
321 | MsgTable mt = (MsgTable)msgTable.getModel(); | ||
322 | int n = mt.load(qb.getEnumeration()); | ||
323 | setFooter(name + ": " + String.valueOf(n)); | ||
324 | qb.close(); | ||
325 | } catch (JMSException ex) { | ||
326 | setFooter(ex.getMessage()); | ||
327 | } | ||
328 | } | ||
329 | |||
330 | /** | ||
331 | * Add a name to the "Queue Name" combo box menu | ||
332 | */ | ||
333 | private void addDestToMenu(String name) { | ||
334 | DefaultComboBoxModel model = (DefaultComboBoxModel)qBox.getModel(); | ||
335 | |||
336 | if (model.getIndexOf(name) < 0) { | ||
337 | // Name is not in menu. Add it. | ||
338 | model.addElement(name); | ||
339 | } | ||
340 | } | ||
341 | |||
342 | /** | ||
343 | * Main | ||
344 | */ | ||
345 | public static void main (String args[]) { | ||
346 | |||
347 | for (int n = 0; n < args.length; n++) { | ||
348 | if (args[n].equals("-b")) { | ||
349 | n++; | ||
350 | serverHost = args[n]; | ||
351 | } else if (args[n].equals("-p")) { | ||
352 | n++; | ||
353 | try { | ||
354 | serverPort = Integer.parseInt(args[n]); | ||
355 | } catch (NumberFormatException e) { | ||
356 | System.err.println("Bad port number: " + args[n]); | ||
357 | System.exit(1); | ||
358 | } | ||
359 | } else { | ||
360 | usage(); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | JFrame frame = new JFrame(); | ||
365 | frame.setTitle(QBrowser.title + " - " + serverHost + ":" + serverPort); | ||
366 | frame.setBackground(Color.white); | ||
367 | frame.getContentPane().setLayout(new BorderLayout()); | ||
368 | frame.getContentPane().add("Center", new QBrowser()); | ||
369 | frame.pack(); | ||
370 | frame.show(); | ||
371 | } | ||
372 | |||
373 | private static void usage() { | ||
374 | System.out.println( | ||
375 | "usage: QBrowser [-b <brokerhost>] [-p <brokerport>]" + "\n" + | ||
376 | " <brokerhost> Host to connect to. Default is " + | ||
377 | DEFAULT_BROKER_HOST + | ||
378 | "\n" + | ||
379 | " <brokerport> Port to connect to. Default is " + | ||
380 | DEFAULT_BROKER_PORT | ||
381 | ); | ||
382 | System.exit(1); | ||
383 | } | ||
384 | |||
385 | public static void dumpException(Exception e) { | ||
386 | Exception linked = null; | ||
387 | if (e instanceof JMSException) { | ||
388 | linked = ((JMSException)e).getLinkedException(); | ||
389 | } | ||
390 | |||
391 | if (linked == null) { | ||
392 | e.printStackTrace(); | ||
393 | } else { | ||
394 | System.err.println(e.toString()); | ||
395 | linked.printStackTrace(); | ||
396 | } | ||
397 | } | ||
398 | |||
399 | /** | ||
400 | * Return a string description of the type of JMS message | ||
401 | */ | ||
402 | static String messageType(Message m) { | ||
403 | |||
404 | if (m instanceof TextMessage) { | ||
405 | return "TextMessage"; | ||
406 | } else if (m instanceof BytesMessage) { | ||
407 | return "BytesMessage"; | ||
408 | } else if (m instanceof MapMessage) { | ||
409 | return "MapMessage"; | ||
410 | } else if (m instanceof ObjectMessage) { | ||
411 | return "ObjectMessage"; | ||
412 | } else if (m instanceof StreamMessage) { | ||
413 | return "StreamMessage"; | ||
414 | } else if (m instanceof Message) { | ||
415 | return "Message"; | ||
416 | } else { | ||
417 | // Unknown Message type | ||
418 | String type = m.getClass().getName(); | ||
419 | StringTokenizer st = new StringTokenizer(type, "."); | ||
420 | String s = null; | ||
421 | while (st.hasMoreElements()) { | ||
422 | s = st.nextToken(); | ||
423 | } | ||
424 | return s; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | /** | ||
429 | * Return a string representation of the body of a JMS | ||
430 | * bytes message. This is basically a hex dump of the body. | ||
431 | * Note, this only looks at the first 1K of the message body. | ||
432 | */ | ||
433 | private static String jmsBytesBodyAsString(Message m) { | ||
434 | byte[] body = new byte[1024]; | ||
435 | int n = 0; | ||
436 | |||
437 | if (m instanceof BytesMessage) { | ||
438 | try { | ||
439 | ((BytesMessage)m).reset(); | ||
440 | n = ((BytesMessage)m).readBytes(body); | ||
441 | } catch (JMSException ex) { | ||
442 | return (ex.toString()); | ||
443 | } | ||
444 | } else if (m instanceof StreamMessage) { | ||
445 | try { | ||
446 | ((StreamMessage)m).reset(); | ||
447 | n = ((StreamMessage)m).readBytes(body); | ||
448 | } catch (JMSException ex) { | ||
449 | return (ex.toString()); | ||
450 | } | ||
451 | } | ||
452 | |||
453 | if (n <= 0) { | ||
454 | return "<empty body>"; | ||
455 | } else { | ||
456 | return(toHexDump(body, n) + | ||
457 | ((n >= body.length ) ? "\n. . ." : "") ); | ||
458 | } | ||
459 | } | ||
460 | |||
461 | /** | ||
462 | * Return a string representation of a JMS message body | ||
463 | */ | ||
464 | private static String jmsMsgBodyAsString(Message m) { | ||
465 | |||
466 | if (m instanceof TextMessage) { | ||
467 | try { | ||
468 | return ((TextMessage) m).getText(); | ||
469 | } catch (JMSException ex) { | ||
470 | return ex.toString(); | ||
471 | } | ||
472 | } else if (m instanceof BytesMessage) { | ||
473 | return jmsBytesBodyAsString(m); | ||
474 | } else if (m instanceof MapMessage) { | ||
475 | MapMessage msg = (MapMessage)m; | ||
476 | HashMap props = new HashMap(); | ||
477 | // Get all MapMessage properties and stuff into a hash table | ||
478 | try { | ||
479 | for (Enumeration enu = msg.getMapNames(); | ||
480 | enu.hasMoreElements();) { | ||
481 | String name = (enu.nextElement()).toString(); | ||
482 | props.put(name, (msg.getObject(name)).toString()); | ||
483 | } | ||
484 | return props.toString(); | ||
485 | } catch (JMSException ex) { | ||
486 | return (ex.toString()); | ||
487 | } | ||
488 | } else if (m instanceof ObjectMessage) { | ||
489 | ObjectMessage msg = (ObjectMessage)m; | ||
490 | Object obj = null; | ||
491 | try { | ||
492 | obj = msg.getObject(); | ||
493 | if (obj != null) { | ||
494 | return obj.toString(); | ||
495 | } else { | ||
496 | return "null"; | ||
497 | } | ||
498 | } catch (Exception ex) { | ||
499 | return (ex.toString()); | ||
500 | } | ||
501 | } else if (m instanceof StreamMessage) { | ||
502 | return jmsBytesBodyAsString(m); | ||
503 | } else if (m instanceof Message) { | ||
504 | return "Can't get body for message of type Message"; | ||
505 | } | ||
506 | return "Unknown message type " + m; | ||
507 | } | ||
508 | |||
509 | /** | ||
510 | * Takes the JMS header fields of a JMS message and puts them in | ||
511 | * a HashMap | ||
512 | */ | ||
513 | private static HashMap jmsHeadersToHashMap(Message m) throws JMSException { | ||
514 | HashMap hdrs = new HashMap(); | ||
515 | String s = null; | ||
516 | |||
517 | s = m.getJMSCorrelationID(); | ||
518 | hdrs.put("JMSCorrelationID", s); | ||
519 | |||
520 | s = String.valueOf(m.getJMSDeliveryMode()); | ||
521 | hdrs.put("JMSDeliverMode", s); | ||
522 | |||
523 | Destination d = m.getJMSDestination(); | ||
524 | if (d != null) { | ||
525 | if (d instanceof Queue) { | ||
526 | s = ((Queue)d).getQueueName(); | ||
527 | } else { | ||
528 | s = ((Topic)d).getTopicName(); | ||
529 | } | ||
530 | } else { | ||
531 | s = ""; | ||
532 | } | ||
533 | hdrs.put("JMSDestination", s); | ||
534 | |||
535 | s = String.valueOf(m.getJMSExpiration()); | ||
536 | hdrs.put("JMSExpiration", s); | ||
537 | |||
538 | s = m.getJMSMessageID(); | ||
539 | hdrs.put("JMSMessageID", s); | ||
540 | |||
541 | s = String.valueOf(m.getJMSPriority()); | ||
542 | hdrs.put("JMSPriority", s); | ||
543 | |||
544 | s = String.valueOf(m.getJMSRedelivered()); | ||
545 | hdrs.put("JMSRedelivered", s); | ||
546 | |||
547 | d = m.getJMSDestination(); | ||
548 | if (d != null) { | ||
549 | if (d instanceof Queue) { | ||
550 | s = ((Queue)d).getQueueName(); | ||
551 | } else { | ||
552 | s = ((Topic)d).getTopicName(); | ||
553 | } | ||
554 | } else { | ||
555 | s = ""; | ||
556 | } | ||
557 | hdrs.put("JMSReplyTo", s); | ||
558 | |||
559 | s = String.valueOf(m.getJMSTimestamp()); | ||
560 | hdrs.put("JMSTimestamp", s); | ||
561 | |||
562 | s = m.getJMSType(); | ||
563 | hdrs.put("JMSType", s); | ||
564 | |||
565 | return hdrs; | ||
566 | } | ||
567 | |||
568 | /** | ||
569 | * Takes a buffer of bytes and returns a hex dump. Each hex digit | ||
570 | * represents 4 bits. The hex digits are formatted into groups of | ||
571 | * 4 (2 bytes, 16 bits). Each line has 8 groups, so each line represents | ||
572 | * 128 bits. | ||
573 | */ | ||
574 | private static String toHexDump(byte[] buf, int length) { | ||
575 | |||
576 | // Buffer must be an even length | ||
577 | if (buf.length % 2 != 0) { | ||
578 | throw new IllegalArgumentException(); | ||
579 | } | ||
580 | |||
581 | int value; | ||
582 | StringBuffer sb = new StringBuffer(buf.length * 2); | ||
583 | |||
584 | /* Assume buf is in network byte order (most significant byte | ||
585 | * is buf[0]). Convert two byte pairs to a short, then | ||
586 | * display as a hex string. | ||
587 | */ | ||
588 | int n = 0; | ||
589 | while (n < buf.length && n < length) { | ||
590 | value = buf[n + 1] & 0xFF; // Lower byte | ||
591 | value |= (buf[n] << 8) & 0xFF00; // Upper byte | ||
592 | String s = Integer.toHexString(value); | ||
593 | // Left bad with 0's | ||
594 | sb.append(pad[4 - s.length()]); | ||
595 | sb.append(s); | ||
596 | n += 2; | ||
597 | |||
598 | if (n % 16 == 0) { | ||
599 | sb.append("\n"); | ||
600 | } else { | ||
601 | sb.append(" "); | ||
602 | } | ||
603 | } | ||
604 | return sb.toString(); | ||
605 | } | ||
606 | |||
607 | /** | ||
608 | * Consumer that listens on the MQ monitoring topic that sends | ||
609 | * out lists of destination names. We use this to update the | ||
610 | * combo-box menu. | ||
611 | */ | ||
612 | public void onMessage(Message msg) { | ||
613 | |||
614 | try { | ||
615 | MapMessage mapMsg = (MapMessage)msg; | ||
616 | String type = mapMsg.getStringProperty("type"); | ||
617 | |||
618 | if (type.equals(DEST_LIST_TOPIC_NAME)) { | ||
619 | String oneRow[] = new String[ 3 ]; | ||
620 | |||
621 | TreeSet names = new TreeSet(); | ||
622 | |||
623 | /* | ||
624 | * Extract list of destinations | ||
625 | */ | ||
626 | for (Enumeration e = mapMsg.getMapNames(); | ||
627 | e.hasMoreElements();) { | ||
628 | String name = (String)e.nextElement(); | ||
629 | Hashtable values = (Hashtable)mapMsg.getObject(name); | ||
630 | |||
631 | // Sort names by putting them into TreeSet | ||
632 | if (values.get("type").toString().equals("queue")) { | ||
633 | names.add((String)values.get("name")); | ||
634 | } | ||
635 | } | ||
636 | |||
637 | // Add sorted names to combo box menu | ||
638 | for (Iterator iter = names.iterator(); iter.hasNext();) { | ||
639 | addDestToMenu((String)iter.next()); | ||
640 | } | ||
641 | } else { | ||
642 | System.err.println( | ||
643 | "Msg received: not destination list metric type"); | ||
644 | } | ||
645 | } catch (Exception e) { | ||
646 | System.err.println("onMessage: Exception caught: " + e); | ||
647 | } | ||
648 | } | ||
649 | |||
650 | class OptionListener implements ItemListener { | ||
651 | public void itemStateChanged(ItemEvent e) { | ||
652 | System.out.println("ItemEvent"); | ||
653 | } | ||
654 | } | ||
655 | |||
656 | class ExitListener implements ActionListener { | ||
657 | public void actionPerformed(ActionEvent e) { | ||
658 | shutdownJMS(); | ||
659 | System.exit(0); | ||
660 | } | ||
661 | } | ||
662 | |||
663 | class BrowseListener implements ActionListener { | ||
664 | public void actionPerformed(ActionEvent e) { | ||
665 | doBrowse(); | ||
666 | } | ||
667 | } | ||
668 | |||
669 | class TableMouseListener extends MouseAdapter { | ||
670 | public void mouseClicked(MouseEvent e) { | ||
671 | if (e.getClickCount() == 2) { | ||
672 | int row = msgTable.getSelectedRow(); | ||
673 | MsgTable mt = (MsgTable)msgTable.getModel(); | ||
674 | Message msg = mt.getMessageAtRow(row); | ||
675 | showDetails(msg, row); | ||
676 | } | ||
677 | } | ||
678 | } | ||
679 | |||
680 | class DetailsListener implements ActionListener { | ||
681 | public void actionPerformed(ActionEvent e) { | ||
682 | int row = msgTable.getSelectedRow(); | ||
683 | if (row < 0) { | ||
684 | setFooter("Please select a message"); | ||
685 | return; | ||
686 | } | ||
687 | MsgTable mt = (MsgTable)msgTable.getModel(); | ||
688 | Message msg = mt.getMessageAtRow(row); | ||
689 | showDetails(msg, row); | ||
690 | } | ||
691 | } | ||
692 | |||
693 | |||
694 | /** | ||
695 | * A table of JMS Messages | ||
696 | */ | ||
697 | class MsgTable extends AbstractTableModel { | ||
698 | |||
699 | final String[] columnNames = | ||
700 | {"#", "Timestamp", "Type", "Mode", "Priority"}; | ||
701 | |||
702 | SimpleDateFormat df = | ||
703 | new SimpleDateFormat("dd/MMM/yyyy:kk:mm:ss z"); | ||
704 | |||
705 | LinkedList list = null; | ||
706 | |||
707 | public int getRowCount() { | ||
708 | if (list == null) { | ||
709 | return 0; | ||
710 | } else { | ||
711 | return list.size(); | ||
712 | } | ||
713 | } | ||
714 | |||
715 | public int getColumnCount() { | ||
716 | return columnNames.length; | ||
717 | } | ||
718 | |||
719 | public String getColumnName(int column) { | ||
720 | return columnNames[column]; | ||
721 | } | ||
722 | |||
723 | public Object getValueAt(int row, int column) { | ||
724 | if (list == null) { | ||
725 | return null; | ||
726 | } | ||
727 | |||
728 | Message m = (Message)list.get(row); | ||
729 | |||
730 | if (m == null) { | ||
731 | return "null"; | ||
732 | } | ||
733 | |||
734 | try { | ||
735 | switch (column) { | ||
736 | case 0: | ||
737 | // Message number is the same as the row number | ||
738 | return new Integer(row); | ||
739 | case 1: | ||
740 | // Need to format into date/time | ||
741 | return df.format(new Date(m.getJMSTimestamp())); | ||
742 | case 2: | ||
743 | return QBrowser.messageType(m); | ||
744 | case 3: | ||
745 | // Delivery mode | ||
746 | int mode = m.getJMSDeliveryMode(); | ||
747 | if (mode == DeliveryMode.PERSISTENT) { | ||
748 | return "P"; | ||
749 | } else if (mode == DeliveryMode.NON_PERSISTENT) { | ||
750 | return "NP"; | ||
751 | } else { | ||
752 | return String.valueOf(mode) + "?"; | ||
753 | } | ||
754 | case 4: | ||
755 | // Priority | ||
756 | return new Integer(m.getJMSPriority()); | ||
757 | default: | ||
758 | return "Bad column value: " + column; | ||
759 | } | ||
760 | } catch (JMSException e) { | ||
761 | return ("Error: " + e); | ||
762 | } | ||
763 | } | ||
764 | |||
765 | |||
766 | |||
767 | /** | ||
768 | * Load and enumeration of messages into the table | ||
769 | */ | ||
770 | int load (Enumeration e) { | ||
771 | if (e == null) { | ||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | list = new LinkedList(); | ||
776 | |||
777 | while (e.hasMoreElements()) { | ||
778 | list.add(e.nextElement()); | ||
779 | } | ||
780 | |||
781 | fireTableDataChanged(); | ||
782 | |||
783 | return list.size(); | ||
784 | } | ||
785 | |||
786 | Message getMessageAtRow(int row) { | ||
787 | if (list == null) return null; | ||
788 | return((Message)list.get(row)); | ||
789 | } | ||
790 | } | ||
791 | |||
792 | |||
793 | /** | ||
794 | * A panel with a text area that knows how to format and display | ||
795 | * a HashMap of values. | ||
796 | */ | ||
797 | class PropertyPanel extends JPanel { | ||
798 | |||
799 | JLabel label = null; | ||
800 | JTextArea textArea = null; | ||
801 | JScrollPane areaScrollPane = null; | ||
802 | |||
803 | PropertyPanel() { | ||
804 | super(true); | ||
805 | setBorder(BorderFactory.createEtchedBorder()); | ||
806 | setLayout(new BorderLayout()); | ||
807 | |||
808 | label = new JLabel(); | ||
809 | |||
810 | textArea = new JTextArea(); | ||
811 | textArea.setFont(new Font("Monospaced", Font.PLAIN, 12)); | ||
812 | textArea.setLineWrap(true); | ||
813 | textArea.setWrapStyleWord(true); | ||
814 | |||
815 | areaScrollPane = new JScrollPane(textArea); | ||
816 | areaScrollPane.setVerticalScrollBarPolicy( | ||
817 | JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); | ||
818 | areaScrollPane.setPreferredSize(new Dimension(500, 150)); | ||
819 | |||
820 | add(BorderLayout.NORTH, label); | ||
821 | add(BorderLayout.CENTER, areaScrollPane); | ||
822 | } | ||
823 | |||
824 | void setTitle(String title) { | ||
825 | label.setText(title); | ||
826 | } | ||
827 | |||
828 | /** | ||
829 | * Display a HashMap in the text window | ||
830 | */ | ||
831 | void load(HashMap map) { | ||
832 | |||
833 | StringBuffer buf = new StringBuffer(); | ||
834 | |||
835 | Set entries = map.entrySet(); | ||
836 | Map.Entry entry = null; | ||
837 | Iterator iter = entries.iterator(); | ||
838 | while (iter.hasNext()) { | ||
839 | entry = (Map.Entry)iter.next(); | ||
840 | String key = entry.getKey().toString(); | ||
841 | |||
842 | Object o = entry.getValue(); | ||
843 | String value = ""; | ||
844 | if (o != null) { | ||
845 | value = o.toString(); | ||
846 | } | ||
847 | |||
848 | buf.append(pad(key + ": ", 20)); | ||
849 | buf.append(value + "\n"); | ||
850 | } | ||
851 | |||
852 | textArea.setText(buf.toString()); | ||
853 | |||
854 | areaScrollPane.scrollRectToVisible(new Rectangle(0, 0, 1, 1)); | ||
855 | |||
856 | } | ||
857 | |||
858 | /** | ||
859 | * Display text in the text window | ||
860 | */ | ||
861 | void load(String s) { | ||
862 | textArea.setText(s); | ||
863 | } | ||
864 | |||
865 | /** | ||
866 | * Pad a string to the specified width, right justified. | ||
867 | * If the string is longer than the width you get back the | ||
868 | * original string. | ||
869 | */ | ||
870 | String pad(String s, int width) { | ||
871 | |||
872 | // Very inefficient, but we don't care | ||
873 | StringBuffer sb = new StringBuffer(); | ||
874 | int padding = width - s.length(); | ||
875 | |||
876 | if (padding <= 0) { | ||
877 | return s; | ||
878 | } | ||
879 | |||
880 | while (padding > 0) { | ||
881 | sb.append(" "); | ||
882 | padding--; | ||
883 | } | ||
884 | sb.append(s); | ||
885 | return sb.toString(); | ||
886 | } | ||
887 | } | ||
888 | } |