001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.network;
020
021import icy.util.StringUtil;
022
023import java.util.ArrayList;
024
025import org.schwering.irc.lib.IRCConnection;
026
027/**
028 * Simple IRCClient class.
029 * 
030 * @author Stephane
031 */
032public class IRCClient extends IRCConnection
033{
034    /** Listeners */
035    protected final ArrayList<IRCEventListenerImpl> listeners;
036
037    /**
038     * Creates a new IRCConnection instance and starts the thread.
039     * If you get confused by the two setDaemon()s: The conn.setDaemon(false) marks the
040     * IRCConnection thread as user thread and the setDaemon(true) marks this class's thread
041     * (which just listens for keyboard input) as daemon thread. Thus, if the IRCConnection
042     * breaks, this console application shuts down, because due to the setDaemon(true) it
043     * will no longer wait for keyboard input (no input would make sense without being
044     * connected to a server).
045     */
046    public IRCClient(String host, int port, String pass, String nickName, String userName, String realName)
047    {
048        super(host, new int[] {port}, pass, nickName, userName, realName);
049
050        listeners = new ArrayList<IRCEventListenerImpl>();
051
052        // default parameters
053        setEncoding("UTF-8");
054        setPong(true);
055        setDaemon(false);
056        setColors(true);
057        // 1 hour for timeout
058        setTimeout(1 * 60 * 60 * 1000);
059    }
060
061    /**
062     * Called on receive text event.
063     */
064    protected void receive(String nick, String target, String text)
065    {
066        // notify listeners about receive
067        fireReceiveEvent(nick, target, text);
068    }
069
070    /**
071     * Send unparsed text to IRC server.
072     */
073    public void send(String target, String text)
074    {
075        if (StringUtil.isEmpty(text))
076            return;
077
078        if (text.charAt(0) == '/')
079        {
080            // we want to see command we are sending
081            receive(null, target, text);
082
083            // prevent some commands
084            if (startsWith(text, "/TARGET") || startsWith(text, "/LIST"))
085                receive(null, target, "Command not autorized.");
086            else
087                send(text.substring(1));
088        }
089        else
090        {
091            doPrivmsg(target, text);
092            // just to see what we send
093            receive(getNick(), target, text);
094        }
095    }
096
097    /**
098     * Checks whether a string starts with another string (case insensitive).
099     */
100    private boolean startsWith(String s1, String s2)
101    {
102        return (s1.length() >= s2.length()) ? s1.substring(0, s2.length()).equalsIgnoreCase(s2) : false;
103    }
104
105    /**
106     * Fire receive event
107     */
108    protected void fireReceiveEvent(String nick, String target, String text)
109    {
110        for (IRCEventListenerImpl l : listeners)
111            l.onReceive(nick, target, text);
112    }
113
114    public void addListener(IRCEventListenerImpl listener)
115    {
116        if (!listeners.contains(listener))
117            listeners.add(listener);
118        addIRCEventListener(listener);
119    }
120
121    public boolean removeListener(IRCEventListenerImpl listener)
122    {
123        listeners.remove(listener);
124        return removeIRCEventListener(listener);
125    }
126
127}