Author: berndf
Date: Fri Jun 1 11:48:05 2012
New Revision: 1345088
URL: http://svn.apache.org/viewvc?rev=1345088&view=rev
Log:
VYSPER-317: store occupant presences, to provide them to later entering
occupants
Modified:
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCStanzaBuilder.java
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCIqAdminHandler.java
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.java
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java
Modified:
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCStanzaBuilder.java
URL:
http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCStanzaBuilder.java?rev=1345088&r1=1345087&r2=1345088&view=diff
==============================================================================
---
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCStanzaBuilder.java
(original)
+++
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCStanzaBuilder.java
Fri Jun 1 11:48:05 2012
@@ -19,23 +19,21 @@
*/
package org.apache.vysper.xmpp.modules.extension.xep0045_muc;
-import java.util.List;
-
-import org.apache.vysper.xml.fragment.Attribute;
import org.apache.vysper.xml.fragment.XMLElement;
-import org.apache.vysper.xml.fragment.XMLFragment;
import org.apache.vysper.xmpp.addressing.Entity;
import org.apache.vysper.xmpp.modules.extension.xep0045_muc.stanzas.X;
import org.apache.vysper.xmpp.stanza.PresenceStanzaType;
import org.apache.vysper.xmpp.stanza.Stanza;
import org.apache.vysper.xmpp.stanza.StanzaBuilder;
+import java.util.List;
+
/**
* Specialized {@link StanzaBuilder} for MUC
*
* @author The Apache MINA Project ([email protected])
*/
-public class MUCStanzaBuilder extends StanzaBuilder {
+public class MUCStanzaBuilder {
public static Stanza createPresenceStanza(Entity from, Entity to,
PresenceStanzaType type, String xNamespaceUri,
List<XMLElement> innerElms) {
@@ -44,18 +42,16 @@ public class MUCStanzaBuilder extends St
public static Stanza createPresenceStanza(Entity from, Entity to,
PresenceStanzaType type, String xNamespaceUri,
XMLElement... innerElms) {
- StanzaBuilder builder = StanzaBuilder.createPresenceStanza(from, to,
null, type, null, null);
- builder.addPreparedElement(new X(xNamespaceUri, innerElms));
-
- return builder.build();
+ return createPresenceStanza(from, to, null, type, null, null,
xNamespaceUri, innerElms).build();
}
- public MUCStanzaBuilder(String stanzaName, String namespaceURI,
List<Attribute> attributes,
- List<XMLFragment> innerFragments) {
- super(stanzaName, namespaceURI, null, attributes, innerFragments);
- }
+ public static StanzaBuilder createPresenceStanza(Entity from, Entity to,
String lang, PresenceStanzaType type,
+ String show, String status,
+ String xNamespaceUri,
XMLElement... innerElms) {
+ StanzaBuilder builder = StanzaBuilder.createPresenceStanza(from, to,
lang, type, show, status);
+ builder.addPreparedElement(new X(xNamespaceUri, innerElms));
- public MUCStanzaBuilder(String stanzaName, String namespaceURI) {
- super(stanzaName, namespaceURI);
+ return builder;
}
+
}
Modified:
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCIqAdminHandler.java
URL:
http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCIqAdminHandler.java?rev=1345088&r1=1345087&r2=1345088&view=diff
==============================================================================
---
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCIqAdminHandler.java
(original)
+++
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCIqAdminHandler.java
Fri Jun 1 11:48:05 2012
@@ -292,7 +292,7 @@ public class MUCIqAdminHandler extends D
MucUserItem presenceItem = new MucUserItem(target, null,
newAffiliation, Role.None);
for (Occupant occupant : room.getOccupants()) {
- StanzaBuilder builder =
MUCStanzaBuilder.createMessageStanza(room.getJID(), occupant.getJid(), null,
null);
+ StanzaBuilder builder =
StanzaBuilder.createMessageStanza(room.getJID(), occupant.getJid(), null, null);
builder.addPreparedElement(presenceItem);
relayStanza(occupant.getJid(), builder.build(),
serverRuntimeContext);
Modified:
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.java
URL:
http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.java?rev=1345088&r1=1345087&r2=1345088&view=diff
==============================================================================
---
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.java
(original)
+++
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.java
Fri Jun 1 11:48:05 2012
@@ -115,6 +115,25 @@ public class MUCPresenceHandler extends
}
+ /**
+ * creates a presence available stanza, consisting of a combination of
+ * a. information about the occupant in the room, (in the
http://jabber.org/protocol/muc#user namespace)
+ * b. information he sent with his latest presence message, e.g. show and
status
+ */
+ private Stanza createPresenceStanzaFromLatest(Entity from, Entity to,
String lang, PresenceStanzaType type,
+ PresenceStanza
templatePresence,
+ String xNamespaceUri,
XMLElement... innerElms) {
+ String show = null;
+ String status = null;
+ if (templatePresence != null) {
+ show = getInnerElementText(templatePresence, "show");
+ status = getInnerElementText(templatePresence, "status");
+ if (lang == null) lang = templatePresence.getXMLLang();
+ }
+ final StanzaBuilder presenceStanza =
MUCStanzaBuilder.createPresenceStanza(from, to, lang, type, show, status,
xNamespaceUri, innerElms);
+ return presenceStanza.build();
+ }
+
private String getInnerElementText(XMLElement element, String childName) {
try {
XMLElement childElm =
element.getSingleInnerElementsNamed(childName);
@@ -144,9 +163,10 @@ public class MUCPresenceHandler extends
return createPresenceErrorStanza(roomJid, newOccupantJid,
stanza.getID(), "auth", "not-authorized");
}
- if (room.isInRoom(newOccupantJid)) {
+ final Occupant occupant = room.findOccupantByJID(newOccupantJid);
+ if (occupant != null) {
// occupant is already in room
- Occupant occupant = room.findOccupantByJID(newOccupantJid);
+ room.recordLatestPresence(newOccupantJid, stanza);
if (nick.equals(occupant.getNick())) {
// nick unchanged, change show and status
logger.debug("{} has updated presence in room {}",
newOccupantJid, roomJid);
@@ -218,6 +238,7 @@ public class MUCPresenceHandler extends
Occupant newOccupant;
try {
newOccupant = room.addOccupant(newOccupantJid, nick);
+ room.recordLatestPresence(newOccupantJid, stanza);
} catch(RuntimeException e) {
final String message = e.getMessage();
logger.debug("{} has not been added as occupant to room {},
reason: " + message, newOccupantJid, roomJid);
@@ -242,13 +263,14 @@ public class MUCPresenceHandler extends
}
// relay presence of all existing room occupants to the now joined
occupant
- for (Occupant occupant : room.getOccupants()) {
- sendExistingOccupantToNewOccupant(newOccupant, occupant, room,
serverRuntimeContext);
+ for (Occupant existingOccupant : room.getOccupants()) {
+ sendOccupantPresenceToNewOccupant(newOccupant,
existingOccupant, room, serverRuntimeContext);
}
// relay presence of the newly added occupant to all existing
occupants
- for (Occupant occupant : room.getOccupants()) {
- sendNewOccupantPresenceToExisting(newOccupant, occupant, room,
serverRuntimeContext, nickRewritten);
+ for (Occupant existingOccupant : room.getOccupants()) {
+ sendNewOccupantPresenceToExisting(newOccupant,
existingOccupant, room, serverRuntimeContext,
+ stanza, nickRewritten);
}
// send discussion history to user
@@ -300,8 +322,8 @@ public class MUCPresenceHandler extends
return null;
}
- private void sendExistingOccupantToNewOccupant(Occupant newOccupant,
Occupant existingOccupant, Room room,
- ServerRuntimeContext serverRuntimeContext) {
+ private void sendOccupantPresenceToNewOccupant(Occupant newOccupant,
Occupant existingOccupant, Room room,
+ ServerRuntimeContext
serverRuntimeContext) {
// <presence
// from='[email protected]/firstwitch'
// to='[email protected]/pda'>
@@ -315,17 +337,21 @@ public class MUCPresenceHandler extends
return;
}
- Entity roomAndOccupantNick = new EntityImpl(room.getJID(),
existingOccupant.getNick());
- Stanza presenceToNewOccupant =
MUCStanzaBuilder.createPresenceStanza(roomAndOccupantNick, newOccupant.getJid(),
- null, NamespaceURIs.XEP0045_MUC_USER, new
MucUserItem(existingOccupant.getAffiliation(),
- existingOccupant.getRole()));
+ final PresenceStanza latestPresence =
room.getLatestPresence(existingOccupant.getJid());
+ Entity roomAndOccupantNick = new EntityImpl(room.getJID(),
existingOccupant.getNick());
+ final MucUserItem mucUserItem = new
MucUserItem(existingOccupant.getAffiliation(), existingOccupant.getRole());
+
+ Stanza presenceToNewOccupant =
createPresenceStanzaFromLatest(roomAndOccupantNick, newOccupant.getJid(),
+ null, null, latestPresence, NamespaceURIs.XEP0045_MUC_USER,
mucUserItem);
+
logger.debug("Room presence from {} sent to {}", newOccupant,
roomAndOccupantNick);
relayStanza(newOccupant.getJid(), presenceToNewOccupant,
serverRuntimeContext);
}
private void sendNewOccupantPresenceToExisting(Occupant newOccupant,
Occupant existingOccupant, Room room,
- ServerRuntimeContext
serverRuntimeContext, boolean nickRewritten) {
+ ServerRuntimeContext
serverRuntimeContext,
+ PresenceStanza presence,
boolean nickRewritten) {
Entity roomAndNewUserNick = new EntityImpl(room.getJID(),
newOccupant.getNick());
List<XMLElement> inner = new ArrayList<XMLElement>();
@@ -350,8 +376,11 @@ public class MUCPresenceHandler extends
Stanza presenceToExisting =
MUCStanzaBuilder.createPresenceStanza(roomAndNewUserNick,
existingOccupant.getJid(), null,
NamespaceURIs.XEP0045_MUC_USER, inner);
+ Stanza presenceToExistingX =
createPresenceStanzaFromLatest(roomAndNewUserNick, existingOccupant.getJid(),
+ null, null, presence, NamespaceURIs.XEP0045_MUC_USER,
inner.toArray(new XMLElement[0]));
+
logger.debug("Room presence from {} sent to {}", roomAndNewUserNick,
existingOccupant);
- relayStanza(existingOccupant.getJid(), presenceToExisting,
serverRuntimeContext);
+ relayStanza(existingOccupant.getJid(), presenceToExistingX,
serverRuntimeContext);
}
private void sendChangeNickUnavailable(Occupant changer, String oldNick,
Occupant receiver, Room room,
Modified:
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java
URL:
http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java?rev=1345088&r1=1345087&r2=1345088&view=diff
==============================================================================
---
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java
(original)
+++
mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java
Fri Jun 1 11:48:05 2012
@@ -40,6 +40,7 @@ import org.apache.vysper.xmpp.modules.se
import
org.apache.vysper.xmpp.modules.servicediscovery.management.ItemRequestListener;
import
org.apache.vysper.xmpp.modules.servicediscovery.management.ServiceDiscoveryRequestException;
import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.apache.vysper.xmpp.stanza.PresenceStanza;
/**
* A chat room
@@ -64,6 +65,8 @@ public class Room implements InfoRequest
// keep in a map to allow for quick access
private Map<Entity, Occupant> occupants = new ConcurrentHashMap<Entity,
Occupant>();
+
+ private Map<Entity, PresenceStanza> occupantsLatestPresence = new
ConcurrentHashMap<Entity, PresenceStanza>();
public Room(Entity jid, String name, RoomType... types) {
if (jid == null) {
@@ -150,13 +153,23 @@ public class Room implements InfoRequest
public Occupant findOccupantByNick(String nick) {
for (Occupant occupant : getOccupants()) {
- if (occupant.getNick().equals(nick))
- return occupant;
+ if (occupant.getNick().equals(nick)) return occupant;
}
return null;
}
+ public void recordLatestPresence(Entity occupantJid, PresenceStanza
presenceStanza) {
+ if (!isInRoom(occupantJid)) return;
+ occupantsLatestPresence.put(occupantJid, presenceStanza);
+ }
+
+ public PresenceStanza getLatestPresence(Entity occupantJid) {
+ final PresenceStanza lastPresence =
occupantsLatestPresence.get(occupantJid);
+ if (lastPresence == null || !isInRoom(occupantJid)) return null;
+ return lastPresence;
+ }
+
public Set<Occupant> getModerators() {
return getByRole(Role.Moderator);
}
@@ -164,8 +177,7 @@ public class Room implements InfoRequest
private Set<Occupant> getByRole(Role role) {
Set<Occupant> matches = new HashSet<Occupant>();
for (Occupant occupant : getOccupants()) {
- if (role.equals(occupant.getRole()))
- matches.add(occupant);
+ if (role.equals(occupant.getRole())) matches.add(occupant);
}
return matches;
}
@@ -180,6 +192,7 @@ public class Room implements InfoRequest
public void removeOccupant(Entity occupantJid) {
occupants.remove(occupantJid);
+ occupantsLatestPresence.remove(occupantJid);
}
public int getOccupantCount() {