/* * History: Message subitem: * <x xmlns='jabber:x:delay' stamp='20120331T22:25:46' /> */ package xmpp.client.service.chat.multi; import java.util.ArrayList; import java.util.Iterator; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.muc.Occupant; import org.jivesoftware.smackx.muc.SubjectUpdatedListener; import xmpp.client.service.ConnectionProvider; import xmpp.client.service.chat.Chat; import xmpp.client.service.chat.InternalChatManager; import xmpp.client.service.user.User; import xmpp.client.service.user.UserService; import xmpp.client.service.user.UserServiceProvider; import android.util.Log; public class MultiChat extends Chat implements SubjectUpdatedListener, UserServiceProvider, ConnectionProvider { private static final String TAG = MultiChat.class.getName(); private org.jivesoftware.smackx.muc.MultiUserChat mMUC; private final MultiChatMessageListener mMessageListener; private final MultiChatParticipantListener mParticipantListener; private final InternalChatManager mInternalChatManager; private final MultiChatParticipantStatusListener mParticipantStatusListener; private final UserServiceProvider mUserServiceProvider; private final MultiChatInfo mMUCInfo; private final ConnectionProvider mConnectionProvider; private boolean mInitDone; public MultiChat(ConnectionProvider connectionProvider, MultiChatInfo mucinfo, InternalChatManager internalChatManager, UserServiceProvider userServiceProvider) { mConnectionProvider = connectionProvider; mMUCInfo = mucinfo; mUserServiceProvider = userServiceProvider; mInternalChatManager = internalChatManager; mMessageListener = new MultiChatMessageListener(this); mParticipantListener = new MultiChatParticipantListener(this); mParticipantStatusListener = new MultiChatParticipantStatusListener( this); mInitDone = false; } @Override public void close() { if (mMUC != null) { mMUC.leave(); mMUC.removeMessageListener(mMessageListener); mMUC = null; } } @Override public int getChatType() { return CHAT_MULTI; } @Override public XMPPConnection getConnection() { return mConnectionProvider.getConnection(); } @Override public String getIdentifier() { if (mMUC != null) { return mMUC.getRoom(); } else { return mMUCInfo.getJid(); } } @Override public String getSubject() { if (mMUC != null) { return mMUC.getSubject(); } else { return null; } } @Override public String getThreadID() { return getIdentifier(); } public ArrayList<String> getUsers() { final ArrayList<String> list = new ArrayList<String>(); if (mMUC != null) { for (final Iterator<String> iterator = mMUC.getOccupants(); iterator .hasNext();) { list.add(iterator.next()); } } return list; } @Override public UserService getUserService() { return mUserServiceProvider.getUserService(); } @Override public boolean init() { if (mInitDone) { return true; } mMUC = new org.jivesoftware.smackx.muc.MultiUserChat(getConnection(), mMUCInfo.getJid()); mMUC.addMessageListener(mMessageListener); mMUC.addParticipantListener(mParticipantListener); mMUC.addParticipantStatusListener(mParticipantStatusListener); mMUC.addSubjectUpdatedListener(this); try { if (mMUCInfo.getPassword() != null && !mMUCInfo.getPassword().isEmpty()) { mMUC.join(mMUCInfo.getNickname(), mMUCInfo.getPassword()); } else { mMUC.join(mMUCInfo.getNickname()); } mInitDone = true; return true; } catch (final XMPPException e) { return false; } } @Override public boolean isMe(String from) { if (StringUtils.parseResource(from).equalsIgnoreCase( mMUCInfo.getNickname())) { return true; } return false; } public void processMessage(MultiChat mChat, Message msg) { try { setupUser(msg.getFrom(), null); } catch (final Exception e) { Log.d(TAG, "setupUser", e); } mInternalChatManager.processMessage(mChat, msg); } public void processParticipantAdminGranted(String participant) { processStatusMessage(StringUtils.parseResource(participant) + " got Admin."); } public void processParticipantAdminRevoked(String participant) { processStatusMessage(StringUtils.parseResource(participant) + " lost Admin."); } public void processParticipantBanned(String participant, String actor, String reason) { processStatusMessage(StringUtils.parseResource(participant) + " banned " + StringUtils.parseResource(participant) + ((reason != null && !reason.isEmpty()) ? (" (Reason: " + reason + ")") : "") + "."); } public void processParticipantJoined(String participant) { processStatusMessage(StringUtils.parseResource(participant) + " joined."); final Presence presence = new Presence(Presence.Type.available, null, 0, null); presence.setFrom(getIdentifier() + "/" + participant); processParticipantPresence(presence); } public void processParticipantKicked(String participant, String actor, String reason) { processStatusMessage(StringUtils.parseResource(participant) + " kicked " + StringUtils.parseResource(participant) + ((reason != null && !reason.isEmpty()) ? (" (Reason: " + reason + ")") : "") + "."); } public void processParticipantLeft(String participant) { processStatusMessage(StringUtils.parseResource(participant) + " left."); final Presence presence = new Presence(Presence.Type.unavailable, null, 0, null); presence.setFrom(getIdentifier() + "/" + participant); processParticipantPresence(presence); } public void processParticipantMembershipGranted(String participant) { processStatusMessage(StringUtils.parseResource(participant) + " got Membership."); } public void processParticipantMembershipRevoked(String participant) { processStatusMessage(StringUtils.parseResource(participant) + " lost Membership."); } public void processParticipantModeratorGranted(String participant) { processStatusMessage(StringUtils.parseResource(participant) + " got Moderator."); } public void processParticipantModeratorRevoked(String participant) { processStatusMessage(StringUtils.parseResource(participant) + " lost Moderator."); } public void processParticipantNicknameChanged(String participant, String newNickname) { processStatusMessage(StringUtils.parseResource(participant) + " changed Nickname to " + newNickname + "."); } public void processParticipantOwnershipGranted(String participant) { processStatusMessage(StringUtils.parseResource(participant) + " got Ownership."); } public void processParticipantOwnershipRevoked(String participant) { processStatusMessage(StringUtils.parseResource(participant) + " lost Ownership."); } public void processParticipantPresence(Presence presence) { if (getUserService().getUserByFullUserLogin(presence.getFrom()) == null) { setupUser(presence.getFrom(), presence); } else { getUserService().presenceChanged(presence); } } public void processParticipantVoiceGranted(String participant) { processStatusMessage(StringUtils.parseResource(participant) + " got Voice."); } public void processParticipantVoiceRevoked(String participant) { processStatusMessage(StringUtils.parseResource(participant) + " lost Voice."); } private void processStatusMessage(String msg) { final Message message = new Message(); message.setFrom(getIdentifier()); message.setBody(msg); processMessage(this, message); } @Override public void sendMessage(String participant, String text) { if (participant.equals(getIdentifier())) { try { mMUC.sendMessage(text); } catch (final XMPPException e) { throw new RuntimeException(e); } } } private User setupUser(String participant, Presence presence) { try { if (isMe(participant)) { return getUserService().getUserMe(); } participant = StringUtils.parseResource(participant); if (presence == null) { presence = mMUC.getOccupantPresence(participant); } final Occupant occupant = mMUC.getOccupant(participant); final ArrayList<String> info = new ArrayList<String>(); if (occupant != null) { info.add(0, occupant.getJid()); info.add(1, occupant.getAffiliation()); info.add(2, occupant.getRole()); } if (presence != null) { return getUserService().setupUser( new User(getIdentifier(), participant, info, presence)); } else { return getUserService().setupUser( new User(getIdentifier(), participant, info, new Presence(Presence.Type.unavailable))); } } catch (final Exception e) { Log.d(TAG, "setupUser", e); } return null; } @Override public void subjectUpdated(String subject, String from) { mInternalChatManager.chatUpdated(this); } }