/* Yaaic - Yet Another Android IRC Client Copyright 2009-2010 Sebastian Kaspari This file is part of Yaaic. Yaaic is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Yaaic is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Yaaic. If not, see . */ package org.yaaic.command; import java.util.HashMap; import android.content.Intent; import org.yaaic.command.handler.AwayHandler; import org.yaaic.command.handler.CloseHandler; import org.yaaic.command.handler.DCCHandler; import org.yaaic.command.handler.DeopHandler; import org.yaaic.command.handler.DevoiceHandler; import org.yaaic.command.handler.EchoHandler; import org.yaaic.command.handler.HelpHandler; import org.yaaic.command.handler.JoinHandler; import org.yaaic.command.handler.KickHandler; import org.yaaic.command.handler.MeHandler; import org.yaaic.command.handler.ModeHandler; import org.yaaic.command.handler.MsgHandler; import org.yaaic.command.handler.NamesHandler; import org.yaaic.command.handler.NickHandler; import org.yaaic.command.handler.NoticeHandler; import org.yaaic.command.handler.OpHandler; import org.yaaic.command.handler.PartHandler; import org.yaaic.command.handler.QueryHandler; import org.yaaic.command.handler.QuitHandler; import org.yaaic.command.handler.TopicHandler; import org.yaaic.command.handler.VoiceHandler; import org.yaaic.command.handler.WhoisHandler; import org.yaaic.exception.CommandException; import org.yaaic.irc.IRCService; import org.yaaic.model.Broadcast; import org.yaaic.model.Conversation; import org.yaaic.model.Message; import org.yaaic.model.Server; /** * Parser for commands * * @author Sebastian Kaspari */ public class CommandParser { private HashMap commands; private HashMap aliases; private static CommandParser instance; private final static String[] serverCommands = { // whitelist of server commands "admin", "motd", "version", "knock", "rules", "vhost", "credits", "license", "setname", "watch", "pong", "cycle", "links", "silence", "who", "dalinfo", "userhost", "list", "stats", "invite", "lusers", "ping", "time", "whowas", "ison", "map", // services "nickserv", "ns", "chanserv", "cs", "authserv", "hostserv", "memoserv", "operserv" }; /** * Create a new CommandParser instance */ private CommandParser() { commands = new HashMap(); // Commands commands.put("nick", new NickHandler()); commands.put("join", new JoinHandler()); commands.put("me", new MeHandler()); commands.put("names", new NamesHandler()); commands.put("echo", new EchoHandler()); commands.put("topic", new TopicHandler()); commands.put("quit", new QuitHandler()); commands.put("op", new OpHandler()); commands.put("voice", new VoiceHandler()); commands.put("deop", new DeopHandler()); commands.put("devoice", new DevoiceHandler()); commands.put("kick", new KickHandler()); commands.put("query", new QueryHandler()); commands.put("part", new PartHandler()); commands.put("close", new CloseHandler()); commands.put("notice", new NoticeHandler()); commands.put("dcc", new DCCHandler()); commands.put("mode", new ModeHandler()); commands.put("help", new HelpHandler()); commands.put("away", new AwayHandler()); commands.put("whois", new WhoisHandler()); commands.put("msg", new MsgHandler()); aliases = new HashMap(); // Aliases aliases.put("j","join"); aliases.put("q", "query"); aliases.put("h", "help"); } /** * Get the global CommandParser instance * * @return */ public static CommandParser getInstance() { if (instance == null) { instance = new CommandParser(); } return instance; } /** * Get the commands HashMap * * @return HashMap - command, commandHandler */ public HashMap getCommands() { return commands; } /** * Get the command aliases HashMap * * @return HashMap - alias, command the alias belogs to */ public HashMap getAliases() { return aliases; } /** * Is the given command a valid client command? * * @param command The (client) command to check (/command) * @return true if the command can be handled by the client, false otherwise */ public boolean isClientCommand(String command) { return commands.containsKey(command.toLowerCase()) || aliases.containsKey(command.toLowerCase()); } /** * Is the given command a valid server command? * * @param command The (server) command to check (/command) * @return true if the command can be handled by a server, false otherwise */ public boolean isServerCommand(String command) { command = command.toLowerCase(); for (String validCommand : serverCommands) { if (validCommand.equals(command)) { return true; } } return false; } /** * Handle a client command * * @param type Type of the command (/type param1 param2 ..) * @param params The parameters of the command (0 is the command itself) * @param server The current server * @param conversation The selected conversation * @param service The service handling the connections */ public void handleClientCommand(String type, String[] params, Server server, Conversation conversation, IRCService service) { BaseHandler command = null; if (commands.containsKey(type.toLowerCase())) { command = commands.get(type); } else if (aliases.containsKey(type.toLowerCase())) { String commandInCommands = aliases.get(type.toLowerCase()); command = commands.get(commandInCommands); } try { command.execute(params, server, conversation, service); } catch(CommandException e) { // Command could not be executed if (conversation != null) { Message errorMessage = new Message(type + ": " + e.getMessage()); errorMessage.setColor(Message.COLOR_RED); conversation.addMessage(errorMessage); Message usageMessage = new Message("Syntax: " + command.getUsage()); conversation.addMessage(usageMessage); Intent intent = Broadcast.createConversationIntent( Broadcast.CONVERSATION_MESSAGE, server.getId(), conversation.getName() ); service.sendBroadcast(intent); } } } /** * Handle a server command * * @param type Type of the command (/type param1 param2 ..) * @param params The parameters of the command (0 is the command itself) * @param server The current server * @param conversation The selected conversation * @param service The service handling the connections */ public void handleServerCommand(String type, String[] params, Server server, Conversation conversation, IRCService service) { if (params.length > 1) { service.getConnection(server.getId()).sendRawLineViaQueue( type.toUpperCase() + " " + BaseHandler.mergeParams(params) ); } else { service.getConnection(server.getId()).sendRawLineViaQueue(type.toUpperCase()); } } /** * Handle an unknown command * * @param type Type of the command (/type param1 param2 ..) * @param server The current server * @param conversation The selected conversation * @param service The service handling the connections */ public void handleUnknownCommand(String type, Server server, Conversation conversation, IRCService service) { if (conversation != null) { Message message = new Message("Unknown command: " + type); message.setColor(Message.COLOR_RED); conversation.addMessage(message); Intent intent = Broadcast.createConversationIntent( Broadcast.CONVERSATION_MESSAGE, server.getId(), conversation.getName() ); service.sendBroadcast(intent); } } /** * Parse the given line * * @param line */ public void parse(String line, Server server, Conversation conversation, IRCService service) { line = line.trim().substring(1); // cut the slash String[] params = line.split(" "); String type = params[0]; if (isClientCommand(type)) { handleClientCommand(type, params, server, conversation, service); } else if (isServerCommand(type)) { handleServerCommand(type, params, server, conversation, service); } else { handleUnknownCommand(type, server, conversation, service); } } }