001: /**
002: * $Revision$
003: * $Date$
004: *
005: * Copyright (C) 2007 Jive Software. All rights reserved.
006: *
007: * This software is published under the terms of the GNU Public License (GPL),
008: * a copy of which is included in this distribution.
009: */package org.jivesoftware.openfire.gateway.protocols.irc;
010:
011: import f00f.net.irc.martyr.IRCConnection;
012: import f00f.net.irc.martyr.commands.*;
013: import f00f.net.irc.martyr.services.AutoReconnect;
014: import f00f.net.irc.martyr.services.AutoRegister;
015: import f00f.net.irc.martyr.services.AutoResponder;
016: import org.apache.log4j.Logger;
017: import org.jivesoftware.openfire.gateway.muc.MUCTransportRoom;
018: import org.jivesoftware.openfire.gateway.pseudoroster.PseudoRoster;
019: import org.jivesoftware.openfire.gateway.pseudoroster.PseudoRosterItem;
020: import org.jivesoftware.openfire.gateway.pseudoroster.PseudoRosterManager;
021: import org.jivesoftware.openfire.gateway.registration.Registration;
022: import org.jivesoftware.openfire.gateway.roster.TransportBuddy;
023: import org.jivesoftware.openfire.gateway.session.TransportSession;
024: import org.jivesoftware.openfire.gateway.type.ChatStateType;
025: import org.jivesoftware.openfire.gateway.type.NameSpace;
026: import org.jivesoftware.openfire.gateway.type.PresenceType;
027: import org.jivesoftware.openfire.gateway.type.TransportLoginStatus;
028: import org.jivesoftware.openfire.gateway.util.StringUtils;
029: import org.jivesoftware.openfire.user.UserNotFoundException;
030: import org.jivesoftware.util.JiveGlobals;
031: import org.xmpp.packet.JID;
032:
033: import java.io.IOException;
034: import java.net.UnknownHostException;
035: import java.util.ArrayList;
036: import java.util.List;
037: import java.util.Timer;
038: import java.util.TimerTask;
039:
040: /**
041: * @author Daniel Henninger
042: */
043: public class IRCSession extends TransportSession {
044:
045: static Logger Log = Logger.getLogger(IRCSession.class);
046:
047: /**
048: * Timer to check for online status.
049: */
050: public Timer timer = new Timer();
051:
052: /**
053: * Interval at which status is checked.
054: */
055: private int timerInterval = 30000; // 30 seconds
056:
057: /**
058: * Status checker.
059: */
060: StatusCheck statusCheck;
061:
062: public IRCSession(Registration registration, JID jid,
063: IRCTransport transport, Integer priority) {
064: super (registration, jid, transport, priority);
065:
066: pseudoRoster = PseudoRosterManager.getInstance()
067: .getPseudoRoster(registration);
068: for (String contact : pseudoRoster.getContacts()) {
069: getBuddyManager().storeBuddy(
070: new IRCBuddy(getBuddyManager(), contact,
071: pseudoRoster.getItem(contact)));
072: }
073: }
074:
075: /**
076: * Our pseudo roster.
077: *
078: * No server side buddy list, so we track it all here.
079: */
080: private PseudoRoster pseudoRoster;
081:
082: public IRCConnection connection;
083: private AutoResponder autoResponder;
084: private AutoRegister autoRegister;
085: private AutoReconnect autoReconnect;
086: private IRCListener listener;
087:
088: public IRCConnection getConnection() {
089: return connection;
090: }
091:
092: public void logIn(PresenceType presenceType, String verboseStatus) {
093: connection = new IRCConnection();
094: autoResponder = new AutoResponder(connection);
095: // autoReconnect = new AutoReconnect(connection);
096: autoRegister = new AutoRegister(connection, getRegistration()
097: .getNickname(), getRegistration().getNickname(),
098: "IM Gateway User", getRegistration().getPassword());
099: listener = new IRCListener(this );
100: listener.enable();
101: new Thread() {
102: public void run() {
103: try {
104: connection.connect(JiveGlobals.getProperty(
105: "plugin.gateway.irc.connecthost",
106: "irc.freenode.net"), JiveGlobals
107: .getIntProperty(
108: "plugin.gateway.irc.connectport",
109: 7000));
110: setPresence(PresenceType.available);
111: setLoginStatus(TransportLoginStatus.LOGGED_IN);
112: try {
113: getTransport().syncLegacyRoster(getJID(),
114: getBuddyManager().getBuddies());
115: } catch (UserNotFoundException e) {
116: Log
117: .debug("IRC: Error finding user while syncing legacy roster.");
118: }
119: List<String> buddyList = new ArrayList<String>();
120: for (TransportBuddy buddy : getBuddyManager()
121: .getBuddies()) {
122: buddyList.add(buddy.getName());
123: }
124: if (!buddyList.isEmpty()) {
125: connection.sendCommand(new IsonCommand(
126: StringUtils.join(buddyList, " ")));
127: }
128: statusCheck = new StatusCheck();
129: timer.schedule(statusCheck, timerInterval,
130: timerInterval);
131: getBuddyManager().activate();
132: } catch (UnknownHostException e) {
133: Log.debug("IRC: Unable to connect to host:", e);
134: sessionDisconnected("IRC server does not appear to exist.");
135: } catch (IOException e) {
136: Log
137: .debug(
138: "IRC: Connection error while trying to connect ot IRC server:",
139: e);
140: sessionDisconnected("Connection failed while trying to contact IRC server..");
141: }
142: }
143: }.start();
144: }
145:
146: public void logOut() {
147: connection.sendCommand(new QuitCommand());
148: cleanUp();
149: sessionDisconnectedNoReconnect(null);
150: }
151:
152: public void cleanUp() {
153: if (timer != null) {
154: try {
155: timer.cancel();
156: } catch (Exception e) {
157: // Ignore
158: }
159: timer = null;
160: }
161: if (statusCheck != null) {
162: try {
163: statusCheck.cancel();
164: } catch (Exception e) {
165: // Ignore
166: }
167: statusCheck = null;
168: }
169: if (listener != null) {
170: try {
171: listener.disable();
172: } catch (Exception e) {
173: // Ignore
174: }
175: listener = null;
176: }
177: if (autoResponder != null) {
178: try {
179: autoResponder.disable();
180: } catch (Exception e) {
181: // Ignore
182: }
183: autoResponder = null;
184: }
185: if (autoRegister != null) {
186: try {
187: autoRegister.disable();
188: } catch (Exception e) {
189: // Ignore
190: }
191: autoRegister = null;
192: }
193: if (autoReconnect != null) {
194: try {
195: autoReconnect.disable();
196: } catch (Exception e) {
197: // Ignore
198: }
199: autoReconnect = null;
200: }
201: if (connection != null) {
202: try {
203: connection.disconnect();
204: } catch (Exception e) {
205: // Ignore
206: }
207: connection = null;
208: }
209: }
210:
211: public void updateStatus(PresenceType presenceType,
212: String verboseStatus) {
213: String awayMsg = ((IRCTransport) getTransport())
214: .convertJabStatusToIRC(presenceType, verboseStatus);
215: if (awayMsg == null) {
216: try {
217: connection.sendCommand(new AwayCommand());
218: // setPresence(PresenceType.available);
219: } catch (Exception e) {
220: // Ignore: is due to lost connection during logout typically
221: }
222: } else {
223: try {
224: connection.sendCommand(new AwayCommand(awayMsg));
225: // setPresence(PresenceType.away);
226: } catch (Exception e) {
227: // Ignore: is due to lost connection during logout typically
228: }
229: }
230: }
231:
232: public void addContact(JID jid, String nickname,
233: ArrayList<String> groups) {
234: String contact = getTransport().convertJIDToID(jid);
235: PseudoRosterItem rosterItem;
236: if (pseudoRoster.hasItem(contact)) {
237: rosterItem = pseudoRoster.getItem(contact);
238: rosterItem.setNickname(nickname);
239: rosterItem.setGroups(groups);
240: } else {
241: rosterItem = pseudoRoster.createItem(contact, nickname,
242: groups);
243: }
244:
245: getBuddyManager().storeBuddy(
246: new IRCBuddy(getBuddyManager(), contact, rosterItem));
247:
248: // connection.sendCommand(new IsonCommand(contact));
249: }
250:
251: public void removeContact(TransportBuddy contact) {
252: String ircContact = getTransport().convertJIDToID(
253: contact.getJID());
254: pseudoRoster.removeItem(ircContact);
255: }
256:
257: public void updateContact(TransportBuddy contact) {
258: String ircContact = getTransport().convertJIDToID(
259: contact.getJID());
260: if (pseudoRoster.hasItem(ircContact)) {
261: PseudoRosterItem rosterItem = pseudoRoster
262: .getItem(ircContact);
263: rosterItem.setNickname(contact.getNickname());
264: rosterItem.setGroups((List<String>) contact.getGroups());
265: // connection.sendCommand(new IsonCommand(ircContact));
266: } else {
267: PseudoRosterItem rosterItem = pseudoRoster.createItem(
268: ircContact, contact.getNickname(),
269: (List<String>) contact.getGroups());
270: getBuddyManager().storeBuddy(
271: new IRCBuddy(getBuddyManager(), ircContact,
272: rosterItem));
273: // connection.sendCommand(new IsonCommand(ircContact));
274: }
275: }
276:
277: public void sendMessage(JID jid, String message) {
278: connection.sendCommand(new MessageCommand(getTransport()
279: .convertJIDToID(jid), message));
280: }
281:
282: public void sendChatState(JID jid, ChatStateType chatState) {
283: // Nothing to do here
284: }
285:
286: /**
287: * @see org.jivesoftware.openfire.gateway.session.TransportSession#sendBuzzNotification(org.xmpp.packet.JID, String)
288: */
289: public void sendBuzzNotification(JID jid, String message) {
290: }
291:
292: /**
293: * @see org.jivesoftware.openfire.gateway.session.TransportSession#updateLegacyAvatar(String, byte[])
294: */
295: public void updateLegacyAvatar(String type, byte[] data) {
296: }
297:
298: /**
299: * @see org.jivesoftware.openfire.gateway.session.TransportSession#getRooms()
300: */
301: @Override
302: public void getRooms() {
303: if (getTransport().getMUCTransport().isRoomCacheOutOfDate()) {
304: getTransport().getMUCTransport().clearRoomCache();
305: connection.sendCommand(new ListCommand());
306: getTransport().getMUCTransport().updateRoomCacheTimestamp();
307: } else {
308: // This will be ignored if no one asked for it.
309: getTransport().getMUCTransport().sendRooms(getJID(),
310: getTransport().getMUCTransport().getCachedRooms());
311: }
312: }
313:
314: /**
315: * @see org.jivesoftware.openfire.gateway.session.TransportSession#getRoomInfo(String room)
316: */
317: @Override
318: public void getRoomInfo(String room) {
319: if (getTransport().getMUCTransport().isRoomCacheOutOfDate()) {
320: connection.sendCommand(new ListCommand(room));
321: } else {
322: // This will be ignored if no one asked for it.
323: MUCTransportRoom mucRoom = getTransport().getMUCTransport()
324: .getCachedRoom(room);
325: if (mucRoom != null) {
326: getTransport()
327: .getMUCTransport()
328: .sendRoomInfo(
329: getJID(),
330: getTransport()
331: .getMUCTransport()
332: .convertIDToJID(
333: mucRoom.getName(), null),
334: mucRoom);
335: } else {
336: getTransport().getMUCTransport().cancelPendingRequest(
337: getJID(),
338: getTransport().getMUCTransport()
339: .convertIDToJID(room, null),
340: NameSpace.DISCO_INFO);
341: }
342: }
343: }
344:
345: /**
346: * @see org.jivesoftware.openfire.gateway.session.TransportSession#getRoomMembers(String room)
347: */
348: @Override
349: public void getRoomMembers(String room) {
350: // transport.cancelPendingRequest(getSession().getJID(), transport.convertIDToJID(roomname, nickname), BaseMUCTransport.DISCO_ITEMS);
351: connection.sendCommand(new NamesCommand(room));
352: }
353:
354: private class StatusCheck extends TimerTask {
355: /**
356: * Send ISON to IRC to check on status of contacts.
357: */
358: public void run() {
359: List<String> buddyList = new ArrayList<String>();
360: for (TransportBuddy buddy : getBuddyManager().getBuddies()) {
361: buddyList.add(buddy.getName());
362: }
363: if (!buddyList.isEmpty()) {
364: connection.sendCommand(new IsonCommand(buddyList));
365: }
366: }
367: }
368:
369: }
|