diff options
author | slewis | 2010-06-24 01:02:35 -0400 |
---|---|---|
committer | slewis | 2010-06-24 01:02:35 -0400 |
commit | 8bdb4a766d927f5644d46d1d068ee67227b56300 (patch) | |
tree | 75de19385bb07d77264cdcff8e8d2e2ffa994b90 /providers/bundles/org.eclipse.ecf.provider.xmpp | |
parent | b39169c5f08e2a1608d1af436f815987bbc04d0d (diff) | |
download | org.eclipse.ecf-8bdb4a766d927f5644d46d1d068ee67227b56300.tar.gz org.eclipse.ecf-8bdb4a766d927f5644d46d1d068ee67227b56300.tar.xz org.eclipse.ecf-8bdb4a766d927f5644d46d1d068ee67227b56300.zip |
Fix for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=316071
Diffstat (limited to 'providers/bundles/org.eclipse.ecf.provider.xmpp')
2 files changed, 121 insertions, 23 deletions
diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/internal/provider/xmpp/smack/ECFConnection.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/internal/provider/xmpp/smack/ECFConnection.java index 026e3513e..65525f765 100644 --- a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/internal/provider/xmpp/smack/ECFConnection.java +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/internal/provider/xmpp/smack/ECFConnection.java @@ -36,10 +36,12 @@ import org.jivesoftware.smack.SASLAuthentication; import org.jivesoftware.smack.SmackConfiguration; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.Bind; +import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.Message.Type; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Presence; -import org.jivesoftware.smack.packet.Message.Type; public class ECFConnection implements ISynchAsynchConnection { @@ -52,8 +54,7 @@ public class ECFConnection implements ISynchAsynchConnection { protected static final String STRING_ENCODING = "UTF-8"; public static final String OBJECT_PROPERTY_NAME = ECFConnection.class - .getName() - + ".object"; + .getName() + ".object"; protected static final int XMPP_DEFAULT_PORT = 5222; protected static final int XMPPS_DEFAULT_PORT = 5223; @@ -70,6 +71,14 @@ public class ECFConnection implements ISynchAsynchConnection { private boolean disconnecting = false; + private int BIND_TIMEOUT = new Integer(System.getProperty( + "org.eclipse.ecf.provider.xmpp.ECFConnection.bindTimeout", "15000")) + .intValue(); + + private Object bindLock = new Object(); + + private String jid; + private final PacketListener packetListener = new PacketListener() { public void processPacket(Packet arg0) { handlePacket(arg0); @@ -220,11 +229,29 @@ public class ECFConnection implements ISynchAsynchConnection { // Login connection.login(username, (String) data, serverResource); - isConnected = true; + waitForBindResult(); + } catch (final XMPPException e) { throw new ContainerConnectException("Login attempt failed", e); } - return null; + return jid; + } + + private void waitForBindResult() throws XMPPException { + // We'll wait a maximum of + long bindTimeout = System.currentTimeMillis() + BIND_TIMEOUT; + synchronized (bindLock) { + while (jid == null && System.currentTimeMillis() < bindTimeout) { + try { + bindLock.wait(1000); + } catch (InterruptedException e) { + } + } + if (jid == null) + throw new XMPPException( + "timeout waiting for server bind result"); + isConnected = true; + } } private String getClientIdentifier() { @@ -245,8 +272,11 @@ public class ECFConnection implements ISynchAsynchConnection { connection.removePacketListener(packetListener); connection.removeConnectionListener(connectionListener); connection.disconnect(); - isConnected = false; connection = null; + synchronized (bindLock) { + jid = null; + isConnected = false; + } } } @@ -288,6 +318,7 @@ public class ECFConnection implements ISynchAsynchConnection { } protected void handlePacket(Packet arg0) { + handleJidPacket(arg0); try { final Object val = arg0.getProperty(OBJECT_PROPERTY_NAME); if (val != null) { @@ -307,6 +338,22 @@ public class ECFConnection implements ISynchAsynchConnection { } } + private void handleJidPacket(Packet packet) { + if (jid != null) + return; + if (packet instanceof IQ) { + IQ iqPacket = (IQ) packet; + if (iqPacket.getType().equals(IQ.Type.RESULT) + && iqPacket instanceof Bind) { + Bind bindPacket = (Bind) iqPacket; + synchronized (bindLock) { + jid = bindPacket.getJid(); + bindLock.notify(); + } + } + } + } + public synchronized void sendAsynch(ID receiver, byte[] data) throws IOException { if (data == null) diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainer.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainer.java index 75587760f..75362ae3a 100644 --- a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainer.java +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainer.java @@ -10,23 +10,40 @@ package org.eclipse.ecf.provider.xmpp; import java.io.IOException; import java.net.ConnectException; -import java.util.*; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; import org.eclipse.ecf.core.ContainerConnectException; import org.eclipse.ecf.core.events.ContainerDisconnectedEvent; import org.eclipse.ecf.core.events.ContainerDisconnectingEvent; -import org.eclipse.ecf.core.identity.*; -import org.eclipse.ecf.core.security.*; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDFactory; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.core.security.Callback; +import org.eclipse.ecf.core.security.CallbackHandler; +import org.eclipse.ecf.core.security.IConnectContext; +import org.eclipse.ecf.core.security.ObjectCallback; +import org.eclipse.ecf.core.security.UnsupportedCallbackException; import org.eclipse.ecf.core.sharedobject.SharedObjectAddException; import org.eclipse.ecf.core.sharedobject.util.IQueueEnqueue; import org.eclipse.ecf.core.user.User; import org.eclipse.ecf.core.util.Event; import org.eclipse.ecf.filetransfer.ISendFileTransferContainerAdapter; -import org.eclipse.ecf.internal.provider.xmpp.*; import org.eclipse.ecf.internal.provider.xmpp.Messages; -import org.eclipse.ecf.internal.provider.xmpp.events.*; +import org.eclipse.ecf.internal.provider.xmpp.XMPPChatRoomContainer; +import org.eclipse.ecf.internal.provider.xmpp.XMPPChatRoomManager; +import org.eclipse.ecf.internal.provider.xmpp.XMPPContainerAccountManager; +import org.eclipse.ecf.internal.provider.xmpp.XMPPContainerContext; +import org.eclipse.ecf.internal.provider.xmpp.XMPPContainerPresenceHelper; +import org.eclipse.ecf.internal.provider.xmpp.XmppPlugin; +import org.eclipse.ecf.internal.provider.xmpp.events.IQEvent; +import org.eclipse.ecf.internal.provider.xmpp.events.MessageEvent; +import org.eclipse.ecf.internal.provider.xmpp.events.PresenceEvent; import org.eclipse.ecf.internal.provider.xmpp.filetransfer.XMPPOutgoingFileTransferHelper; import org.eclipse.ecf.internal.provider.xmpp.search.XMPPUserSearchManager; -import org.eclipse.ecf.internal.provider.xmpp.smack.*; +import org.eclipse.ecf.internal.provider.xmpp.smack.ECFConnection; +import org.eclipse.ecf.internal.provider.xmpp.smack.ECFConnectionObjectPacketEvent; +import org.eclipse.ecf.internal.provider.xmpp.smack.ECFConnectionPacketEvent; import org.eclipse.ecf.presence.IAccountManager; import org.eclipse.ecf.presence.IPresenceContainerAdapter; import org.eclipse.ecf.presence.chatroom.IChatRoomContainer; @@ -35,13 +52,23 @@ import org.eclipse.ecf.presence.im.IChatManager; import org.eclipse.ecf.presence.roster.IRosterManager; import org.eclipse.ecf.presence.search.IUserSearchManager; import org.eclipse.ecf.presence.service.IPresenceService; -import org.eclipse.ecf.provider.comm.*; -import org.eclipse.ecf.provider.generic.*; +import org.eclipse.ecf.provider.comm.AsynchEvent; +import org.eclipse.ecf.provider.comm.ConnectionCreateException; +import org.eclipse.ecf.provider.comm.ISynchAsynchConnection; +import org.eclipse.ecf.provider.generic.ClientSOContainer; +import org.eclipse.ecf.provider.generic.ContainerMessage; +import org.eclipse.ecf.provider.generic.SOConfig; +import org.eclipse.ecf.provider.generic.SOContainerConfig; +import org.eclipse.ecf.provider.generic.SOContext; +import org.eclipse.ecf.provider.generic.SOWrapper; import org.eclipse.ecf.provider.xmpp.identity.XMPPID; import org.eclipse.osgi.util.NLS; import org.jivesoftware.smack.Roster; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.packet.*; +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.Packet; +import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smackx.packet.MUCUser; import org.jivesoftware.smackx.packet.XHTMLExtension; @@ -57,8 +84,7 @@ public class XMPPContainer extends ClientSOContainer implements .getNamespaceIdentifier(); public static final String CONTAINER_HELPER_ID = XMPPContainer.class - .getName() - + ".xmpphandler"; //$NON-NLS-1$ + .getName() + ".xmpphandler"; //$NON-NLS-1$ protected static final String GOOGLE_SERVICENAME = "gmail.com"; //$NON-NLS-1$ @@ -239,9 +265,34 @@ public class XMPPContainer extends ClientSOContainer implements return super.getAdapter(clazz); } + private String trimResourceFromJid(String jid) { + int slashIndex = jid.indexOf('/'); + if (slashIndex > 0) { + return jid.substring(slashIndex + 1); + } else + return null; + } + + private void resetTargetResource(ID originalTarget, Object serverData) { + // Reset resource to that given by server + if (originalTarget instanceof XMPPID) { + XMPPID xmppOriginalTarget = (XMPPID) originalTarget; + if (serverData != null && serverData instanceof String) { + String jid = (String) serverData; + String jidResource = trimResourceFromJid(jid); + if (jidResource != null) { + xmppOriginalTarget.setResourceName(jidResource); + } + } + } + } + protected ID handleConnectResponse(ID originalTarget, Object serverData) throws Exception { if (originalTarget != null && !originalTarget.equals(getID())) { + // First reset target resource to whatever the server says it is + resetTargetResource(originalTarget, serverData); + addNewRemoteMember(originalTarget, null); final ECFConnection conn = getECFConnection(); @@ -371,8 +422,8 @@ public class XMPPContainer extends ClientSOContainer implements final Object extension = i.next(); if (extension instanceof XHTMLExtension) { final XHTMLExtension xhtmlExtension = (XHTMLExtension) extension; - deliverEvent(new MessageEvent((Message) packet, xhtmlExtension - .getBodies())); + deliverEvent(new MessageEvent((Message) packet, + xhtmlExtension.getBodies())); return true; } if (packet instanceof Presence && extension instanceof MUCUser) { @@ -392,8 +443,9 @@ public class XMPPContainer extends ClientSOContainer implements */ protected SOContext createSharedObjectContext(SOConfig soconfig, IQueueEnqueue queue) { - return new XMPPContainerContext(soconfig.getSharedObjectID(), soconfig - .getHomeContainerID(), this, soconfig.getProperties(), queue); + return new XMPPContainerContext(soconfig.getSharedObjectID(), + soconfig.getHomeContainerID(), this, soconfig.getProperties(), + queue); } /* @@ -437,8 +489,7 @@ public class XMPPContainer extends ClientSOContainer implements handleSharedObjectDisposeMessage(contMessage); } else { debug(NLS - .bind( - Messages.XMPPContainer_UNRECOGONIZED_CONTAINER_MESSAGE, + .bind(Messages.XMPPContainer_UNRECOGONIZED_CONTAINER_MESSAGE, contMessage)); } } else { |