diff options
author | slewis | 2006-12-22 00:23:13 +0000 |
---|---|---|
committer | slewis | 2006-12-22 00:23:13 +0000 |
commit | 188c69644afec81e6a18a8a4021d2a814ff3f26c (patch) | |
tree | a2c24fbf1a609b27db4ff4ec08d10d5df7108010 /providers/bundles/org.eclipse.ecf.provider.xmpp | |
parent | ff9366e22c42910fc52f470430be3bbf79ce618d (diff) | |
download | org.eclipse.ecf-188c69644afec81e6a18a8a4021d2a814ff3f26c.tar.gz org.eclipse.ecf-188c69644afec81e6a18a8a4021d2a814ff3f26c.tar.xz org.eclipse.ecf-188c69644afec81e6a18a8a4021d2a814ff3f26c.zip |
Added new (v2) implementation of xmpp/xmpps providers
Diffstat (limited to 'providers/bundles/org.eclipse.ecf.provider.xmpp')
16 files changed, 2401 insertions, 413 deletions
diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/plugin.xml b/providers/bundles/org.eclipse.ecf.provider.xmpp/plugin.xml index 116c0abab..5ac5ebcb3 100644 --- a/providers/bundles/org.eclipse.ecf.provider.xmpp/plugin.xml +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/plugin.xml @@ -54,6 +54,58 @@ </containerFactory> </extension> <extension + point="org.eclipse.ecf.containerFactory"> + <containerFactory + class="org.eclipse.ecf.provider.xmpp.XMPPContainerInstantiator" + description="XMPP (Jabber) v2" + name="ecf.xmpp.smack.v2"> + <property + value="true" + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.usepassword"/> + <property + value="<user>@<jabberserver>[:port]" + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.examplegroupid"/> + <property + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.defaultgroupid" + value=""/> + <property + value="xmpp:" + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.urlprefix"/> + <property + value="Account:" + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.groupIDLabel"/> + <property + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.namespace" + value="ecf.xmpp.smack"/> + </containerFactory> + </extension> + <extension + point="org.eclipse.ecf.containerFactory"> + <containerFactory + class="org.eclipse.ecf.provider.xmpp.XMPPSContainerInstantiator" + description="XMPP SSL (Jabber) v2" + name="ecf.xmpps.smack.v2"> + <property + value="true" + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.usepassword"/> + <property + value="<user>@<jabberserver>[:port]" + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.examplegroupid"/> + <property + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.defaultgroupid" + value=""/> + <property + value="xmpp:" + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.urlprefix"/> + <property + value="Account:" + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.groupIDLabel"/> + <property + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.namespace" + value="ecf.xmpps.smack"/> + </containerFactory> + </extension> + <extension point="org.eclipse.ecf.identity.namespace"> <namespace class="org.eclipse.ecf.provider.xmpp.identity.XMPPNamespace" diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/IProviderDirectory.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/IProviderDirectory.java deleted file mode 100644 index 9972a94c3..000000000 --- a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/IProviderDirectory.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004, 2005 Jean-Michel Lemieux, Jeff McAffer and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Hyperbola is an RCP application developed for the book - * Eclipse Rich Client Platform - - * Designing, Coding, and Packaging Java Applications - * (http://eclipsercp.org) - * Contributors: - * Jean-Michel Lemieux and Jeff McAffer - initial implementation - *******************************************************************************/ -package org.eclipse.ecf.provider.xmpp; - -import org.eclipse.core.runtime.IBundleGroup; - -public interface IProviderDirectory { - - public void installProvider(IBundleGroup provider); - - public IBundleGroup[] getProviders(); - - public IBundleGroup getProvider(String elementName, String namespace, String type); - - public IBundleGroup getProvider(String id, String version); -} diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPChatRoomContainer.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPChatRoomContainer.java new file mode 100644 index 000000000..25c21922f --- /dev/null +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPChatRoomContainer.java @@ -0,0 +1,477 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ +package org.eclipse.ecf.provider.xmpp; + +import java.io.IOException; +import java.util.HashMap; + +import org.eclipse.ecf.core.ContainerConnectException; +import org.eclipse.ecf.core.events.ContainerConnectedEvent; +import org.eclipse.ecf.core.events.ContainerConnectingEvent; +import org.eclipse.ecf.core.events.ContainerDisconnectedEvent; +import org.eclipse.ecf.core.events.ContainerDisconnectingEvent; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +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.NameCallback; +import org.eclipse.ecf.core.sharedobject.ISharedObjectContainerConfig; +import org.eclipse.ecf.core.sharedobject.SharedObjectAddException; +import org.eclipse.ecf.core.sharedobject.util.IQueueEnqueue; +import org.eclipse.ecf.core.util.ECFException; +import org.eclipse.ecf.internal.provider.xmpp.XmppPlugin; +import org.eclipse.ecf.presence.IMessageListener; +import org.eclipse.ecf.presence.chat.IChatParticipantListener; +import org.eclipse.ecf.presence.chat.IChatRoomContainer; +import org.eclipse.ecf.presence.chat.IChatRoomMessageSender; +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.events.ChatMembershipEvent; +import org.eclipse.ecf.provider.xmpp.events.IQEvent; +import org.eclipse.ecf.provider.xmpp.events.MessageEvent; +import org.eclipse.ecf.provider.xmpp.events.PresenceEvent; +import org.eclipse.ecf.provider.xmpp.identity.XMPPRoomID; +import org.eclipse.ecf.provider.xmpp.smack.ECFConnection; +import org.jivesoftware.smack.PacketListener; +import org.jivesoftware.smack.XMPPConnection; +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.muc.InvitationRejectionListener; +import org.jivesoftware.smackx.muc.MultiUserChat; +import org.jivesoftware.smackx.muc.ParticipantStatusListener; + +public class XMPPChatRoomContainer extends ClientSOContainer implements + IChatRoomContainer { + + private static final String CONTAINER_HELPER_ID = XMPPContainer.class + .getName() + + ".xmppgroupchathandler"; + + protected ID containerHelperID; + + protected XMPPChatRoomContainerHelper containerHelper; + + protected MultiUserChat multiuserchat; + + protected Namespace usernamespace = null; + + public XMPPChatRoomContainer(ISharedObjectContainerConfig config, + ECFConnection conn, Namespace usernamespace) + throws IDCreateException { + super(config); + this.connection = conn; + this.config = config; + this.usernamespace = usernamespace; + this.containerHelperID = IDFactory.getDefault().createStringID( + CONTAINER_HELPER_ID); + this.containerHelper = new XMPPChatRoomContainerHelper(usernamespace, + getXMPPConnection()); + } + + public XMPPChatRoomContainer(ECFConnection conn, Namespace usernamespace) + throws IDCreateException { + this(new SOContainerConfig(IDFactory.getDefault().createGUID()), conn, + usernamespace); + } + + public void dispose() { + disconnect(); + if (containerHelperID != null) { + getSharedObjectManager().removeSharedObject(containerHelperID); + containerHelperID = null; + } + if (containerHelper != null) + containerHelper.dispose(getID()); + containerHelper = null; + super.dispose(); + } + + protected void sendMessage(ContainerMessage data) throws IOException { + synchronized (getConnectLock()) { + ID toID = data.getToContainerID(); + if (toID == null) { + data.setToContainerID(remoteServerID); + } + super.sendMessage(data); + } + } + + protected void handleChatMessage(Message mess) throws IOException { + SOWrapper wrap = getSharedObjectWrapper(containerHelperID); + if (wrap != null) { + wrap.deliverEvent(new MessageEvent(mess)); + } + } + + protected boolean verifyToIDForSharedObjectMessage(ID toID) { + return true; + } + + protected void handleContainerMessage(ContainerMessage mess) + throws IOException { + if (mess == null) { + debug("got null container message...ignoring"); + return; + } + Object data = mess.getData(); + if (data instanceof ContainerMessage.CreateMessage) { + handleCreateMessage(mess); + } else if (data instanceof ContainerMessage.CreateResponseMessage) { + handleCreateResponseMessage(mess); + } else if (data instanceof ContainerMessage.SharedObjectMessage) { + handleSharedObjectMessage(mess); + } else if (data instanceof ContainerMessage.SharedObjectDisposeMessage) { + handleSharedObjectDisposeMessage(mess); + } else { + debug("got unrecognized container message...ignoring: " + mess); + } + } + + protected void handleIQMessage(IQ mess) throws IOException { + SOWrapper wrap = getSharedObjectWrapper(containerHelperID); + if (wrap != null) { + wrap.deliverEvent(new IQEvent(mess)); + } + } + + protected void handlePresenceMessage(Presence mess) throws IOException { + SOWrapper wrap = getSharedObjectWrapper(containerHelperID); + if (wrap != null) { + wrap.deliverEvent(new PresenceEvent(mess)); + } + } + + protected void handleChatMembershipEvent(String from, boolean add) { + SOWrapper wrap = getSharedObjectWrapper(containerHelperID); + if (wrap != null) { + wrap.deliverEvent(new ChatMembershipEvent(from, add)); + } + } + + protected void handleXMPPMessage(Packet aPacket) { + try { + if (aPacket instanceof IQ) { + handleIQMessage((IQ) aPacket); + } else if (aPacket instanceof Message) { + handleChatMessage((Message) aPacket); + } else if (aPacket instanceof Presence) { + handlePresenceMessage((Presence) aPacket); + } else { + // unexpected message + debug("got unexpected packet " + aPacket); + } + } catch (IOException e) { + logException("Exception in handleXMPPMessage", e); + } + } + + protected XMPPConnection getXMPPConnection() { + return ((ECFConnection) getConnection()).getXMPPConnection(); + } + + protected void addSharedObjectToContainer(ID remote) + throws SharedObjectAddException { + getSharedObjectManager().addSharedObject(containerHelperID, + containerHelper, new HashMap()); + } + + protected void cleanUpConnectFail() { + if (containerHelper != null) { + getSharedObjectManager().removeSharedObject(containerHelperID); + containerHelper = null; + containerHelperID = null; + } + connectionState = DISCONNECTED; + remoteServerID = null; + } + + public Namespace getConnectNamespace() { + return IDFactory.getDefault().getNamespaceByName( + XmppPlugin.getDefault().getRoomNamespaceIdentifier()); + } + + public void connect(ID remote, IConnectContext connectContext) + throws ContainerConnectException { + if (!(remote instanceof XMPPRoomID)) { + throw new ContainerConnectException("remote " + remote + + " is not of room id type"); + } + XMPPRoomID roomID = (XMPPRoomID) remote; + fireContainerEvent(new ContainerConnectingEvent(this.getID(), remote, + connectContext)); + synchronized (getConnectLock()) { + try { + connectionState = CONNECTING; + remoteServerID = null; + addSharedObjectToContainer(remote); + multiuserchat = new MultiUserChat(getXMPPConnection(), roomID + .getMucString()); + // Get nickname from join context + String nick = null; + try { + Callback[] callbacks = new Callback[1]; + callbacks[0] = new NameCallback("Nickname", roomID + .getNickname()); + if (connectContext != null) { + CallbackHandler handler = connectContext + .getCallbackHandler(); + if (handler != null) { + handler.handle(callbacks); + } + } + if (callbacks[0] instanceof NameCallback) { + NameCallback cb = (NameCallback) callbacks[0]; + nick = cb.getName(); + } + } catch (Exception e) { + throw new ContainerConnectException( + "Exception in CallbackHandler.handle(<callbacks>)", + e); + } + String nickname = null; + if (nick == null || nick.equals("")) + nickname = roomID.getNickname(); + else + nickname = nick; + multiuserchat.addMessageListener(new PacketListener() { + public void processPacket(Packet arg0) { + handleXMPPMessage(arg0); + } + }); + multiuserchat.addParticipantListener(new PacketListener() { + public void processPacket(Packet arg0) { + handleXMPPMessage(arg0); + } + }); + multiuserchat + .addParticipantStatusListener(new ParticipantStatusListener() { + public void joined(String arg0) { + handleChatMembershipEvent(arg0, true); + } + + public void left(String arg0) { + handleChatMembershipEvent(arg0, false); + } + + public void voiceGranted(String arg0) { + // TODO Auto-generated method stub + System.out + .println("voiceGranted(" + arg0 + ")"); + } + + public void voiceRevoked(String arg0) { + // TODO Auto-generated method stub + System.out + .println("voiceRevoked(" + arg0 + ")"); + } + + public void membershipGranted(String arg0) { + // TODO Auto-generated method stub + System.out.println("membershipGranted(" + arg0 + + ")"); + } + + public void membershipRevoked(String arg0) { + // TODO Auto-generated method stub + System.out.println("membershipRevoked(" + arg0 + + ")"); + } + + public void moderatorGranted(String arg0) { + // TODO Auto-generated method stub + System.out.println("moderatorGranted(" + arg0 + + ")"); + } + + public void moderatorRevoked(String arg0) { + // TODO Auto-generated method stub + System.out.println("moderatorRevoked(" + arg0 + + ")"); + } + + public void ownershipGranted(String arg0) { + // TODO Auto-generated method stub + System.out.println("ownershipGranted(" + arg0 + + ")"); + } + + public void ownershipRevoked(String arg0) { + // TODO Auto-generated method stub + System.out.println("ownershipRevoked(" + arg0 + + ")"); + } + + public void adminGranted(String arg0) { + // TODO Auto-generated method stub + System.out + .println("adminGranted(" + arg0 + ")"); + } + + public void adminRevoked(String arg0) { + // TODO Auto-generated method stub + System.out + .println("adminRevoked(" + arg0 + ")"); + } + + public void kicked(String arg0, String arg1, + String arg2) { + // TODO Auto-generated method stub + System.out.println("kicked(" + arg0 + "," + + arg1 + "," + arg2 + ")"); + + } + + public void banned(String arg0, String arg1, + String arg2) { + // TODO Auto-generated method stub + System.out.println("kicked(" + arg0 + "," + + arg1 + "," + arg2 + ")"); + + } + + public void nicknameChanged(String arg0, String arg1) { + // TODO Auto-generated method stub + System.out.println("kicked(" + arg0 + "," + + arg1 + ")"); + + } + }); + multiuserchat + .addInvitationRejectionListener(new InvitationRejectionListener() { + public void invitationDeclined(String arg0, + String arg1) { + // TODO Auto-generated method stub + System.out.println("invitationDeclined(" + arg0 + + "," + arg1 + ")"); + } + }); + multiuserchat.join(nickname); + connectionState = CONNECTED; + remoteServerID = roomID; + fireContainerEvent(new ContainerConnectedEvent(this.getID(), + roomID)); + } catch (Exception e) { + cleanUpConnectFail(); + ContainerConnectException ce = new ContainerConnectException( + "Exception joining " + roomID); + ce.setStackTrace(e.getStackTrace()); + throw ce; + } + } + } + + public void disconnect() { + ID groupID = getConnectedID(); + fireContainerEvent(new ContainerDisconnectingEvent(this.getID(), + groupID)); + synchronized (getConnectLock()) { + // If we are currently connected + if (isConnected()) { + try { + multiuserchat.leave(); + } catch (Exception e) { + traceStack("Exception in multi user chat.leave", e); + } + } + connectionState = DISCONNECTED; + remoteServerID = null; + this.connection = null; + } + // notify listeners + fireContainerEvent(new ContainerDisconnectedEvent(this.getID(), groupID)); + } + + protected SOContext createSharedObjectContext(SOConfig soconfig, + IQueueEnqueue queue) { + return new XMPPContainerContext(soconfig.getSharedObjectID(), soconfig + .getHomeContainerID(), this, soconfig.getProperties(), queue); + } + + protected ID createChatRoomID(String groupName) throws IDCreateException { + String username = getXMPPConnection().getUser(); + int atIndex = username.indexOf('@'); + if (atIndex > 0) + username = username.substring(0, atIndex); + String host = getXMPPConnection().getHost(); + Namespace ns = getConnectNamespace(); + ID targetID = IDFactory.getDefault().createID(ns, + new Object[] { username, host, null, groupName, username }); + return targetID; + } + + protected ISynchAsynchConnection createConnection(ID remoteSpace, + Object data) throws ConnectionCreateException { + return null; + } + + public void addMessageListener(IMessageListener listener) { + if (containerHelper != null) { + containerHelper.addMessageListener(listener); + } + } + + public void removeMessageListener(IMessageListener msgListener) { + if (containerHelper != null) { + containerHelper.removeMessageListener(msgListener); + } + } + + public IChatRoomMessageSender getChatMessageSender() { + return new IChatRoomMessageSender() { + public void sendMessage(String messageBody) throws ECFException { + if (multiuserchat != null) { + try { + multiuserchat.sendMessage(messageBody); + } catch (Exception e) { + ECFException except = new ECFException( + "Send message exception", e); + throw except; + } + } + } + }; + } + + public void connect(String groupName) throws ContainerConnectException { + ID targetID = null; + try { + targetID = createChatRoomID(groupName); + } catch (IDCreateException e) { + throw new ContainerConnectException( + "Exception creating chat room id", e); + } + this.connect(targetID, null); + } + + public void addChatParticipantListener( + IChatParticipantListener participantListener) { + if (containerHelper != null) { + containerHelper.addChatParticipantListener(participantListener); + } + } + + public void removeChatParticipantListener( + IChatParticipantListener participantListener) { + if (containerHelper != null) { + containerHelper.removeChatParticipantListener(participantListener); + } + } + +}
\ No newline at end of file diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPChatRoomContainerHelper.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPChatRoomContainerHelper.java new file mode 100644 index 000000000..0b22a28d2 --- /dev/null +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPChatRoomContainerHelper.java @@ -0,0 +1,313 @@ +/**************************************************************************** + * Copyright (c) 2004 Composent, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Composent, Inc. - initial API and implementation + *****************************************************************************/ +package org.eclipse.ecf.provider.xmpp; + +import java.net.URISyntaxException; +import java.util.Iterator; +import java.util.Vector; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.core.sharedobject.ISharedObject; +import org.eclipse.ecf.core.sharedobject.ISharedObjectConfig; +import org.eclipse.ecf.core.sharedobject.ISharedObjectContext; +import org.eclipse.ecf.core.sharedobject.SharedObjectInitException; +import org.eclipse.ecf.core.util.Event; +import org.eclipse.ecf.presence.IMessageListener; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.chat.IChatParticipantListener; +import org.eclipse.ecf.provider.xmpp.events.ChatMembershipEvent; +import org.eclipse.ecf.provider.xmpp.events.MessageEvent; +import org.eclipse.ecf.provider.xmpp.events.PresenceEvent; +import org.eclipse.ecf.provider.xmpp.identity.XMPPID; +import org.eclipse.ecf.provider.xmpp.identity.XMPPRoomID; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.Presence; +import org.jivesoftware.smack.packet.Presence.Mode; +import org.jivesoftware.smack.packet.Presence.Type; + +public class XMPPChatRoomContainerHelper implements ISharedObject { + + ISharedObjectConfig config = null; + + Vector messageListeners = new Vector(); + Namespace usernamespace = null; + XMPPConnection connection = null; + Vector participantListeners = new Vector(); + + protected void trace(String message) { + + } + + protected void addChatParticipantListener(IChatParticipantListener listener) { + participantListeners.add(listener); + } + + protected void removeChatParticipantListener( + IChatParticipantListener listener) { + participantListeners.remove(listener); + } + + protected void addMessageListener(IMessageListener listener) { + messageListeners.add(listener); + } + + protected void removeMessageListener(IMessageListener listener) { + messageListeners.add(listener); + } + + public XMPPChatRoomContainerHelper(Namespace usernamespace, + XMPPConnection conn) { + super(); + this.usernamespace = usernamespace; + this.connection = conn; + } + + protected ISharedObjectContext getContext() { + return config.getContext(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#init(org.eclipse.ecf.core.ISharedObjectConfig) + */ + public void init(ISharedObjectConfig initData) + throws SharedObjectInitException { + this.config = initData; + } + + protected ID createUserIDFromName(String name) { + ID result = null; + try { + result = new XMPPID(usernamespace, name); + return result; + } catch (Exception e) { + return null; + } + } + + protected Message.Type[] ALLOWED_MESSAGES = { Message.Type.GROUP_CHAT }; + + protected Message filterMessageType(Message msg) { + for (int i = 0; i < ALLOWED_MESSAGES.length; i++) { + if (ALLOWED_MESSAGES[i].equals(msg.getType())) { + return msg; + } + } + return null; + } + + protected String canonicalizeRoomFrom(String from) { + if (from == null) + return null; + int atIndex = from.indexOf('@'); + String hostname = null; + String username = null; + int index = from.indexOf("/"); + if (atIndex > 0 && index > 0) { + hostname = from.substring(atIndex + 1, index); + username = from.substring(index + 1); + return username + "@" + hostname; + } + return from; + } + + protected IMessageListener.Type createMessageType(Message.Type type) { + if (type == null) + return IMessageListener.Type.NORMAL; + if (type == Message.Type.CHAT) { + return IMessageListener.Type.CHAT; + } else if (type == Message.Type.NORMAL) { + return IMessageListener.Type.NORMAL; + } else if (type == Message.Type.GROUP_CHAT) { + return IMessageListener.Type.GROUP_CHAT; + } else if (type == Message.Type.HEADLINE) { + return IMessageListener.Type.SYSTEM; + } else if (type == Message.Type.HEADLINE) { + return IMessageListener.Type.SYSTEM; + } else + return IMessageListener.Type.NORMAL; + } + + protected void fireMessage(ID from, ID to, IMessageListener.Type type, + String subject, String body) { + for (Iterator i = messageListeners.iterator(); i.hasNext();) { + IMessageListener l = (IMessageListener) i.next(); + l.handleMessage(from, to, type, subject, body); + } + } + + protected String canonicalizeRoomTo(String to) { + if (to == null) + return null; + int index = to.indexOf("/"); + if (index > 0) { + return to.substring(0, index); + } else + return to; + } + + protected ID createRoomIDFromName(String from) { + try { + return new XMPPRoomID(usernamespace, connection, from); + } catch (URISyntaxException e) { + return null; + } + } + + protected void handleMessageEvent(MessageEvent evt) { + Message msg = evt.getMessage(); + String from = msg.getFrom(); + String to = msg.getTo(); + String body = msg.getBody(); + String subject = msg.getSubject(); + ID fromID = createUserIDFromName(canonicalizeRoomFrom(from)); + ID toID = createUserIDFromName(canonicalizeRoomTo(to)); + msg = filterMessageType(msg); + if (msg != null) + fireMessage(fromID, toID, createMessageType(msg.getType()), + subject, body); + } + + protected IPresence.Type createIPresenceType(Presence xmppPresence) { + if (xmppPresence == null) + return IPresence.Type.AVAILABLE; + Type type = xmppPresence.getType(); + if (type == Presence.Type.AVAILABLE) { + return IPresence.Type.AVAILABLE; + } else if (type == Presence.Type.ERROR) { + return IPresence.Type.ERROR; + } else if (type == Presence.Type.SUBSCRIBE) { + return IPresence.Type.SUBSCRIBE; + } else if (type == Presence.Type.SUBSCRIBED) { + return IPresence.Type.SUBSCRIBED; + } else if (type == Presence.Type.UNSUBSCRIBE) { + return IPresence.Type.UNSUBSCRIBE; + } else if (type == Presence.Type.UNSUBSCRIBED) { + return IPresence.Type.UNSUBSCRIBED; + } else if (type == Presence.Type.UNAVAILABLE) { + return IPresence.Type.UNAVAILABLE; + } + return IPresence.Type.AVAILABLE; + } + + protected IPresence.Mode createIPresenceMode(Presence xmppPresence) { + if (xmppPresence == null) + return IPresence.Mode.AVAILABLE; + Mode mode = xmppPresence.getMode(); + if (mode == Presence.Mode.AVAILABLE) { + return IPresence.Mode.AVAILABLE; + } else if (mode == Presence.Mode.AWAY) { + return IPresence.Mode.AWAY; + } else if (mode == Presence.Mode.CHAT) { + return IPresence.Mode.CHAT; + } else if (mode == Presence.Mode.DO_NOT_DISTURB) { + return IPresence.Mode.DND; + } else if (mode == Presence.Mode.EXTENDED_AWAY) { + return IPresence.Mode.EXTENDED_AWAY; + } else if (mode == Presence.Mode.INVISIBLE) { + return IPresence.Mode.INVISIBLE; + } + return IPresence.Mode.AVAILABLE; + } + + protected IPresence createIPresence(Presence xmppPresence) { + String status = xmppPresence.getStatus(); + IPresence newPresence = new org.eclipse.ecf.presence.Presence( + createIPresenceType(xmppPresence), status, + createIPresenceMode(xmppPresence)); + return newPresence; + } + + protected void handlePresenceEvent(PresenceEvent evt) { + Presence xmppPresence = evt.getPresence(); + String from = canonicalizeRoomFrom(xmppPresence.getFrom()); + IPresence newPresence = createIPresence(xmppPresence); + ID fromID = createUserIDFromName(from); + fireParticipant(fromID, newPresence); + } + + protected void handleChatMembershipEvent(ChatMembershipEvent evt) { + String from = canonicalizeRoomFrom(evt.getFrom()); + ID fromID = createUserIDFromName(from); + fireChatParticipant(fromID, evt.isAdd()); + } + + protected void fireParticipant(ID fromID, IPresence presence) { + for (Iterator i = participantListeners.iterator(); i.hasNext();) { + IChatParticipantListener l = (IChatParticipantListener) i.next(); + l.handlePresence(fromID, presence); + } + } + + protected void fireChatParticipant(ID fromID, boolean join) { + for (Iterator i = participantListeners.iterator(); i.hasNext();) { + IChatParticipantListener l = (IChatParticipantListener) i.next(); + if (join) { + l.handleArrivedInChat(fromID); + } else { + l.handleDepartedFromChat(fromID); + } + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#handleEvent(org.eclipse.ecf.core.util.Event) + */ + public void handleEvent(Event event) { + trace("handleEvent(" + event + ")"); + if (event instanceof MessageEvent) { + handleMessageEvent((MessageEvent) event); + } else if (event instanceof PresenceEvent) { + handlePresenceEvent((PresenceEvent) event); + } else if (event instanceof ChatMembershipEvent) { + handleChatMembershipEvent((ChatMembershipEvent) event); + } else + trace("unrecognized event " + event); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#handleEvents(org.eclipse.ecf.core.util.Event[]) + */ + public void handleEvents(Event[] events) { + for (int i = 0; i < events.length; i++) { + this.handleEvent(events[i]); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#dispose(org.eclipse.ecf.core.identity.ID) + */ + public void dispose(ID containerID) { + messageListeners.clear(); + participantListeners.clear(); + this.config = null; + this.connection = null; + this.usernamespace = null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class clazz) { + return null; + } +} diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPChatRoomManager.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPChatRoomManager.java new file mode 100644 index 000000000..6652941b3 --- /dev/null +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPChatRoomManager.java @@ -0,0 +1,346 @@ +/**************************************************************************** + * Copyright (c) 2004 Composent, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Composent, Inc. - initial API and implementation + *****************************************************************************/ + +package org.eclipse.ecf.provider.xmpp; + +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Vector; + +import org.eclipse.ecf.core.ContainerCreateException; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.presence.chat.IChatRoomContainer; +import org.eclipse.ecf.presence.chat.IChatRoomManager; +import org.eclipse.ecf.presence.chat.IChatRoomInvitationListener; +import org.eclipse.ecf.presence.chat.IChatRoomInfo; +import org.eclipse.ecf.provider.xmpp.identity.XMPPID; +import org.eclipse.ecf.provider.xmpp.identity.XMPPRoomID; +import org.eclipse.ecf.provider.xmpp.smack.ECFConnection; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smackx.muc.HostedRoom; +import org.jivesoftware.smackx.muc.InvitationListener; +import org.jivesoftware.smackx.muc.MultiUserChat; +import org.jivesoftware.smackx.muc.RoomInfo; + +public class XMPPChatRoomManager implements IChatRoomManager { + + ID containerID = null; + + Namespace connectNamespace = null; + + Vector invitationListeners = new Vector(); + + ECFConnection ecfConnection = null; + + Vector chatrooms = new Vector(); + + ID connectedID = null; + + public XMPPChatRoomManager(ID containerID) { + this.containerID = containerID; + } + + protected void addChat(IChatRoomContainer container) { + chatrooms.add(container); + } + + protected void removeChat(IChatRoomContainer container) { + chatrooms.remove(container); + } + + protected ID createRoomIDFromName(String from) { + try { + return new XMPPRoomID(connectNamespace, ecfConnection + .getXMPPConnection(), from); + } catch (URISyntaxException e) { + return null; + } + } + + protected ID createUserIDFromName(String name) { + ID result = null; + try { + result = new XMPPID(connectNamespace, name); + return result; + } catch (Exception e) { + return null; + } + } + + protected void setConnection(Namespace connectNamespace, ID connectedID, + ECFConnection connection) { + this.connectNamespace = connectNamespace; + this.connectedID = connectedID; + this.ecfConnection = connection; + if (connection != null) { + // Setup invitation listener + MultiUserChat.addInvitationListener(ecfConnection + .getXMPPConnection(), new InvitationListener() { + public void invitationReceived(XMPPConnection arg0, + String arg1, String arg2, String arg3, String arg4, + Message arg5) { + fireInvitationReceived(createRoomIDFromName(arg1), + createUserIDFromName(arg2), + createUserIDFromName(arg5.getTo()), arg5 + .getSubject(), arg3); + } + }); + } + } + + protected void disposeChatRooms() { + for (Iterator i = chatrooms.iterator(); i.hasNext();) { + IChatRoomContainer cc = (IChatRoomContainer) i.next(); + cc.dispose(); + } + chatrooms.clear(); + } + + public void dispose() { + invitationListeners.clear(); + containerID = null; + connectNamespace = null; + disposeChatRooms(); + setConnection(null, null, null); + } + + class ECFRoomInfo implements IChatRoomInfo { + + RoomInfo info; + + XMPPRoomID roomID; + + ID connectedID; + + public ECFRoomInfo(XMPPRoomID roomID, RoomInfo info, ID connectedID) { + this.roomID = roomID; + this.info = info; + this.connectedID = connectedID; + } + + public String getDescription() { + return info.getDescription(); + } + + public String getSubject() { + return info.getSubject(); + } + + public ID getRoomID() { + return roomID; + } + + public int getParticipantsCount() { + return info.getOccupantsCount(); + } + + public String getName() { + return roomID.getLongName(); + } + + public boolean isPersistent() { + return info.isPersistent(); + } + + public boolean requiresPassword() { + return info.isPasswordProtected(); + } + + public boolean isModerated() { + return info.isModerated(); + } + + public ID getConnectedID() { + return roomID; + } + + public Object getAdapter(Class clazz) { + return null; + } + + public IChatRoomContainer createChatRoomContainer() + throws ContainerCreateException { + IChatRoomContainer chatContainer = null; + if (ecfConnection == null) + throw new ContainerCreateException("disconnected"); + try { + chatContainer = new XMPPChatRoomContainer(ecfConnection, + connectNamespace); + addChat(chatContainer); + return chatContainer; + } catch (IDCreateException e) { + throw new ContainerCreateException( + "Exception creating chat container", e); + } + } + + public String toString() { + StringBuffer buf = new StringBuffer("ECFRoomInfo["); + buf.append("id=").append(containerID).append(";name=" + getName()); + buf.append(";service=" + getConnectedID()); + buf.append(";count=" + getParticipantsCount()); + buf.append(";subject=" + getSubject()).append( + ";desc=" + getDescription()); + buf.append(";pers=" + isPersistent()).append( + ";pw=" + requiresPassword()); + buf.append(";mod=" + isModerated()).append("]"); + return buf.toString(); + } + } + + public IChatRoomManager[] getChildren() { + return new IChatRoomManager[0]; + } + + protected ID createIDFromHostedRoom(HostedRoom room) { + try { + return new XMPPRoomID(connectNamespace, ecfConnection + .getXMPPConnection(), room.getJid(), room.getName()); + } catch (URISyntaxException e) { + // debug output + return null; + } + } + + protected IChatRoomContainer findReceiverChatRoom(ID toID) { + if (toID == null) + return null; + XMPPRoomID roomID = null; + if (toID instanceof XMPPRoomID) { + roomID = (XMPPRoomID) toID; + String mucname = roomID.getMucString(); + for (Iterator i = chatrooms.iterator(); i.hasNext();) { + IChatRoomContainer cont = (IChatRoomContainer) i.next(); + if (cont == null) + continue; + ID tid = cont.getConnectedID(); + if (tid != null && tid instanceof XMPPRoomID) { + XMPPRoomID targetID = (XMPPRoomID) tid; + String tmuc = targetID.getMucString(); + if (tmuc.equals(mucname)) { + return cont; + } + } + } + } + return null; + } + + protected ID[] getChatRooms() { + if (ecfConnection == null) + return null; + XMPPConnection conn = ecfConnection.getXMPPConnection(); + if (conn == null) + return null; + Collection result = new ArrayList(); + try { + Collection svcs = MultiUserChat.getServiceNames(conn); + for (Iterator svcsi = svcs.iterator(); svcsi.hasNext();) { + String svc = (String) svcsi.next(); + Collection rooms = MultiUserChat.getHostedRooms(conn, svc); + for (Iterator roomsi = rooms.iterator(); roomsi.hasNext();) { + HostedRoom room = (HostedRoom) roomsi.next(); + ID roomID = createIDFromHostedRoom(room); + if (roomID != null) + result.add(roomID); + } + } + } catch (XMPPException e) { + return null; + } + return (ID[]) result.toArray(new ID[] {}); + } + + protected IChatRoomInfo getChatRoomInfo(ID roomID) { + if (!(roomID instanceof XMPPRoomID)) + return null; + XMPPRoomID cRoomID = (XMPPRoomID) roomID; + try { + RoomInfo info = MultiUserChat.getRoomInfo(ecfConnection + .getXMPPConnection(), cRoomID.getMucString()); + if (info != null) { + return new ECFRoomInfo(cRoomID, info, connectedID); + } + } catch (XMPPException e) { + return null; + } + return null; + } + + public IChatRoomInfo getChatRoomInfo(String roomname) { + try { + if (ecfConnection == null) + return null; + // Create roomid + XMPPConnection conn = ecfConnection.getXMPPConnection(); + XMPPRoomID roomID = new XMPPRoomID(connectNamespace, conn, roomname); + String mucName = roomID.getMucString(); + RoomInfo info = MultiUserChat.getRoomInfo(conn, mucName); + if (info != null) { + return new ECFRoomInfo(roomID, info, connectedID); + } + } catch (Exception e) { + return null; + } + return null; + } + + public IChatRoomInfo[] getChatRoomsInfo() { + ID[] chatRooms = getChatRooms(); + if (chatRooms == null) + return null; + IChatRoomInfo[] res = new IChatRoomInfo[chatRooms.length]; + int count = 0; + for (int i = 0; i < chatRooms.length; i++) { + IChatRoomInfo infoResult = getChatRoomInfo(chatRooms[i]); + if (infoResult != null) { + res[count++] = infoResult; + } + } + IChatRoomInfo[] results = new IChatRoomInfo[count]; + for (int i = 0; i < count; i++) { + results[i] = res[i]; + } + return results; + } + + public Object getAdapter(Class adapter) { + return null; + } + + public void addInvitationListener(IChatRoomInvitationListener listener) { + invitationListeners.add(listener); + } + + public void removeInvitationListener(IChatRoomInvitationListener listener) { + invitationListeners.remove(listener); + } + + protected void fireInvitationReceived(ID roomID, ID fromID, ID toID, + String subject, String body) { + for (Iterator i = invitationListeners.iterator(); i.hasNext();) { + IChatRoomInvitationListener l = (IChatRoomInvitationListener) i + .next(); + l.handleInvitationReceived(roomID, fromID, subject, body); + } + } + + public IChatRoomManager getParent() { + return 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 new file mode 100644 index 000000000..b569bdfe8 --- /dev/null +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainer.java @@ -0,0 +1,492 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ +package org.eclipse.ecf.provider.xmpp; + +import java.io.IOException; +import java.net.ConnectException; +import java.util.HashMap; +import java.util.Iterator; + +import org.eclipse.ecf.core.ContainerConnectException; +import org.eclipse.ecf.core.events.ContainerConnectedEvent; +import org.eclipse.ecf.core.events.ContainerDisconnectedEvent; +import org.eclipse.ecf.core.events.ContainerDisconnectingEvent; +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.IOutgoingFileTransferContainerAdapter; +import org.eclipse.ecf.internal.provider.xmpp.XmppPlugin; +import org.eclipse.ecf.presence.IAccountManager; +import org.eclipse.ecf.presence.IMessageListener; +import org.eclipse.ecf.presence.IMessageSender; +import org.eclipse.ecf.presence.IPresenceContainerAdapter; +import org.eclipse.ecf.presence.IPresenceListener; +import org.eclipse.ecf.presence.IPresenceSender; +import org.eclipse.ecf.presence.IRosterSubscriptionListener; +import org.eclipse.ecf.presence.chat.IChatRoomContainer; +import org.eclipse.ecf.presence.chat.IChatRoomManager; +import org.eclipse.ecf.presence.roster.IRosterManager; +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.events.IQEvent; +import org.eclipse.ecf.provider.xmpp.events.MessageEvent; +import org.eclipse.ecf.provider.xmpp.events.PresenceEvent; +import org.eclipse.ecf.provider.xmpp.identity.XMPPID; +import org.eclipse.ecf.provider.xmpp.smack.ECFConnection; +import org.eclipse.ecf.provider.xmpp.smack.ECFConnectionObjectPacketEvent; +import org.eclipse.ecf.provider.xmpp.smack.ECFConnectionPacketEvent; +import org.jivesoftware.smack.Roster; +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; + +public class XMPPContainer extends ClientSOContainer { + + public static final int DEFAULT_KEEPALIVE = 30000; + + public static final String CONNECT_NAMESPACE = XmppPlugin.getDefault() + .getNamespaceIdentifier(); + + public static final String CONTAINER_HELPER_ID = XMPPContainer.class + .getName() + + ".xmpphandler"; + + protected static final String GOOGLE_SERVICENAME = "gmail.com"; + + protected int keepAlive = 0; + + protected XMPPContainerAccountManager accountManager = null; + + protected XMPPChatRoomManager chatRoomManager = null; + + protected XMPPOutgoingFileTransferContainerAdapter outgoingFileTransferContainerAdapter = null; + + protected XMPPContainerPresenceHelper presenceHelper = null; + + protected ID presenceHelperID = null; + + protected XMPPContainer(SOContainerConfig config, int keepAlive) + throws Exception { + super(config); + this.keepAlive = keepAlive; + accountManager = new XMPPContainerAccountManager(); + chatRoomManager = new XMPPChatRoomManager(getID()); + this.presenceHelperID = IDFactory.getDefault().createStringID( + CONTAINER_HELPER_ID); + presenceHelper = new XMPPContainerPresenceHelper(this); + outgoingFileTransferContainerAdapter = new XMPPOutgoingFileTransferContainerAdapter( + this); + } + + public XMPPContainer() throws Exception { + this(DEFAULT_KEEPALIVE); + } + + public XMPPContainer(int ka) throws Exception { + this(new SOContainerConfig(IDFactory.getDefault().createGUID()), ka); + } + + public XMPPContainer(String userhost, int ka) throws Exception { + this(new SOContainerConfig(IDFactory.getDefault().createStringID( + userhost)), ka); + } + + protected IRosterManager getRosterManager() { + return presenceHelper.getRosterManager(); + } + + IPresenceContainerAdapter presenceContainerAdapter = new IPresenceContainerAdapter() { + + public IPresenceSender getPresenceSender() { + return presenceHelper.getRosterManager().getPresenceSender(); + } + + public IRosterManager getRosterManager() { + return presenceHelper.getRosterManager(); + } + + public void addMessageListener(IMessageListener listener) { + presenceHelper.addMessageListener(listener); + } + + public void removeMessageListener(IMessageListener listener) { + presenceHelper.removeMessageListener(listener); + } + + public IMessageSender getMessageSender() { + return presenceHelper.getMessageSender(); + } + + public IAccountManager getAccountManager() { + return accountManager; + } + + public IChatRoomManager getChatRoomManager() { + return chatRoomManager; + } + + public void addPresenceListener(IPresenceListener listener) { + } + + public void addRosterSubscriptionListener( + IRosterSubscriptionListener listener) { + } + + public void removePresenceListener(IPresenceListener listener) { + } + + public void removeRosterSubscriptionListener( + IRosterSubscriptionListener listener) { + } + + public Object getAdapter(Class clazz) { + // XXX this is being used to distinguish between this, more modern + // version of + // IPresenceContainerAdapter implementation and the older one. + // This should be removed + if (clazz.equals(IPresenceContainerAdapter.class)) + return this; + else + return null; + } + + }; + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.provider.generic.SOContainer#getConnectNamespace() + */ + public Namespace getConnectNamespace() { + return IDFactory.getDefault().getNamespaceByName( + XmppPlugin.getDefault().getNamespaceIdentifier()); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.provider.generic.ClientSOContainer#connect(org.eclipse.ecf.core.identity.ID, + * org.eclipse.ecf.core.security.IConnectContext) + */ + public void connect(ID remote, IConnectContext joinContext) + throws ContainerConnectException { + try { + getSharedObjectManager().addSharedObject(presenceHelperID, + presenceHelper, new HashMap()); + super.connect(remote, joinContext); + } catch (ContainerConnectException e) { + disconnect(); + throw e; + } catch (SharedObjectAddException e1) { + disconnect(); + throw new ContainerConnectException( + "Exception adding shared object " + presenceHelperID, e1); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.provider.generic.ClientSOContainer#disconnect() + */ + public void disconnect() { + ID groupID = getConnectedID(); + fireContainerEvent(new ContainerDisconnectingEvent(this.getID(), + groupID)); + synchronized (getConnectLock()) { + // If we are currently connected + if (isConnected()) { + ISynchAsynchConnection conn = getConnection(); + synchronized (conn) { + synchronized (getGroupMembershipLock()) { + memberLeave(groupID, null); + } + try { + conn.disconnect(); + } catch (IOException e) { + dumpStack("Exception disconnecting", e); + } + } + } + connectionState = DISCONNECTED; + this.connection = null; + remoteServerID = null; + accountManager.setConnection(null); + chatRoomManager.setConnection(null, null, null); + } + // notify listeners + fireContainerEvent(new ContainerDisconnectedEvent(this.getID(), groupID)); + dispose(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.provider.generic.ClientSOContainer#dispose() + */ + public void dispose() { + if (presenceHelper != null) + getSharedObjectManager().removeSharedObject(presenceHelperID); + presenceHelperID = null; + presenceHelper = null; + if (chatRoomManager != null) + chatRoomManager.dispose(); + chatRoomManager = null; + if (accountManager != null) + accountManager.dispose(); + accountManager = null; + if (outgoingFileTransferContainerAdapter != null) + outgoingFileTransferContainerAdapter.dispose(); + outgoingFileTransferContainerAdapter = null; + super.dispose(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.provider.generic.SOContainer#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class clazz) { + if (clazz.equals(IPresenceContainerAdapter.class)) + return presenceContainerAdapter; + if (clazz.equals(IOutgoingFileTransferContainerAdapter.class)) + return outgoingFileTransferContainerAdapter; + else + return super.getAdapter(clazz); + } + + protected ID handleConnectResponse(ID originalTarget, Object serverData) + throws Exception { + if (originalTarget != null && !originalTarget.equals(getID())) { + addNewRemoteMember(originalTarget, null); + + ECFConnection conn = getECFConnection(); + accountManager.setConnection(conn.getXMPPConnection()); + chatRoomManager.setConnection(getConnectNamespace(), + originalTarget, conn); + presenceHelper.setUser(new User(originalTarget)); + + // notify listeners + fireContainerEvent(new ContainerConnectedEvent(this.getID(), + originalTarget)); + return originalTarget; + + } else + throw new ConnectException("invalid response from server"); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.provider.generic.ClientSOContainer#createConnection(org.eclipse.ecf.core.identity.ID, + * java.lang.Object) + */ + protected ISynchAsynchConnection createConnection(ID remoteSpace, + Object data) throws ConnectionCreateException { + ISynchAsynchConnection conn = null; + boolean google = false; + if (remoteSpace instanceof XMPPID) { + XMPPID theID = (XMPPID) remoteSpace; + String host = theID.getHostname(); + if (host.toLowerCase().equals(GOOGLE_SERVICENAME)) { + google = true; + } + } + return new ECFConnection(google, getConnectNamespace(), receiver); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.provider.generic.ClientSOContainer#getConnectData(org.eclipse.ecf.core.identity.ID, + * org.eclipse.ecf.core.security.IConnectContext) + */ + protected Object getConnectData(ID remote, IConnectContext joinContext) + throws IOException, UnsupportedCallbackException { + Callback[] callbacks = createAuthorizationCallbacks(); + if (joinContext != null && callbacks != null && callbacks.length > 0) { + CallbackHandler handler = joinContext.getCallbackHandler(); + if (handler != null) { + handler.handle(callbacks); + } + if (callbacks[0] instanceof ObjectCallback) { + ObjectCallback cb = (ObjectCallback) callbacks[0]; + return cb.getObject(); + } + } + return null; + } + + protected Object createConnectData(ID target, Callback[] cbs, Object data) { + // first one is password callback + if (cbs.length > 0) { + if (cbs[0] instanceof ObjectCallback) { + ObjectCallback cb = (ObjectCallback) cbs[0]; + return cb.getObject(); + } + } + return data; + } + + protected Callback[] createAuthorizationCallbacks() { + Callback[] cbs = new Callback[1]; + cbs[0] = new ObjectCallback(); + return cbs; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.provider.generic.ClientSOContainer#getConnectTimeout() + */ + protected int getConnectTimeout() { + return keepAlive; + } + + protected Roster getRoster() throws IOException { + ECFConnection connection = getECFConnection(); + if (connection != null) { + return connection.getRoster(); + } else + return null; + } + + protected void deliverEvent(Event evt) { + SOWrapper wrap = getSharedObjectWrapper(presenceHelperID); + if (wrap != null) + wrap.deliverEvent(evt); + else + trace("deliverEvent(" + evt + ") wrapper object is unavailable"); + } + + protected void handleXMPPMessage(Packet aPacket) throws IOException { + if (!handleAsExtension(aPacket)) { + if (aPacket instanceof IQ) { + deliverEvent(new IQEvent((IQ) aPacket)); + } else if (aPacket instanceof Message) { + deliverEvent(new MessageEvent((Message) aPacket)); + } else if (aPacket instanceof Presence) { + deliverEvent(new PresenceEvent((Presence) aPacket)); + } else { + // unexpected message + debug("got unexpected packet " + aPacket.toXML()); + } + } + } + + protected boolean handleAsExtension(Packet packet) { + // XXX this is where the xmpp extension mechanism support needs to be + // added + Iterator i = packet.getExtensions(); + for (; i.hasNext();) { + Object extension = i.next(); + trace("XMPPContainer.handleAsExtension(ext=" + extension + + ",packet=" + packet.toXML() + ")"); + if (packet instanceof Presence && extension instanceof MUCUser) { + trace("XMPPContainer.handleAsExtension: received presence for MUCUser"); + return true; + } + } + return false; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.provider.generic.SOContainer#createSharedObjectContext(org.eclipse.ecf.provider.generic.SOConfig, + * org.eclipse.ecf.core.sharedobject.util.IQueueEnqueue) + */ + protected SOContext createSharedObjectContext(SOConfig soconfig, + IQueueEnqueue queue) { + return new XMPPContainerContext(soconfig.getSharedObjectID(), soconfig + .getHomeContainerID(), this, soconfig.getProperties(), queue); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.provider.generic.ClientSOContainer#processAsynch(org.eclipse.ecf.provider.comm.AsynchEvent) + */ + protected void processAsynch(AsynchEvent e) { + try { + if (e instanceof ECFConnectionPacketEvent) { + // It's a regular xmpp message + handleXMPPMessage((Packet) e.getData()); + return; + } else if (e instanceof ECFConnectionObjectPacketEvent) { + // It's an ECF object message + ECFConnectionObjectPacketEvent evt = (ECFConnectionObjectPacketEvent) e; + Object obj = evt.getObjectValue(); + // this should be a ContainerMessage + Object cm = deserializeContainerMessage((byte[]) obj); + if (cm == null) + throw new IOException("deserialized object is null"); + ContainerMessage contMessage = (ContainerMessage) cm; + IChatRoomContainer chat = chatRoomManager + .findReceiverChatRoom(contMessage.getToContainerID()); + if (chat != null && chat instanceof XMPPChatRoomContainer) { + XMPPChatRoomContainer cont = (XMPPChatRoomContainer) chat; + cont.handleContainerMessage(contMessage); + return; + } + Object data = contMessage.getData(); + if (data instanceof ContainerMessage.CreateMessage) { + handleCreateMessage(contMessage); + } else if (data instanceof ContainerMessage.CreateResponseMessage) { + handleCreateResponseMessage(contMessage); + } else if (data instanceof ContainerMessage.SharedObjectMessage) { + handleSharedObjectMessage(contMessage); + } else if (data instanceof ContainerMessage.SharedObjectDisposeMessage) { + handleSharedObjectDisposeMessage(contMessage); + } else { + debug("got unrecognized container message...ignoring: " + + contMessage); + } + } else { + // Unexpected type... + debug("got unexpected event: " + e); + } + } catch (Exception except) { + System.err.println("Exception in processAsynch"); + except.printStackTrace(System.err); + dumpStack("Exception processing event " + e, except); + } + } + + protected ECFConnection getECFConnection() { + return (ECFConnection) super.getConnection(); + } + + // utility methods + + protected void trace(String msg) { + } + + protected void dumpStack(String msg, Throwable t) { + } + +}
\ No newline at end of file diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainerAccountManager.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainerAccountManager.java new file mode 100644 index 000000000..d83be147b --- /dev/null +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainerAccountManager.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ +package org.eclipse.ecf.provider.xmpp; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.ecf.core.util.ECFException; +import org.eclipse.ecf.presence.IAccountManager; +import org.jivesoftware.smack.AccountManager; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPException; + +public class XMPPContainerAccountManager implements IAccountManager { + + private static final String NOT_CONNECTED = "not connected"; + + AccountManager accountManager = null; + + protected void traceAndThrow(String msg, Throwable t) throws ECFException { + throw new ECFException(msg, t); + } + + protected AccountManager getAccountManagerOrThrowIfNull() + throws ECFException { + if (accountManager == null) + throw new ECFException(NOT_CONNECTED); + return accountManager; + } + + public XMPPContainerAccountManager() { + } + + public void dispose() { + accountManager = null; + } + + protected void setConnection(XMPPConnection connection) { + this.accountManager = (connection == null) ? null : new AccountManager( + connection); + } + + public boolean changePassword(String newpassword) throws ECFException { + try { + getAccountManagerOrThrowIfNull().changePassword(newpassword); + } catch (XMPPException e) { + traceAndThrow("server exception changing password", e); + } + return true; + } + + public boolean createAccount(String username, String password, + Map attributes) throws ECFException { + try { + getAccountManagerOrThrowIfNull().createAccount(username, password, + attributes); + } catch (XMPPException e) { + traceAndThrow("server exception creating account for " + username, + e); + } + return true; + } + + public boolean deleteAccount() throws ECFException { + try { + getAccountManagerOrThrowIfNull().deleteAccount(); + } catch (XMPPException e) { + traceAndThrow("server exception deleting account", e); + } + return true; + } + + public String getAccountCreationInstructions() { + if (accountManager == null) + return ""; + return accountManager.getAccountInstructions(); + } + + public String[] getAccountAttributeNames() { + if (accountManager == null) + return new String[0]; + Iterator i = accountManager.getAccountAttributes(); + List l = new ArrayList(); + for (; i.hasNext();) { + l.add(i.next()); + } + return (String[]) l.toArray(new String[] {}); + } + + public Object getAccountAttribute(String name) { + if (accountManager == null) + return null; + return accountManager.getAccountAttribute(name); + } + + public boolean isAccountCreationSupported() { + if (accountManager == null) + return false; + return accountManager.supportsAccountCreation(); + } + +} diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainerContext.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainerContext.java new file mode 100644 index 000000000..557fd4892 --- /dev/null +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainerContext.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ +package org.eclipse.ecf.provider.xmpp; + +import java.util.Map; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.sharedobject.util.IQueueEnqueue; +import org.eclipse.ecf.provider.generic.SOContainer; +import org.eclipse.ecf.provider.generic.SOContext; + +public class XMPPContainerContext extends SOContext { + + public XMPPContainerContext(ID objID, ID homeID, SOContainer cont, + Map props, IQueueEnqueue queue) { + super(objID, homeID, cont, props, queue); + } +} diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainerInstantiator.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainerInstantiator.java new file mode 100644 index 000000000..c9eea6334 --- /dev/null +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainerInstantiator.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ +package org.eclipse.ecf.provider.xmpp; + +import org.eclipse.ecf.core.ContainerCreateException; +import org.eclipse.ecf.core.ContainerTypeDescription; +import org.eclipse.ecf.core.IContainer; +import org.eclipse.ecf.core.sharedobject.ISharedObjectContainer; +import org.eclipse.ecf.filetransfer.IOutgoingFileTransferContainerAdapter; +import org.eclipse.ecf.presence.IPresenceContainerAdapter; +import org.eclipse.ecf.presence.chat.IChatRoomManager; +import org.eclipse.ecf.provider.generic.GenericContainerInstantiator; + +public class XMPPContainerInstantiator extends GenericContainerInstantiator { + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.provider.IContainerInstantiator#createInstance(ContainerDescription, + * java.lang.Object[]) + */ + public IContainer createInstance(ContainerTypeDescription description, + Object[] args) throws ContainerCreateException { + try { + Integer ka = new Integer(XMPPContainer.DEFAULT_KEEPALIVE); + String name = null; + if (args != null) { + if (args.length > 0) { + name = (String) args[0]; + if (args.length > 1) { + ka = getIntegerFromArg(args[1]); + } + } + } + if (name == null) { + if (ka == null) { + return new XMPPContainer(); + } else { + return new XMPPContainer(ka.intValue()); + } + } else { + if (ka == null) { + ka = new Integer(XMPPContainer.DEFAULT_KEEPALIVE); + } + return new XMPPContainer(name, ka.intValue()); + } + } catch (Exception e) { + throw new ContainerCreateException( + "Exception creating generic container", e); + } + } + + public String[] getSupportedAdapterTypes( + ContainerTypeDescription description) { + return new String[] { IChatRoomManager.class.getName(), + IPresenceContainerAdapter.class.getName(), + IOutgoingFileTransferContainerAdapter.class.getName(), + ISharedObjectContainer.class.getName() }; + } + +}
\ No newline at end of file diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/container/XMPPPresenceSharedObjectEx.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainerPresenceHelper.java index 3cc9f7f1a..6e7066a1c 100644 --- a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/container/XMPPPresenceSharedObjectEx.java +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPContainerPresenceHelper.java @@ -6,172 +6,270 @@ * * Contributors: Composent, Inc. - initial API and implementation ******************************************************************************/ -package org.eclipse.ecf.provider.xmpp.container; +package org.eclipse.ecf.provider.xmpp; -import java.net.URISyntaxException; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Vector; import org.eclipse.ecf.core.identity.ID; -import org.eclipse.ecf.core.identity.Namespace; import org.eclipse.ecf.core.sharedobject.ISharedObject; import org.eclipse.ecf.core.sharedobject.ISharedObjectConfig; import org.eclipse.ecf.core.sharedobject.ISharedObjectContext; import org.eclipse.ecf.core.sharedobject.SharedObjectInitException; import org.eclipse.ecf.core.sharedobject.events.ISharedObjectActivatedEvent; -import org.eclipse.ecf.core.sharedobject.events.ISharedObjectDeactivatedEvent; import org.eclipse.ecf.core.sharedobject.events.ISharedObjectMessageEvent; import org.eclipse.ecf.core.sharedobject.events.ISharedObjectMessageListener; import org.eclipse.ecf.core.user.IUser; import org.eclipse.ecf.core.user.User; import org.eclipse.ecf.core.util.ECFException; import org.eclipse.ecf.core.util.Event; -import org.eclipse.ecf.presence.IAccountManager; import org.eclipse.ecf.presence.IMessageListener; -import org.eclipse.ecf.presence.IPresenceListener; -import org.eclipse.ecf.presence.IRosterSubscriptionListener; -import org.eclipse.ecf.presence.chat.IInvitationListener; +import org.eclipse.ecf.presence.IMessageSender; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.IPresenceSender; import org.eclipse.ecf.presence.roster.AbstractRosterManager; -import org.eclipse.ecf.presence.roster.IPresence; -import org.eclipse.ecf.presence.roster.IPresenceSender; import org.eclipse.ecf.presence.roster.IRosterGroup; import org.eclipse.ecf.presence.roster.IRosterItem; import org.eclipse.ecf.presence.roster.IRosterManager; import org.eclipse.ecf.presence.roster.IRosterSubscriptionSender; import org.eclipse.ecf.provider.xmpp.events.IQEvent; -import org.eclipse.ecf.provider.xmpp.events.InvitationReceivedEvent; import org.eclipse.ecf.provider.xmpp.events.MessageEvent; import org.eclipse.ecf.provider.xmpp.events.PresenceEvent; import org.eclipse.ecf.provider.xmpp.identity.XMPPID; import org.eclipse.ecf.provider.xmpp.identity.XMPPRoomID; -import org.jivesoftware.smack.AccountManager; +import org.eclipse.ecf.provider.xmpp.smack.ECFConnection; import org.jivesoftware.smack.Roster; import org.jivesoftware.smack.RosterEntry; import org.jivesoftware.smack.RosterGroup; -import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.RosterPacket; import org.jivesoftware.smack.packet.Presence.Mode; import org.jivesoftware.smack.packet.Presence.Type; -import org.jivesoftware.smack.packet.RosterPacket.Item; -public class XMPPPresenceSharedObjectEx implements ISharedObject, - IAccountManager { +public class XMPPContainerPresenceHelper implements ISharedObject { ISharedObjectConfig config = null; - XMPPConnection connection = null; - - AccountManager accountManager = null; - Vector messageListeners = new Vector(); Vector sharedObjectMessageListeners = new Vector(); - Vector invitationListeners = new Vector(); + XMPPContainer container = null; - Namespace namespace = null; + public XMPPContainerPresenceHelper(XMPPContainer container) { + this.container = container; + } - XMPPClientSOContainer container = null; + // ISharedObject implementation - public XMPPPresenceSharedObjectEx(XMPPClientSOContainer container) { - this.container = container; + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#init(org.eclipse.ecf.core.ISharedObjectConfig) + */ + public void init(ISharedObjectConfig initData) + throws SharedObjectInitException { + this.config = initData; } - protected void fireInvitationReceived(ID roomID, ID fromID, ID toID, - String subject, String body) { - for (Iterator i = invitationListeners.iterator(); i.hasNext();) { - IInvitationListener l = (IInvitationListener) i.next(); - l.handleInvitationReceived(roomID, fromID, subject, body); + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#handleEvent(org.eclipse.ecf.core.util.Event) + */ + public void handleEvent(Event event) { + trace("handleEvent(" + event + ")"); + if (event instanceof ISharedObjectActivatedEvent) { + } else if (event instanceof IQEvent) { + handleIQEvent((IQEvent) event); + } else if (event instanceof MessageEvent) { + handleMessageEvent((MessageEvent) event); + } else if (event instanceof PresenceEvent) { + handlePresenceEvent((PresenceEvent) event); + } else if (event instanceof ISharedObjectMessageEvent) { + fireSharedObjectMessageListeners((ISharedObjectMessageEvent) event); + } else { + trace("unhandled event=" + event); } } - protected void addInvitationListener(IInvitationListener listener) { - invitationListeners.add(listener); + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#handleEvents(org.eclipse.ecf.core.util.Event[]) + */ + public void handleEvents(Event[] events) { + for (int i = 0; i < events.length; i++) { + handleEvent(events[i]); + } } - protected void removeInvitationListener(IInvitationListener listener) { - invitationListeners.remove(listener); + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#dispose(org.eclipse.ecf.core.identity.ID) + */ + public void dispose(ID containerID) { + if (messageListeners != null) + messageListeners.clear(); + messageListeners = null; + if (sharedObjectMessageListeners != null) + sharedObjectMessageListeners.clear(); + sharedObjectMessageListeners = null; + container = null; + config = null; } - protected void addMessageListener(IMessageListener listener) { - messageListeners.add(listener); + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class clazz) { + return null; } - protected void removeMessageListener(IMessageListener listener) { - messageListeners.add(listener); - } + // end ISharedObject implementation - protected void addSharedObjectMessageListener( - ISharedObjectMessageListener listener) { - sharedObjectMessageListeners.add(listener); - } + IMessageSender messageSender = new IMessageSender() { + public void sendMessage(ID toID, String subject, String message) + throws ECFException { + try { + getConnectionOrThrowIfNull().sendMessage(toID, message); + } catch (IOException e) { + traceStack("Exception in sendmessage to " + toID + + " with message " + message, e); + } + } - protected void removeSharedObjectMessageListener( - ISharedObjectMessageListener listener) { - sharedObjectMessageListeners.remove(listener); + }; + + protected IMessageSender getMessageSender() { + return messageSender; } - protected String canonicalizePresenceFrom(String from) { - if (from == null) - return null; - else - return from; + protected org.eclipse.ecf.presence.roster.Roster roster = new org.eclipse.ecf.presence.roster.Roster(); + + protected PresenceRosterManager rosterManager = new PresenceRosterManager( + roster); + + class PresenceRosterManager extends AbstractRosterManager { + + public PresenceRosterManager( + org.eclipse.ecf.presence.roster.Roster roster) { + super(roster); + } + + public void notifySubscriptionListener(ID fromID, IPresence presence) { + this.fireSubscriptionListener(fromID, presence); + } + + public void notifyRosterUpdate(IRosterItem changedItem) { + fireRosterUpdate(changedItem); + } + + public void setUser(IUser user) { + ((org.eclipse.ecf.presence.roster.Roster) getRoster()) + .setUser(user); + notifyRosterUpdate(null); + } + + org.eclipse.ecf.presence.IPresenceSender rosterPresenceSender = new org.eclipse.ecf.presence.IPresenceSender() { + public void sendPresenceUpdate(ID toID, + org.eclipse.ecf.presence.IPresence presence) + throws ECFException { + try { + getConnectionOrThrowIfNull().sendPresenceUpdate(toID, + createPresence(presence)); + } catch (IOException e) { + traceAndThrowECFException("sendPresenceUpdate", e); + } + } + + }; + /* - * int index = from.indexOf("/"); if (index > 0) { return - * from.substring(0, index); } else return from; + * (non-Javadoc) + * + * @see org.eclipse.ecf.presence.roster.AbstractRosterManager#getPresenceSender() */ - } + public IPresenceSender getPresenceSender() { + return rosterPresenceSender; + } - protected void debug(String msg) { - System.out.println(config.getSharedObjectID() + ":" + msg); - } + org.eclipse.ecf.presence.roster.IRosterSubscriptionSender rosterSubscriptionSender = new org.eclipse.ecf.presence.roster.IRosterSubscriptionSender() { + public void sendRosterAdd(String user, String name, String[] groups) + throws ECFException { + try { + getConnectionOrThrowIfNull().sendRosterAdd(user, name, + groups); + } catch (IOException e) { + traceAndThrowECFException("sendRosterAdd", e); + } + } - protected void disconnect() { - ISharedObjectContext context = getContext(); - if (context != null) { - context.disconnect(); + public void sendRosterRemove(ID userID) throws ECFException { + try { + if (!(userID instanceof XMPPID)) + throw new ECFException("invalid userID"); + XMPPID xmppID = (XMPPID) userID; + getConnectionOrThrowIfNull().sendRosterRemove( + xmppID.getUsernameAtHost()); + } catch (IOException e) { + traceAndThrowECFException("sendRosterRemove", e); + } + } + + }; + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.presence.roster.AbstractRosterManager#getRosterSubscriptionSender() + */ + public IRosterSubscriptionSender getRosterSubscriptionSender() { + return rosterSubscriptionSender; } + } - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObject#dispose(org.eclipse.ecf.core.identity.ID) - */ - public void dispose(ID containerID) { - config = null; - accountManager = null; - invitationListeners.clear(); - invitationListeners = null; + public IRosterManager getRosterManager() { + return rosterManager; } - protected void dumpStack(String msg, Throwable e) { - e.printStackTrace(System.err); + public void setUser(IUser user) { + rosterManager.setUser(user); + } + + protected void addMessageListener(IMessageListener listener) { + messageListeners.add(listener); } - protected void fireMessage(ID from, ID to, IMessageListener.Type type, - String subject, String body) { + protected void fireMessageListeners(ID from, ID to, + IMessageListener.Type type, String subject, String body) { for (Iterator i = messageListeners.iterator(); i.hasNext();) { IMessageListener l = (IMessageListener) i.next(); l.handleMessage(from, to, type, subject, body); } } - private void addToRoster(IRosterItem[] items) { - for (int i = 0; i < items.length; i++) - roster.addItem(items[i]); - rosterManager.notifyRosterUpdate(null); + protected void removeMessageListener(IMessageListener listener) { + messageListeners.add(listener); + } + + protected void addSharedObjectMessageListener( + ISharedObjectMessageListener listener) { + sharedObjectMessageListeners.add(listener); } - protected void fireSharedObjectMessage(ISharedObjectMessageEvent event) { + protected void fireSharedObjectMessageListeners( + ISharedObjectMessageEvent event) { for (Iterator i = sharedObjectMessageListeners.iterator(); i.hasNext();) { ISharedObjectMessageListener l = (ISharedObjectMessageListener) i .next(); @@ -179,17 +277,15 @@ public class XMPPPresenceSharedObjectEx implements ISharedObject, } } - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObject#getAdapter(java.lang.Class) - */ - public Object getAdapter(Class clazz) { - return null; + protected void removeSharedObjectMessageListener( + ISharedObjectMessageListener listener) { + sharedObjectMessageListeners.remove(listener); } - protected XMPPConnection getConnection() { - return connection; + private void addToRoster(IRosterItem[] items) { + for (int i = 0; i < items.length; i++) + roster.addItem(items[i]); + rosterManager.notifyRosterUpdate(null); } protected ISharedObjectContext getContext() { @@ -200,81 +296,6 @@ public class XMPPPresenceSharedObjectEx implements ISharedObject, return userID.getUsername(); } - protected void handleDeactivatedEvent(ISharedObjectDeactivatedEvent event) { - debug("Got deactivated event: " + event); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObject#handleEvent(org.eclipse.ecf.core.util.Event) - */ - public void handleEvent(Event event) { - debug("handleEvent(" + event + ")"); - if (event instanceof ISharedObjectActivatedEvent) { - } else if (event instanceof IQEvent) { - handleIQEvent((IQEvent) event); - } else if (event instanceof MessageEvent) { - handleMessageEvent((MessageEvent) event); - } else if (event instanceof PresenceEvent) { - handlePresenceEvent((PresenceEvent) event); - } else if (event instanceof InvitationReceivedEvent) { - handleInvitationEvent((InvitationReceivedEvent) event); - } else if (event instanceof ISharedObjectDeactivatedEvent) { - handleDeactivatedEvent((ISharedObjectDeactivatedEvent) event); - } else if (event instanceof ISharedObjectMessageEvent) { - fireSharedObjectMessage((ISharedObjectMessageEvent) event); - } else { - debug("unrecognized event " + event); - } - } - - protected ID createRoomIDFromName(String from) { - try { - return new XMPPRoomID(namespace, connection, from); - } catch (URISyntaxException e) { - dumpStack("Exception in createRoomIDFromName", e); - return null; - } - } - - protected ID createUserIDFromName(String name) { - ID result = null; - try { - result = new XMPPID(namespace, name); - return result; - } catch (Exception e) { - dumpStack("Exception in createIDFromName", e); - return null; - } - } - - protected void handleInvitationEvent(InvitationReceivedEvent event) { - XMPPConnection conn = event.getConnection(); - if (conn == connection) { - ID roomID = createRoomIDFromName(event.getRoom()); - ID fromID = createUserIDFromName(event.getInviter()); - Message mess = event.getMessage(); - ID toID = createUserIDFromName(mess.getTo()); - String subject = mess.getSubject(); - String body = event.getReason(); - fireInvitationReceived(roomID, fromID, toID, subject, body); - } else { - debug("got invitation event for other connection " + event); - } - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObject#handleEvents(org.eclipse.ecf.core.util.Event[]) - */ - public void handleEvents(Event[] events) { - for (int i = 0; i < events.length; i++) { - handleEvent(events[i]); - } - } - protected void handleIQEvent(IQEvent evt) { IQ iq = evt.getIQ(); if (iq instanceof RosterPacket) { @@ -293,13 +314,10 @@ public class XMPPPresenceSharedObjectEx implements ISharedObject, } } } else { - debug("Received non rosterpacket IQ message: " + iq.toXML()); + trace("Received non rosterpacket IQ message: " + iq.toXML()); } } - private void removeFromRoster(Item item) { - } - private void removeItemFromRoster(Collection rosterItems, XMPPID itemIDToRemove) { synchronized (rosterItems) { @@ -331,35 +349,23 @@ public class XMPPPresenceSharedObjectEx implements ISharedObject, } } - protected Message.Type[] ALLOWED_MESSAGES = { Message.Type.CHAT, - Message.Type.ERROR, Message.Type.HEADLINE, Message.Type.NORMAL }; - - protected Message filterMessageType(Message msg) { - for (int i = 0; i < ALLOWED_MESSAGES.length; i++) { - if (ALLOWED_MESSAGES[i].equals(msg.getType())) { - return msg; - } - } - return null; - } - protected void handleMessageEvent(MessageEvent evt) { Message msg = evt.getMessage(); String from = msg.getFrom(); String to = msg.getTo(); String body = msg.getBody(); String subject = msg.getSubject(); - ID fromID = createIDFromName(canonicalizePresenceFrom(from)); - ID toID = createIDFromName(canonicalizePresenceFrom(to)); + ID fromID = createIDFromName(from); + ID toID = createIDFromName(to); msg = filterMessageType(msg); if (msg != null) - fireMessage(fromID, toID, createMessageType(msg.getType()), - subject, body); + fireMessageListeners(fromID, toID, + createMessageType(msg.getType()), subject, body); } protected void handlePresenceEvent(PresenceEvent evt) { Presence xmppPresence = evt.getPresence(); - String from = canonicalizePresenceFrom(xmppPresence.getFrom()); + String from = xmppPresence.getFrom(); IPresence newPresence = createIPresence(xmppPresence); XMPPID fromID = createIDFromName(from); if (newPresence.getType().equals(IPresence.Type.SUBSCRIBE) @@ -414,22 +420,11 @@ public class XMPPPresenceSharedObjectEx implements ISharedObject, rosterManager.notifyRosterUpdate(null); } - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObject#init(org.eclipse.ecf.core.ISharedObjectConfig) - */ - public void init(ISharedObjectConfig initData) - throws SharedObjectInitException { - this.config = initData; - this.namespace = getContext().getConnectNamespace(); - } - protected XMPPID createIDFromName(String name) { try { - return new XMPPID(namespace, name); + return new XMPPID(container.getConnectNamespace(), name); } catch (Exception e) { - dumpStack("Exception in createIDFromName", e); + traceStack("Exception in createIDFromName", e); return null; } } @@ -453,7 +448,7 @@ public class XMPPPresenceSharedObjectEx implements ISharedObject, protected IPresence createIPresence(Presence xmppPresence) { String status = xmppPresence.getStatus(); - IPresence newPresence = new org.eclipse.ecf.presence.roster.Presence( + IPresence newPresence = new org.eclipse.ecf.presence.Presence( createIPresenceType(xmppPresence), status, createIPresenceMode(xmppPresence)); return newPresence; @@ -566,7 +561,7 @@ public class XMPPPresenceSharedObjectEx implements ISharedObject, : ((RosterGroup) o).getName(); if (groupName == null || groupName.equals("")) { - createRosterEntry(result, parent, user); + createRosterEntry(parent, user, result); continue; } // See if group is already in roster @@ -578,29 +573,30 @@ public class XMPPPresenceSharedObjectEx implements ISharedObject, rosterGroup = new org.eclipse.ecf.presence.roster.RosterGroup( parent, groupName); - org.eclipse.ecf.presence.roster.RosterEntry oldEntry = findRosterEntry( - rosterGroup, user); - // Now create new roster entry - new org.eclipse.ecf.presence.roster.RosterEntry(rosterGroup, - user, new org.eclipse.ecf.presence.roster.Presence( - IPresence.Type.UNAVAILABLE, - IPresence.Type.UNAVAILABLE.toString(), - IPresence.Mode.AWAY)); + if (findRosterEntry(rosterGroup, user) == null) { + // Now create new roster entry + new org.eclipse.ecf.presence.roster.RosterEntry( + rosterGroup, user, + new org.eclipse.ecf.presence.Presence( + IPresence.Type.UNAVAILABLE, + IPresence.Type.UNAVAILABLE.toString(), + IPresence.Mode.AWAY)); + } // Only add localGrp if not already in list if (!groupFound) result.add(rosterGroup); } } else - createRosterEntry(result, parent, user); + createRosterEntry(parent, user, result); return (IRosterItem[]) result.toArray(new IRosterItem[] {}); } - private void createRosterEntry(List result, Object parent, IUser user) { + private void createRosterEntry(Object parent, IUser user, List result) { org.eclipse.ecf.presence.roster.RosterEntry oldEntry = findRosterEntry( (org.eclipse.ecf.presence.roster.RosterGroup) null, user); if (oldEntry == null) { org.eclipse.ecf.presence.roster.RosterEntry newEntry = new org.eclipse.ecf.presence.roster.RosterEntry( - parent, user, new org.eclipse.ecf.presence.roster.Presence( + parent, user, new org.eclipse.ecf.presence.Presence( IPresence.Type.UNAVAILABLE, IPresence.Type.UNAVAILABLE.toString(), IPresence.Mode.AWAY)); @@ -649,159 +645,60 @@ public class XMPPPresenceSharedObjectEx implements ISharedObject, return null; } - // return new org.eclipse.ecf.presence.roster.RosterGroup(parent, grp); + // utility methods - protected void setConnection(XMPPConnection connection) { - this.connection = connection; - if (connection != null) { - accountManager = new AccountManager(connection); - } + protected ECFConnection getConnectionOrThrowIfNull() throws IOException { + ECFConnection conn = container.getECFConnection(); + if (conn == null) + throw new IOException("Not connected"); + return conn; } - public boolean changePassword(String newpassword) throws ECFException { - if (accountManager == null) - throw new ECFException("not connected"); - try { - accountManager.changePassword(newpassword); - } catch (XMPPException e) { - dumpStack("server exception changing password", e); - throw new ECFException("server exception changing password", e); - } - return true; + protected void traceAndThrowECFException(String msg, Throwable t) + throws ECFException { + throw new ECFException(msg, t); } - public boolean createAccount(String username, String password, - Map attributes) throws ECFException { - if (accountManager == null) - throw new ECFException("not connected"); - try { - accountManager.createAccount(username, password, attributes); - } catch (XMPPException e) { - dumpStack("server exception creating account for " + username, e); - throw new ECFException("server exception creating account for " - + username, e); - } - return true; - } + protected void trace(String msg) { - public boolean deleteAccount() throws ECFException { - if (accountManager == null) - throw new ECFException("not connected"); - try { - accountManager.deleteAccount(); - } catch (XMPPException e) { - dumpStack("server exception deleting account", e); - throw new ECFException("server exception deleting account", e); - } - return true; } - public String getAccountCreationInstructions() { - if (accountManager == null) - return null; - return accountManager.getAccountInstructions(); + protected void traceStack(String msg, Throwable e) { + } - public String[] getAccountAttributeNames() { - if (accountManager == null) + protected ID createRoomIDFromName(String from) { + try { + ECFConnection ecfConnection = getConnectionOrThrowIfNull(); + return new XMPPRoomID(container.getConnectNamespace(), + ecfConnection.getXMPPConnection(), from); + } catch (Exception e) { + traceStack("Exception in createRoomIDFromName", e); return null; - Iterator i = accountManager.getAccountAttributes(); - List l = new ArrayList(); - for (; i.hasNext();) { - l.add(i.next()); } - return (String[]) l.toArray(new String[] {}); } - public Object getAccountAttribute(String name) { - if (accountManager == null) + protected ID createUserIDFromName(String name) { + ID result = null; + try { + result = new XMPPID(container.getConnectNamespace(), name); + return result; + } catch (Exception e) { + traceStack("Exception in createIDFromName", e); return null; - return accountManager.getAccountAttribute(name); - } - - public boolean isAccountCreationSupported() { - if (accountManager == null) - return false; - return accountManager.supportsAccountCreation(); - } - - public IRosterManager getRosterManager() { - return rosterManager; - } - - public void setUser(IUser user) { - rosterManager.setUser(user); - } - - protected org.eclipse.ecf.presence.roster.Roster roster = new org.eclipse.ecf.presence.roster.Roster(); - - protected PresenceRosterManager rosterManager = new PresenceRosterManager( - roster); - - class PresenceRosterManager extends AbstractRosterManager { - - public PresenceRosterManager( - org.eclipse.ecf.presence.roster.Roster roster) { - super(roster); - } - - public void notifySubscriptionListener(ID fromID, IPresence presence) { - this.fireSubscriptionListener(fromID, presence); - } - - public void notifyRosterUpdate(IRosterItem changedItem) { - fireRosterUpdate(changedItem); - } - - public void setUser(IUser user) { - ((org.eclipse.ecf.presence.roster.Roster) getRoster()) - .setUser(user); - notifyRosterUpdate(null); } + } - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.presence.roster.AbstractRosterManager#getPresenceSender() - */ - public IPresenceSender getPresenceSender() { - return container.getPresenceSender(); - } + protected Message.Type[] ALLOWED_MESSAGES = { Message.Type.CHAT, + Message.Type.ERROR, Message.Type.HEADLINE, Message.Type.NORMAL }; - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.presence.roster.AbstractRosterManager#getRosterSubscriptionSender() - */ - public IRosterSubscriptionSender getRosterSubscriptionSender() { - return container.getRosterSubscriptionSender(); + protected Message filterMessageType(Message msg) { + for (int i = 0; i < ALLOWED_MESSAGES.length; i++) { + if (ALLOWED_MESSAGES[i].equals(msg.getType())) { + return msg; + } } - - } - - public Presence createPresence(org.eclipse.ecf.presence.IPresence presence) { - // TODO Auto-generated method stub return null; } - public void addPresenceListener(IPresenceListener listener) { - // TODO Auto-generated method stub - - } - - public void addSubscribeListener(IRosterSubscriptionListener listener) { - // TODO Auto-generated method stub - - } - - public void removePresenceListener(IPresenceListener listener) { - // TODO Auto-generated method stub - - } - - public void removeSubscribeListener(IRosterSubscriptionListener listener) { - // TODO Auto-generated method stub - - } - } diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPOutgoingFileTransferContainerAdapter.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPOutgoingFileTransferContainerAdapter.java new file mode 100644 index 000000000..547052e33 --- /dev/null +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPOutgoingFileTransferContainerAdapter.java @@ -0,0 +1,117 @@ +/**************************************************************************** + * Copyright (c) 2004 Composent, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Composent, Inc. - initial API and implementation + *****************************************************************************/ + +package org.eclipse.ecf.provider.xmpp; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.filetransfer.BaseFileTransferInfo; +import org.eclipse.ecf.filetransfer.IFileTransferInfo; +import org.eclipse.ecf.filetransfer.IFileTransferListener; +import org.eclipse.ecf.filetransfer.IIncomingFileTransferRequestListener; +import org.eclipse.ecf.filetransfer.IOutgoingFileTransferContainerAdapter; +import org.eclipse.ecf.filetransfer.OutgoingFileTransferException; +import org.eclipse.ecf.filetransfer.events.IFileTransferEvent; +import org.eclipse.ecf.provider.xmpp.filetransfer.XMPPOutgoingFileTransfer; +import org.eclipse.ecf.provider.xmpp.identity.XMPPID; +import org.eclipse.ecf.provider.xmpp.smack.ECFConnection; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smackx.filetransfer.FileTransferManager; + +public class XMPPOutgoingFileTransferContainerAdapter implements + IOutgoingFileTransferContainerAdapter { + + List transferListeners = new ArrayList(); + + List incomingTransferListeners = new ArrayList(); + + XMPPContainer container = null; + + public XMPPOutgoingFileTransferContainerAdapter(XMPPContainer container) { + this.container = container; + } + + public void dispose() { + if (transferListeners != null) + transferListeners.clear(); + transferListeners = null; + + if (incomingTransferListeners != null) + incomingTransferListeners.clear(); + incomingTransferListeners = null; + container = null; + } + + protected void addFileTransferListener(IFileTransferListener listener) { + transferListeners.add(listener); + } + + protected void removeFileTransferListener(IFileTransferListener listener) { + transferListeners.remove(listener); + } + + public void addListener(IIncomingFileTransferRequestListener listener) { + incomingTransferListeners.add(listener); + } + + public void sendOutgoingRequest(ID targetReceiver, + IFileTransferInfo localFileToSend, + IFileTransferListener progressListener, Map options) + throws OutgoingFileTransferException { + ECFConnection ecfConnection = container.getECFConnection(); + if (ecfConnection == null || !ecfConnection.isConnected()) + throw new OutgoingFileTransferException("not connected"); + XMPPConnection xmppConnection = ecfConnection.getXMPPConnection(); + FileTransferManager manager = new FileTransferManager(xmppConnection); + + XMPPOutgoingFileTransfer fileTransfer = new XMPPOutgoingFileTransfer( + manager, (XMPPID) targetReceiver, localFileToSend, + progressListener); + + try { + fileTransfer.startSend(localFileToSend.getFile(), localFileToSend + .getDescription()); + } catch (XMPPException e) { + throw new OutgoingFileTransferException( + "Exception sending start request", e); + } + } + + protected void fireFileTransferEvent(IFileTransferEvent event) { + for (Iterator i = transferListeners.iterator(); i.hasNext();) { + IFileTransferListener l = (IFileTransferListener) i.next(); + l.handleTransferEvent(event); + } + } + + public Namespace getOutgoingFileTransferNamespace() { + return container.getConnectNamespace(); + } + + public boolean removeListener(IIncomingFileTransferRequestListener listener) { + return incomingTransferListeners.remove(listener); + } + + public void sendOutgoingRequest(ID targetReceiver, File localFileToSend, + IFileTransferListener transferListener, Map options) + throws OutgoingFileTransferException { + sendOutgoingRequest(targetReceiver, new BaseFileTransferInfo( + localFileToSend), transferListener, options); + } + +} diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPSContainer.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPSContainer.java new file mode 100644 index 000000000..deef4c13a --- /dev/null +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPSContainer.java @@ -0,0 +1,68 @@ +/**************************************************************************** + * Copyright (c) 2004 Composent, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Composent, Inc. - initial API and implementation + *****************************************************************************/ +package org.eclipse.ecf.provider.xmpp; + +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.internal.provider.xmpp.XmppPlugin; +import org.eclipse.ecf.provider.comm.ConnectionCreateException; +import org.eclipse.ecf.provider.comm.ISynchAsynchConnection; +import org.eclipse.ecf.provider.xmpp.identity.XMPPID; +import org.eclipse.ecf.provider.xmpp.smack.ECFConnection; + +public class XMPPSContainer extends XMPPContainer { + public XMPPSContainer() throws Exception { + super(); + } + + /** + * @param ka + * @throws Exception + */ + public XMPPSContainer(int ka) throws Exception { + super(ka); + } + + /** + * @param userhost + * @param ka + * @throws Exception + */ + public XMPPSContainer(String userhost, int ka) throws Exception { + super(userhost, ka); + } + + public Namespace getConnectNamespace() { + return IDFactory.getDefault().getNamespaceByName( + XmppPlugin.getDefault().getSecureNamespaceIdentifier()); + } + + protected ISynchAsynchConnection createConnection(ID remoteSpace, + Object data) throws ConnectionCreateException { + boolean google = false; + boolean secure = false; + if (remoteSpace instanceof XMPPID) { + XMPPID theID = (XMPPID) remoteSpace; + String host = theID.getHostname(); + if (host.toLowerCase().equals(GOOGLE_SERVICENAME)) { + google = true; + secure = false; + } else { + google = false; + secure = true; + } + } + return new ECFConnection(google, getConnectNamespace(), receiver, + secure); + } + +} diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPSContainerInstantiator.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPSContainerInstantiator.java new file mode 100644 index 000000000..090c996e3 --- /dev/null +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/XMPPSContainerInstantiator.java @@ -0,0 +1,53 @@ +/**************************************************************************** + * Copyright (c) 2004 Composent, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Composent, Inc. - initial API and implementation + *****************************************************************************/ +package org.eclipse.ecf.provider.xmpp; + +import org.eclipse.ecf.core.ContainerTypeDescription; +import org.eclipse.ecf.core.ContainerCreateException; +import org.eclipse.ecf.core.IContainer; + +public class XMPPSContainerInstantiator extends XMPPContainerInstantiator { + public XMPPSContainerInstantiator() { + super(); + } + + public IContainer createInstance(ContainerTypeDescription description, + Object[] args) throws ContainerCreateException { + try { + Integer ka = new Integer(XMPPSContainer.DEFAULT_KEEPALIVE); + String name = null; + if (args != null) { + if (args.length > 0) { + name = (String) args[0]; + if (args.length > 1) { + ka = getIntegerFromArg(args[1]); + } + } + } + if (name == null) { + if (ka == null) { + return new XMPPSContainer(); + } else { + return new XMPPSContainer(ka.intValue()); + } + } else { + if (ka == null) { + ka = new Integer(XMPPSContainer.DEFAULT_KEEPALIVE); + } + return new XMPPSContainer(name, ka.intValue()); + } + } catch (Exception e) { + throw new ContainerCreateException( + "Exception creating generic container", e); + } + } + +} diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/container/XMPPClientSOContainer.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/container/XMPPClientSOContainer.java index d577011fa..fbfb2d11e 100644 --- a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/container/XMPPClientSOContainer.java +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/container/XMPPClientSOContainer.java @@ -56,11 +56,10 @@ import org.eclipse.ecf.presence.IPresenceContainerAdapter; import org.eclipse.ecf.presence.IPresenceListener; import org.eclipse.ecf.presence.IPresenceSender; import org.eclipse.ecf.presence.IRosterSubscriptionListener; -import org.eclipse.ecf.presence.IMessageListener.Type; import org.eclipse.ecf.presence.chat.IChatRoomContainer; import org.eclipse.ecf.presence.chat.IChatRoomManager; -import org.eclipse.ecf.presence.chat.IInvitationListener; -import org.eclipse.ecf.presence.chat.IRoomInfo; +import org.eclipse.ecf.presence.chat.IChatRoomInvitationListener; +import org.eclipse.ecf.presence.chat.IChatRoomInfo; import org.eclipse.ecf.presence.roster.IRosterManager; import org.eclipse.ecf.presence.roster.IRosterSubscriptionSender; import org.eclipse.ecf.provider.comm.AsynchEvent; @@ -101,7 +100,7 @@ public class XMPPClientSOContainer extends ClientSOContainer implements public static final int DEFAULT_KEEPALIVE = 30000; - Trace trace = Trace.create("XMPPClientSOContainer"); + Trace trace = Trace.create("XMPPContainer"); public static final String NAMESPACE_IDENTIFIER = XmppPlugin.getDefault() .getNamespaceIdentifier(); @@ -350,10 +349,10 @@ public class XMPPClientSOContainer extends ClientSOContainer implements Iterator i = packet.getExtensions(); for (; i.hasNext();) { Object extension = i.next(); - trace("XMPPClientSOContainer.handleAsExtension(ext=" + extension + trace("XMPPContainer.handleAsExtension(ext=" + extension + ",packet=" + packet.toXML() + ")"); if (packet instanceof Presence && extension instanceof MUCUser) { - trace("XMPPClientSOContainer.handleAsExtension: received presence for MUCUser"); + trace("XMPPContainer.handleAsExtension: received presence for MUCUser"); return true; } } @@ -491,6 +490,10 @@ public class XMPPClientSOContainer extends ClientSOContainer implements return delegate.getRosterManager(); } + protected ECFConnection getECFConnection() { + return (ECFConnection) super.getConnection(); + } + public Object getAdapter(Class clazz) { if (clazz.equals(IPresenceContainerAdapter.class)) { return new IPresenceContainerAdapter() { @@ -514,8 +517,7 @@ public class XMPPClientSOContainer extends ClientSOContainer implements public IMessageSender getMessageSender() { return new IMessageSender() { - public void sendMessage(ID toID, Type type, String subject, - String message) { + public void sendMessage(ID toID, String subject, String message) { try { XMPPClientSOContainer.this.sendMessage(toID, message); @@ -621,25 +623,25 @@ public class XMPPClientSOContainer extends ClientSOContainer implements return XMPPClientSOContainer.this.getChatRooms(); } - public IRoomInfo getChatRoomInfo(String roomname) { + public IChatRoomInfo getChatRoomInfo(String roomname) { return XMPPClientSOContainer.this .getChatRoomInfo(roomname); } - public IRoomInfo[] getChatRoomsInfo() { + public IChatRoomInfo[] getChatRoomsInfo() { ID[] chatRooms = getChatRooms(); if (chatRooms == null) return null; - IRoomInfo[] res = new IRoomInfo[chatRooms.length]; + IChatRoomInfo[] res = new IChatRoomInfo[chatRooms.length]; int count = 0; for (int i = 0; i < chatRooms.length; i++) { - IRoomInfo infoResult = XMPPClientSOContainer.this + IChatRoomInfo infoResult = XMPPClientSOContainer.this .getChatRoomInfo(chatRooms[i]); if (infoResult != null) { res[count++] = infoResult; } } - IRoomInfo[] results = new IRoomInfo[count]; + IChatRoomInfo[] results = new IChatRoomInfo[count]; for (int i = 0; i < count; i++) { results[i] = res[i]; } @@ -651,12 +653,12 @@ public class XMPPClientSOContainer extends ClientSOContainer implements } public void addInvitationListener( - IInvitationListener listener) { + IChatRoomInvitationListener listener) { delegate.addInvitationListener(listener); } public void removeInvitationListener( - IInvitationListener listener) { + IChatRoomInvitationListener listener) { delegate.removeInvitationListener(listener); } @@ -727,7 +729,7 @@ public class XMPPClientSOContainer extends ClientSOContainer implements return (ID[]) result.toArray(new ID[] {}); } - class ECFRoomInfo implements IRoomInfo { + class ECFRoomInfo implements IChatRoomInfo { RoomInfo info; @@ -811,7 +813,7 @@ public class XMPPClientSOContainer extends ClientSOContainer implements } } - protected IRoomInfo getChatRoomInfo(ID roomID) { + protected IChatRoomInfo getChatRoomInfo(ID roomID) { if (!(roomID instanceof XMPPRoomID)) return null; XMPPRoomID cRoomID = (XMPPRoomID) roomID; @@ -828,7 +830,7 @@ public class XMPPClientSOContainer extends ClientSOContainer implements return null; } - protected IRoomInfo getChatRoomInfo(String roomname) { + protected IChatRoomInfo getChatRoomInfo(String roomname) { try { // Create roomid XMPPRoomID roomID = new XMPPRoomID(getConnectNamespace(), delegate @@ -940,17 +942,17 @@ public class XMPPClientSOContainer extends ClientSOContainer implements return rosterSubscriptionSender; } - org.eclipse.ecf.presence.roster.IPresenceSender rosterPresenceSender = new org.eclipse.ecf.presence.roster.IPresenceSender() { + org.eclipse.ecf.presence.IPresenceSender rosterPresenceSender = new org.eclipse.ecf.presence.IPresenceSender() { public void sendPresenceUpdate(ID toID, - org.eclipse.ecf.presence.roster.IPresence presence) + org.eclipse.ecf.presence.IPresence presence) throws ECFException { sendPresenceUpdate(toID, presence); } }; - protected org.eclipse.ecf.presence.roster.IPresenceSender getPresenceSender() { + protected org.eclipse.ecf.presence.IPresenceSender getPresenceSender() { return rosterPresenceSender; } }
\ No newline at end of file diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/container/XMPPGroupChatSOContainer.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/container/XMPPGroupChatSOContainer.java index ba650fc3b..c73154934 100644 --- a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/container/XMPPGroupChatSOContainer.java +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/container/XMPPGroupChatSOContainer.java @@ -30,7 +30,7 @@ import org.eclipse.ecf.core.sharedobject.util.IQueueEnqueue; import org.eclipse.ecf.core.util.ECFException; import org.eclipse.ecf.internal.provider.xmpp.XmppPlugin; import org.eclipse.ecf.presence.IMessageListener; -import org.eclipse.ecf.presence.chat.IChatMessageSender; +import org.eclipse.ecf.presence.chat.IChatRoomMessageSender; import org.eclipse.ecf.presence.chat.IChatParticipantListener; import org.eclipse.ecf.presence.chat.IChatRoomContainer; import org.eclipse.ecf.provider.comm.ConnectionCreateException; @@ -438,8 +438,8 @@ public class XMPPGroupChatSOContainer extends ClientSOContainer implements } } - public IChatMessageSender getChatMessageSender() { - return new IChatMessageSender() { + public IChatRoomMessageSender getChatMessageSender() { + return new IChatRoomMessageSender() { public void sendMessage(String messageBody) throws ECFException { if (multiuserchat != null) { try { diff --git a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/container/XMPPPresenceSharedObject.java b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/container/XMPPPresenceSharedObject.java index 2b9b0fd1c..42aab9a9e 100644 --- a/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/container/XMPPPresenceSharedObject.java +++ b/providers/bundles/org.eclipse.ecf.provider.xmpp/src/org/eclipse/ecf/provider/xmpp/container/XMPPPresenceSharedObject.java @@ -38,12 +38,12 @@ import org.eclipse.ecf.presence.IAccountManager; import org.eclipse.ecf.presence.IMessageListener; import org.eclipse.ecf.presence.IPresence; import org.eclipse.ecf.presence.IPresenceListener; +import org.eclipse.ecf.presence.IPresenceSender; import org.eclipse.ecf.presence.IRosterEntry; import org.eclipse.ecf.presence.IRosterGroup; import org.eclipse.ecf.presence.IRosterSubscriptionListener; -import org.eclipse.ecf.presence.chat.IInvitationListener; +import org.eclipse.ecf.presence.chat.IChatRoomInvitationListener; import org.eclipse.ecf.presence.roster.AbstractRosterManager; -import org.eclipse.ecf.presence.roster.IPresenceSender; import org.eclipse.ecf.presence.roster.IRosterItem; import org.eclipse.ecf.presence.roster.IRosterManager; import org.eclipse.ecf.presence.roster.IRosterSubscriptionSender; @@ -84,12 +84,13 @@ public class XMPPPresenceSharedObject implements ISharedObject, IAccountManager Vector subscribeListeners = new Vector(); - Vector invitationListeners = new Vector(); - Namespace namespace = null; XMPPClientSOContainer container = null; + Vector invitationListeners = new Vector(); + + public XMPPPresenceSharedObject(XMPPClientSOContainer container) { this.container = container; } @@ -97,16 +98,16 @@ public class XMPPPresenceSharedObject implements ISharedObject, IAccountManager protected void fireInvitationReceived(ID roomID, ID fromID, ID toID, String subject, String body) { for (Iterator i = invitationListeners.iterator(); i.hasNext();) { - IInvitationListener l = (IInvitationListener) i.next(); + IChatRoomInvitationListener l = (IChatRoomInvitationListener) i.next(); l.handleInvitationReceived(roomID, fromID, subject, body); } } - protected void addInvitationListener(IInvitationListener listener) { + protected void addInvitationListener(IChatRoomInvitationListener listener) { invitationListeners.add(listener); } - protected void removeInvitationListener(IInvitationListener listener) { + protected void removeInvitationListener(IChatRoomInvitationListener listener) { invitationListeners.remove(listener); } @@ -176,8 +177,6 @@ public class XMPPPresenceSharedObject implements ISharedObject, IAccountManager public void dispose(ID containerID) { config = null; accountManager = null; - invitationListeners.clear(); - invitationListeners = null; } protected void dumpStack(String msg, Throwable e) { @@ -731,7 +730,7 @@ public class XMPPPresenceSharedObject implements ISharedObject, IAccountManager super(roster); } - public void notifySubscriptionListener(ID fromID, org.eclipse.ecf.presence.roster.IPresence presence) { + public void notifySubscriptionListener(ID fromID, org.eclipse.ecf.presence.IPresence presence) { super.fireSubscriptionListener(fromID, presence); } @@ -749,10 +748,10 @@ public class XMPPPresenceSharedObject implements ISharedObject, IAccountManager } // XXX Testing - protected org.eclipse.ecf.presence.roster.IPresence getPresenceState() { - return new org.eclipse.ecf.presence.roster.Presence( - org.eclipse.ecf.presence.roster.IPresence.Type.AVAILABLE, "available", - org.eclipse.ecf.presence.roster.IPresence.Mode.AVAILABLE); + protected org.eclipse.ecf.presence.IPresence getPresenceState() { + return new org.eclipse.ecf.presence.Presence( + org.eclipse.ecf.presence.IPresence.Type.AVAILABLE, "available", + org.eclipse.ecf.presence.IPresence.Mode.AVAILABLE); } public void setUser(IUser user) { @@ -763,7 +762,7 @@ public class XMPPPresenceSharedObject implements ISharedObject, IAccountManager org.eclipse.ecf.presence.roster.RosterGroup group1 = new org.eclipse.ecf.presence.roster.RosterGroup( getRoster(), "group1"); org.eclipse.ecf.presence.roster.RosterEntry entry1 = new org.eclipse.ecf.presence.roster.RosterEntry( - group1, (IUser) new User(createStringID("foo")), (org.eclipse.ecf.presence.roster.IPresence) getPresenceState()); + group1, (IUser) new User(createStringID("foo")), (org.eclipse.ecf.presence.IPresence) getPresenceState()); r.addItem(group1); // XXX end testing fireRosterUpdate(null); |