/* * Copyright 2011 Ronald Kurniawan. * * This file is part of CodeTraq. * * CodeTraq 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. * * CodeTraq 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 CodeTraq. If not, see <http://www.gnu.org/licenses/>. */ package net.mobid.codetraq.talkers; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.logging.Level; import net.mobid.codetraq.ConnectionType; import net.mobid.codetraq.ITalker; import net.mobid.codetraq.utils.LogService; import net.sf.jml.Email; import net.sf.jml.MsnContact; import net.sf.jml.MsnContactList; import net.sf.jml.MsnContactPending; import net.sf.jml.MsnList; import net.sf.jml.MsnMessenger; import net.sf.jml.MsnSwitchboard; import net.sf.jml.MsnUserStatus; import net.sf.jml.event.MsnContactListAdapter; import net.sf.jml.event.MsnMessengerAdapter; import net.sf.jml.event.MsnSwitchboardAdapter; import net.sf.jml.impl.MsnMessengerFactory; /** * This is the implementation of ITalker interface for MSN Protocol. * We are using JML for implementation. * * @author Ronald Kurniawan * @version 0.1 */ public class MSNTalker implements ITalker { private String _username = null; private String _password = null; private ConnectionType _cType = null; private MsnMessenger _messenger = null; private List<String> _pendingCheckUser = new ArrayList<String>(); private final Object swid = "CODETRAQ"; private boolean _switchboardOn = false; /** * Creates a new MSNTalker. You should provide the password as * an encrypted <code>String</code> inside the configuration file. See * <code>PasswordProcessor.java</code> for more information on how we encrypt * or decrypt text. <b>DO NOT</b> store plaintext passwords in your configuration * file. * @param username - User's MSN username * @param password - User's MSN password * @param cType - a <code>ConnectionType</code> object */ public MSNTalker(String username, String password, ConnectionType cType) { _username = username; _password = password; _cType = cType; _messenger = MsnMessengerFactory.createMsnMessenger(_username, _password); initMessenger(); connect(); } /** * Returns the list of users that has not been approved into our contact list. * @return a <code>List</code> of pending contacts */ public List<String> getPendingCheckUser() { return _pendingCheckUser; } /** * Logs into MSN. */ public final void connect() { if (_messenger != null) { _messenger.login(); System.out.printf("Connecting to %s on port %d...%n", _messenger.getConnection().getRemoteIP(), _messenger.getConnection().getRemotePort()); } } /** * Sends a message to a contact. * @param recipientAddress - recipient's MSN username * @param message - message to send * @return <code>true</code> if message is sent successfully, <code>false</code> otherwise */ public boolean talk(String recipientAddress, String message) { if (_messenger != null && _switchboardOn) { MsnContact c = _messenger.getContactList().getContactByEmail(Email.parseStr(recipientAddress)); if (c.getStatus() != MsnUserStatus.OFFLINE) { _messenger.sendText(Email.parseStr(recipientAddress), message); return true; } } return false; } /** * Logs out from MSN. */ public void disconnect() { if (_messenger != null) { _messenger.logout(); } } /** * Checks whether a contact is in our contact list. * @param recipientAddress - contact's MSN username * @return <code>true</code> if contact is in our list, <code>false</code> otherwise */ public boolean isInContactList(String recipientAddress) { if (_messenger != null) { MsnContactList contactList = _messenger.getContactList(); MsnContact c = contactList.getContactByEmail(Email.parseStr(recipientAddress)); if (c != null && c.isInList(MsnList.AL)) { return true; } } return false; } /** * Adds a user into our contact list. * @param recipientAddress - contact's MSN username */ public void addToContactList(String recipientAddress) { if (_messenger != null) { _messenger.addFriend(Email.parseStr(recipientAddress), recipientAddress); } } /** * Checks whether a contact is online and ready to receive messages. * @param recipientAddress - contact's MSN username * @return <code>true</code> if contact is online, <code>false</code> otherwise */ public boolean recipientOnline(String recipientAddress) { if (_messenger != null) { MsnContactList contactList = _messenger.getContactList(); MsnContact c = contactList.getContactByEmail(Email.parseStr(recipientAddress)); if (c != null && c.isInList(MsnList.AL)) { if (c.getStatus() != MsnUserStatus.OFFLINE) { return true; } } } return false; } /* * Clears the pending contact list. */ private void clearPendingCheckUserList() { if (_pendingCheckUser != null && !_pendingCheckUser.isEmpty()) { Iterator it = _pendingCheckUser.iterator(); while (it.hasNext()) { String notificationID = it.next().toString(); if (!isInContactList(notificationID)) { addToContactList(notificationID); } } _pendingCheckUser.clear(); } } /* * Initialises our MSN object. As a rule we need to add "listeners" to MSN object, * and try to catch every possible situations. Without these "listeners", the * MSN object will not work correctly. */ private void initMessenger() { if (_messenger != null) { _messenger.addMessengerListener(new MsnMessengerAdapter() { public void loginCompleted(MsnMessenger messenger) { LogService.writeMessage(messenger.getOwner().getEmail().getEmailAddress() + " logged in."); _messenger.addContactListListener(new MsnContactListAdapter() { @Override public void contactListSyncCompleted(MsnMessenger messenger) { super.contactListSyncCompleted(messenger); clearPendingCheckUserList(); System.out.printf("Syncing contact list completed%n"); System.out.printf("There are %d contacts on the list.%n", messenger.getContactList().getContacts().length); } @Override public void contactListInitCompleted(MsnMessenger messenger) { } @Override public void contactAddedMe(MsnMessenger messenger, MsnContact contact) { messenger.addFriend(contact.getEmail(), contact.getDisplayName()); } @Override public void contactAddedMe(MsnMessenger messenger, MsnContactPending[] pending) { for (int i = 0; i < pending.length; i++) { MsnContactPending p = pending[i]; messenger.addFriend(p.getEmail(), p.getDisplayName()); } } @Override public void contactStatusChanged(MsnMessenger messenger, MsnContact contact) { super.contactStatusChanged(messenger, contact); } }); _messenger.addSwitchboardListener(new MsnSwitchboardAdapter() { @Override public void switchboardStarted(MsnSwitchboard switchboard) { if (!switchboard.getAttachment().equals(swid)) { return; } _switchboardOn = true; LogService.writeMessage(_cType.toString() + " switchboard started"); } @Override public void switchboardClosed(MsnSwitchboard switchboard) { _switchboardOn = false; LogService.writeMessage(_cType.toString() + " switchboard closed"); _messenger.newSwitchboard(swid); } }); _messenger.newSwitchboard(swid); } public void logout(MsnMessenger messenger) { LogService.writeMessage(messenger.getOwner().getEmail().getEmailAddress() + " logged out."); } public void exceptionCaught(MsnMessenger messenger, Throwable t) { LogService.writeLog(Level.SEVERE, t); } }); } } }