Commit 9a434fd3 authored by Daniel Henninger's avatar Daniel Henninger Committed by dhenninger

[GATE-55] Restructuring work to incorporate lack of need of transports in roster.

[GATE-13] Working on "what features the client supports" functionality for things like typing notifications.
[GATE-1] Messing with threads a tad.

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk/src/plugins/gateway@5787 b35dd754-fafc-0310-a699-88a17e54d16e
parent fc67ab7c
...@@ -24,6 +24,7 @@ import org.jivesoftware.wildfire.roster.*; ...@@ -24,6 +24,7 @@ import org.jivesoftware.wildfire.roster.*;
import org.jivesoftware.wildfire.user.PresenceEventListener; import org.jivesoftware.wildfire.user.PresenceEventListener;
import org.jivesoftware.wildfire.user.UserAlreadyExistsException; import org.jivesoftware.wildfire.user.UserAlreadyExistsException;
import org.jivesoftware.wildfire.user.UserNotFoundException; import org.jivesoftware.wildfire.user.UserNotFoundException;
import org.jivesoftware.wildfire.user.PresenceEventDispatcher;
import org.xmpp.component.Component; import org.xmpp.component.Component;
import org.xmpp.component.ComponentManager; import org.xmpp.component.ComponentManager;
import org.xmpp.forms.DataForm; import org.xmpp.forms.DataForm;
...@@ -69,6 +70,7 @@ public abstract class BaseTransport implements Component, RosterEventListener, P ...@@ -69,6 +70,7 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
public void initialize(JID jid, ComponentManager componentManager) { public void initialize(JID jid, ComponentManager componentManager) {
this.jid = jid; this.jid = jid;
this.componentManager = componentManager; this.componentManager = componentManager;
sessionManager.startThreadManager(jid);
} }
/** /**
...@@ -215,91 +217,9 @@ public abstract class BaseTransport implements Component, RosterEventListener, P ...@@ -215,91 +217,9 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
Log.debug("Unable to find registration."); Log.debug("Unable to find registration.");
return reply; return reply;
} }
Registration registration = registrations.iterator().next();
// This packet is to the transport itself. // This packet is to the transport itself.
if (packet.getType() == null) { if (packet.getType() == Presence.Type.probe) {
// A user's resource has come online.
TransportSession session;
try {
session = sessionManager.getSession(from);
if (session.hasResource(from.getResource())) {
Log.debug("An existing resource has changed status: " + from);
if (session.getPriority(from.getResource()) != packet.getPriority()) {
session.updatePriority(from.getResource(), packet.getPriority());
}
if (session.isHighestPriority(from.getResource())) {
// Well, this could represent a status change.
session.updateStatus(getPresenceType(packet), packet.getStatus());
}
}
else {
Log.debug("A new resource has come online: " + from);
// This is a new resource, lets send them what we know.
session.addResource(from.getResource(), packet.getPriority());
// Tell the new resource what the state of their buddy list is.
session.resendContactStatuses(from);
// If this priority is the highest, treat it's status as golden
if (session.isHighestPriority(from.getResource())) {
session.updateStatus(getPresenceType(packet), packet.getStatus());
}
}
}
catch (NotFoundException e) {
Log.debug("A new session has come online: " + from);
session = this.registrationLoggedIn(registration, from, getPresenceType(packet), packet.getStatus(), packet.getPriority());
sessionManager.storeSession(from, session);
}
}
else if (packet.getType() == Presence.Type.unavailable) {
// A user's resource has gone offline.
TransportSession session;
try {
session = sessionManager.getSession(from);
if (session.getResourceCount() > 1) {
String resource = from.getResource();
// Just one of the resources, lets adjust accordingly.
if (session.isHighestPriority(resource)) {
Log.debug("A high priority resource (of multiple) has gone offline: " + from);
// Ooh, the highest resource went offline, drop to next highest.
session.removeResource(resource);
// Lets ask the next highest resource what it's presence is.
Presence p = new Presence(Presence.Type.probe);
p.setTo(session.getJIDWithHighestPriority());
p.setFrom(this.getJID());
sendPacket(p);
}
else {
Log.debug("A low priority resource (of multiple) has gone offline: " + from);
// Meh, lower priority, big whoop.
session.removeResource(resource);
}
}
else {
Log.debug("A final resource has gone offline: " + from);
// No more resources, byebye.
if (session.isLoggedIn()) {
this.registrationLoggedOut(session);
}
sessionManager.removeSession(from);
}
}
catch (NotFoundException e) {
Log.debug("Ignoring unavailable presence for inactive seession.");
}
}
else if (packet.getType() == Presence.Type.probe) {
// Client is asking for presence status. // Client is asking for presence status.
TransportSession session; TransportSession session;
try { try {
...@@ -329,16 +249,6 @@ public abstract class BaseTransport implements Component, RosterEventListener, P ...@@ -329,16 +249,6 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
// Presence probe, lets try to tell them. // Presence probe, lets try to tell them.
session.retrieveContactStatus(to); session.retrieveContactStatus(to);
} }
else if (packet.getType() == Presence.Type.subscribe) {
// User wants to add someone to their legacy roster.
// TODO: experimenting with doing this a different way
//session.addContact(packet.getTo());
}
else if (packet.getType() == Presence.Type.unsubscribe) {
// User wants to remove someone from their legacy roster.
// TODO: experimenting with doing this a different way
//session.removeContact(packet.getTo());
}
else { else {
// Anything else we will ignore for now. // Anything else we will ignore for now.
} }
...@@ -786,7 +696,9 @@ public abstract class BaseTransport implements Component, RosterEventListener, P ...@@ -786,7 +696,9 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
*/ */
public void start() { public void start() {
RosterEventDispatcher.addListener(this); RosterEventDispatcher.addListener(this);
PresenceEventDispatcher.addListener(this);
// Probe all registered users [if they are logged in] to auto-log them in // Probe all registered users [if they are logged in] to auto-log them in
// TODO: This is no longer going to work... need to find a way that doesn't involve presence packets or anything like that
for (Registration registration : registrationManager.getRegistrations()) { for (Registration registration : registrationManager.getRegistrations()) {
if (SessionManager.getInstance().getSessionCount(registration.getJID().getNode()) > 0) { if (SessionManager.getInstance().getSessionCount(registration.getJID().getNode()) > 0) {
Presence p = new Presence(Presence.Type.probe); Presence p = new Presence(Presence.Type.probe);
...@@ -804,6 +716,7 @@ public abstract class BaseTransport implements Component, RosterEventListener, P ...@@ -804,6 +716,7 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
*/ */
public void shutdown() { public void shutdown() {
RosterEventDispatcher.removeListener(this); RosterEventDispatcher.removeListener(this);
PresenceEventDispatcher.removeListener(this);
// Disconnect everyone's session // Disconnect everyone's session
for (TransportSession session : sessionManager.getSessions()) { for (TransportSession session : sessionManager.getSessions()) {
registrationLoggedOut(session); registrationLoggedOut(session);
...@@ -904,7 +817,7 @@ public abstract class BaseTransport implements Component, RosterEventListener, P ...@@ -904,7 +817,7 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
Roster roster = rosterManager.getRoster(userjid.getNode()); Roster roster = rosterManager.getRoster(userjid.getNode());
try { try {
RosterItem gwitem = roster.getRosterItem(contactjid); RosterItem gwitem = roster.getRosterItem(contactjid);
Boolean changed = false; boolean changed = false;
if (gwitem.getSubStatus() != RosterItem.SUB_BOTH) { if (gwitem.getSubStatus() != RosterItem.SUB_BOTH) {
gwitem.setSubStatus(RosterItem.SUB_BOTH); gwitem.setSubStatus(RosterItem.SUB_BOTH);
changed = true; changed = true;
...@@ -1300,10 +1213,12 @@ public abstract class BaseTransport implements Component, RosterEventListener, P ...@@ -1300,10 +1213,12 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
*/ */
public boolean addingContact(Roster roster, RosterItem item, boolean persistent) { public boolean addingContact(Roster roster, RosterItem item, boolean persistent) {
Log.debug("addingContact "+roster.getUsername()+":"+item.getJid()+" is "+persistent); Log.debug("addingContact "+roster.getUsername()+":"+item.getJid()+" is "+persistent);
if (item.getJid().getDomain().equals(this.getJID()) && item.getJid().getNode() != null) { return !(item.getJid().getDomain().equals(this.getJID()) &&
return false; item.getJid().getNode() != null) && persistent;
} // if (item.getJid().getDomain().equals(this.getJID()) && item.getJid().getNode() != null) {
return persistent; // return false;
// }
// return persistent;
} }
/** /**
...@@ -1394,8 +1309,53 @@ public abstract class BaseTransport implements Component, RosterEventListener, P ...@@ -1394,8 +1309,53 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
* *
* @see org.jivesoftware.wildfire.user.PresenceEventListener#availableSession(org.jivesoftware.wildfire.ClientSession, org.xmpp.packet.Presence) * @see org.jivesoftware.wildfire.user.PresenceEventListener#availableSession(org.jivesoftware.wildfire.ClientSession, org.xmpp.packet.Presence)
*/ */
public void availableSession(ClientSession session, Presence presence) { public void availableSession(ClientSession clSession, Presence packet) {
Log.debug("availableSession "+session+":"+presence); Log.debug("availableSession "+clSession+":"+packet);
JID from = packet.getFrom();
Collection<Registration> registrations = registrationManager.getRegistrations(from, this.transportType);
if (registrations.isEmpty()) {
// User is not registered with us.
return;
}
Registration registration = registrations.iterator().next();
// A user's resource has come online.
TransportSession session;
try {
session = sessionManager.getSession(from);
if (session.hasResource(from.getResource())) {
Log.debug("An existing resource has changed status: " + from);
if (session.getPriority(from.getResource()) != packet.getPriority()) {
session.updatePriority(from.getResource(), packet.getPriority());
}
if (session.isHighestPriority(from.getResource())) {
// Well, this could represent a status change.
session.updateStatus(getPresenceType(packet), packet.getStatus());
}
}
else {
Log.debug("A new resource has come online: " + from);
// This is a new resource, lets send them what we know.
session.addResource(from.getResource(), packet.getPriority());
// Tell the new resource what the state of their buddy list is.
session.resendContactStatuses(from);
// If this priority is the highest, treat it's status as golden
if (session.isHighestPriority(from.getResource())) {
session.updateStatus(getPresenceType(packet), packet.getStatus());
}
}
}
catch (NotFoundException e) {
Log.debug("A new session has come online: " + from);
session = this.registrationLoggedIn(registration, from, getPresenceType(packet), packet.getStatus(), packet.getPriority());
sessionManager.storeSession(from, session);
}
} }
/** /**
...@@ -1403,9 +1363,57 @@ public abstract class BaseTransport implements Component, RosterEventListener, P ...@@ -1403,9 +1363,57 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
* *
* @see org.jivesoftware.wildfire.user.PresenceEventListener#unavailableSession(org.jivesoftware.wildfire.ClientSession, org.xmpp.packet.Presence) * @see org.jivesoftware.wildfire.user.PresenceEventListener#unavailableSession(org.jivesoftware.wildfire.ClientSession, org.xmpp.packet.Presence)
*/ */
public void unavailableSession(ClientSession session, Presence presence) { public void unavailableSession(ClientSession clSession, Presence packet) {
Log.debug("unavailableSession "+session+":"+presence); Log.debug("unavailableSession "+clSession+":"+packet);
JID from = packet.getFrom();
Collection<Registration> registrations = registrationManager.getRegistrations(from, this.transportType);
if (registrations.isEmpty()) {
// User is not registered with us.
return;
}
// A user's resource has gone offline.
TransportSession session;
try {
session = sessionManager.getSession(from);
if (session.getResourceCount() > 1) {
String resource = from.getResource();
// Just one of the resources, lets adjust accordingly.
if (session.isHighestPriority(resource)) {
Log.debug("A high priority resource (of multiple) has gone offline: " + from);
// Ooh, the highest resource went offline, drop to next highest.
session.removeResource(resource);
// Lets ask the next highest resource what it's presence is.
Presence p = new Presence(Presence.Type.probe);
p.setTo(session.getJIDWithHighestPriority());
p.setFrom(this.getJID());
sendPacket(p);
}
else {
Log.debug("A low priority resource (of multiple) has gone offline: " + from);
// Meh, lower priority, big whoop.
session.removeResource(resource);
}
}
else {
Log.debug("A final resource has gone offline: " + from);
// No more resources, byebye.
if (session.isLoggedIn()) {
this.registrationLoggedOut(session);
}
sessionManager.removeSession(from);
}
}
catch (NotFoundException e) {
Log.debug("Ignoring unavailable presence for inactive seession.");
}
} }
/** /**
...@@ -1413,8 +1421,35 @@ public abstract class BaseTransport implements Component, RosterEventListener, P ...@@ -1413,8 +1421,35 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
* *
* @see org.jivesoftware.wildfire.user.PresenceEventListener#presencePriorityChanged(org.jivesoftware.wildfire.ClientSession, org.xmpp.packet.Presence) * @see org.jivesoftware.wildfire.user.PresenceEventListener#presencePriorityChanged(org.jivesoftware.wildfire.ClientSession, org.xmpp.packet.Presence)
*/ */
public void presencePriorityChanged(ClientSession session, Presence presence) { public void presencePriorityChanged(ClientSession clSession, Presence packet) {
Log.debug("presencePriorityChanged "+session+":"+presence); Log.debug("presencePriorityChanged "+clSession+":"+packet);
JID from = packet.getFrom();
Collection<Registration> registrations = registrationManager.getRegistrations(from, this.transportType);
if (registrations.isEmpty()) {
// User is not registered with us.
return;
}
TransportSession session;
try {
session = sessionManager.getSession(from);
if (session.hasResource(from.getResource())) {
Log.debug("An existing resource has changed status: " + from);
if (session.getPriority(from.getResource()) != packet.getPriority()) {
session.updatePriority(from.getResource(), packet.getPriority());
}
if (session.isHighestPriority(from.getResource())) {
// Well, this could represent a status change.
session.updateStatus(getPresenceType(packet), packet.getStatus());
}
}
}
catch (NotFoundException e) {
// Not actually logged in.
}
} }
/** /**
...@@ -1422,8 +1457,32 @@ public abstract class BaseTransport implements Component, RosterEventListener, P ...@@ -1422,8 +1457,32 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
* *
* @see org.jivesoftware.wildfire.user.PresenceEventListener#presenceChanged(org.jivesoftware.wildfire.ClientSession, org.xmpp.packet.Presence) * @see org.jivesoftware.wildfire.user.PresenceEventListener#presenceChanged(org.jivesoftware.wildfire.ClientSession, org.xmpp.packet.Presence)
*/ */
public void presenceChanged(ClientSession session, Presence presence) { public void presenceChanged(ClientSession clSession, Presence packet) {
Log.debug("presenceChanged "+session+":"+presence); Log.debug("presenceChanged "+clSession+":"+packet);
JID from = packet.getFrom();
Collection<Registration> registrations = registrationManager.getRegistrations(from, this.transportType);
if (registrations.isEmpty()) {
// User is not registered with us.
return;
}
TransportSession session;
try {
session = sessionManager.getSession(from);
if (session.hasResource(from.getResource())) {
Log.debug("An existing resource has changed status: " + from);
if (session.isHighestPriority(from.getResource())) {
// Well, this could represent a status change.
session.updateStatus(getPresenceType(packet), packet.getStatus());
}
}
}
catch (NotFoundException e) {
// Not actually logged in.
}
} }
/** /**
......
/**
* $Revision$
* $Date$
*
* Copyright (C) 2006 Jive Software. 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 org.jivesoftware.wildfire.gateway;
/**
* An enumeration for supported features.
*
* This represents features that the client supports that we have detected and
* can make use of.
*
* @author Daniel Henninger
*/
public enum SupportedFeature {
/**
* Chat States (XEP-0085)
*/
chatstates
}
...@@ -17,6 +17,7 @@ import org.jivesoftware.wildfire.roster.Roster; ...@@ -17,6 +17,7 @@ import org.jivesoftware.wildfire.roster.Roster;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.ArrayList;
/** /**
* Interface for a transport session. * Interface for a transport session.
...@@ -90,6 +91,11 @@ public abstract class TransportSession implements Runnable { ...@@ -90,6 +91,11 @@ public abstract class TransportSession implements Runnable {
*/ */
public TransportLoginStatus loginStatus = TransportLoginStatus.LOGGED_OUT; public TransportLoginStatus loginStatus = TransportLoginStatus.LOGGED_OUT;
/**
* Supported features.
*/
public ArrayList<SupportedFeature> supportedFeatures = new ArrayList<SupportedFeature>();
/** /**
* Associates a resource with the session, and tracks it's priority. * Associates a resource with the session, and tracks it's priority.
* *
...@@ -250,6 +256,43 @@ public abstract class TransportSession implements Runnable { ...@@ -250,6 +256,43 @@ public abstract class TransportSession implements Runnable {
return (resources.containsValue(resource)); return (resources.containsValue(resource));
} }
/**
* Sets a feature that the client supports.
*
* @param feature Feature that the session supports.
*/
public void setSupportedFeature(SupportedFeature feature) {
if (!supportedFeatures.contains(feature)) {
supportedFeatures.add(feature);
}
}
/**
* Removes a feature that the client supports.
*
* @param feature Feature to be removed from the supported list.
*/
public void removeSupportedFeature(SupportedFeature feature) {
supportedFeatures.remove(feature);
}
/**
* Clears all of the supported features recorded.
*/
public void clearSupportedFeatures() {
supportedFeatures.clear();
}
/**
* Retrieves whether this session supports a specific feature.
*
* @param feature Feature to check for support of.
* @return True or false if the session supports the specified feature.
*/
public Boolean isFeatureSupported(SupportedFeature feature) {
return supportedFeatures.contains(feature);
}
/** /**
* Updates the login status. * Updates the login status.
* *
......
...@@ -53,6 +53,11 @@ public class TransportSessionManager { ...@@ -53,6 +53,11 @@ public class TransportSessionManager {
*/ */
BaseTransport transport; BaseTransport transport;
/**
* Group of all threads related to this session.
*/
public ThreadGroup threadGroup;
/** /**
* Creates the transport session manager instance and initializes. * Creates the transport session manager instance and initializes.
* *
...@@ -72,6 +77,34 @@ public class TransportSessionManager { ...@@ -72,6 +77,34 @@ public class TransportSessionManager {
timer.cancel(); timer.cancel();
} }
/**
* Initialize the thread group manager.
*
* @param jid JID for naming purposes of the thread group manager.
*/
public void startThreadManager(JID jid) {
threadGroup = new ThreadGroup(jid.toString());
}
/**
* Destroys the thread group manager.
*/
public void stopThreadManager() {
threadGroup.destroy();
}
/**
* Starts a thread associated with a session.
*
* @param session Session the thread will be associated with.
* @return A thread wrapped around the session.
*/
public Thread startThread(TransportSession session) {
Thread sessionThread = new Thread(threadGroup, session);
sessionThread.start();
return sessionThread;
}
/** /**
* Retrieve the session instance for a given JID. * Retrieve the session instance for a given JID.
* *
......
...@@ -81,8 +81,7 @@ public class IRCTransport extends BaseTransport { ...@@ -81,8 +81,7 @@ public class IRCTransport extends BaseTransport {
public TransportSession registrationLoggedIn(Registration registration, JID jid, PresenceType presenceType, String verboseStatus, Integer priority) { public TransportSession registrationLoggedIn(Registration registration, JID jid, PresenceType presenceType, String verboseStatus, Integer priority) {
Log.debug("Logging in to IRC gateway."); Log.debug("Logging in to IRC gateway.");
TransportSession session = new IRCSession(registration, jid, this, priority); TransportSession session = new IRCSession(registration, jid, this, priority);
Thread sessionThread = new Thread(session); this.getSessionManager().startThread(session);
sessionThread.start();
((IRCSession)session).logIn(presenceType, verboseStatus); ((IRCSession)session).logIn(presenceType, verboseStatus);
return session; return session;
} }
......
...@@ -83,8 +83,7 @@ public class MSNTransport extends BaseTransport { ...@@ -83,8 +83,7 @@ public class MSNTransport extends BaseTransport {
public TransportSession registrationLoggedIn(Registration registration, JID jid, PresenceType presenceType, String verboseStatus, Integer priority) { public TransportSession registrationLoggedIn(Registration registration, JID jid, PresenceType presenceType, String verboseStatus, Integer priority) {
Log.debug("Logging in to MSN gateway."); Log.debug("Logging in to MSN gateway.");
TransportSession session = new MSNSession(registration, jid, this, priority); TransportSession session = new MSNSession(registration, jid, this, priority);
Thread sessionThread = new Thread(session); this.getSessionManager().startThread(session);
sessionThread.start();
((MSNSession)session).logIn(presenceType, verboseStatus); ((MSNSession)session).logIn(presenceType, verboseStatus);
return session; return session;
} }
......
...@@ -84,8 +84,7 @@ public class OSCARTransport extends BaseTransport { ...@@ -84,8 +84,7 @@ public class OSCARTransport extends BaseTransport {
*/ */
public TransportSession registrationLoggedIn(Registration registration, JID jid, PresenceType presenceType, String verboseStatus, Integer priority) { public TransportSession registrationLoggedIn(Registration registration, JID jid, PresenceType presenceType, String verboseStatus, Integer priority) {
TransportSession session = new OSCARSession(registration, jid, this, priority); TransportSession session = new OSCARSession(registration, jid, this, priority);
Thread sessionThread = new Thread(session); this.getSessionManager().startThread(session);
sessionThread.start();
((OSCARSession)session).logIn(presenceType, verboseStatus); ((OSCARSession)session).logIn(presenceType, verboseStatus);
return session; return session;
} }
......
...@@ -83,8 +83,7 @@ public class YahooTransport extends BaseTransport { ...@@ -83,8 +83,7 @@ public class YahooTransport extends BaseTransport {
public TransportSession registrationLoggedIn(Registration registration, JID jid, PresenceType presenceType, String verboseStatus, Integer priority) { public TransportSession registrationLoggedIn(Registration registration, JID jid, PresenceType presenceType, String verboseStatus, Integer priority) {
Log.debug("Logging in to Yahoo gateway."); Log.debug("Logging in to Yahoo gateway.");
TransportSession session = new YahooSession(registration, jid, this, priority); TransportSession session = new YahooSession(registration, jid, this, priority);
Thread sessionThread = new Thread(session); this.getSessionManager().startThread(session);
sessionThread.start();
((YahooSession)session).logIn(presenceType, verboseStatus); ((YahooSession)session).logIn(presenceType, verboseStatus);
return session; return session;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment