MsgParser.java :  » Messenger » tigertalk » client » Java Open Source

Java Open Source » Messenger » tigertalk 
tigertalk » client » MsgParser.java
package client;

import java.util.*;

import msgs.*;
import msgs.TTConstants.Actions;

import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;

/**
 * MsgParser: Parses incoming messages from the server
 * Team 9: Andrew Hayworth, Brian Parrella, Ryan Kortmann, Nina Papa
 * @author Andrew Hayworth
 */

public class MsgParser extends Thread implements TTConstants {
  private ClientMsg cmsg;
  private static boolean go;
  
  // this is lazy gui coding ... but I'm a lazy guy. 
  private JDialog jd;
  private JTextArea jta;
  
  public MsgParser() {
    go = true;
  }
  
  public void run() {
    while (go) {
      // only process if there's something to process
      if(!(ServerListener.inQ.isEmpty())){
        cmsg = ServerListener.inQ.remove(0);
        System.out.println(cmsg.getAction());
        switch (cmsg.getAction()) {
        
        case ADMIN_DISCONNECT:
          System.out.println("Disco msg recvd");
          // shit, we gotta gtfo!
          System.exit(0);
          break;
        case ADMIN_LIST_CHATS:
          ArrayList<String> a = new ArrayList<String>();
          a.addAll(TTClient.pmChats.keySet());
          String[] as = makeStringArray(a);
          cmsg.setChats(as);
          ServerSender.outQ.add(cmsg);
          break;
        // msgs sent to and from the server with action OFFLINE_MSG are offline PM messages, and responses from the server
        case OFFLINE_MSG:
          if (cmsg instanceof PMMsg) {
            // we only actually care if they came back online. the server sneds OK for every new message we send,
            //but I dont actually care if it fails, so i never test for that.
            if (((PMMsg)cmsg).getSpecialResponse() == 3 ) {
              // they came back online, so we change the chat with their name to reflect this and resend the last message requested
              TTClient.pmChats.get(((PMMsg)cmsg).getWantsUser()).setSpecialResponse(0);
              TTClient.pmChats.get(((PMMsg)cmsg).getWantsUser()).setTargetIP(((PMMsg)cmsg).getUserIP());
              PMSender.outQ.add(new SimpleMsg(((PMMsg)cmsg).getMsg(), TTClient.name, TTClient.pmChats.get(((PMMsg)cmsg).getWantsUser()).getTargetName(), TTClient.pmChats.get(((PMMsg)cmsg).getWantsUser()).getTargetIP(), TTClient.pmChats.get(((PMMsg)cmsg).getWantsUser()).getFromIP(), false));
              break;
            }
          }
          if (cmsg instanceof OfflinePMMsg) {
            /// HERE BE HACKS!!! DONT TOUCH!!!
            // sweet, someone needed to talk to us so badly that they left us a message!
            // this is the case that we already have a window open for them
            if (TTClient.pmChats.containsKey(((OfflinePMMsg)cmsg).getFromUser())) {
              TTClient.pmChats.get(((OfflinePMMsg)cmsg).getFromUser()).setVisible(true);
              TTClient.pmChats.get(((OfflinePMMsg)cmsg).getFromUser()).updateWindow(((OfflinePMMsg)cmsg).getMsg());
              TTClient.pmChats.get(((OfflinePMMsg)cmsg).getFromUser()).setSpecialResponse(2);
            }
            else {
              // we dont have a window open for them yet, create one!
              TTClient.pmChats.put(((OfflinePMMsg)cmsg).getFromUser(), new PMChat(new PMMsg(TTClient.ip, TTClient.name, null, TTClient.key, ((OfflinePMMsg)cmsg).getFromUser())));
              TTClient.pmChats.get(((OfflinePMMsg)cmsg).getFromUser()).updateWindow("**** Messages sent to you while offline ****");
              TTClient.pmChats.get(((OfflinePMMsg)cmsg).getFromUser()).updateWindow(((OfflinePMMsg)cmsg).getMsg());
              TTClient.pmChats.get(((OfflinePMMsg)cmsg).getFromUser()).setFromIP(((OfflinePMMsg)cmsg).getIp());
              TTClient.pmChats.get(((OfflinePMMsg)cmsg).getFromUser()).setSpecialResponse(2);
            } 
          }
          break;
          // we tried to pm a user, check the response from the server to see if we're allowed
        case PM_USER:
          // not allowed to pm -- ie, we're blocked
          if (((PMMsg)cmsg).getSpecialResponse() == 1) {
            JOptionPane.showMessageDialog(null, "Msg Failed!", "Not allowed to PM this user", JOptionPane.ERROR_MESSAGE);
            break;
          }
          // allowed to pm, but they're offline
          // send to the server instead
          else if (((PMMsg)cmsg).getSpecialResponse() == 2) {    
            // we should create a new chat, and instead of simplemsgs , we send pmmsgs to the server
            if (!(TTClient.pmChats.containsKey(((PMMsg)cmsg).getWantsUser()))) {
              //they have no window open for this user yet
              JOptionPane.showMessageDialog(null, "Requested user is offline -- all messages will be stored and sent to the user when they log on.", "User offline!", JOptionPane.INFORMATION_MESSAGE);
              TTClient.pmChats.put(((PMMsg)cmsg).getWantsUser(), new PMChat((PMMsg) cmsg));
              TTClient.pmChats.get(((PMMsg)cmsg).getWantsUser()).setSpecialResponse(2);
            }
            else
            {
              // have a window, raise it.
              TTClient.pmChats.get(((PMMsg)cmsg).getWantsUser()).setVisible(true);
              TTClient.pmChats.get(((PMMsg)cmsg).getWantsUser()).setSpecialResponse(2);
            }
            break;
          }
          //yay, we're allowed to pm and they're online!
          else {
            if(!(TTRunningClient.jf.isVisible()))
            {
            //  TTClient.trayIcon.displayMessage("Message from: " + ((PMMsg)cmsg).getWantsUser(), ((PMMsg)cmsg).getMsg(), org.jdesktop.jdic.tray.TrayIcon.INFO_MESSAGE_TYPE);
            }
            
            if (!(TTClient.pmChats.containsKey(((PMMsg)cmsg).getWantsUser()))) {
              TTClient.pmChats.put(((PMMsg)cmsg).getWantsUser(), new PMChat((PMMsg) cmsg));
            }
            else
            {
              TTClient.pmChats.get(((PMMsg)cmsg).getWantsUser()).setVisible(true);
            }
            break;
          }
        case KEEP_ALIVE:
          // server sends periodic keepalives. it just expects a reply, it doesnt care what it is, just resend the last thing we got in.
          ServerSender.outQ.add(cmsg);
          break;
        case PROFILE_UPDATE:
          // we tried to update our profile. success == silent, failure == this case:
          if (cmsg.getResponse() == TTConstants.Responses.DENY) {
            JOptionPane.showMessageDialog(null, "Update Failed!", "Update Failed!", JOptionPane.ERROR_MESSAGE);
          }
          break;
        case PROFILE_REQUEST:
          // we either wanted to update our profile, or are looking at someone elses.
          // if we're currently updating our profile, display the editor window
          if (TTClient.updatingProfile) {
            TTClient.updatingProfile = false;
            jd = new JDialog();
            JButton send = new JButton("Send");
            send.setMnemonic('S');
            JButton cancel = new JButton("Cancel");
            cancel.setMnemonic('C');
            jta = new JTextArea(10, 10);
            jta.setText(((ProfileMsg)cmsg).getProfile());
            JScrollPane jsp = new JScrollPane(jta);
            JPanel jp = new JPanel();
            jd.add(jsp, BorderLayout.CENTER);
            jp.add(send);
            jp.add(cancel);
            jd.add(jp, BorderLayout.SOUTH);
            jd.setSize(200,200);
            jd.setTitle("Edit Profile");
            jd.setLocationRelativeTo(null);
            jd.setVisible(true);
            cancel.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent ae) { jd.dispose(); }
            });
            send.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent ae) {
                ProfileMsg pm = new ProfileMsg(TTClient.ip, TTClient.name, TTClient.pwd, TTClient.key, true, jta.getText());
                pm.setProfile(jta.getText());
                pm.setAction(Actions.PROFILE_UPDATE);
                ServerSender.outQ.add(pm);
                jd.dispose();
              }
            });
            
          }
          // must have not been actually editing, just viewing 
          else {
            if (cmsg.getResponse() == Responses.OK) {
              JDialog jd = new JDialog();
              JPanel jp = new JPanel();
              JEditorPane jep = new JEditorPane();
              jep.setContentType("text/html");
              jep.setEditable(false);
              jep.setText(((ProfileMsg)cmsg).getProfile());
              System.out.println(jep.getText());
              JScrollPane jsp = new JScrollPane(jep);
              //jp.add(jsp);
              //jd.add(jp);
              jd.add(jsp);
              jd.setSize(200,200);
              jd.setTitle("Profile: " + ((ProfileMsg)cmsg).getWantsProfile());
              jd.setLocationRelativeTo(null);
              jd.setVisible(true);
            }
            // whoops, can't do that.
            else {
              JOptionPane.showMessageDialog(null, "Not allowed to view this profile", "Denied!", JOptionPane.ERROR_MESSAGE);
            }
          }
          break;
        case OFFLINE_NOTICE:
          // one of our buddies went offline
          TTClient.blDataStatus.remove(cmsg.getUser());
          TTClient.blDataStatus.put(cmsg.getUser(), 0);
          TTClient.updateBLNeeded = true;
          TTClient.playLogout();
          //gah, broken systems!
          // make sure that if they have a chat, they now know they're offline...
          if (TTClient.pmChats.containsKey(cmsg.getUser())) {
            TTClient.pmChats.get(cmsg.getUser()).setSpecialResponse(2);
          }
          break;
        case ONLINE_NOTICE:
          // one of our buddies came online
          TTClient.blDataStatus.remove(cmsg.getUser());
          TTClient.blDataStatus.put(cmsg.getUser(), 1);
          TTClient.updateBLNeeded = true;
          TTClient.playLogin();
          if (TTClient.pmChats.containsKey(cmsg.getUser())) {
            TTClient.pmChats.get(cmsg.getUser()).setSpecialResponse(0);
          }
          break;
        case WANT_BL:
          // we requested our buddy list
          if (((BLMsg) cmsg).getBuddyList() != null) {
            TTClient.blData = makeStringArray(((BLMsg)cmsg).getBuddyList());
            HashMap<String, Integer> h = new HashMap<String, Integer>();
            
            // hackish method of getting things into the online status table initially
            for (String s : TTClient.blData) {
              h.put(s, 0);
            }
            // now we query the entire group status
            QueryMsg qm = new QueryMsg(TTClient.ip, TTClient.name, TTClient.pwd, TTClient.key, TTClient.name);
            qm.setAction(TTConstants.Actions.QUERY_GROUP);
            qm.setUserList(h);
            ServerSender.outQ.add(qm);
            TTClient.updateBLNeeded = true;
          }
          else {
            // have no buddy list -- just add a blank line or something
            String[] s = { "" };
            TTClient.blData = s;
            TTClient.updateBLNeeded = true;
          }
          break;
        case QUERY_GROUP:
          // we got back a hashtable full of the status of the group
          TTClient.blDataStatus = ((QueryMsg)cmsg).getUserList();
          TTClient.updateBLNeeded = true;
          break;
        case BL_UPDATE:
          // we tried to update our list. complain if things failed
          if (cmsg.getResponse() != Responses.OK) {
            JOptionPane.showMessageDialog(null, "BuddyList update failed!", "Update failed!", JOptionPane.WARNING_MESSAGE);
          }
          else {
            // reset our copy of bl data.
            TTClient.blData = null;
            TTClient.blData = makeStringArray(((BLMsg)cmsg).getBuddyList());
            HashMap<String, Integer> h = new HashMap<String, Integer>();
            for (String s : TTClient.blData) {
              h.put(s, 0);
            }
            // and query for group status again
            QueryMsg qm = new QueryMsg(TTClient.ip, TTClient.name, TTClient.pwd, TTClient.key, TTClient.name);
            qm.setAction(TTConstants.Actions.QUERY_GROUP);
            qm.setUserList(h);
            ServerSender.outQ.add(qm);
            TTClient.updateBLNeeded = true;
          }
          break;
        case CHAT_UPDATE:
          // a group chat update message came in
          // if we do find the chat in the chat table
          //System.out.println("Chat title is " + ((ChatMsg)cmsg).getTitle());
          if (TTClient.chats.containsKey(((ChatMsg)cmsg).getTitle()) && (cmsg.getResponse() == Responses.OK)) {
            // update it
            //System.out.println(((ChatMsg)cmsg).getTitle());
            TTClient.chats.get(((ChatMsg)cmsg).getTitle()).updateChat(cmsg.getUser(), cmsg.getMsg());
            if (!cmsg.getUser().equals(TTClient.name)) TTClient.playMsgIn(); // only chime if it was an external update.
          }
          // otherwise, we just ignore the message, we must not be caring about it anymore or its a mistake
          //else System.out.println("couldnt find chat");
          break;
        case JOIN_CHAT:
          // we tried to join a chat
          if (cmsg.getResponse() == Responses.OK) {
            ((ChatMsg)cmsg).getMembers().add(TTClient.name);
            // sweet, create a new one
            TTClient.chats.put(((ChatMsg)cmsg).getTitle(), new Chat((ChatMsg)cmsg));
          }
          else {
            // complain 
            JOptionPane.showMessageDialog(null, "Not allowed to join this chat, or it doesn't exist.", "Join chat failed!", JOptionPane.ERROR_MESSAGE);
          }
          break;
        case NEW_CHAT:
          // we tried to create a chat
          if (cmsg.getResponse() != Responses.DENY) {
            // yay, add it to the list of running group chats!
            TTClient.chats.put(((ChatMsg)cmsg).getTitle(), new Chat((ChatMsg) cmsg));
          }
          else {
            // whine and cry
            JOptionPane.showMessageDialog(null, "Server does not allow you to create this chat.", "Create chat failed!", JOptionPane.ERROR_MESSAGE);
          }
          break;
        }
      }
      else {
        // queue was empty, so sleep as not to absolutely kill CPU/memory usage.
        // YES, this was a real problem until we added this in!
        try { Thread.sleep(100); }
        catch(InterruptedException e) {}
      }
    }
  }
  
  //OH MY GOD I HATE JAVA WHY CAN'T I JUST CAST FROM OBJECT[] TO STRING[] ??
  // this method exists as a convient way to get from an object[] array to a string[] array
  private String[] makeStringArray(ArrayList<String> al) {
    String[] s = new String[al.size()];
    for (int i = 0; i < s.length; i++) {
      s[i] = al.get(i);
      System.out.println(i + " " + s[i]);
    }
    return s;
  }
  
  /**
   * Kills off this thread/class
   */
  public static void killMsgParser() {
    while (go) {
      if (ServerListener.inQ.isEmpty()) go = false;
      else try {
        Thread.sleep(10);
      } 
      catch (Exception e) {}
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.