Package org.eclipse.ecf.internal.presence.bot.kosmos

Source Code of org.eclipse.ecf.internal.presence.bot.kosmos.ChatRoomMessageHandler

/*******************************************************************************
* Copyright (c) 2007, 2008 Remy Suen and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    Remy Suen <remy.suen@gmail.com> - initial API and implementation
*    Markus Kuppe <mkuppe@versant.com> - bug 184036
*    Nick Boldt <codeslave@ca.ibm.com> - bug 206528, 209410
*    Dominik Goepel <dominik.goepel@gmx.de> - bug 216644
******************************************************************************/
package org.eclipse.ecf.internal.presence.bot.kosmos;

import java.io.BufferedReader;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.identity.IDCreateException;
import org.eclipse.ecf.core.identity.IDFactory;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.presence.IIMMessageEvent;
import org.eclipse.ecf.presence.IIMMessageListener;
import org.eclipse.ecf.presence.bot.IChatRoomBotEntry;
import org.eclipse.ecf.presence.bot.IChatRoomMessageHandler;
import org.eclipse.ecf.presence.chatroom.IChatRoomContainer;
import org.eclipse.ecf.presence.chatroom.IChatRoomMessage;
import org.eclipse.ecf.presence.chatroom.IChatRoomMessageSender;
import org.eclipse.ecf.presence.im.IChatID;
import org.eclipse.ecf.presence.im.IChatMessageEvent;
import org.eclipse.ecf.presence.im.IChatMessageSender;
import org.eclipse.osgi.util.NLS;

public class ChatRoomMessageHandler implements IChatRoomMessageHandler {

  private static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$

  private static final String LICENSE = "###############################################################################" //$NON-NLS-1$
      + NEWLINE
      + "# Copyright (c) 2007, 2008 Remy Suen and others." //$NON-NLS-1$
      + NEWLINE
      + "# All rights reserved. This program and the accompaning materials" //$NON-NLS-1$
      + NEWLINE
      + "# are made available under the terms of the Eclipse Public License v1.0" //$NON-NLS-1$
      + NEWLINE
      + "# which accompanies this distribution, and is available at" //$NON-NLS-1$
      + NEWLINE
      + "# http://www.eclipse.org/legal/epl-v10.html" //$NON-NLS-1$
      + NEWLINE
      + "#" //$NON-NLS-1$
      + NEWLINE
      + "# Contributors:" //$NON-NLS-1$
      + NEWLINE
      + "#    Remy Suen <remy.suen@gmail.com> - initial API and implementation" //$NON-NLS-1$
      + NEWLINE
      + "#    Markus Kuppe <mkuppe@versant.com> - bug 184036" //$NON-NLS-1$
      + NEWLINE
      +" *    Nick Boldt <codeslave@ca.ibm.com> - bug 206528, 209410" //$NON-NLS-1$
      + NEWLINE
      +" *    Dominik Goepel <dominik.goepel@gmx.de> - bug 216644" //$NON-NLS-1$
      + NEWLINE
      +" *    Nitin Dahyabhai <nitind@us.ibm.com> - bug 308908"
      + NEWLINE
      + "################################################################################"; //$NON-NLS-1$

  private static final String BUG_DATABASE_PREFIX = "https://bugs.eclipse.org/bugs/show_bug.cgi?id="; //$NON-NLS-1$
  private static final String BUG_DATABASE_POSTFIX = "&ctype=xml"; //$NON-NLS-1$

  private static final String SHORT_DESC_OPEN_TAG = "<short_desc>"; //$NON-NLS-1$
  private static final String SHORT_DESC_CLOSE_TAG = "</short_desc>"; //$NON-NLS-1$

  private static final String PRODUCT_OPEN_TAG = "<product>"; //$NON-NLS-1$
  private static final String PRODUCT_CLOSE_TAG = "</product>"; //$NON-NLS-1$

  private static final String COMPONENT_OPEN_TAG = "<component>"; //$NON-NLS-1$
  private static final String COMPONENT_CLOSE_TAG = "</component>"; //$NON-NLS-1$

  private static final String VERSION_OPEN_TAG = "<version>"; //$NON-NLS-1$
  private static final String VERSION_CLOSE_TAG = "</version>"; //$NON-NLS-1$

  private static final String REP_PLATFORM_OPEN_TAG = "<rep_platform>"; //$NON-NLS-1$
  private static final String REP_PLATFORM_CLOSE_TAG = "</rep_platform>"; //$NON-NLS-1$

  private static final String OP_SYS_OPEN_TAG = "<op_sys>"; //$NON-NLS-1$
  private static final String OP_SYS_CLOSE_TAG = "</op_sys>"; //$NON-NLS-1$

