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() {


Reply via email to