/* * Copyright 2006-2010 Daniel Henninger. All rights reserved. * * This software is published under the terms of the GNU Public License (GPL), * a copy of which is included in this distribution. */ package net.sf.kraken.protocols.simple; import javax.sip.ListeningPoint; import javax.sip.SipFactory; import net.sf.kraken.BaseTransport; import net.sf.kraken.registration.Registration; import net.sf.kraken.session.TransportSession; import net.sf.kraken.type.PresenceType; import net.sf.kraken.type.TransportLoginStatus; import org.jivesoftware.util.LocaleUtils; import org.xmpp.packet.JID; /** * A transport implementation for SIMPLE protocol. * @author Patrick Siu * @author Daniel Henninger */ public class SimpleTransport extends BaseTransport<SimpleBuddy> { SipFactory sipFactory = null; public SimpleTransport() { super(); // Initialize the SipFactory sipFactory = SipFactory.getInstance(); sipFactory.setPathName("gov.nist"); } @Override public TransportSession<SimpleBuddy> registrationLoggedIn(Registration registration, JID jid, PresenceType presenceType, String verboseStatus, Integer priority) { TransportSession<SimpleBuddy> session = new SimpleSession(registration, jid, this, priority); // Possibly more work here! session.logIn(presenceType, verboseStatus); return session; } @Override public void registrationLoggedOut(TransportSession<SimpleBuddy> session) { session.logOut(); ((SimpleSession) session).removeStack(); // Just in case. session.setLoginStatus(TransportLoginStatus.LOGGED_OUT); } /** */ @Override public String getTerminologyUsername() { return LocaleUtils.getLocalizedString("gateway.simple.username", "kraken"); } @Override public String getTerminologyPassword() { return LocaleUtils.getLocalizedString("gateway.simple.password", "kraken"); } /** * @see net.sf.kraken.BaseTransport#getTerminologyNickname() */ @Override public String getTerminologyNickname() { // If this string is needed, then take it. Just put a draft code to ensure integrity. return null; } /** * @see net.sf.kraken.BaseTransport#getTerminologyRegistration() */ @Override public String getTerminologyRegistration() { return LocaleUtils.getLocalizedString("gateway.simple.registration", "kraken"); } /** * @see net.sf.kraken.BaseTransport#isPasswordRequired() */ @Override public Boolean isPasswordRequired() { // Just put a draft code to ensure integrity. return true; } /** * @see net.sf.kraken.BaseTransport#isNicknameRequired() */ @Override public Boolean isNicknameRequired() { // Just put a draft code to ensure integrity. return false; } /** * @see net.sf.kraken.BaseTransport#isUsernameValid(String) */ @Override public Boolean isUsernameValid(String username) { // Just put a draft code to ensure integrity. // Log.debug("SimpleTransport.isUsernameValid: Checking '" + username + "'"); // Boolean result = username.matches("\\w+"); // return username.matches("[^ \\p{Cntrl}()@,;:\\\\\"\\[\\]]+@[^ \\p{Cntrl}()@,;:\\\\\"\\[\\]]+"); return username.matches("\\w+"); } // The following code are generic custom classes for SIP-XMPP conversion. public SimplePresence convertXMPPStatusToSIP(PresenceType xmppStatus) { SimplePresence simplePresence = new SimplePresence(); switch (xmppStatus) { case available: // simplePresence.setRpid(SimplePresence.Rpid.UNKNOWN); simplePresence.setDmNote("Online"); break; case away: simplePresence.setRpid(SimplePresence.Rpid.AWAY); break; case chat: simplePresence.setRpid(SimplePresence.Rpid.OTHER); simplePresence.setDmNote("Free to chat"); break; case dnd: simplePresence.setRpid(SimplePresence.Rpid.BUSY); break; case unavailable: simplePresence.setTupleStatus(SimplePresence.TupleStatus.CLOSED); break; case unknown: simplePresence.setRpid(SimplePresence.Rpid.UNKNOWN); break; case xa: simplePresence.setRpid(SimplePresence.Rpid.AWAY); break; default: break; } return simplePresence; } public PresenceType convertSIPStatusToXMPP(SimplePresence simplePresence) { if (simplePresence.getTupleStatus().isOpen()) { switch (simplePresence.getRpid()) { case APPOINTMENT: return PresenceType.dnd; case AWAY: return PresenceType.away; case BREAKFAST: return PresenceType.xa; case BUSY: return PresenceType.dnd; case DINNER: return PresenceType.xa; case HOLIDAY: return PresenceType.xa; case IN_TRANSIT: return PresenceType.xa; case LOOKING_FOR_WORK: return PresenceType.dnd; case LUNCH: case MEAL: return PresenceType.xa; case MEETING: return PresenceType.dnd; case ON_THE_PHONE: return PresenceType.away; case OTHER: return PresenceType.available; case PERFORMANCE: return PresenceType.dnd; case PERMANENT_ABSENCE: return PresenceType.unavailable; case PLAYING: return PresenceType.away; case PRESENTATION: return PresenceType.dnd; case SHOPPING: return PresenceType.xa; case SLEEPING: return PresenceType.xa; case SPECTATOR: return PresenceType.xa; case STEERING: return PresenceType.xa; case TRAVEL: return PresenceType.xa; case TV: return PresenceType.away; case UNKNOWN: return PresenceType.unknown; case VACATION: return PresenceType.xa; case WORKING: return PresenceType.dnd; case WORSHIP: return PresenceType.dnd; default: return PresenceType.available; } } else { return PresenceType.unavailable; } } /** * An improved method to do the trick. */ @Override public String convertJIDToID(JID jid) { String node = jid.getNode(); while (!JID.unescapeNode(node).equals(node)) { node = JID.unescapeNode(node); } return node; } int portOffset = 0; synchronized int generateListenerPort() { return (ListeningPoint.PORT_5060 + (++portOffset)); } }