diff options
Diffstat (limited to 'src/com/isode/stroke/muc/MUC.java')
-rw-r--r-- | src/com/isode/stroke/muc/MUC.java | 682 |
1 files changed, 70 insertions, 612 deletions
diff --git a/src/com/isode/stroke/muc/MUC.java b/src/com/isode/stroke/muc/MUC.java index ed3c34a..9806e34 100644 --- a/src/com/isode/stroke/muc/MUC.java +++ b/src/com/isode/stroke/muc/MUC.java @@ -1,7 +1,14 @@ /* - * Copyright (c) 2010-2015, Isode Limited, London, England. + * Copyright (c) 2010-2014 Isode Limited. * All rights reserved. + * See the COPYING file for more information. */ +/* + * Copyright (c) 2015 Tarun Gupta. + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + package com.isode.stroke.muc; import java.util.Collections; @@ -37,614 +44,65 @@ import com.isode.stroke.signals.SignalConnection; import com.isode.stroke.signals.Slot1; import com.isode.stroke.signals.Slot2; -/** - * Class representing multi user chat room - * - */ -public class MUC { - - public enum JoinResult { JoinFailed, JoinSucceeded }; - public enum LeavingType { Disconnect, LeaveBan, LeaveDestroy, LeaveKick, LeaveNotMember, LeavePart }; - - public Signal3<ErrorPayload,JID, MUCOccupant.Affiliation> onAffiliationChangeFailed = - new Signal3<ErrorPayload,JID, MUCOccupant.Affiliation>(); - public Signal1<ErrorPayload> onAffiliationListFailed = new Signal1<ErrorPayload>(); - public Signal2<MUCOccupant.Affiliation, Vector<JID>> onAffiliationListReceived = - new Signal2<MUCOccupant.Affiliation, Vector<JID>>(); - public Signal1<ErrorPayload> onConfigurationFailed = new Signal1<ErrorPayload>(); - public Signal1<Form> onConfigurationFormReceived = new Signal1<Form>(); - public Signal1<String> onJoinComplete = new Signal1<String>(); - public Signal1<ErrorPayload> onJoinFailed = new Signal1<ErrorPayload>(); - public Signal3<String, MUCOccupant.Affiliation, MUCOccupant.Affiliation> onOccupantAffiliationChanged = - new Signal3<String, MUCOccupant.Affiliation, MUCOccupant.Affiliation>(); - public Signal1<MUCOccupant> onOccupantJoined = new Signal1<MUCOccupant>(); - - public Signal3<MUCOccupant, LeavingType, String> onOccupantLeft = - new Signal3<MUCOccupant, LeavingType, String>(); - public Signal1<Presence> onOccupantPresenceChange = new Signal1<Presence>(); - public Signal3<String, MUCOccupant, MUCOccupant.Role> onOccupantRoleChanged = - new Signal3<String, MUCOccupant, MUCOccupant.Role>(); - - public Signal3<ErrorPayload,JID,MUCOccupant.Role> onRoleChangeFailed = - new Signal3<ErrorPayload,JID,MUCOccupant.Role>(); - - public final Signal onUnlocked = new Signal(); - - private boolean createAsReservedIfNew; - private IQRouter iqRouter_; - private boolean joinComplete_; - private Date joinSince_; - private boolean joinSucceeded_; - private MUCRegistry mucRegistry; - private Map<String, MUCOccupant> occupants = new HashMap<String, MUCOccupant>(); - private JID ownMUCJID; - private String password; - private DirectedPresenceSender presenceSender; - private StanzaChannel stanzaChannel; - private boolean unlocking; - private SignalConnection signalPresRcvd; - - /** - * Create a MUC Session - * @param stanzaChannel stanza channel, not null - * @param iqRouter IQ stanza router, not null - * @param presenceSender Presence Sender, not null - * @param muc JID of the chat room, not null - * @param mucRegistry MUC registry, not null - * - * @see #disconnect() - */ - public MUC(StanzaChannel stanzaChannel, IQRouter iqRouter, - DirectedPresenceSender presenceSender, final JID muc, - MUCRegistry mucRegistry) { - ownMUCJID = muc; - this.stanzaChannel = stanzaChannel; - this.iqRouter_ = iqRouter; - this.presenceSender = presenceSender; - this.mucRegistry = mucRegistry; - this.createAsReservedIfNew = false; - this.unlocking = false; - signalPresRcvd = this.stanzaChannel.onPresenceReceived.connect( - new Slot1<Presence>() { - @Override - public void call(Presence p1) { - handleIncomingPresence(p1); - } - }); - } - - /** - * Cancel the command for configuring room - */ - public void cancelConfigureRoom() { - MUCOwnerPayload mucPayload = new MUCOwnerPayload(); - mucPayload.setPayload(new Form(Form.Type.CANCEL_TYPE)); - GenericRequest<MUCOwnerPayload> request = new GenericRequest<MUCOwnerPayload>( - IQ.Type.Set, getJID(), mucPayload, iqRouter_); - request.send(); - } - - /** - * Change the affiliation of the given Jabber ID. - * It must be called with the real JID, not the room JID. - * @param jid real jabber ID, not null - * @param affiliation new affiliation, not null - */ - public void changeAffiliation(final JID jid, final MUCOccupant.Affiliation affiliation) { - final MUCAdminPayload mucPayload = new MUCAdminPayload(); - MUCItem item = new MUCItem(); - item.affiliation = affiliation; - item.realJID = jid.toBare(); - mucPayload.addItem(item); - GenericRequest<MUCAdminPayload> request = new GenericRequest<MUCAdminPayload>( - IQ.Type.Set, getJID(), mucPayload, iqRouter_); - request.onResponse.connect(new Slot2<MUCAdminPayload, ErrorPayload>() { - @Override - public void call(MUCAdminPayload p1, ErrorPayload p2) { - handleAffiliationChangeResponse(mucPayload,p2,jid,affiliation); - } - }); - request.send(); - } - - /** - * Change the role of the specified occupant. It must be - * called with the room JID, not the real JID. - * @param jid Jabber ID of the occupant in the chat room, not null - * @param role new role, not null - */ - public void changeOccupantRole(final JID jid, final MUCOccupant.Role role) { - final MUCAdminPayload mucPayload = new MUCAdminPayload(); - MUCItem item = new MUCItem(); - item.role = role; - item.nick = jid.getResource(); - mucPayload.addItem(item); - GenericRequest<MUCAdminPayload> request = new GenericRequest<MUCAdminPayload>( - IQ.Type.Set, getJID(), mucPayload, iqRouter_); - request.onResponse.connect(new Slot2<MUCAdminPayload, ErrorPayload>() { - @Override - public void call(MUCAdminPayload p1, ErrorPayload p2) { - handleOccupantRoleChangeResponse(mucPayload,p2,jid,role); - } - }); - request.send(); - } - - /** - * Change the subject of the chat room - * @param subject new subject, not null - */ - public void changeSubject(String subject) { - Message message = new Message(); - message.setSubject(subject); - message.setType(Message.Type.Groupchat); - message.setTo(ownMUCJID.toBare()); - stanzaChannel.sendMessage(message); - } - - /** - * Configure a chat room room - * @param form form to be used for configuration, not null - */ - public void configureRoom(Form form) { - MUCOwnerPayload mucPayload = new MUCOwnerPayload(); - mucPayload.setPayload(form); - GenericRequest<MUCOwnerPayload> request = new GenericRequest<MUCOwnerPayload>( - IQ.Type.Set, getJID(), mucPayload, iqRouter_); - if (unlocking) { - request.onResponse.connect(new Slot2<MUCOwnerPayload, ErrorPayload>() { - @Override - public void call(MUCOwnerPayload p1, ErrorPayload p2) { - handleCreationConfigResponse(p1, p2); - } - }); - }else { - request.onResponse.connect(new Slot2<MUCOwnerPayload, ErrorPayload>() { - @Override - public void call(MUCOwnerPayload p1, ErrorPayload p2) { - handleConfigurationResultReceived(p1, p2); - } - }); - } - request.send(); - } - - /** - * Destroy the chat room - */ - public void destroyRoom() { - MUCOwnerPayload mucPayload = new MUCOwnerPayload(); - MUCDestroyPayload mucDestroyPayload = new MUCDestroyPayload(); - mucPayload.setPayload(mucDestroyPayload); - GenericRequest<MUCOwnerPayload> request = new GenericRequest<MUCOwnerPayload>( - IQ.Type.Set, getJID(), mucPayload, iqRouter_); - request.onResponse.connect(new Slot2<MUCOwnerPayload, ErrorPayload>() { - @Override - public void call(MUCOwnerPayload p1, ErrorPayload p2) { - handleConfigurationResultReceived(p1,p2); - } - }); - request.send(); - } - - /** - * Returns the (bare) JID of the MUC. - * @return bare JID(i.e. without resource) - */ - public JID getJID() { - return ownMUCJID.toBare(); - } - - /** - * Get the MUC occupant with the given nick name - * @param nick nick name, not null - * @return MUC occupant if it exists or null if not - */ - public MUCOccupant getOccupant(String nick) { - return occupants.get(nick); - } - - /** - * Determine if the room contains occupant with given nick - * @param nick given nick - * @return true if the occupant exists, false otherwise - */ - public boolean hasOccupant(String nick) { - return occupants.containsKey(nick); - } - - public Map<String, MUCOccupant> getOccupants() { - return Collections.unmodifiableMap(occupants); - } - - /** - * Invite the person with give JID to the chat room - * @param person jabber ID o the person to invite,not nul - */ - public void invitePerson(JID person) { - invitePerson(person, "", false, false); - } - - /** - * Send an invite for the person to join the MUC - * @param person jabber ID of the person to invite, not null - * @param reason join reason, not null - * @param isImpromptu - */ - public void invitePerson(JID person, String reason, boolean isImpromptu) { - invitePerson(person, reason, isImpromptu, false); - } - - - /** - * Send an invite for the person to join the MUC - * @param person jabber ID of the person to invite, not null - * @param reason join reason, not null - * @param isImpromptu - * @param isReuseChat - */ - public void invitePerson(JID person, String reason, boolean isImpromptu, boolean isReuseChat) { - Message message = new Message(); - message.setTo(person); - message.setType(Message.Type.Normal); - MUCInvitationPayload invite = new MUCInvitationPayload(); - invite.setReason(reason); - invite.setIsImpromptu(isImpromptu); - invite.setIsContinuation(isReuseChat); - invite.setJID(ownMUCJID.toBare()); - message.addPayload(invite); - stanzaChannel.sendMessage(message); - } - - /** - * Join the MUC with default context. - * @param nick nick name of the user, not null - */ - public void joinAs(String nick) { - joinSince_ = null; - internalJoin(nick); - } - - /** - * Join the MUC with context since date. - * @param nick nick name, not null - * @param since date since the nick joined, not null - */ - public void joinWithContextSince(String nick, Date since) { - joinSince_ = since; - internalJoin(nick); - } - - /** - * Kick the given occupant out of the chat room - * @param jid jabber ID of the user to kick, not null - */ - public void kickOccupant(JID jid) { - changeOccupantRole(jid, MUCOccupant.Role.NoRole); - } - - /** - * Leave the chat room - */ - public void part() { - presenceSender.removeDirectedPresenceReceiver(ownMUCJID, - DirectedPresenceSender.SendPresence.AndSendPresence); - mucRegistry.removeMUC(getJID()); - } - - /** - * Send a request to get a list of users for the given affiliation - * @param affiliation affiliation, not null - */ - public void requestAffiliationList(final MUCOccupant.Affiliation affiliation) { - MUCAdminPayload mucPayload = new MUCAdminPayload(); - MUCItem item = new MUCItem(); - item.affiliation = affiliation; - mucPayload.addItem(item); - GenericRequest<MUCAdminPayload> request = new GenericRequest<MUCAdminPayload>( - IQ.Type.Get, getJID(), mucPayload, iqRouter_); - request.onResponse.connect(new Slot2<MUCAdminPayload, ErrorPayload>() { - @Override - public void call(MUCAdminPayload p1, ErrorPayload p2) { - handleAffiliationListResponse(p1,p2,affiliation); - } - }); - request.send(); - } - - /** - * Send a request for getting form for configuring a room - */ - public void requestConfigurationForm() { - MUCOwnerPayload mucPayload = new MUCOwnerPayload(); - GenericRequest<MUCOwnerPayload> request = new GenericRequest<MUCOwnerPayload>( - IQ.Type.Get, getJID(), mucPayload, iqRouter_); - request.onResponse.connect(new Slot2<MUCOwnerPayload, ErrorPayload>() { - @Override - public void call(MUCOwnerPayload p1, ErrorPayload p2) { - handleConfigurationFormReceived(p1,p2); - } - }); - request.send(); - } - - /** - * Set the reserved status of room to true. - * By default a new room with the default configuration is created. - * The effect of calling this function is to leave the room in reserved state - * but not configured so that it can be configured later. - */ - public void setCreateAsReservedIfNew() { - createAsReservedIfNew = true; - } - - /** - * Set the password used for entering the room. - * @param newPassword password, can be null - */ - public void setPassword(String newPassword) { - password = newPassword; - } - - /** - * Get the nick name of the MUC room - * @return nick name, can be null - */ - private String getOwnNick() { - return ownMUCJID.getResource(); - } - - private void handleAffiliationChangeResponse(MUCAdminPayload ref, - ErrorPayload error, JID jid, MUCOccupant.Affiliation affiliation) { - if (error != null) { - onAffiliationChangeFailed.emit(error, jid, affiliation); - } - } - - private void handleAffiliationListResponse(MUCAdminPayload payload, - ErrorPayload error, MUCOccupant.Affiliation affiliation) { - if (error != null) { - onAffiliationListFailed.emit(error); - } else { - Vector<JID> jids = new Vector<JID>(); - for (MUCItem item : payload.getItems()) { - if (item.realJID != null) { - jids.add(item.realJID); - } - } - onAffiliationListReceived.emit(affiliation, jids); - } - } - - private void handleConfigurationFormReceived(MUCOwnerPayload payload, - ErrorPayload error) { - Form form = null; - if (payload != null) { - form = payload.getForm(); - } - if (error != null || form == null) { - onConfigurationFailed.emit(error); - } else { - onConfigurationFormReceived.emit(form); - } - } - - private void handleConfigurationResultReceived( - MUCOwnerPayload payload, ErrorPayload error) { - if (error != null) { - onConfigurationFailed.emit(error); - } - } - - private void handleCreationConfigResponse(MUCOwnerPayload ref , ErrorPayload error) { - unlocking = false; - if (error != null) { - presenceSender.removeDirectedPresenceReceiver(ownMUCJID, - DirectedPresenceSender.SendPresence.AndSendPresence); - onJoinFailed.emit(error); - } else { - onJoinComplete.emit(getOwnNick()); /* Previously, this wasn't needed here, - as the presence duplication bug caused an emit elsewhere. */ - } - } - - private void handleIncomingPresence(Presence presence) { - if (!isFromMUC(presence.getFrom())) { - return; - } - - MUCUserPayload mucPayload = null; - - MUCUserPayload dummyUserPayload = new MUCUserPayload(); - for (MUCUserPayload payload : presence.getPayloads(dummyUserPayload)) { - if (!payload.getItems().isEmpty() || !payload.getStatusCodes().isEmpty()) { - mucPayload = payload; - } - } - - // On the first incoming presence, check if our join has succeeded - // (i.e. we start getting non-error presence from the MUC) or not - if (!joinSucceeded_) { - if(presence.getType() == Presence.Type.Error) { - onJoinFailed.emit(presence.getPayload(new ErrorPayload())); - return; - } else { - joinSucceeded_ = true; - presenceSender.addDirectedPresenceReceiver(ownMUCJID, - DirectedPresenceSender.SendPresence.AndSendPresence); - } - } - - String nick = presence.getFrom().getResource(); - if (nick == null || nick.isEmpty()) { - return; - } - MUCOccupant.Role role = MUCOccupant.Role.NoRole; - MUCOccupant.Affiliation affiliation= MUCOccupant.Affiliation.NoAffiliation; - JID realJID = null; - if (mucPayload != null && mucPayload.getItems().size() > 0) { - role = mucPayload.getItems().get(0).role != null - ? mucPayload.getItems().get(0).role : MUCOccupant.Role.NoRole; - affiliation = mucPayload.getItems().get(0).affiliation != null - ? mucPayload.getItems().get(0).affiliation : MUCOccupant.Affiliation.NoAffiliation; - realJID = mucPayload.getItems().get(0).realJID; - } - - //100 is non-anonymous - //TODO: 100 may also be specified in a <message/> - //170 is room logging to http - //TODO: Nick changes - - if (presence.getType() == Presence.Type.Unavailable) { - LeavingType type = LeavingType.LeavePart; - if (mucPayload != null) { - if (mucPayload.getPayload() instanceof MUCDestroyPayload) { - type = LeavingType.LeaveDestroy; - } else for (MUCUserPayload.StatusCode status : mucPayload.getStatusCodes()) { - if (status.code == 307) { - type = LeavingType.LeaveKick; - } else if (status.code == 301) { - type = LeavingType.LeaveBan; - } else if (status.code == 321) { - type = LeavingType.LeaveNotMember; - } - } - } - - if (presence.getFrom().equals(ownMUCJID)) { - handleUserLeft(type); - return; - }else { - if (occupants.containsKey(nick)) { - //TODO: part type - onOccupantLeft.emit(occupants.get(nick), type, ""); - occupants.remove(nick); - } - } - } else if (presence.getType() == Presence.Type.Available) { - MUCOccupant occupant = new MUCOccupant(nick, role, affiliation); - boolean isJoin = true; - if (realJID != null) { - occupant.setRealJID(realJID); - } - if (occupants.containsKey(nick)) { - isJoin = false; - MUCOccupant oldOccupant = occupants.get(nick); - if (oldOccupant.getRole() != role) { - onOccupantRoleChanged.emit(nick, occupant, oldOccupant.getRole()); - } - if (oldOccupant.getAffiliation() != affiliation) { - onOccupantAffiliationChanged.emit(nick, affiliation, oldOccupant.getAffiliation()); - } - occupants.remove(nick); - } - occupants.put(nick, occupant); - - if (isJoin) { - onOccupantJoined.emit(occupant); - } - onOccupantPresenceChange.emit(presence); - } - - if (mucPayload != null && !joinComplete_) { - for (MUCUserPayload.StatusCode status : mucPayload.getStatusCodes()) { - if(status.code == 110) { - /* Simply knowing this is your presence is enough, 210 doesn't seem to be necessary. */ - joinComplete_ = true; - if (!ownMUCJID.equals(presence.getFrom())) { - presenceSender.removeDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender.SendPresence.DontSendPresence); - ownMUCJID = presence.getFrom(); - presenceSender.addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender.SendPresence.AndSendPresence); - } - onJoinComplete.emit(getOwnNick()); - } - if (status.code == 201) { - /* Room is created and locked */ - /* Currently deal with this by making an instant room */ - if (!ownMUCJID.equals(presence.getFrom())) { - presenceSender.removeDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender.SendPresence.DontSendPresence); - ownMUCJID = presence.getFrom(); - presenceSender.addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender.SendPresence.AndSendPresence); - } - if (createAsReservedIfNew) { - unlocking = true; - requestConfigurationForm(); - } else { - MUCOwnerPayload mucOwnerPayload = new MUCOwnerPayload(); - presenceSender.addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender.SendPresence.DontSendPresence); - mucOwnerPayload.setPayload(new Form(Form.Type.SUBMIT_TYPE)); - GenericRequest<MUCOwnerPayload> request = new GenericRequest<MUCOwnerPayload>(IQ.Type.Set, - getJID(), mucOwnerPayload, iqRouter_); - request.onResponse.connect(new Slot2<MUCOwnerPayload, ErrorPayload>() { - @Override - public void call(MUCOwnerPayload p1,ErrorPayload p2) { - handleCreationConfigResponse(p1,p2); - - } - }); - request.send(); - } - } - } - } - } - - private void handleOccupantRoleChangeResponse(MUCAdminPayload ref , ErrorPayload error, JID jid, MUCOccupant.Role role) { - if (error != null) { - onRoleChangeFailed.emit(error, jid, role); - } - } - private void internalJoin(String nick) { - //TODO: history request - joinComplete_ = false; - joinSucceeded_ = false; - - mucRegistry.addMUC(getJID()); - - ownMUCJID = new JID(ownMUCJID.getNode(), ownMUCJID.getDomain(), nick); - - Presence joinPresence = new Presence(presenceSender.getLastSentUndirectedPresence()); - if(joinPresence.getType() != Presence.Type.Available) { - throw new RuntimeException("From[" + joinPresence.getFrom() + "] and" + - " To[" + joinPresence.getTo() + "] is not available"); - } - joinPresence.setTo(ownMUCJID); - MUCPayload mucPayload = new MUCPayload(); - if (joinSince_ != null) { - mucPayload.setSince(joinSince_); - } - if (password != null) { - mucPayload.setPassword(password); - } - joinPresence.addPayload(mucPayload); - presenceSender.sendPresence(joinPresence); - } - - - private boolean isFromMUC(final JID j) { - return ownMUCJID.compare(j, CompareType.WithoutResource) == 0; - } - - public void handleUserLeft(LeavingType type) { - String resource = ownMUCJID.getResource(); - if (occupants.containsKey(resource)) { - MUCOccupant me = occupants.get(resource); - occupants.remove(resource); - onOccupantLeft.emit(me, type, ""); - } - occupants.clear(); - joinComplete_ = false; - joinSucceeded_ = false; - presenceSender.removeDirectedPresenceReceiver(ownMUCJID, - DirectedPresenceSender.SendPresence.DontSendPresence); - } - - /** - * Disconnect signals for this MUC. - * This method should be called when the MUC object is no longer in use - * so as to enable the garbage collector to remove this object from used space. - */ - public void disconnect() { - signalPresRcvd.onDestroyed.emit(); - } -} +public abstract class MUC { + + public enum JoinResult { JoinSucceeded, JoinFailed }; + public enum LeavingType { LeavePart, LeaveKick, LeaveBan, LeaveDestroy, LeaveNotMember, Disconnect }; + + /** + * Returns the (bare) JID of the MUC. + */ + public abstract JID getJID(); + + /** + * Returns if the room is unlocked and other people can join the room. + * @return True if joinable by others; false otherwise. + */ + public abstract boolean isUnlocked(); + + public abstract void joinAs(final String nick); + public abstract void joinWithContextSince(final String nick, final Date since); + /*public abstract void queryRoomInfo(); */ + /*public abstract void queryRoomItems(); */ + /*public abstract String getCurrentNick(); */ + public abstract Map<String, MUCOccupant> getOccupants(); + public abstract void changeNickname(final String newNickname); + public abstract void part(); + /*public abstract void handleIncomingMessage(Message::ref message); */ + /** Expose public so it can be called when e.g. user goes offline */ + public abstract void handleUserLeft(LeavingType l); + /** Get occupant information*/ + public abstract MUCOccupant getOccupant(final String nick); + public abstract boolean hasOccupant(final String nick); + public abstract void kickOccupant(final JID jid); + public abstract void changeOccupantRole(final JID jid, MUCOccupant.Role role); + public abstract void requestAffiliationList(MUCOccupant.Affiliation aff); + public abstract void changeAffiliation(final JID jid, MUCOccupant.Affiliation affiliation); + public abstract void changeSubject(final String subject); + public abstract void requestConfigurationForm(); + public abstract void configureRoom(Form f); + public abstract void cancelConfigureRoom(); + public abstract void destroyRoom(); + /** Send an invite for the person to join the MUC */ + public abstract void invitePerson(final JID person, final String reason, boolean isImpromptu, boolean isReuseChat); + public abstract void setCreateAsReservedIfNew(); + public abstract void setPassword(final String password); + + public final Signal1<String> onJoinComplete = new Signal1<String>(); + public final Signal1<ErrorPayload> onJoinFailed = new Signal1<ErrorPayload>(); + public final Signal3<ErrorPayload, JID, MUCOccupant.Role> onRoleChangeFailed = new Signal3<ErrorPayload, JID, MUCOccupant.Role>(); + public final Signal3<ErrorPayload, JID, MUCOccupant.Affiliation> onAffiliationChangeFailed = new Signal3<ErrorPayload, JID, MUCOccupant.Affiliation>(); + public final Signal1<ErrorPayload> onConfigurationFailed = new Signal1<ErrorPayload>(); + public final Signal1<ErrorPayload> onAffiliationListFailed = new Signal1<ErrorPayload>(); + public final Signal1<Presence> onOccupantPresenceChange = new Signal1<Presence>(); + public final Signal3<String, MUCOccupant, MUCOccupant.Role> onOccupantRoleChanged = new Signal3<String, MUCOccupant, MUCOccupant.Role>(); + public final Signal3<String, MUCOccupant.Affiliation /*new*/, MUCOccupant.Affiliation /*old*/> onOccupantAffiliationChanged = new Signal3<String, MUCOccupant.Affiliation, MUCOccupant.Affiliation>(); + public final Signal1<MUCOccupant> onOccupantJoined = new Signal1<MUCOccupant>(); + public final Signal2<String, String> onOccupantNicknameChanged = new Signal2<String, String>(); + public final Signal3<MUCOccupant, LeavingType, String> onOccupantLeft = new Signal3<MUCOccupant, LeavingType, String>(); + public final Signal1<Form> onConfigurationFormReceived = new Signal1<Form>(); + public final Signal2<MUCOccupant.Affiliation, Vector<JID> > onAffiliationListReceived = new Signal2<MUCOccupant.Affiliation, Vector<JID> >(); + public final Signal onUnlocked = new Signal(); + /* public final Signal1<MUCInfo> onInfoResult; */ + /* public final Signal1<blah> onItemsResult; */ +}
\ No newline at end of file |