1 /* 2 * Copyright (c) 2000, 2017 Oracle and/or its affiliates. All rights reserved. 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the Eclipse Distribution License v. 1.0, which is available at 6 * http://www.eclipse.org/org/documents/edl-v10.php. 7 * 8 * SPDX-License-Identifier: BSD-3-Clause 9 */ 10 11 /* 12 * @(#)SimpleChat.java 1.13 07/02/07 13 */ 14 15 import java.awt.*; 16 import java.awt.event.*; 17 import java.io.Serializable; 18 import java.net.InetAddress; 19 import java.util.Vector; 20 import java.util.Enumeration; 21 22 import javax.jms.*; 23 24 /** 25 * The SimpleChat example is a basic 'chat' application that uses 26 * the JMS APIs. It uses JMS Topics to represent chat rooms or 27 * chat topics. 28 * 29 * When the application is launched, use the 'Chat' menu to 30 * start or connect to a chat session. 31 * 32 * The command line option '-DimqAddressList='can be used to affect 33 * how the application connects to the message service provided by 34 * the Oracle GlassFish(tm) Server Message Queue software. 35 * 36 * It should be pointed out that the bulk of the application is 37 * AWT - code for the GUI. The code that implements the messages 38 * sent/received by the chat application is small in size. 39 * 40 * The SimpleChat example consists of the following classes, all 41 * contained in one file: 42 * 43 * SimpleChat - contains main() entry point, GUI/JMS 44 * initialization code. 45 * SimpleChatPanel - GUI for message textareas. 46 * SimpleChatDialog - GUI for "Connect" popup dialog. 47 * ChatObjMessage - chat message class. 48 * 49 * Description of the ChatObjMessage class and how it is used 50 * ========================================================== 51 * The ChatObjMessage class is used to broadcast messages in 52 * the JMS simplechat example. 53 * The interface SimpleChatMessageTypes (defined in this file) 54 * has several message 'types': 55 * 56 * From the interface definition: 57 * public static int JOIN = 0; 58 * public static int MSG = 1; 59 * public static int LEAVE = 2; 60 * 61 * JOIN - for applications to announce that they just joined the chat 62 * MSG - for normal text messages 63 * LEAVE - for applications to announce that are leaving the chat 64 * 65 * Each ChatObjMessage also has fields to indicate who the sender is 66 * - a simple String identifier. 67 * 68 * When the chat application enters a chat session, it broadcasts a JOIN 69 * message. Everybody currently in the chat session will get this and 70 * the chat GUI will recognize the message of type JOIN and will print 71 * something like this in the 'Messages in chat:' textarea: 72 * 73 * *** johndoe has joined chat session 74 * 75 * Once an application has entered a chat session, messages sent as part of 76 * a normal 'chat' are sent as ChatObjMessage's of type MSG. Upon seeing 77 * these messages, the chat GUI simply displays the sender and the message 78 * text as follows: 79 * 80 * johndoe: Hello World ! 81 * 82 * When a chat disconnect is done, prior to doing the various JMS cleanup 83 * operations, a LEAVE message is sent. The chat GUI sees this and prints 84 * something like: 85 * 86 * *** johndoe has left chat session 87 * 88 * 89 */ 90 public class SimpleChat implements ActionListener, 91 WindowListener, 92 MessageListener { 93 94 ConnectionFactory connectionFactory; 95 Connection connection; 96 Session session; 97 MessageProducer msgProducer; 98 MessageConsumer msgConsumer; 99 Topic topic; 100 101 boolean connected = false; 102 103 String name, hostName, topicName, outgoingMsgTypeString; 104 int outgoingMsgType; 105 106 Frame frame; 107 SimpleChatPanel scp; 108 SimpleChatDialog scd = null; 109 MenuItem connectItem, disconnectItem, clearItem, exitItem; 110 Button sendB, connectB, cancelB; 111 112 SimpleChatMessageCreator outgoingMsgCreator; 113 114 SimpleChatMessageCreator txtMsgCreator, objMsgCreator, mapMsgCreator, bytesMsgCreator, streamMsgCreator; 115 116 /** 117 * @param args Arguments passed via the command line. These are 118 * used to create the ConnectionFactory. 119 */ main(String[] args)120 public static void main(String[] args) { 121 SimpleChat sc = new SimpleChat(); 122 123 sc.initGui(); 124 sc.initJms(args); 125 } 126 127 /** 128 * SimpleChat constructor. 129 * Initializes the chat user name, topic, hostname. 130 */ SimpleChat()131 public SimpleChat() { 132 name = System.getProperty("user.name", "johndoe"); 133 topicName = "defaulttopic"; 134 135 try { 136 hostName = InetAddress.getLocalHost().getHostName(); 137 } catch (Exception e) { 138 hostName = "localhost"; 139 } 140 } 141 getMessageCreator(int type)142 public SimpleChatMessageCreator getMessageCreator(int type) { 143 switch (type) { 144 case SimpleChatDialog.MSG_TYPE_TEXT: 145 if (txtMsgCreator == null) { 146 txtMsgCreator = new SimpleChatTextMessageCreator(); 147 } 148 return (txtMsgCreator); 149 150 case SimpleChatDialog.MSG_TYPE_OBJECT: 151 if (objMsgCreator == null) { 152 objMsgCreator = new SimpleChatObjMessageCreator(); 153 } 154 return (objMsgCreator); 155 156 case SimpleChatDialog.MSG_TYPE_MAP: 157 if (mapMsgCreator == null) { 158 mapMsgCreator = new SimpleChatMapMessageCreator(); 159 } 160 return (mapMsgCreator); 161 162 case SimpleChatDialog.MSG_TYPE_BYTES: 163 if (bytesMsgCreator == null) { 164 bytesMsgCreator = new SimpleChatBytesMessageCreator(); 165 } 166 return (bytesMsgCreator); 167 168 case SimpleChatDialog.MSG_TYPE_STREAM: 169 if (streamMsgCreator == null) { 170 streamMsgCreator = new SimpleChatStreamMessageCreator(); 171 } 172 return (streamMsgCreator); 173 } 174 175 return (null); 176 } 177 getMessageCreator(Message msg)178 public SimpleChatMessageCreator getMessageCreator(Message msg) { 179 if (msg instanceof TextMessage) { 180 if (txtMsgCreator == null) { 181 txtMsgCreator = new SimpleChatTextMessageCreator(); 182 } 183 return (txtMsgCreator); 184 } else if (msg instanceof ObjectMessage) { 185 if (objMsgCreator == null) { 186 objMsgCreator = new SimpleChatObjMessageCreator(); 187 } 188 return (objMsgCreator); 189 } else if (msg instanceof MapMessage) { 190 if (mapMsgCreator == null) { 191 mapMsgCreator = new SimpleChatMapMessageCreator(); 192 } 193 return (mapMsgCreator); 194 } else if (msg instanceof BytesMessage) { 195 if (bytesMsgCreator == null) { 196 bytesMsgCreator = new SimpleChatBytesMessageCreator(); 197 } 198 return (bytesMsgCreator); 199 } else if (msg instanceof StreamMessage) { 200 if (streamMsgCreator == null) { 201 streamMsgCreator = new SimpleChatStreamMessageCreator(); 202 } 203 return (streamMsgCreator); 204 } 205 206 return (null); 207 } 208 209 /* 210 * BEGIN INTERFACE ActionListener 211 */ 212 /** 213 * Detects the various UI actions and performs the 214 * relevant action: 215 * Connect menu item (on Chat menu): Show Connect dialog 216 * Disconnect menu item (on Chat menu): Disconnect from chat 217 * Connect button (on Connect dialog): Connect to specified 218 * chat 219 * Cancel button (on Connect dialog): Hide Connect dialog 220 * Send button: Send message to chat 221 * Clear menu item (on Chat menu): Clear chat textarea 222 * Exit menu item (on Chat menu): Exit application 223 * 224 * @param ActionEvent UI event 225 */ actionPerformed(ActionEvent e)226 public void actionPerformed(ActionEvent e) { 227 Object obj = e.getSource(); 228 229 if (obj == connectItem) { 230 queryForChatNames(); 231 } else if (obj == disconnectItem) { 232 doDisconnect(); 233 } else if (obj == connectB) { 234 scd.setVisible(false); 235 236 topicName = scd.getChatTopicName(); 237 name = scd.getChatUserName(); 238 outgoingMsgTypeString = scd.getMsgTypeString(); 239 outgoingMsgType = scd.getMsgType(); 240 doConnect(); 241 } else if (obj == cancelB) { 242 scd.setVisible(false); 243 } else if (obj == sendB) { 244 sendNormalMessage(); 245 } else if (obj == clearItem) { 246 scp.clear(); 247 } else if (obj == exitItem) { 248 exit(); 249 } 250 } 251 /* 252 * END INTERFACE ActionListener 253 */ 254 255 /* 256 * BEGIN INTERFACE WindowListener 257 */ windowClosing(WindowEvent e)258 public void windowClosing(WindowEvent e) { 259 e.getWindow().dispose(); 260 } windowClosed(WindowEvent e)261 public void windowClosed(WindowEvent e) { 262 exit(); 263 } windowActivated(WindowEvent e)264 public void windowActivated(WindowEvent e) { } windowDeactivated(WindowEvent e)265 public void windowDeactivated(WindowEvent e) { } windowDeiconified(WindowEvent e)266 public void windowDeiconified(WindowEvent e) { } windowIconified(WindowEvent e)267 public void windowIconified(WindowEvent e) { } windowOpened(WindowEvent e)268 public void windowOpened(WindowEvent e) { } 269 /* 270 * END INTERFACE WindowListener 271 */ 272 273 /* 274 * BEGIN INTERFACE MessageListener 275 */ 276 /** 277 * Display chat message on gui. 278 * 279 * @param msg message received 280 */ onMessage(Message msg)281 public void onMessage(Message msg) { 282 String sender, msgText; 283 int type; 284 SimpleChatMessageCreator inboundMsgCreator; 285 286 inboundMsgCreator = getMessageCreator(msg); 287 288 if (inboundMsgCreator == null) { 289 errorMessage("Message received is not supported ! "); 290 return; 291 } 292 293 /* 294 * Need to fetch msg values in this order. 295 */ 296 type = inboundMsgCreator.getChatMessageType(msg); 297 sender = inboundMsgCreator.getChatMessageSender(msg); 298 msgText = inboundMsgCreator.getChatMessageText(msg); 299 300 if (type == SimpleChatMessageTypes.BADTYPE) { 301 errorMessage("Message received in wrong format ! "); 302 return; 303 } 304 305 scp.newMessage(sender, type, msgText); 306 } 307 /* 308 * END INTERFACE MessageListener 309 */ 310 311 312 /* 313 * Popup the SimpleChatDialog to query the user for the chat user 314 * name and chat topic. 315 */ queryForChatNames()316 private void queryForChatNames() { 317 if (scd == null) { 318 scd = new SimpleChatDialog(frame); 319 connectB = scd.getConnectButton(); 320 connectB.addActionListener(this); 321 cancelB = scd.getCancelButton(); 322 cancelB.addActionListener(this); 323 } 324 325 scd.setChatUserName(name); 326 scd.setChatTopicName(topicName); 327 scd.show(); 328 } 329 330 /* 331 * Performs the actual chat connect. 332 * The createChatSession() method does the real work 333 * here, creating: 334 * Connection 335 * Session 336 * Topic 337 * MessageConsumer 338 * MessageProducer 339 */ doConnect()340 private void doConnect() { 341 if (connectedToChatSession()) 342 return; 343 344 outgoingMsgCreator = getMessageCreator(outgoingMsgType); 345 346 if (createChatSession(topicName) == false) { 347 errorMessage("Unable to create Chat session. " + 348 "Please verify a broker is running"); 349 return; 350 } 351 setConnectedToChatSession(true); 352 353 connectItem.setEnabled(false); 354 disconnectItem.setEnabled(true); 355 356 scp.setUserName(name); 357 scp.setDestName(topicName); 358 scp.setMsgType(outgoingMsgTypeString); 359 scp.setHostName(hostName); 360 scp.setEnabled(true); 361 } 362 363 /* 364 * Disconnects from chat session. 365 * destroyChatSession() performs the JMS cleanup. 366 */ doDisconnect()367 private void doDisconnect() { 368 if (!connectedToChatSession()) 369 return; 370 371 destroyChatSession(); 372 373 setConnectedToChatSession(false); 374 375 connectItem.setEnabled(true); 376 disconnectItem.setEnabled(false); 377 scp.setEnabled(false); 378 } 379 380 /* 381 * These methods set/return a flag that indicates 382 * whether the application is currently involved in 383 * a chat session. 384 */ setConnectedToChatSession(boolean b)385 private void setConnectedToChatSession(boolean b) { 386 connected = b; 387 } connectedToChatSession()388 private boolean connectedToChatSession() { 389 return (connected); 390 } 391 392 /* 393 * Exit application. Does some cleanup if 394 * necessary. 395 */ exit()396 private void exit() { 397 doDisconnect(); 398 System.exit(0); 399 } 400 401 /* 402 * Create the application GUI. 403 */ initGui()404 private void initGui() { 405 406 frame = new Frame("Simple Chat"); 407 408 frame.addWindowListener(this); 409 410 MenuBar menubar = createMenuBar(); 411 412 frame.setMenuBar(menubar); 413 414 scp = new SimpleChatPanel(); 415 scp.setUserName(name); 416 scp.setDestName(topicName); 417 scp.setHostName(hostName); 418 sendB = scp.getSendButton(); 419 sendB.addActionListener(this); 420 421 frame.add(scp); 422 frame.pack(); 423 frame.setVisible(true); 424 425 scp.setEnabled(false); 426 } 427 428 /* 429 * Create menubar for application. 430 */ createMenuBar()431 private MenuBar createMenuBar() { 432 MenuBar mb = new MenuBar(); 433 Menu chatMenu; 434 435 chatMenu = (Menu) mb.add(new Menu("Chat")); 436 connectItem = (MenuItem) chatMenu.add(new MenuItem("Connect ...")); 437 disconnectItem = (MenuItem) chatMenu.add(new MenuItem("Disconnect")); 438 clearItem = (MenuItem) chatMenu.add(new MenuItem("Clear Messages")); 439 exitItem = (MenuItem) chatMenu.add(new MenuItem("Exit")); 440 441 disconnectItem.setEnabled(false); 442 443 connectItem.addActionListener(this); 444 disconnectItem.addActionListener(this); 445 clearItem.addActionListener(this); 446 exitItem.addActionListener(this); 447 448 return (mb); 449 } 450 451 /* 452 * Send message using text that is currently in the SimpleChatPanel 453 * object. The text message is obtained via scp.getMessage() 454 * 455 * An object of type ChatObjMessage is created containing the typed 456 * text. A JMS ObjectMessage is used to encapsulate this ChatObjMessage 457 * object. 458 */ sendNormalMessage()459 private void sendNormalMessage() { 460 Message msg; 461 462 if (!connectedToChatSession()) { 463 errorMessage("Cannot send message: Not connected to chat session!"); 464 465 return; 466 } 467 468 try { 469 msg = outgoingMsgCreator.createChatMessage(session, 470 name, 471 SimpleChatMessageTypes.NORMAL, 472 scp.getMessage()); 473 474 msgProducer.send(msg); 475 scp.setMessage(""); 476 scp.requestFocus(); 477 } catch (Exception ex) { 478 errorMessage("Caught exception while sending NORMAL message: " + ex); 479 } 480 } 481 482 /* 483 * Send a message to the chat session to inform people 484 * we just joined the chat. 485 */ sendJoinMessage()486 private void sendJoinMessage() { 487 Message msg; 488 489 try { 490 msg = outgoingMsgCreator.createChatMessage(session, 491 name, 492 SimpleChatMessageTypes.JOIN, 493 null); 494 495 msgProducer.send(msg); 496 } catch (Exception ex) { 497 errorMessage("Caught exception while sending JOIN message: " + ex); 498 } 499 } 500 /* 501 * Send a message to the chat session to inform people 502 * we are leaving the chat. 503 */ sendLeaveMessage()504 private void sendLeaveMessage() { 505 Message msg; 506 507 try { 508 msg = outgoingMsgCreator.createChatMessage(session, 509 name, 510 SimpleChatMessageTypes.LEAVE, 511 null); 512 513 msgProducer.send(msg); 514 } catch (Exception ex) { 515 errorMessage("Caught exception while sending LEAVE message: " + ex); 516 } 517 } 518 519 /* 520 * JMS initialization. 521 * This is simply creating the ConnectionFactory. 522 */ initJms(String args[])523 private void initJms(String args[]) { 524 /* XXX: chg for JMS1.1 to use BasicConnectionFactory for non-JNDI useage 525 * remove --- Use BasicConnectionFactory directly - no JNDI 526 */ 527 try { 528 connectionFactory 529 = new com.sun.messaging.ConnectionFactory(); 530 } catch (Exception e) { 531 errorMessage("Caught Exception: " + e); 532 } 533 } 534 535 /* 536 * Create 'chat session'. This involves creating: 537 * Connection 538 * Session 539 * Topic 540 * MessageConsumer 541 * MessageProducer 542 */ createChatSession(String topicStr)543 private boolean createChatSession(String topicStr) { 544 try { 545 /* 546 * Create the connection... 547 * 548 */ 549 connection = connectionFactory.createConnection(); 550 551 /* 552 * Not transacted 553 * Auto acknowledegement 554 */ 555 session = connection.createSession(false, 556 Session.AUTO_ACKNOWLEDGE); 557 558 topic = session.createTopic(topicStr); 559 msgProducer = session.createProducer(topic); 560 /* 561 * Non persistent delivery 562 */ 563 msgProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); 564 msgConsumer = session.createConsumer(topic); 565 msgConsumer.setMessageListener(this); 566 567 connection.start(); 568 569 sendJoinMessage(); 570 571 return true; 572 573 } catch (Exception e) { 574 errorMessage("Caught Exception: " + e); 575 e.printStackTrace(); 576 return false; 577 } 578 } 579 /* 580 * Destroy/close 'chat session'. 581 */ destroyChatSession()582 private void destroyChatSession() { 583 try { 584 sendLeaveMessage(); 585 586 msgConsumer.close(); 587 msgProducer.close(); 588 session.close(); 589 connection.close(); 590 591 topic = null; 592 msgConsumer = null; 593 msgProducer = null; 594 session = null; 595 connection = null; 596 597 } catch (Exception e) { 598 errorMessage("Caught Exception: " + e); 599 } 600 601 } 602 603 /* 604 * Display error. Right now all we do is dump to 605 * stderr. 606 */ errorMessage(String s)607 private void errorMessage(String s) { 608 System.err.println(s); 609 } 610 611 612 } 613 614 /** 615 * This class provides the bulk of the UI: 616 * sendMsgTA TextArea for typing messages to send 617 * msgsTA TextArea for displaying messages in chat 618 * sendB Send button for activating a message 'Send'. 619 * 620 * ...and various labels to indicate the chat topic name, 621 * the user name, and host name. 622 * 623 */ 624 class SimpleChatPanel extends Panel implements SimpleChatMessageTypes { 625 private String destName, 626 userName, 627 msgType, 628 hostName; 629 630 private Button sendB; 631 632 private Label destLabel, userLabel, msgTypeLabel, msgsLabel, 633 sendMsgLabel; 634 635 private TextArea msgsTA; 636 637 private TextArea sendMsgTA; 638 639 /** 640 * SimpleChatPanel constructor 641 */ SimpleChatPanel()642 public SimpleChatPanel() { 643 init(); 644 } 645 646 /** 647 * Set the chat username 648 * @param userName Chat userName 649 */ setUserName(String userName)650 public void setUserName(String userName) { 651 this.userName = userName; 652 userLabel.setText("User Id: " + userName); 653 sendB.setLabel("Send Message as " + userName); 654 } 655 /** 656 * Set the chat hostname. This is pretty much 657 * the host that the router is running on. 658 * @param hostName Chat hostName 659 */ setHostName(String hostName)660 public void setHostName(String hostName) { 661 this.hostName = hostName; 662 } 663 /** 664 * Sets the topic name. 665 * @param destName Chat topic name 666 */ setDestName(String destName)667 public void setDestName(String destName) { 668 this.destName = destName; 669 destLabel.setText("Topic: " + destName); 670 } 671 setMsgType(String msgType)672 public void setMsgType(String msgType) { 673 this.msgType = msgType; 674 msgTypeLabel.setText("Outgoing Msg Type: " + msgType); 675 } 676 677 /** 678 * Returns the 'Send' button. 679 */ getSendButton()680 public Button getSendButton() { 681 return(sendB); 682 } 683 684 /** 685 * Clears the chat message text area. 686 */ clear()687 public void clear() { 688 msgsTA.setText(""); 689 } 690 691 /** 692 * Appends the passed message to the chat message text area. 693 * @param msg Message to display 694 */ newMessage(String sender, int type, String text)695 public void newMessage(String sender, int type, String text) { 696 switch (type) { 697 case NORMAL: 698 msgsTA.append(sender + ": " + text + "\n"); 699 break; 700 701 case JOIN: 702 msgsTA.append("*** " + sender + " has joined chat session\n"); 703 break; 704 705 case LEAVE: 706 msgsTA.append("*** " + sender + " has left chat session\n"); 707 break; 708 709 default: 710 } 711 } 712 713 /** 714 * Sets the string to display on the chat message textarea 715 * @param s String to display 716 */ setMessage(String s)717 public void setMessage(String s) { 718 sendMsgTA.setText(s); 719 } 720 /** 721 * Returns the contents of the chat message textarea 722 */ getMessage()723 public String getMessage() { 724 return (sendMsgTA.getText()); 725 } 726 727 /* 728 * Init chat panel GUI elements. 729 */ init()730 private void init() { 731 732 Panel dummyPanel; 733 734 setLayout(new BorderLayout(0, 0)); 735 736 destLabel = new Label("Topic:"); 737 738 userLabel = new Label("User Id: "); 739 740 msgTypeLabel = new Label("Outgoing Msg Type:"); 741 742 743 744 dummyPanel = new Panel(); 745 dummyPanel.setLayout(new BorderLayout(0, 0)); 746 dummyPanel.add("North", destLabel); 747 dummyPanel.add("Center", userLabel); 748 dummyPanel.add("South", msgTypeLabel); 749 add("North", dummyPanel); 750 751 dummyPanel = new Panel(); 752 dummyPanel.setLayout(new BorderLayout(0, 0)); 753 msgsLabel = new Label("Messages in chat:"); 754 msgsTA = new TextArea(15, 40); 755 msgsTA.setEditable(false); 756 757 dummyPanel.add("North", msgsLabel); 758 dummyPanel.add("Center", msgsTA); 759 add("Center", dummyPanel); 760 761 dummyPanel = new Panel(); 762 dummyPanel.setLayout(new BorderLayout(0, 0)); 763 sendMsgLabel = new Label("Type Message:"); 764 sendMsgTA = new TextArea(5, 40); 765 sendB = new Button("Send Message"); 766 dummyPanel.add("North", sendMsgLabel); 767 dummyPanel.add("Center", sendMsgTA); 768 dummyPanel.add("South", sendB); 769 add("South", dummyPanel); 770 } 771 } 772 773 /** 774 * Dialog for querying the chat user name and chat topic. 775 * 776 */ 777 class SimpleChatDialog extends Dialog { 778 779 public final static int MSG_TYPE_UNDEFINED = -1; 780 public final static int MSG_TYPE_OBJECT = 0; 781 public final static int MSG_TYPE_TEXT = 1; 782 public final static int MSG_TYPE_MAP = 2; 783 public final static int MSG_TYPE_BYTES = 3; 784 public final static int MSG_TYPE_STREAM = 4; 785 786 private TextField nameF, topicF; 787 private Choice msgTypeChoice; 788 private Button connectB, cancelB; 789 790 /** 791 * SimpleChatDialog constructor. 792 * @param f Parent frame. 793 */ SimpleChatDialog(Frame f)794 public SimpleChatDialog(Frame f) { 795 super(f, "Simple Chat: Connect information", true); 796 init(); 797 setResizable(false); 798 } 799 800 /** 801 * Return 'Connect' button 802 */ getConnectButton()803 public Button getConnectButton() { 804 return (connectB); 805 } 806 /** 807 * Return 'Cancel' button 808 */ getCancelButton()809 public Button getCancelButton() { 810 return (cancelB); 811 } 812 813 /** 814 * Return chat user name entered. 815 */ getChatUserName()816 public String getChatUserName() { 817 if (nameF == null) 818 return (null); 819 return (nameF.getText()); 820 } 821 /** 822 * Set chat user name. 823 * @param s chat user name 824 */ setChatUserName(String s)825 public void setChatUserName(String s) { 826 if (nameF == null) 827 return; 828 nameF.setText(s); 829 } 830 831 /** 832 * Set chat topic 833 * @param s chat topic 834 */ setChatTopicName(String s)835 public void setChatTopicName(String s) { 836 if (topicF == null) 837 return; 838 topicF.setText(s); 839 } 840 /** 841 * Return chat topic 842 */ getChatTopicName()843 public String getChatTopicName() { 844 if (topicF == null) 845 return (null); 846 return (topicF.getText()); 847 } 848 849 /* 850 * Get message type 851 */ getMsgType()852 public int getMsgType() { 853 if (msgTypeChoice == null) 854 return (MSG_TYPE_UNDEFINED); 855 return (msgTypeChoice.getSelectedIndex()); 856 } 857 getMsgTypeString()858 public String getMsgTypeString() { 859 if (msgTypeChoice == null) 860 return (null); 861 return (msgTypeChoice.getSelectedItem()); 862 } 863 864 /* 865 * Init GUI elements. 866 */ init()867 private void init() { 868 Panel p, dummyPanel, labelPanel, valuePanel; 869 GridBagLayout labelGbag, valueGbag; 870 GridBagConstraints labelConstraints, valueConstraints; 871 Label chatNameLabel, chatTopicLabel, 872 msgTypeLabel; 873 int i, j; 874 875 p = new Panel(); 876 p.setLayout(new BorderLayout()); 877 878 dummyPanel = new Panel(); 879 dummyPanel.setLayout(new BorderLayout()); 880 881 /***/ 882 labelPanel = new Panel(); 883 labelGbag = new GridBagLayout(); 884 labelConstraints = new GridBagConstraints(); 885 labelPanel.setLayout(labelGbag); 886 j = 0; 887 888 valuePanel = new Panel(); 889 valueGbag = new GridBagLayout(); 890 valueConstraints = new GridBagConstraints(); 891 valuePanel.setLayout(valueGbag); 892 i = 0; 893 894 chatNameLabel = new Label("Chat User Name:", Label.RIGHT); 895 chatTopicLabel = new Label("Chat Topic:", Label.RIGHT); 896 msgTypeLabel = new Label("Outgoing Msg Type:", Label.RIGHT); 897 898 labelConstraints.gridx = 0; 899 labelConstraints.gridy = j++; 900 labelConstraints.weightx = 1.0; 901 labelConstraints.weighty = 1.0; 902 labelConstraints.anchor = GridBagConstraints.EAST; 903 labelGbag.setConstraints(chatNameLabel, labelConstraints); 904 labelPanel.add(chatNameLabel); 905 906 labelConstraints.gridy = j++; 907 labelGbag.setConstraints(chatTopicLabel, labelConstraints); 908 labelPanel.add(chatTopicLabel); 909 910 labelConstraints.gridy = j++; 911 labelGbag.setConstraints(msgTypeLabel, labelConstraints); 912 labelPanel.add(msgTypeLabel); 913 914 nameF = new TextField(20); 915 topicF = new TextField(20); 916 msgTypeChoice = new Choice(); 917 msgTypeChoice.insert("ObjectMessage", MSG_TYPE_OBJECT); 918 msgTypeChoice.insert("TextMessage", MSG_TYPE_TEXT); 919 msgTypeChoice.insert("MapMessage", MSG_TYPE_MAP); 920 msgTypeChoice.insert("BytesMessage", MSG_TYPE_BYTES); 921 msgTypeChoice.insert("StreamMessage", MSG_TYPE_STREAM); 922 msgTypeChoice.select(MSG_TYPE_STREAM); 923 924 valueConstraints.gridx = 0; 925 valueConstraints.gridy = i++; 926 valueConstraints.weightx = 1.0; 927 valueConstraints.weighty = 1.0; 928 valueConstraints.anchor = GridBagConstraints.WEST; 929 valueGbag.setConstraints(nameF, valueConstraints); 930 valuePanel.add(nameF); 931 932 valueConstraints.gridy = i++; 933 valueGbag.setConstraints(topicF, valueConstraints); 934 valuePanel.add(topicF); 935 936 valueConstraints.gridy = i++; 937 valueGbag.setConstraints(msgTypeChoice, valueConstraints); 938 valuePanel.add(msgTypeChoice); 939 940 dummyPanel.add("West", labelPanel); 941 dummyPanel.add("Center", valuePanel); 942 /***/ 943 944 p.add("North", dummyPanel); 945 946 dummyPanel = new Panel(); 947 connectB = new Button("Connect"); 948 cancelB = new Button("Cancel"); 949 dummyPanel.add(connectB); 950 dummyPanel.add(cancelB); 951 952 p.add("South", dummyPanel); 953 954 add(p); 955 pack(); 956 } 957 } 958 959 interface SimpleChatMessageTypes { 960 public static int JOIN = 0; 961 public static int NORMAL = 1; 962 public static int LEAVE = 2; 963 public static int BADTYPE = -1; 964 } 965 966 interface SimpleChatMessageCreator { createChatMessage(Session session, String sender, int type, String text)967 public Message createChatMessage(Session session, String sender, 968 int type, String text); isUsable(Message msg)969 public boolean isUsable(Message msg); getChatMessageType(Message msg)970 public int getChatMessageType(Message msg); getChatMessageSender(Message msg)971 public String getChatMessageSender(Message msg); getChatMessageText(Message msg)972 public String getChatMessageText(Message msg); 973 } 974 975 class SimpleChatTextMessageCreator implements 976 SimpleChatMessageCreator, SimpleChatMessageTypes { 977 private static String MSG_SENDER_PROPNAME = "SIMPLECHAT_MSG_SENDER"; 978 private static String MSG_TYPE_PROPNAME = "SIMPLECHAT_MSG_TYPE"; 979 createChatMessage(Session session, String sender, int type, String text)980 public Message createChatMessage(Session session, String sender, 981 int type, String text) { 982 TextMessage txtMsg = null; 983 984 try { 985 txtMsg = session.createTextMessage(); 986 txtMsg.setStringProperty(MSG_SENDER_PROPNAME, sender); 987 txtMsg.setIntProperty(MSG_TYPE_PROPNAME, type); 988 txtMsg.setText(text); 989 } catch (Exception ex) { 990 System.err.println("Caught exception while creating message: " + ex); 991 } 992 993 return (txtMsg); 994 } 995 isUsable(Message msg)996 public boolean isUsable(Message msg) { 997 if (msg instanceof TextMessage) { 998 return (true); 999 } 1000 1001 return (false); 1002 } 1003 getChatMessageType(Message msg)1004 public int getChatMessageType(Message msg) { 1005 int type = BADTYPE; 1006 1007 try { 1008 TextMessage txtMsg = (TextMessage)msg; 1009 type = txtMsg.getIntProperty(MSG_TYPE_PROPNAME); 1010 } catch (Exception ex) { 1011 System.err.println("Caught exception: " + ex); 1012 } 1013 1014 return (type); 1015 } 1016 getChatMessageSender(Message msg)1017 public String getChatMessageSender(Message msg) { 1018 String sender = null; 1019 1020 try { 1021 TextMessage txtMsg = (TextMessage)msg; 1022 sender = txtMsg.getStringProperty(MSG_SENDER_PROPNAME); 1023 } catch (Exception ex) { 1024 System.err.println("Caught exception: " + ex); 1025 } 1026 1027 return (sender); 1028 } 1029 getChatMessageText(Message msg)1030 public String getChatMessageText(Message msg) { 1031 String text = null; 1032 1033 try { 1034 TextMessage txtMsg = (TextMessage)msg; 1035 text = txtMsg.getText(); 1036 } catch (Exception ex) { 1037 System.err.println("Caught exception: " + ex); 1038 } 1039 1040 return (text); 1041 } 1042 } 1043 1044 class SimpleChatObjMessageCreator implements 1045 SimpleChatMessageCreator, SimpleChatMessageTypes { createChatMessage(Session session, String sender, int type, String text)1046 public Message createChatMessage(Session session, String sender, 1047 int type, String text) { 1048 ObjectMessage objMsg = null; 1049 ChatObjMessage sMsg; 1050 1051 try { 1052 objMsg = session.createObjectMessage(); 1053 sMsg = new ChatObjMessage(sender, type, text); 1054 objMsg.setObject(sMsg); 1055 } catch (Exception ex) { 1056 System.err.println("Caught exception while creating message: " + ex); 1057 } 1058 1059 return (objMsg); 1060 } 1061 isUsable(Message msg)1062 public boolean isUsable(Message msg) { 1063 try { 1064 ChatObjMessage sMsg = getSimpleChatMessage(msg); 1065 if (sMsg == null) { 1066 return (false); 1067 } 1068 } catch (Exception ex) { 1069 System.err.println("Caught exception: " + ex); 1070 } 1071 1072 return (true); 1073 } 1074 getChatMessageType(Message msg)1075 public int getChatMessageType(Message msg) { 1076 int type = BADTYPE; 1077 1078 try { 1079 ChatObjMessage sMsg = getSimpleChatMessage(msg); 1080 if (sMsg != null) { 1081 type = sMsg.getType(); 1082 } 1083 } catch (Exception ex) { 1084 System.err.println("Caught exception: " + ex); 1085 } 1086 1087 return (type); 1088 } 1089 getChatMessageSender(Message msg)1090 public String getChatMessageSender(Message msg) { 1091 String sender = null; 1092 1093 try { 1094 ChatObjMessage sMsg = getSimpleChatMessage(msg); 1095 if (sMsg != null) { 1096 sender = sMsg.getSender(); 1097 } 1098 } catch (Exception ex) { 1099 System.err.println("Caught exception: " + ex); 1100 } 1101 1102 return (sender); 1103 } 1104 getChatMessageText(Message msg)1105 public String getChatMessageText(Message msg) { 1106 String text = null; 1107 1108 try { 1109 ChatObjMessage sMsg = getSimpleChatMessage(msg); 1110 if (sMsg != null) { 1111 text = sMsg.getMessage(); 1112 } 1113 } catch (Exception ex) { 1114 System.err.println("Caught exception: " + ex); 1115 } 1116 1117 return (text); 1118 } 1119 getSimpleChatMessage(Message msg)1120 private ChatObjMessage getSimpleChatMessage(Message msg) { 1121 ObjectMessage objMsg; 1122 ChatObjMessage sMsg = null; 1123 1124 if (!(msg instanceof ObjectMessage)) { 1125 System.err.println("SimpleChatObjMessageCreator: Message received not of type ObjectMessage!"); 1126 return (null); 1127 } 1128 1129 objMsg = (ObjectMessage)msg; 1130 1131 try { 1132 sMsg = (ChatObjMessage)objMsg.getObject(); 1133 } catch (Exception ex) { 1134 System.err.println("Caught exception: " + ex); 1135 } 1136 1137 return (sMsg); 1138 } 1139 } 1140 1141 class SimpleChatMapMessageCreator implements 1142 SimpleChatMessageCreator, SimpleChatMessageTypes { 1143 private static String MAPMSG_SENDER_PROPNAME = "SIMPLECHAT_MAPMSG_SENDER"; 1144 private static String MAPMSG_TYPE_PROPNAME = "SIMPLECHAT_MAPMSG_TYPE"; 1145 private static String MAPMSG_TEXT_PROPNAME = "SIMPLECHAT_MAPMSG_TEXT"; 1146 createChatMessage(Session session, String sender, int type, String text)1147 public Message createChatMessage(Session session, String sender, 1148 int type, String text) { 1149 MapMessage mapMsg = null; 1150 1151 try { 1152 mapMsg = session.createMapMessage(); 1153 mapMsg.setInt(MAPMSG_TYPE_PROPNAME, type); 1154 mapMsg.setString(MAPMSG_SENDER_PROPNAME, sender); 1155 mapMsg.setString(MAPMSG_TEXT_PROPNAME, text); 1156 } catch (Exception ex) { 1157 System.err.println("Caught exception while creating message: " + ex); 1158 } 1159 1160 return (mapMsg); 1161 } 1162 isUsable(Message msg)1163 public boolean isUsable(Message msg) { 1164 if (msg instanceof MapMessage) { 1165 return (true); 1166 } 1167 1168 return (false); 1169 } 1170 getChatMessageType(Message msg)1171 public int getChatMessageType(Message msg) { 1172 int type = BADTYPE; 1173 1174 try { 1175 MapMessage mapMsg = (MapMessage)msg; 1176 type = mapMsg.getInt(MAPMSG_TYPE_PROPNAME); 1177 } catch (Exception ex) { 1178 System.err.println("Caught exception: " + ex); 1179 } 1180 1181 return (type); 1182 } 1183 getChatMessageSender(Message msg)1184 public String getChatMessageSender(Message msg) { 1185 String sender = null; 1186 1187 try { 1188 MapMessage mapMsg = (MapMessage)msg; 1189 sender = mapMsg.getString(MAPMSG_SENDER_PROPNAME); 1190 } catch (Exception ex) { 1191 System.err.println("Caught exception: " + ex); 1192 } 1193 1194 return (sender); 1195 } 1196 getChatMessageText(Message msg)1197 public String getChatMessageText(Message msg) { 1198 String text = null; 1199 1200 try { 1201 MapMessage mapMsg = (MapMessage)msg; 1202 text = mapMsg.getString(MAPMSG_TEXT_PROPNAME); 1203 } catch (Exception ex) { 1204 System.err.println("Caught exception: " + ex); 1205 } 1206 1207 return (text); 1208 } 1209 } 1210 1211 class SimpleChatBytesMessageCreator implements 1212 SimpleChatMessageCreator, SimpleChatMessageTypes { 1213 createChatMessage(Session session, String sender, int type, String text)1214 public Message createChatMessage(Session session, String sender, 1215 int type, String text) { 1216 BytesMessage bytesMsg = null; 1217 1218 try { 1219 byte b[]; 1220 1221 bytesMsg = session.createBytesMessage(); 1222 bytesMsg.writeInt(type); 1223 /* 1224 * Write length of sender and text strings 1225 */ 1226 b = sender.getBytes(); 1227 bytesMsg.writeInt(b.length); 1228 bytesMsg.writeBytes(b); 1229 1230 if (text != null) { 1231 b = text.getBytes(); 1232 bytesMsg.writeInt(b.length); 1233 bytesMsg.writeBytes(b); 1234 } else { 1235 bytesMsg.writeInt(0); 1236 } 1237 } catch (Exception ex) { 1238 System.err.println("Caught exception while creating message: " + ex); 1239 } 1240 1241 return (bytesMsg); 1242 } 1243 isUsable(Message msg)1244 public boolean isUsable(Message msg) { 1245 if (msg instanceof BytesMessage) { 1246 return (true); 1247 } 1248 1249 return (false); 1250 } 1251 getChatMessageType(Message msg)1252 public int getChatMessageType(Message msg) { 1253 int type = BADTYPE; 1254 1255 try { 1256 BytesMessage bytesMsg = (BytesMessage)msg; 1257 type = bytesMsg.readInt(); 1258 } catch (Exception ex) { 1259 System.err.println("Caught exception: " + ex); 1260 } 1261 1262 return (type); 1263 } 1264 getChatMessageSender(Message msg)1265 public String getChatMessageSender(Message msg) { 1266 String sender = null; 1267 1268 sender = readSizeFetchString(msg); 1269 1270 return (sender); 1271 } 1272 getChatMessageText(Message msg)1273 public String getChatMessageText(Message msg) { 1274 String text = null; 1275 1276 text = readSizeFetchString(msg); 1277 1278 return (text); 1279 } 1280 readSizeFetchString(Message msg)1281 private String readSizeFetchString(Message msg) { 1282 String stringData = null; 1283 1284 try { 1285 BytesMessage bytesMsg = (BytesMessage)msg; 1286 int length, needToRead; 1287 byte b[]; 1288 1289 length = bytesMsg.readInt(); 1290 1291 if (length == 0) { 1292 return (""); 1293 } 1294 1295 b = new byte [length]; 1296 1297 /* 1298 * Loop to keep reading until all the bytes are read in 1299 */ 1300 needToRead = length; 1301 while (needToRead > 0) { 1302 byte tmpBuf[] = new byte [needToRead]; 1303 int ret = bytesMsg.readBytes(tmpBuf); 1304 if (ret > 0) { 1305 for (int i=0; i < ret; ++i) { 1306 b[b.length - needToRead +i] = tmpBuf[i]; 1307 } 1308 needToRead -= ret; 1309 } 1310 } 1311 1312 stringData = new String(b); 1313 } catch (Exception ex) { 1314 System.err.println("Caught exception: " + ex); 1315 } 1316 1317 return (stringData); 1318 } 1319 } 1320 1321 class SimpleChatStreamMessageCreator implements 1322 SimpleChatMessageCreator, SimpleChatMessageTypes { 1323 createChatMessage(Session session, String sender, int type, String text)1324 public Message createChatMessage(Session session, String sender, 1325 int type, String text) { 1326 StreamMessage streamMsg = null; 1327 1328 try { 1329 byte b[]; 1330 1331 streamMsg = session.createStreamMessage(); 1332 streamMsg.writeInt(type); 1333 streamMsg.writeString(sender); 1334 1335 if (text == null) { 1336 text = ""; 1337 } 1338 streamMsg.writeString(text); 1339 } catch (Exception ex) { 1340 System.err.println("Caught exception while creating message: " + ex); 1341 } 1342 1343 return (streamMsg); 1344 } 1345 isUsable(Message msg)1346 public boolean isUsable(Message msg) { 1347 if (msg instanceof StreamMessage) { 1348 return (true); 1349 } 1350 1351 return (false); 1352 } 1353 getChatMessageType(Message msg)1354 public int getChatMessageType(Message msg) { 1355 int type = BADTYPE; 1356 1357 try { 1358 StreamMessage streamMsg = (StreamMessage)msg; 1359 type = streamMsg.readInt(); 1360 } catch (Exception ex) { 1361 System.err.println("getChatMessageType(): Caught exception: " + ex); 1362 } 1363 1364 return (type); 1365 } 1366 getChatMessageSender(Message msg)1367 public String getChatMessageSender(Message msg) { 1368 String sender = null; 1369 1370 try { 1371 StreamMessage streamMsg = (StreamMessage)msg; 1372 sender = streamMsg.readString(); 1373 } catch (Exception ex) { 1374 System.err.println("getChatMessageSender(): Caught exception: " + ex); 1375 } 1376 1377 return (sender); 1378 } 1379 getChatMessageText(Message msg)1380 public String getChatMessageText(Message msg) { 1381 String text = null; 1382 1383 try { 1384 StreamMessage streamMsg = (StreamMessage)msg; 1385 text = streamMsg.readString(); 1386 } catch (Exception ex) { 1387 System.err.println("getChatMessageText(): Caught exception: " + ex); 1388 } 1389 1390 return (text); 1391 } 1392 1393 } 1394 1395 1396 1397 1398 /** 1399 * Object representing a message sent by chat application. 1400 * We use this class and wrap a javax.jms.ObjectMessage 1401 * around it instead of using a javax.jms.TextMessage 1402 * because a simple string is not sufficient. We want 1403 * be able to to indicate that a message is one of these 1404 * types: 1405 * join message ('Hi, I just joined') 1406 * regular message (For regular chat messages) 1407 * leave message ('Bye, I'm leaving') 1408 * 1409 */ 1410 class ChatObjMessage implements java.io.Serializable, SimpleChatMessageTypes { 1411 private int type = NORMAL; 1412 private String sender, 1413 message; 1414 1415 /** 1416 * ChatObjMessage constructor. Construct a message with the given 1417 * sender and message. 1418 * @param sender Message sender 1419 * @param type Message type 1420 * @param message The message to send 1421 */ ChatObjMessage(String sender, int type, String message)1422 public ChatObjMessage(String sender, int type, String message) { 1423 this.sender = sender; 1424 this.type = type; 1425 this.message = message; 1426 } 1427 1428 /** 1429 * Returns message sender. 1430 */ getSender()1431 public String getSender() { 1432 return (sender); 1433 } 1434 1435 /** 1436 * Returns message type 1437 */ getType()1438 public int getType() { 1439 return (type); 1440 } 1441 1442 /** 1443 * Sets the message string 1444 * @param message The message string 1445 */ setMessage(String message)1446 public void setMessage(String message) { 1447 this.message = message; 1448 } 1449 /** 1450 * Returns the message string 1451 */ getMessage()1452 public String getMessage() { 1453 return (message); 1454 } 1455 } 1456