  private static final String BUG_STATUS_OPEN_TAG = "<bug_status>"; //$NON-NLS-1$
  private static final String BUG_STATUS_CLOSE_TAG = "</bug_status>"; //$NON-NLS-1$

  private static final String RESOLUTION_OPEN_TAG = "<resolution>"; //$NON-NLS-1$
  private static final String RESOLUTION_CLOSE_TAG = "</resolution>"; //$NON-NLS-1$

  private static final String BUG_SEVERITY_OPEN_TAG = "<bug_severity>"; //$NON-NLS-1$
  private static final String BUG_SEVERITY_CLOSE_TAG = "</bug_severity>"; //$NON-NLS-1$

  private static final String ASSIGNED_TO_CLOSE_TAG = "</assigned_to>"; //$NON-NLS-1$

  private static final String BUG_NOT_FOUND_TAG = "<bug error=\"NotFound\">"; //$NON-NLS-1$

  private static final File HTML_FILE_MESSAGES = new File(
      System.getProperty("user.home") + File.separator + "public_html" + File.separator + "messages.html"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  private static final File HTML_FILE_COMMANDS = new File(
      System.getProperty("user.home") + File.separator + "public_html" + File.separator + "commands.html"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

  private static final String URL_REGEX = "(http://.+|https://.+|ftp://.+)"; //$NON-NLS-1$
  private static final String CMD_REGEX = "(~.+)"; //$NON-NLS-1$
  private static final String BINDING_REGEX = "(\\{[0-9]+\\})"; //$NON-NLS-1$

  private static final Pattern URL_PATTERN = Pattern.compile(URL_REGEX);
  private static final Pattern CMD_PATTERN = Pattern.compile(CMD_REGEX);
  private static final Pattern BINDING_PATTERN = Pattern
      .compile(BINDING_REGEX);

  private Map messageSenders;
  private Map newsgroups;
  private Set operators;
  private Properties messages;
  private Properties commands;
  private JavadocAnalyzer analyzer;

  private IContainer container;

  private IChatMessageSender chatMessageSender;
 
  /**
   * The name of this bot. May be <code>null</code> if the name could not be retrieved from the container.
   */
  private String botName;

  private String password;

  private static final String xmlDecode(String string) {
    if (string == null || string.equals("")) { //$NON-NLS-1$
      return ""; //$NON-NLS-1$
    }

    int index = string.indexOf("&amp;"); //$NON-NLS-1$
    while (index != -1) {
      string = string.substring(0, index) + '&'
          + string.substring(index + 5);
      index = string.indexOf("&amp;", index + 1); //$NON-NLS-1$
    }

    index = string.indexOf("&quot;"); //$NON-NLS-1$
    while (index != -1) {
      string = string.substring(0, index) + '"'
          + string.substring(index + 6);
      index = string.indexOf("&quot;", index + 1); //$NON-NLS-1$
    }

    index = string.indexOf("&apos;"); //$NON-NLS-1$
    while (index != -1) {
      string = string.substring(0, index) + '\''
          + string.substring(index + 6);
      index = string.indexOf("&apos;", index + 1); //$NON-NLS-1$
    }

    index = string.indexOf("&lt;"); //$NON-NLS-1$
    while (index != -1) {
      string = string.substring(0, index) + '<'
          + string.substring(index + 4);
      index = string.indexOf("&lt;", index + 1); //$NON-NLS-1$
    }

    index = string.indexOf("&gt;"); //$NON-NLS-1$
    while (index != -1) {
      string = string.substring(0, index) + '>'
          + string.substring(index + 4);
      index = string.indexOf("&gt;", index + 1); //$NON-NLS-1$
    }
    return string;
  }

  public ChatRoomMessageHandler() {
    messageSenders = new HashMap();
    analyzer = new JavadocAnalyzer();

    try {
      parseOperators();
    } catch (Exception e) {
      operators = Collections.EMPTY_SET;
    }

    try {
      parseMessages();
    } catch (Exception e) {
      messages = new Properties();
    }

    try {
      parseCommands();
    } catch (Exception e) {
      commands = new Properties();
    }

    try {
      writeCommandsToHTML();
    } catch (Exception e) {
      e.printStackTrace();
    }      

    try {
      parseNewsgroup();
    } catch (Exception e) {
      newsgroups = Collections.EMPTY_MAP;
    }
  }

  private void parseOperators() throws IOException {
    Properties properties = new Properties();
    InputStream stream = FileLocator.openStream(Activator.getBundle(),
        new Path("operators.properties"), false);
    properties.load(stream);
    stream.close();
    String operatorString = properties.getProperty("operators");
    String[] operators = operatorString.split(",");
    this.operators = new HashSet(operators.length);
    for (int i = 0; i < operators.length; i++) {
      this.operators.add(operators[i].trim());
    }
  }

  private void parseMessages() throws IOException {
    messages = new Properties();
    InputStream stream = FileLocator.openStream(Activator.getBundle(),
        new Path("messages.properties"), false);
    messages.load(stream);
    stream.close();
  }

  /*
   * collect commands from custom.properties -- only want those for which
   * there's a matching *_Regex key/value pair, eg., EclipseHelp +
   * EclipseHelp_Regex
   */
  private void parseCommands() throws IOException {
    commands = new Properties();
    Properties commandsAll = new Properties();
    commandsAll.load(ChatRoomMessageHandler.class
        .getResourceAsStream("custom.properties")); //$NON-NLS-1$
    Enumeration keys = commandsAll.keys();
    while (keys.hasMoreElements()) {
      String key = (String) keys.nextElement();
      String keyRegex = key + "_Regex"; //$NON-NLS-1$
      if (commandsAll.keySet().contains(keyRegex)) {
        commands.setProperty(commandsAll.get(keyRegex).toString(),
            commandsAll.get(key).toString());
      }
    }
  }

  private void parseNewsgroup() throws IOException {
    Properties properties = new Properties();
    properties.load(JavadocAnalyzer.class
        .getResourceAsStream("newsgroup.txt"));
    newsgroups = new HashMap();
    for (Iterator it = properties.keySet().iterator(); it.hasNext();) {
      Object key = it.next();
      Object value = properties.get(key);
      newsgroups.put(key, value);
      newsgroups.put(value, value);
    }
  }

  private void sendMessage(ID id, String message) {
    try {
      if (container != null) {
        IChatRoomMessageSender sender = (IChatRoomMessageSender) messageSenders
            .get(id);
        if (sender == null) {
          chatMessageSender.sendChatMessage(id, message);
        } else {
          sender.sendMessage(message);
        }
      }
    } catch (ECFException e) {
      e.printStackTrace();
      container.disconnect();
      container = null;
    }
  }

  private void sendBug(ID roomID, String target, String number, String comment) {
    String urlString = BUG_DATABASE_PREFIX + number;
    if (comment != null) {
      urlString = urlString + "#c" + comment; //$NON-NLS-1$
    }
    try {
      HttpURLConnection hURL = (HttpURLConnection) new URL(
          BUG_DATABASE_PREFIX + number + BUG_DATABASE_POSTFIX)
          .openConnection();
      hURL.setAllowUserInteraction(true);
      hURL.connect();
      BufferedReader reader = new BufferedReader(new InputStreamReader(
          hURL.getInputStream()));
      StringBuffer buffer = new StringBuffer();
      try {
        if (hURL.getResponseCode() != HttpURLConnection.HTTP_OK) {
          sendMessage(roomID, (target != null ? target + ": " : "")
              + NLS.bind(CustomMessages.Bug, number, urlString));
          return;
        }

        String input = reader.readLine();
        synchronized (buffer) {
          buffer.append(input);
          while (input != null
              && input.indexOf(ASSIGNED_TO_CLOSE_TAG) == -1) {
            if (input.indexOf(BUG_NOT_FOUND_TAG) != -1) { /*
                                     * handle
                                     * case
                                     * where
                                     * bug
                                     * does
                                     * not
                                     * exist,
                                     * eg.
                                     * ~bug1234
                                     */
              sendMessage(
                  roomID,
                  (target != null ? target + ": " : "")
                      + NLS
                          .bind(
                              CustomMessages
                                  .getString(CustomMessages.Bug_Not_Found),
                              number));
              return;
            }
            input = reader.readLine();
            buffer.append(input);
          }
        }
        hURL.disconnect();
      } catch (EOFException e) {
        hURL.disconnect();
        sendMessage(roomID, (target != null ? target + ": " : "")
            + NLS.bind(CustomMessages.Bug, number, urlString));
        e.printStackTrace();
        return;
      }
      String webPage = buffer.toString();
      int summaryStartIndex = webPage.indexOf(SHORT_DESC_OPEN_TAG);
      int summaryEndIndex = webPage.indexOf(SHORT_DESC_CLOSE_TAG,
          summaryStartIndex);
      if (summaryStartIndex != -1 & summaryEndIndex != -1) {
        try {
          String summary = webPage.substring(summaryStartIndex
              + SHORT_DESC_OPEN_TAG.length(), summaryEndIndex);
          String product = webPage.substring(webPage
              .indexOf(PRODUCT_OPEN_TAG)
              + PRODUCT_OPEN_TAG.length(), webPage
              .indexOf(PRODUCT_CLOSE_TAG));
          String component = webPage.substring(webPage
              .indexOf(COMPONENT_OPEN_TAG)
              + COMPONENT_OPEN_TAG.length(), webPage
              .indexOf(COMPONENT_CLOSE_TAG));
          String version = webPage.substring(webPage
              .indexOf(VERSION_OPEN_TAG)
              + VERSION_OPEN_TAG.length(), webPage
              .indexOf(VERSION_CLOSE_TAG));
          String platform = webPage.substring(webPage
              .indexOf(REP_PLATFORM_OPEN_TAG)
              + REP_PLATFORM_OPEN_TAG.length(), webPage
              .indexOf(REP_PLATFORM_CLOSE_TAG));
          String os = webPage.substring(webPage
              .indexOf(OP_SYS_OPEN_TAG)
              + OP_SYS_OPEN_TAG.length(), webPage
              .indexOf(OP_SYS_CLOSE_TAG));
          String status = webPage.substring(webPage
              .indexOf(BUG_STATUS_OPEN_TAG)
              + BUG_STATUS_OPEN_TAG.length(), webPage
              .indexOf(BUG_STATUS_CLOSE_TAG));
          String severity = webPage.substring(webPage
              .indexOf(BUG_SEVERITY_OPEN_TAG)
              + BUG_SEVERITY_OPEN_TAG.length(), webPage
              .indexOf(BUG_SEVERITY_CLOSE_TAG));
          String assignee = webPage.substring(webPage.substring(0,
              webPage.indexOf(ASSIGNED_TO_CLOSE_TAG))
              .lastIndexOf('>') + 1, webPage
              .indexOf(ASSIGNED_TO_CLOSE_TAG));

          int resolutionStartIndex = webPage
              .indexOf(RESOLUTION_OPEN_TAG);
          if (resolutionStartIndex != -1) {
            String resolution = webPage.substring(
                resolutionStartIndex
                    + RESOLUTION_OPEN_TAG.length(), webPage
                    .indexOf(RESOLUTION_CLOSE_TAG));
            sendMessage(roomID, (target != null ? target + ": "
                : "")
                + NLS.bind(CustomMessages
                    .getString(CustomMessages.BugContent),
                    new Object[] { number, urlString,
                        product, component, version,
                        platform, os, status,
                        resolution, severity, assignee,
                        xmlDecode(summary) }));
          } else {
            sendMessage(roomID, (target != null ? target + ": "
                : "")
                + NLS.bind(CustomMessages
                    .getString(CustomMessages.BugContent2),
                    new Object[] { number, urlString,
                        product, component, version,
                        platform, os, status, severity,
                        assignee, xmlDecode(summary) }));
          }
        } catch (RuntimeException e) {
          sendMessage(roomID, (target != null ? target + ": " : "")
              + NLS.bind(CustomMessages
                  .getString(CustomMessages.Bug),
                  new Object[] { number, urlString }));
        }
      } else {
        sendMessage(roomID, (target != null ? target + ": " : "")
            + NLS.bind(
                CustomMessages.getString(CustomMessages.Bug),
                new Object[] { number, urlString }));
      }
    } catch (IOException e) {
      sendMessage(roomID, (target != null ? target + ": " : "")
          + NLS.bind(CustomMessages.getString(CustomMessages.Bug),
              new Object[] { number, urlString }));
      e.printStackTrace();
    }
  }

  private void sendNewsgroupSearch(ID roomID, String target, String query) {
    String[] strings = query.split(" "); //$NON-NLS-1$
    if (strings.length == 1) {
      sendMessage(roomID, (target != null ? target + ": " : "")
          + CustomMessages
              .getString(CustomMessages.NewsgroupSearch_Invalid));
      return;
    }
    for (int i = 0; i < strings.length; i++) {
      try {
        strings[i] = URLEncoder.encode(strings[i].trim(), "UTF-8"); //$NON-NLS-1$
      } catch (UnsupportedEncodingException e) {
        // technically this should never happen, but better safe than
        // sorry
        strings[i] = URLEncoder.encode(strings[i].trim());
      }
    }

    /*
     * support either a lookup in the newsgroups static list, or input of
     * eclipse.foo.bar as a presumed valid group
     */
    String newsgroup = strings[0].startsWith("eclipse.") ? "news."
        + strings[0] : (String) newsgroups.get(strings[0]);

    /*
     * if newsgroup doesn't start with "eclipse." and lookup fails, we get
     * back null; help the user when this happens
     */
    if (newsgroup == null) {
      sendMessage(
          roomID,
          (target != null ? target + ": " : "")
              + CustomMessages
                  .getString(CustomMessages.NewsgroupSearch_InvalidGroup));
      return;
    }
    StringBuffer buffer = new StringBuffer();
    synchronized (buffer) {
      for (int i = 1; i < strings.length; i++) {
        buffer.append(strings[i] + '+');
      }
      buffer.deleteCharAt(buffer.length() - 1);
    }
    sendMessage(roomID, (target != null ? target + ": " : "")
        + NLS.bind(CustomMessages
            .getString(CustomMessages.NewsgroupSearch), newsgroup,
            buffer.toString()));
  }

  private void sendGoogle(ID roomID, String target, String searchString) {
    searchString = searchString.replace(' ', '+');
    sendMessage(roomID, (target != null ? target + ": " : "")
        + NLS.bind(CustomMessages.getString(CustomMessages.Google),
            searchString));
  }

  private void sendWiki(ID roomID, String target, String articleName) {
    articleName = articleName.replace(' ', '_');
    sendMessage(roomID, (target != null ? target + ": " : "")
        + NLS.bind(CustomMessages.getString(CustomMessages.Wiki),
            articleName));
  }

  private void sendEclipseHelp(ID roomID, String target, String searchString) {
    searchString = searchString.replace(' ', '+');
    sendMessage(roomID, (target != null ? target + ": " : "")
        + NLS.bind(
            CustomMessages.getString(CustomMessages.EclipseHelp),
            searchString));
  }

  private void sendJavaDoc(ID roomID, String target, String parameter) {
    String message = null;
    int index = parameter.indexOf('#');
    if (index == -1) {
      message = analyzer.getJavadocs(parameter);
    } else {
      String className = parameter.substring(0, index);
      parameter = parameter.substring(index + 1);
      index = parameter.indexOf('(');
      if (index == -1) {
        message = className + '#' + parameter + " - "
            + analyzer.getJavadocs(className, parameter);
      } else {
        String method = parameter.substring(0, index);
        parameter = parameter.substring(index + 1);
        parameter = parameter.substring(0, parameter.indexOf(')'));
        String[] parameters = parameter.split(",");
        for (int i = 0; i < parameters.length; i++) {
          parameters[i] = parameters[i].trim();
        }
        message = className + '#' + method + " - "
            + analyzer.getJavadocs(className, method, parameters);
      }
    }
    sendMessage(roomID, (target != null ? target + ": " : "") + message);
  }

  private void sendMessageList(ID roomID, String target) {
    sendMessage(roomID, (target != null ? target + ": " : "")
        + CustomMessages.getString(CustomMessages.MessageList));
  }

  private void sendSearchPlugins(ID roomID, String target, String searchString) {
    searchString = searchString.replace(' ', '+');
    sendMessage(roomID, (target != null ? target + ": " : "")
        + NLS.bind(CustomMessages
            .getString(CustomMessages.SearchPlugins), searchString));
  }

  private void sendCQ(ID roomID, String target, String id, String comment) {
    String suffix = id;
    if (comment != null) {
      suffix += "#c" + comment;
    }
    sendMessage(roomID, (target != null ? target + ": " : "")
        + NLS.bind(CustomMessages.getString(CustomMessages.CQ), id,
            suffix));
  }

  private void writeToHTML(File file, String title, Properties properties)
      throws IOException {
    FileWriter out = new FileWriter(file);
    out
        .write("<html>\n<head><title>" + title + "</title></head>\n<body>\n<table cellspacing=\"2\" cellpadding=\"2\" border=\"0\">\n"); //$NON-NLS-1$
    Set set = properties.keySet();
    String[] propertiesSorted = (String[]) set.toArray(new String[set
        .size()]);
    Arrays.sort(propertiesSorted);

    for (int i = 0; i < propertiesSorted.length; i++) {
      String output = properties.getProperty(propertiesSorted[i]);
      out.write(formatTableRow(propertiesSorted[i], output));
    }

    out.write("</table>\n</body></html>\n"); //$NON-NLS-1$
    out.flush();

    try {
      out.close();
    } catch (IOException e) {
      // ignored
    }
  }

  private void writeMessagesToHTML() throws IOException {
    writeToHTML(HTML_FILE_MESSAGES, "KOS-MOS Messages", messages); //$NON-NLS-1$
  }

  private void writeCommandsToHTML() throws IOException {
    writeToHTML(HTML_FILE_COMMANDS, "KOS-MOS Commands", commands); //$NON-NLS-1$
  }

  private String formatTableRow(String key, String val) {
    return "<tr valign=\"top\"><td><b>" //$NON-NLS-1$
        + key.replaceAll(" ", "&#160;") //$NON-NLS-1$ //$NON-NLS-2$
        + "</b></td><td>" //$NON-NLS-1$
        + text2html(val)
        + "</td></tr>\n<tr><td colspan=\"2\"><hr noshade=\"noshade\" size=\"1\" width=\"100%\"/></td></tr>\n\n"; //$NON-NLS-1$
  }

  private String text2html(String val) {
    StringTokenizer st = new StringTokenizer(val, " )(\"", true); //$NON-NLS-1$
    StringBuffer sb = new StringBuffer();
    while (st.hasMoreTokens()) {
      String tok = st.nextToken();
      Matcher patternMatcher = URL_PATTERN.matcher(tok);
      if (patternMatcher.matches()) {
        sb.append("<a href=\""); //$NON-NLS-1$
        sb.append(patternMatcher.group(1));
        sb.append("\">"); //$NON-NLS-1$
        if (patternMatcher.group(1).length() >= 120) // break long
        // URLs
        {
          StringTokenizer st2 = new StringTokenizer(patternMatcher
              .group(1), " /&", true); //$NON-NLS-1$
          StringBuffer sb2 = new StringBuffer();
          while (st2.hasMoreTokens()) {
            sb2.append(st2.nextToken());
            if (sb2.length() >= 100) {
              sb2.append(" "); //$NON-NLS-1$
            }
          }
          sb.append(sb2.toString().replaceAll(BINDING_REGEX,
              "<b style=\"color:green\">$1</b>")); //$NON-NLS-1$
        } else {
          sb.append(patternMatcher.group(1).replaceAll(BINDING_REGEX,
              "<b style=\"color:green\">$1</b>")); //$NON-NLS-1$
        }
        sb.append("</a>"); //$NON-NLS-1$
      } else {
        Matcher cmdMatcher = CMD_PATTERN.matcher(tok);
        if (cmdMatcher.matches()) {
          sb.append("<b style=\"color:red\">"); //$NON-NLS-1$
          sb.append(cmdMatcher.group(1));
          sb.append("</b>"); //$NON-NLS-1$
        } else {
          Matcher bindingMatcher = BINDING_PATTERN.matcher(tok);
          if (bindingMatcher.matches()) {
            sb.append("<b style=\"color:green\">"); //$NON-NLS-1$
            sb.append(bindingMatcher.group(1));
            sb.append("</b>"); //$NON-NLS-1$
          } else {
            sb.append(tok);
          }
        }
      }
    }
    return sb.toString();
  }

  private boolean isProcessed(ID roomID, String target, String msg) {
    String reply = (String) messages.get(msg);
    if (reply == null) {
      return false;
    }
    sendMessage(roomID, (target != null ? target + ": " : "") + reply); //$NON-NLS-1$
    return true;
  }

  private void learn(ID roomID, String contents) {
    String key = contents.split(" ")[0].toLowerCase();
    try {
      URL url = FileLocator.find(Activator.getBundle(), new Path(
          "messages.properties"), null);
      url = FileLocator.resolve(url);

      String property = messages.getProperty(key);
      if (property == null) {
        OutputStream stream = new FileOutputStream(url.getPath());
        messages.setProperty(key, contents.substring(key.length())
            .trim());
        messages.store(stream, LICENSE);
        writeMessagesToHTML();
        sendMessage(roomID, NLS.bind(CustomMessages
            .getString(CustomMessages.Learn_Reply), key));
      } else {
        sendMessage(roomID, NLS.bind(CustomMessages
            .getString(CustomMessages.Learn_Conflict), key,
            property));
      }
    } catch (Exception e) {
      sendMessage(roomID, NLS.bind(CustomMessages
          .getString(CustomMessages.Learn_Failure), key));
    }
  }

  private void update(ID roomID, String contents) {
    String key = contents.split(" ")[0].toLowerCase();
    try {
      URL url = FileLocator.find(Activator.getBundle(), new Path(
          "messages.properties"), null);
      url = FileLocator.resolve(url);

      OutputStream stream = new FileOutputStream(url.getPath());
      messages.setProperty(key, contents.substring(key.length()).trim());
      messages.store(stream, LICENSE);
      writeMessagesToHTML();
      sendMessage(roomID, NLS.bind(CustomMessages
          .getString(CustomMessages.Learn_Update), key));
    } catch (Exception e) {
      sendMessage(roomID, NLS.bind(CustomMessages
          .getString(CustomMessages.Learn_Failure), key));
    }
  }

  private void remove(ID roomID, String contents) {
    String key = contents.split(" ")[0].toLowerCase();
    try {
      URL url = FileLocator.find(Activator.getBundle(), new Path(
          "messages.properties"), null);
      url = FileLocator.resolve(url);

      OutputStream stream = new FileOutputStream(url.getPath());
      messages.remove(key);
      messages.store(stream, LICENSE);
      writeMessagesToHTML();
      sendMessage(roomID, NLS.bind(CustomMessages
          .getString(CustomMessages.Learn_Remove), key));
    } catch (Exception e) {
      sendMessage(roomID, NLS.bind(CustomMessages
          .getString(CustomMessages.Learn_Failure), key));
    }
  }

  private void send(ID fromID, ID roomID, String target, String msg) {
    /* handle operator-added messages - see messages.properties */
    if (isProcessed(roomID, target, msg)) {
      return;
    }

    /* handle custom commands - see custom.properties */
    Matcher cmdMatcher = null;
    Enumeration keys = commands.keys();
    while (keys.hasMoreElements()) {
      String key = (String) keys.nextElement();
      Pattern pattern = Pattern.compile(key);
      cmdMatcher = pattern.matcher(msg);
      if (cmdMatcher.matches()) {
        break;
      }
    }

    if (cmdMatcher != null && cmdMatcher.matches()) {
      if (cmdMatcher.group(1).equals("add ")) { //$NON-NLS-1$
        if (operators.contains(fromID.getName())) {
          learn(roomID, cmdMatcher.group(2));
        } else {
          sendMessage(roomID, NLS.bind(CustomMessages
              .getString(CustomMessages.No_Operation_Privileges),
              fromID.getName()));
        }
      } else if (cmdMatcher.group(1).equals("set ") || cmdMatcher.group(1).equals("update ")) { //$NON-NLS-1$ //$NON-NLS-2$
        if (operators.contains(fromID.getName())) {
          update(roomID, cmdMatcher.group(2));
        } else {
          sendMessage(roomID, NLS.bind(CustomMessages
              .getString(CustomMessages.No_Operation_Privileges),
              fromID.getName()));
        }
      } else if (cmdMatcher.group(1).equals("remove ")) { //$NON-NLS-1$
        if (operators.contains(fromID.getName())) {
          remove(roomID, cmdMatcher.group(2));
        } else {
          sendMessage(roomID, NLS.bind(CustomMessages
              .getString(CustomMessages.No_Operation_Privileges),
              fromID.getName()));
        }
      } else if (cmdMatcher.group(1).equals("") || cmdMatcher.group(1).equals("bug") || cmdMatcher.group(1).equals("bug ")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        msg = cmdMatcher.group(2);
        int index = msg.indexOf('c');
        if (index == -1) {
          try {
            // try to parse the string to see that we have a valid
            // number
            Integer.parseInt(msg);
            sendBug(roomID, target, msg, null);
          } catch (NumberFormatException e) {
            // ignored
          }
        } else {
          try {
            // try to parse the string to see that we have a valid
            // number
            Integer.parseInt(msg.substring(0, index));
            sendBug(roomID, target, msg.substring(0, index), msg
                .substring(index + 1));
          } catch (NumberFormatException e) {
            // ignored
          }
        }
      } else if (cmdMatcher.group(1).equals("cq") || cmdMatcher.group(1).equals("cq ")) { //$NON-NLS-1$ //$NON-NLS-2$
        msg = cmdMatcher.group(2);
        int index = msg.indexOf('c');
        if (index == -1) {
          try {
            // try to parse the string to see that we have a valid
            // number
            Integer.parseInt(msg);
            sendCQ(roomID, target, msg, null);
          } catch (NumberFormatException e) {
            // ignored
          }
        } else {
          try {
            // try to parse the string to see that we have a valid
            // number
            Integer.parseInt(msg.substring(0, index));
            sendCQ(roomID, target, msg.substring(0, index), msg
                .substring(index + 1));
          } catch (NumberFormatException e) {
            // ignored
          }
        }
      } else if (cmdMatcher.group(1).equals("javadoc ") || cmdMatcher.group(1).equals("api ")) { //$NON-NLS-1$ //$NON-NLS-2$
        sendJavaDoc(roomID, target, cmdMatcher.group(2));
      } else if (cmdMatcher.group(1).equals("news ") || cmdMatcher.group(1).equals("newsgroup ")) { //$NON-NLS-1$ //$NON-NLS-2$
        sendNewsgroupSearch(roomID, target, cmdMatcher.group(2));
      } else if (cmdMatcher.group(1).equals("g ")) { //$NON-NLS-1$
        sendGoogle(roomID, target, cmdMatcher.group(2));
      } else if (cmdMatcher.group(1).equals("wiki ")) { //$NON-NLS-1$
        sendWiki(roomID, target, cmdMatcher.group(2));
      } else if (cmdMatcher.group(1).equals("eh ")) { //$NON-NLS-1$
        sendEclipseHelp(roomID, target, cmdMatcher.group(2));
      } else if (cmdMatcher.group(1).equals("list")) { //$NON-NLS-1$
        sendMessageList(roomID, target);
      } else if (cmdMatcher.group(1).equals("searchplugins ")) { //$NON-NLS-1$
        sendSearchPlugins(roomID, target, cmdMatcher.group(2));
      }
    }
  }

  private String[] parseInput(String msg) {
    if (msg.startsWith("tell")) { //$NON-NLS-1$
      msg = msg.substring(5);
      int index = msg.indexOf(' ');
      if (index == -1) {
        return null;
      }
      String user = msg.substring(0, index);
      msg = msg.substring(index + 1);
      index = msg.indexOf(' ');
      if (index == -1) {
        return null;
      }
      String tmp = msg.substring(0, index);
      if (tmp.equals("about")) { //$NON-NLS-1$
        msg = msg.substring(index + 1);
      }
      return new String[] { user, msg };
    } else {
      return new String[] { null, msg };
    }
  }

  private void handleMessage(ID fromID, ID roomID, String message) {
    try {
      String[] info = parseInput(message);
      if (info != null) {
        send(fromID, roomID, info[0], info[1]);
      }
    } catch (RuntimeException e) {
      e.printStackTrace();
    }
  }

  public void handleRoomMessage(IChatRoomMessage message) {
    ID fromID = message.getFromID();
    String name = fromID.getName();
    if (name.charAt(0) == '#' || name.equals(botName)) { // skip messages
      // from the
      // channel or
      // self
      return;
    }

    String msg = message.getMessage();
    switch (msg.charAt(0)) {
    case '~':
    case '!':
      msg = msg.substring(1).trim();
      int index = msg.indexOf(' ');
      if (index == -1) {
        handleMessage(fromID, message.getChatRoomID(), msg
            .toLowerCase());
      } else {
        handleMessage(fromID, message.getChatRoomID(), msg.substring(0,
            index).toLowerCase()
            + msg.substring(index));
      }
      break;
    default:
      String upperCase = msg.toUpperCase();
      if (upperCase.startsWith("KOS-MOS:")
          || upperCase.startsWith("KOS-MOS,")) {
        msg = upperCase.substring(8).trim();
        switch (msg.charAt(0)) {
        case '~':
        case '!':
          msg = msg.substring(1).trim();
          index = msg.indexOf(' ');
          if (index == -1) {
            handleMessage(fromID, message.getChatRoomID(), msg
                .toLowerCase());
          } else {
            handleMessage(fromID, message.getChatRoomID(), msg
                .substring(0, index).toLowerCase()
                + msg.substring(index));
          }
          break;
        }
      } else {
        String[] split = msg.split("\\s"); //$NON-NLS-1$
        for (int i = 0; i < split.length; i++) {
          if (split[i].length() > 0) {
            switch (split[i].charAt(0)) {
            case '~':
            case '!':
              handleMessage(fromID, message.getChatRoomID(),
                  split[i].substring(1).trim().toLowerCase());
              break;
            }
          }
        }
      }
    }
  }

  public void init(IChatRoomBotEntry robot) {
    // nothing to do
  }

  public void preChatRoomConnect(IChatRoomContainer roomContainer, ID roomID) {
    // retrieve our name
    ID connectedID = container.getConnectedID();
    botName = connectedID.getName();
    IChatID chatID = (IChatID) connectedID.getAdapter(IChatID.class);
    if (chatID != null) {
      botName = chatID.getUsername();
    }
   
    messageSenders.put(roomID, roomContainer.getChatRoomMessageSender());
    if (password != null) {
      try {
        sendMessage(IDFactory.getDefault().createStringID("nickserv"),
            "identify " + password);
      } catch (IDCreateException e) {
      }
    }
  }

  public void preContainerConnect(IContainer container, ID targetID) {
    File file = new File(Platform.getInstanceLocation().getURL().getPath(),
        "password.properties");
    if (file.exists()) {
      Properties properties = new Properties();
      try {
        properties.load(new FileInputStream(file));
        password = properties.getProperty("password");
      } catch (FileNotFoundException e) {
      } catch (IOException e) {
      }
    }
    this.container = container;
    IChatRoomContainer chatRoomContainer = (IChatRoomContainer) container
        .getAdapter(IChatRoomContainer.class);
    chatMessageSender = chatRoomContainer.getPrivateMessageSender();
    chatRoomContainer.addMessageListener(new IIMMessageListener() {
      public void handleMessageEvent(IIMMessageEvent e) {
        if (e instanceof IChatMessageEvent) {
          IChatMessageEvent event = (IChatMessageEvent) e;
          String msg = event.getChatMessage().getBody();
          switch (msg.charAt(0)) {
          case '~':
          case '!':
            handleMessage(event.getFromID(), event.getFromID(), msg
                .substring(1).trim());
            break;
          default:
            handleMessage(event.getFromID(), event.getFromID(), msg
                .trim());
            break;
          }
        }
      }
    });
  }

}
TOP

Related Classes of org.eclipse.ecf.internal.presence.bot.kosmos.ChatRoomMessageHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.