Java tutorial
/** * Licensed to Jasig under one or more contributor license * agreements. See the NOTICE file distributed with this work * for additional information regarding copyright ownership. * Jasig licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a * copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.jasig.irclog; import java.io.IOException; import org.jasig.irclog.events.ActionEvent; import org.jasig.irclog.events.ConnectEvent; import org.jasig.irclog.events.DisconnectEvent; import org.jasig.irclog.events.JoinEvent; import org.jasig.irclog.events.KickEvent; import org.jasig.irclog.events.MessageEvent; import org.jasig.irclog.events.ModeEvent; import org.jasig.irclog.events.NickChangeEvent; import org.jasig.irclog.events.NoticeEvent; import org.jasig.irclog.events.PartEvent; import org.jasig.irclog.events.PingEvent; import org.jasig.irclog.events.PrivateMessageEvent; import org.jasig.irclog.events.QuitEvent; import org.jasig.irclog.events.TimeEvent; import org.jasig.irclog.events.TopicEvent; import org.jasig.irclog.events.VersionEvent; import org.jibble.pircbot.Colors; import org.jibble.pircbot.IrcException; import org.jibble.pircbot.NickAlreadyInUseException; import org.jibble.pircbot.PircBot; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.core.Ordered; import com.googlecode.shutdownlistener.ShutdownListener; /** * Implementation of PircBot that converts all the callbacks into strongly typed event objects. * Also handles automatic reconnecting to the configured server. * * @author Eric Dalquist <a href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a> * @version $Revision$ */ public class EventLogBot extends PircBot implements IrcBot, ShutdownListener, Ordered, ApplicationListener<ContextRefreshedEvent>, ApplicationEventPublisherAware { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); private volatile boolean quit = false; private ApplicationEventPublisher applicationEventPublisher; private boolean stripFormatting = true; private String host = null; private int port = 6667; private String password = null; private long reconnectDelay = 10000; /** * Remove colors and formatting from user generated messages recieved from the server */ public void setStripFormatting(boolean stripColors) { this.stripFormatting = stripColors; } /** * @see #setName(String) */ public void setBotName(String name) { this.setName(name); } /** * The host to connect to */ public void setHost(String host) { this.host = host; } /** * The port to connect on */ public void setPort(int port) { this.port = port; } /** * The password to use */ public void setPassword(String password) { this.password = password; } /** * How long to wait after disconnection before reconnection */ public void setReconnectDelay(long reconnectDelay) { this.reconnectDelay = reconnectDelay; } @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher = applicationEventPublisher; } @Override public void onApplicationEvent(ContextRefreshedEvent event) { this.logger.debug("{}", event); this.logger.debug("Connecting to " + host + ":" + port); try { this.connect(host, port, password); } catch (NickAlreadyInUseException e) { logger.error(e.getMessage(), e); } catch (IOException e) { logger.error(e.getMessage(), e); } catch (IrcException e) { logger.error(e.getMessage(), e); } //TODO on connect error setup retry? } @Override public void shutdown() { this.logger.debug("Shutting Down EventLogBot for " + host + ":" + port); this.quit = true; this.disconnect(); this.dispose(); } @Override public int getOrder() { return 0; } /** * @see org.jibble.pircbot.PircBot#onConnect() */ @Override protected void onConnect() { if (this.password != null) { this.logger.info("Authenticating '" + this.getName() + "'."); this.identify(this.password); } final ConnectEvent event = new ConnectEvent(this); this.applicationEventPublisher.publishEvent(event); } /** * @see org.jibble.pircbot.PircBot#onKick(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override protected void onKick(String channel, String kickerNick, String kickerLogin, String kickerHostname, String recipientNick, String reason) { final KickEvent event = new KickEvent(this, channel, kickerNick, kickerLogin, kickerHostname, recipientNick, reason); this.applicationEventPublisher.publishEvent(event); } /** * @see org.jibble.pircbot.PircBot#onQuit(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override protected void onQuit(String sourceNick, String sourceLogin, String sourceHostname, String reason) { final QuitEvent event = new QuitEvent(this, sourceNick, sourceLogin, sourceHostname, reason); if (!this.quit && (sourceNick.equalsIgnoreCase(this.getNick()) || sourceNick.equalsIgnoreCase(this.getName()))) { this.logger.info("Quit server for unknown reason, try to reconnect: " + event); this.safeReconnect(); } else { this.logger.info("Quit server due to shutdown, will not attempt to reconnect: " + event); } this.applicationEventPublisher.publishEvent(event); } /** * @see org.jibble.pircbot.PircBot#onDisconnect() */ @Override protected void onDisconnect() { final DisconnectEvent event = new DisconnectEvent(this); this.applicationEventPublisher.publishEvent(event); this.safeReconnect(); } protected void safeReconnect() { while (!this.quit && !this.isConnected()) { try { this.logger.info("Attempting to reconnect to server."); this.reconnect(); } catch (Exception e) { this.logger.error("Failed to reconnect", e); try { Thread.sleep(this.reconnectDelay); } catch (InterruptedException ie) { this.logger.error("Failed to wait to reconnect", ie); } } } } /** * @see org.jibble.pircbot.PircBot#onAction(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override protected void onAction(String sender, String login, String hostname, String target, String action) { final ActionEvent event = new ActionEvent(this, sender, login, hostname, target, action); this.applicationEventPublisher.publishEvent(event); } /** * @see org.jibble.pircbot.PircBot#onJoin(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override protected void onJoin(String channel, String sender, String login, String hostname) { final JoinEvent event = new JoinEvent(this, channel, sender, login, hostname); this.applicationEventPublisher.publishEvent(event); } /** * @see org.jibble.pircbot.PircBot#onMessage(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override protected void onMessage(String channel, String sender, String login, String hostname, String message) { if (this.stripFormatting) { message = Colors.removeFormattingAndColors(message); } final MessageEvent event = new MessageEvent(this, channel, sender, login, hostname, message); this.applicationEventPublisher.publishEvent(event); } /** * @see org.jibble.pircbot.PircBot#onMode(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override protected void onMode(String channel, String sourceNick, String sourceLogin, String sourceHostname, String mode) { final ModeEvent event = new ModeEvent(this, channel, sourceNick, sourceLogin, sourceHostname, mode); this.applicationEventPublisher.publishEvent(event); } /** * @see org.jibble.pircbot.PircBot#onNickChange(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override protected void onNickChange(String oldNick, String login, String hostname, String newNick) { final NickChangeEvent event = new NickChangeEvent(this, oldNick, login, hostname, newNick); this.applicationEventPublisher.publishEvent(event); } /** * @see org.jibble.pircbot.PircBot#onNotice(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override protected void onNotice(String sourceNick, String sourceLogin, String sourceHostname, String target, String notice) { final NoticeEvent event = new NoticeEvent(this, sourceNick, sourceLogin, sourceHostname, target, notice); this.applicationEventPublisher.publishEvent(event); } /** * @see org.jibble.pircbot.PircBot#onPart(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override protected void onPart(String channel, String sender, String login, String hostname) { final PartEvent event = new PartEvent(this, channel, sender, login, hostname); this.applicationEventPublisher.publishEvent(event); } /** * @see org.jibble.pircbot.PircBot#onPing(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override protected void onPing(String sourceNick, String sourceLogin, String sourceHostname, String target, String pingValue) { final PingEvent event = new PingEvent(this, sourceNick, sourceLogin, sourceHostname, target, pingValue); this.applicationEventPublisher.publishEvent(event); } /** * @see org.jibble.pircbot.PircBot#onPrivateMessage(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override protected void onPrivateMessage(String sender, String login, String hostname, String message) { if (this.stripFormatting) { message = Colors.removeFormattingAndColors(message); } final PrivateMessageEvent event = new PrivateMessageEvent(this, sender, login, hostname, message); this.applicationEventPublisher.publishEvent(event); } /** * @see org.jibble.pircbot.PircBot#onTime(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override protected void onTime(String sourceNick, String sourceLogin, String sourceHostname, String target) { final TimeEvent event = new TimeEvent(this, sourceNick, sourceLogin, sourceHostname, target); this.applicationEventPublisher.publishEvent(event); } /** * @see org.jibble.pircbot.PircBot#onTopic(java.lang.String, java.lang.String, java.lang.String, long, boolean) */ @Override protected void onTopic(String channel, String topic, String setBy, long date, boolean changed) { final TopicEvent event = new TopicEvent(this, channel, topic, setBy, date, changed); this.applicationEventPublisher.publishEvent(event); } /** * @see org.jibble.pircbot.PircBot#onVersion(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override protected void onVersion(String sourceNick, String sourceLogin, String sourceHostname, String target) { final VersionEvent event = new VersionEvent(this, sourceNick, sourceLogin, sourceHostname, target); this.applicationEventPublisher.publishEvent(event); } }