Package org.eclipse.ecf.internal.provider.xmpp

Source Code of org.eclipse.ecf.internal.provider.xmpp.XMPPChatRoomContainer

/*******************************************************************************
* 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.internal.provider.xmpp;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

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.events.ChatMembershipEvent;
import org.eclipse.ecf.internal.provider.xmpp.events.IQEvent;
import org.eclipse.ecf.internal.provider.xmpp.events.MessageEvent;
import org.eclipse.ecf.internal.provider.xmpp.events.PresenceEvent;
import org.eclipse.ecf.internal.provider.xmpp.smack.ECFConnection;
import org.eclipse.ecf.presence.IIMMessageListener;
import org.eclipse.ecf.presence.chatroom.IChatRoomAdminListener;
import org.eclipse.ecf.presence.chatroom.IChatRoomAdminSender;
import org.eclipse.ecf.presence.chatroom.IChatRoomContainer;
import org.eclipse.ecf.presence.chatroom.IChatRoomMessageSender;
import org.eclipse.ecf.presence.chatroom.IChatRoomParticipantListener;
import org.eclipse.ecf.presence.im.IChatMessageSender;
import org.eclipse.ecf.presence.im.IChatMessage.Type;
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.XMPPContainer;
import org.eclipse.ecf.provider.xmpp.identity.XMPPRoomID;
import org.eclipse.osgi.util.NLS;
import org.jivesoftware.smack.PacketListener;
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.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;
import org.jivesoftware.smackx.muc.SubjectUpdatedListener;

public class XMPPChatRoomContainer extends ClientSOContainer implements IChatRoomContainer {

  private static final String CONTAINER_HELPER_ID = XMPPContainer.class.getName() + ".xmppgroupchathandler"; //$NON-NLS-1$

  private ID containerHelperID;

  private XMPPChatRoomContainerHelper containerHelper;

  private MultiUserChat multiuserchat;

  private List chatRoomAdminListeners;

  private IChatRoomAdminSender chatRoomAdminSender;

  public XMPPChatRoomContainer(ISharedObjectContainerConfig config, ECFConnection conn, Namespace usernamespace) throws IDCreateException {
    super(config);
    this.connection = conn;
    this.config = config;
    this.containerHelperID = IDFactory.getDefault().createStringID(CONTAINER_HELPER_ID);
    this.containerHelper = new XMPPChatRoomContainerHelper(usernamespace, getXMPPConnection());
    this.chatRoomAdminListeners = new ArrayList();
  }

  protected void sendInvitation(ID toUser, String subject, String body) throws ECFException {
    if (toUser == null)
      throw new ECFException(Messages.XMPPChatRoomContainer_EXCEPTION_TARGET_USER_NOT_NULL);
    synchronized (getConnectLock()) {
      if (multiuserchat == null)
        throw new ContainerConnectException(Messages.XMPPChatRoomContainer_EXCEPTION_NOT_CONNECTED);
      multiuserchat.invite(toUser.getName(), (body == null) ? "" : body); //$NON-NLS-1$
    }
  }

  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;
    if (chatRoomAdminListeners != null)
      chatRoomAdminListeners.clear();
    chatRoomAdminListeners = null;
    super.dispose();
  }

  protected void sendMessage(ContainerMessage data) throws IOException {
    synchronized (getConnectLock()) {
      final ID toID = data.getToContainerID();
      if (toID == null) {
        data.setToContainerID(remoteServerID);
      }
      super.sendMessage(data);
    }
  }

  protected void handleChatMessage(Message mess) throws IOException {
    final SOWrapper wrap = getSharedObjectWrapper(containerHelperID);
    if (wrap != null) {
      wrap.deliverEvent(new MessageEvent(mess));
    }
  }

  protected boolean verifyToIDForSharedObjectMessage(ID toID) {
    return true;
  }

  public void handleContainerMessage(ContainerMessage mess) throws IOException {
    if (mess == null) {
      debug("got null container message...ignoring"); //$NON-NLS-1$
      return;
    }
    final 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); //$NON-NLS-1$
    }
  }

  protected void handleIQMessage(IQ mess) throws IOException {
    final SOWrapper wrap = getSharedObjectWrapper(containerHelperID);
    if (wrap != null) {
      wrap.deliverEvent(new IQEvent(mess));
    }
  }

  protected void handlePresenceMessage(Presence mess) throws IOException {
    final SOWrapper wrap = getSharedObjectWrapper(containerHelperID);
    if (wrap != null) {
      wrap.deliverEvent(new PresenceEvent(mess));
    }
  }

  protected void handleChatMembershipEvent(String from, boolean add) {
    final 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); //$NON-NLS-1$
      }
    } catch (final IOException e) {
      traceStack("Exception in handleXMPPMessage", e); //$NON-NLS-1$
    }
  }

  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(NLS.bind(Messages.XMPPChatRoomContainer_Exception_Connect_Wrong_Type, remote));
    }
    final 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 {
          final Callback[] callbacks = new Callback[1];
          callbacks[0] = new NameCallback(Messages.XMPPChatRoomContainer_NAME_CALLBACK_NICK, roomID.getNickname());
          if (connectContext != null) {
            final CallbackHandler handler = connectContext.getCallbackHandler();
            if (handler != null) {
              handler.handle(callbacks);
            }
          }
          if (callbacks[0] instanceof NameCallback) {
            final NameCallback cb = (NameCallback) callbacks[0];
            nick = cb.getName();
          }
        } catch (final Exception e) {
          throw new ContainerConnectException(Messages.XMPPChatRoomContainer_EXCEPTION_CALLBACKHANDLER, e);
        }
        String nickname = null;
        if (nick == null || nick.equals("")) //$NON-NLS-1$
          nickname = roomID.getNickname();
        else
          nickname = nick;
        multiuserchat.addSubjectUpdatedListener(new SubjectUpdatedListener() {
          public void subjectUpdated(String subject, String from) {
            fireSubjectUpdated(subject, from);
          }
        });

        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 + ")"); //$NON-NLS-1$ //$NON-NLS-2$
          }

          public void voiceRevoked(String arg0) {
            // TODO Auto-generated method stub
            System.out.println("voiceRevoked(" + arg0 + ")"); //$NON-NLS-1$ //$NON-NLS-2$
          }

          public void membershipGranted(String arg0) {
            // TODO Auto-generated method stub
            System.out.println("membershipGranted(" + arg0 //$NON-NLS-1$
                + ")"); //$NON-NLS-1$
          }

          public void membershipRevoked(String arg0) {
            // TODO Auto-generated method stub
            System.out.println("membershipRevoked(" + arg0 //$NON-NLS-1$
                + ")"); //$NON-NLS-1$
          }

          public void moderatorGranted(String arg0) {
            // TODO Auto-generated method stub
            System.out.println("moderatorGranted(" + arg0 //$NON-NLS-1$
                + ")"); //$NON-NLS-1$
          }

          public void moderatorRevoked(String arg0) {
            // TODO Auto-generated method stub
            System.out.println("moderatorRevoked(" + arg0 //$NON-NLS-1$
                + ")"); //$NON-NLS-1$
          }

          public void ownershipGranted(String arg0) {
            // TODO Auto-generated method stub
            System.out.println("ownershipGranted(" + arg0 //$NON-NLS-1$
                + ")"); //$NON-NLS-1$
          }

          public void ownershipRevoked(String arg0) {
            // TODO Auto-generated method stub
            System.out.println("ownershipRevoked(" + arg0 //$NON-NLS-1$
                + ")"); //$NON-NLS-1$
          }

          public void adminGranted(String arg0) {
            // TODO Auto-generated method stub
            System.out.println("adminGranted(" + arg0 + ")"); //$NON-NLS-1$ //$NON-NLS-2$
          }

          public void adminRevoked(String arg0) {
            // TODO Auto-generated method stub
            System.out.println("adminRevoked(" + arg0 + ")"); //$NON-NLS-1$ //$NON-NLS-2$
          }

          public void kicked(String arg0, String arg1, String arg2) {
            // TODO Auto-generated method stub
            System.out.println("kicked(" + arg0 + "," //$NON-NLS-1$ //$NON-NLS-2$
                + arg1 + "," + arg2 + ")"); //$NON-NLS-1$ //$NON-NLS-2$

          }

          public void banned(String arg0, String arg1, String arg2) {
            // TODO Auto-generated method stub
            System.out.println("banned(" + arg0 + "," //$NON-NLS-1$ //$NON-NLS-2$
                + arg1 + "," + arg2 + ")"); //$NON-NLS-1$ //$NON-NLS-2$

          }

          public void nicknameChanged(String arg0, String arg1) {
            // TODO Auto-generated method stub
            System.out.println("nicknameChanged(" + arg0 //$NON-NLS-1$
                + "," + arg1 + ")"); //$NON-NLS-1$ //$NON-NLS-2$

          }
        });
        multiuserchat.addInvitationRejectionListener(new InvitationRejectionListener() {
          public void invitationDeclined(String arg0, String arg1) {
            // TODO Auto-generated method stub
            System.out.println("invitationDeclined(" + arg0 //$NON-NLS-1$
                + "," + arg1 + ")"); //$NON-NLS-1$ //$NON-NLS-2$
          }
        });
        multiuserchat.join(nickname);
        connectionState = CONNECTED;
        remoteServerID = roomID;
        containerHelper.setRoomID(remoteServerID);
        fireContainerEvent(new ContainerConnectedEvent(this.getID(), roomID));
      } catch (final Exception e) {
        cleanUpConnectFail();
        final ContainerConnectException ce = new ContainerConnectException(NLS.bind(Messages.XMPPChatRoomContainer_EXCEPTION_JOINING_ROOM, roomID));
        ce.setStackTrace(e.getStackTrace());
        throw ce;
      }
    }
  }

  /**
   * @param subject
   * @param from
   */
  protected void fireSubjectUpdated(String subject, String from) {
    List notify = null;
    synchronized (chatRoomAdminListeners) {
      notify = new ArrayList(chatRoomAdminListeners);
    }
    for (final Iterator i = notify.iterator(); i.hasNext();) {
      final IChatRoomAdminListener l = (IChatRoomAdminListener) i.next();
      l.handleSubjectChange(containerHelper.createUserIDFromName(from), subject);
    }
  }

  public void disconnect() {
    final ID groupID = getConnectedID();
    fireContainerEvent(new ContainerDisconnectingEvent(this.getID(), groupID));
    synchronized (getConnectLock()) {
      // If we are currently connected
      if (isConnected()) {
        try {
          multiuserchat.leave();
        } catch (final Exception e) {
          traceStack("Exception in multi user chat.leave", e); //$NON-NLS-1$
        }
      }
      connectionState = DISCONNECTED;
      remoteServerID = null;
      if (containerHelper != null)
        containerHelper.disconnect();
      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();
    final int atIndex = username.indexOf('@');
    if (atIndex > 0)
      username = username.substring(0, atIndex);
    final String host = getXMPPConnection().getHost();
    final Namespace ns = getConnectNamespace();
    final 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;
  }

  IChatMessageSender privateSender = new IChatMessageSender() {
    public void sendChatMessage(ID toID, ID threadID, Type type, String subject, String body, Map properties) throws ECFException {
      // TODO Auto-generated method stub
    }

    public void sendChatMessage(ID toID, String body) throws ECFException {
      // TODO Auto-generated method stub
    }

  };

  public IChatMessageSender getPrivateMessageSender() {
    return privateSender;
  }

  public IChatRoomMessageSender getChatRoomMessageSender() {
    return new IChatRoomMessageSender() {
      public void sendMessage(String messageBody) throws ECFException {
        if (multiuserchat != null) {
          try {
            multiuserchat.sendMessage(messageBody);
          } catch (final Exception e) {
            final ECFException except = new ECFException(Messages.XMPPChatRoomContainer_EXCEPTION_SEND_MESSAGE, e);
            throw except;
          }
        }
      }
    };
  }

  public void connect(String groupName) throws ContainerConnectException {
    ID targetID = null;
    try {
      targetID = createChatRoomID(groupName);
    } catch (final IDCreateException e) {
      throw new ContainerConnectException(Messages.XMPPChatRoomContainer_EXCEPTION_CREATING_ROOM_ID, e);
    }
    this.connect(targetID, null);
  }

  public void addChatRoomParticipantListener(IChatRoomParticipantListener participantListener) {
    if (containerHelper != null) {
      containerHelper.addChatParticipantListener(participantListener);
    }
  }

  public void removeChatRoomParticipantListener(IChatRoomParticipantListener participantListener) {
    if (containerHelper != null) {
      containerHelper.removeChatParticipantListener(participantListener);
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ecf.presence.chatroom.IChatRoomContainer#addMessageListener(org.eclipse.ecf.presence.IIMMessageListener)
   */
  public void addMessageListener(IIMMessageListener listener) {
    containerHelper.addChatRoomMessageListener(listener);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ecf.presence.chatroom.IChatRoomContainer#removeMessageListener(org.eclipse.ecf.presence.IIMMessageListener)
   */
  public void removeMessageListener(IIMMessageListener listener) {
    containerHelper.removeChatRoomMessageListener(listener);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ecf.presence.chatroom.IChatRoomContainer#addChatRoomSubjectListener(org.eclipse.ecf.presence.chatroom.IChatRoomAdminListener)
   */
  public void addChatRoomAdminListener(IChatRoomAdminListener subjectListener) {
    if (subjectListener == null)
      return;
    chatRoomAdminListeners.add(subjectListener);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ecf.presence.chatroom.IChatRoomContainer#removeChatRoomSubjectListener(org.eclipse.ecf.presence.chatroom.IChatRoomAdminListener)
   */
  public void removeChatRoomAdminListener(IChatRoomAdminListener subjectListener) {
    if (subjectListener == null)
      return;
    chatRoomAdminListeners.remove(subjectListener);
  }

  /* (non-Javadoc)
   * @see org.eclipse.ecf.presence.chatroom.IChatRoomContainer#getChatRoomParticipants()
   */
  public ID[] getChatRoomParticipants() {
    return containerHelper.getChatRoomParticipants();
  }

  /* (non-Javadoc)
   * @see org.eclipse.ecf.presence.chatroom.IChatRoomContainer#getChatRoomAdminSender()
   */
  public IChatRoomAdminSender getChatRoomAdminSender() {
    synchronized (this) {
      if (chatRoomAdminSender == null) {
        chatRoomAdminSender = new IChatRoomAdminSender() {
          public void sendSubjectChange(String newsubject) throws ECFException {
            if (multiuserchat == null)
              throw new ECFException(Messages.XMPPChatRoomContainer_EXCEPTION_NOT_CONNECTED);
            try {
              multiuserchat.changeSubject(newsubject);
            } catch (final XMPPException e) {
              throw new ECFException(e);
            }
          }

        };
      }
    }
    return chatRoomAdminSender;
  }
}
TOP

Related Classes of org.eclipse.ecf.internal.provider.xmpp.XMPPChatRoomContainer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.