Author: ngn
Date: Sun Aug  9 20:32:14 2009
New Revision: 802586

URL: http://svn.apache.org/viewvc?rev=802586&view=rev
Log:
Implemented basic support for entering a room (VYSPER-109). However, none of 
the extended support (password protected rooms, affiliation, member-only rooms 
and so on) is yet implemented.

Added:
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCEnterRoomHandler.java
      - copied, changed from r800979, 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCIQHandler.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/storage/InMemoryOccupantStorageProvider.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/TestUtil.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCEnterRoomHandlerTestCase.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/RoomTestCase.java
Removed:
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCIQHandler.java
Modified:
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCModule.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Affiliation.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Conference.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Occupant.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Role.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/AbstractDiscoTestCase.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCRoomInfoDiscoTestCase.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/ConferenceTestCase.java

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCModule.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCModule.java?rev=802586&r1=802585&r2=802586&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCModule.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCModule.java
 Sun Aug  9 20:32:14 2009
@@ -132,7 +132,6 @@
             } else {
                 return null;
             }
-            
         }
     }
     

Copied: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCEnterRoomHandler.java
 (from r800979, 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCIQHandler.java)
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCEnterRoomHandler.java?p2=mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCEnterRoomHandler.java&p1=mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCIQHandler.java&r1=800979&r2=802586&rev=802586&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCIQHandler.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCEnterRoomHandler.java
 Sun Aug  9 20:32:14 2009
@@ -17,15 +17,26 @@
  *  under the License.
  *
  */
-package org.apache.vysper.xmpp.modules.extension.xep0045_muc;
+package org.apache.vysper.xmpp.modules.extension.xep0045_muc.handler;
 
 import org.apache.vysper.compliance.SpecCompliant;
-import org.apache.vysper.xmpp.modules.core.base.handler.DefaultIQHandler;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.delivery.DeliveryException;
+import org.apache.vysper.xmpp.delivery.failure.IgnoreFailureStrategy;
+import org.apache.vysper.xmpp.modules.core.base.handler.DefaultPresenceHandler;
+import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Conference;
+import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Occupant;
+import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Room;
 import org.apache.vysper.xmpp.protocol.NamespaceURIs;
 import org.apache.vysper.xmpp.server.ServerRuntimeContext;
 import org.apache.vysper.xmpp.server.SessionContext;
-import org.apache.vysper.xmpp.stanza.IQStanza;
+import org.apache.vysper.xmpp.stanza.PresenceStanza;
+import org.apache.vysper.xmpp.stanza.PresenceStanzaType;
 import org.apache.vysper.xmpp.stanza.Stanza;
+import org.apache.vysper.xmpp.stanza.StanzaBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Implementation of <a 
href="http://xmpp.org/extensions/xep-0045.html";>XEP-0045 Multi-user chat</a>.
@@ -33,10 +44,15 @@
  *  
  * @author The Apache MINA Project ([email protected])
  */
-...@speccompliant(spec="xep-0045", status= 
SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = 
SpecCompliant.ComplianceCoverage.PARTIAL)
-public class MUCIQHandler extends DefaultIQHandler {
+...@speccompliant(spec="xep-0045", section="7.1", status= 
SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = 
SpecCompliant.ComplianceCoverage.PARTIAL)
+public class MUCEnterRoomHandler extends DefaultPresenceHandler {
 
-    public MUCIQHandler() {
+    final Logger logger = LoggerFactory.getLogger(MUCEnterRoomHandler.class);
+
+    private Conference conference;
+    
+    public MUCEnterRoomHandler(Conference conference) {
+        this.conference = conference;
     }
 
     @Override
@@ -44,9 +60,114 @@
         return verifyInnerNamespace(stanza, NamespaceURIs.XEP0045_MUC);
     }
 
+    private Stanza sendError(Entity roomJid, Entity occupantJid, String error) 
{
+        //        <presence
+        //        from='[email protected]'
+        //        to='[email protected]/pda'
+        //        type='error'>
+        //      <error type='modify'>
+        //        <jid-malformed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
+        //      </error>
+        //    </presence>
+
+        StanzaBuilder builder = StanzaBuilder.createPresenceStanza(roomJid, 
occupantJid, null, 
+                PresenceStanzaType.ERROR, null, null);
+        
+        // "Note: If an error occurs in relation to joining a room, the 
service SHOULD include 
+        // the MUC child element (i.e., <x 
xmlns='http://jabber.org/protocol/muc'/>) in the 
+        // <presence/> stanza of type "error"."
+        builder.startInnerElement("x", 
NamespaceURIs.XEP0045_MUC).endInnerElement();
+        builder.startInnerElement("error").addAttribute("type", "modify");
+        builder.startInnerElement(error, 
NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS).endInnerElement();
+        builder.endInnerElement();
+        
+        return PresenceStanza.getWrapper(builder.getFinalStanza());
+    }
+    
     @Override
-    protected Stanza handleGet(IQStanza stanza, ServerRuntimeContext 
serverRuntimeContext, SessionContext sessionContext) {
-        // stub
+    protected Stanza executePresenceLogic(PresenceStanza stanza, 
ServerRuntimeContext serverRuntimeContext, SessionContext sessionContext) {
+        // TODO handle null
+        Entity roomAndNick = stanza.getTo();
+        
+        Entity roomJid = roomAndNick.getBareJID();
+        String nick = roomAndNick.getResource();
+        
+        // TODO handle null
+        Entity newOccupantJid = stanza.getFrom();
+        
+        // user did not send nick name
+        if(nick == null) {
+            return sendError(roomJid, newOccupantJid, "jid-malformed");
+        }
+        
+        // TODO what to use for the room name?
+        Room room = conference.findOrCreateRoom(roomJid, roomJid.getNode());
+        
+        Occupant newOccupant = room.addOccupant(newOccupantJid, nick);
+        
+        // relay presence of all existing room occupants to the now joined 
occupant
+        for(Occupant occupant : room.getOccupants()) {
+            sendExistingOccupantToNewOccupant(newOccupant, occupant, room, 
sessionContext);
+        }
+        
+        // relay presence of the newly added occupant to all existing occupants
+        for(Occupant occupant : room.getOccupants()) {
+            sendNewOccupantPresence(newOccupant, occupant, room, 
sessionContext);
+        }
+        
         return null;
     }
+    
+    private void sendExistingOccupantToNewOccupant(Occupant newOccupant, 
Occupant existingOccupant, Room room, SessionContext sessionContext) {
+        //            <presence
+        //            from='[email protected]/firstwitch'
+        //            to='[email protected]/pda'>
+        //          <x xmlns='http://jabber.org/protocol/muc#user'>
+        //            <item affiliation='owner' role='moderator'/>
+        //          </x>
+        //        </presence>
+        
+        // do not send own presence
+        if(existingOccupant.getJid().equals(newOccupant.getJid())) {
+            return;
+        }
+        
+        Entity roomAndOccupantNick = new EntityImpl(room.getJID(), 
existingOccupant.getName());
+        StanzaBuilder builder = 
StanzaBuilder.createPresenceStanza(roomAndOccupantNick, newOccupant.getJid(), 
null, null, null, null);
+        builder.startInnerElement("x", NamespaceURIs.XEP0045_MUC_USER);
+        builder.startInnerElement("item")
+            .addAttribute("affiliation", 
existingOccupant.getAffiliation().toString())
+            .addAttribute("role", existingOccupant.getRole().toString())
+            .endInnerElement();
+        builder.endInnerElement();
+        
+        relayStanza(newOccupant.getJid(), builder.getFinalStanza(), 
sessionContext);
+    }
+    
+    private void sendNewOccupantPresence(Occupant newOccupant, Occupant 
existingOccupant, Room room, SessionContext sessionContext) {
+        Entity roomAndNewUserNick = new EntityImpl(room.getJID(), 
newOccupant.getName());
+        
+        StanzaBuilder builder = 
StanzaBuilder.createPresenceStanza(roomAndNewUserNick, 
existingOccupant.getJid(), null, null, null, null);
+        builder.startInnerElement("x", NamespaceURIs.XEP0045_MUC_USER);
+        builder.startInnerElement("item")
+            .addAttribute("affiliation", 
newOccupant.getAffiliation().toString())
+            .addAttribute("role", newOccupant.getRole().toString())
+            .endInnerElement();
+        
+        if(existingOccupant.getJid().equals(newOccupant.getJid())) {
+            // send status to indicate that this is the users own presence
+            builder.startInnerElement("status").addAttribute("code", 
"110").endInnerElement();
+        }
+        builder.endInnerElement();
+
+        relayStanza(existingOccupant.getJid(), builder.getFinalStanza(), 
sessionContext);
+    }
+    
+    protected void relayStanza(Entity receiver, Stanza stanza, SessionContext 
sessionContext) {
+        try {
+                
sessionContext.getServerRuntimeContext().getStanzaRelay().relay(receiver, 
stanza, new IgnoreFailureStrategy());
+        } catch (DeliveryException e) {
+                logger.warn("presence relaying failed ", e);
+        }
+}
 }

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Affiliation.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Affiliation.java?rev=802586&r1=802585&r2=802586&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Affiliation.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Affiliation.java
 Sun Aug  9 20:32:14 2009
@@ -22,24 +22,35 @@
 import org.apache.vysper.compliance.SpecCompliant;
 
 /**
- * These affiliations are long-lived in that they persist across a user's 
visits to the room and are not affected by happenings in the room. In addition, 
there is no one-to-one mapping between these affiliations and an occupant's 
role within the room. Affiliations are granted, revoked, and maintained based 
on the user's bare JID.
+ * These affiliations are long-lived in that they persist across a user's 
visits to the room and 
+ * are not affected by happenings in the room. In addition, there is no 
one-to-one mapping between 
+ * these affiliations and an occupant's role within the room. Affiliations are 
granted, revoked, 
+ * and maintained based on the user's bare JID.
  * 
- * If a user without a defined affiliation enters a room, the user's 
affiliation is defined as "none"; however, this affiliation does not persist 
across visits (i.e., a service does not maintain a "none list" across visits).
+ * If a user without a defined affiliation enters a room, the user's 
affiliation is defined as "none"; 
+ * however, this affiliation does not persist across visits (i.e., a service 
does not maintain a "none 
+ * list" across visits).
  * 
- * The member affiliation provides a way for a room owner or admin to specify 
a "whitelist" of users who are allowed to enter a members-only room. When a 
member enters a members-only room, his or her affiliation does not change, no 
matter what his or her role is. The member affiliation also provides a way for 
users to effectively register with an open room and thus be lastingly 
associated with that room in some way (one result may be that the user's 
nickname is reserved in the room).
+ * The member affiliation provides a way for a room owner or admin to specify 
a "whitelist" of users 
+ * who are allowed to enter a members-only room. When a member enters a 
members-only room, his or her 
+ * affiliation does not change, no matter what his or her role is. The member 
affiliation also provides 
+ * a way for users to effectively register with an open room and thus be 
lastingly associated with that 
+ * room in some way (one result may be that the user's nickname is reserved in 
the room).
  * 
  * An outcast is a user who has been banned from a room and who is not allowed 
to enter the room.
  * 
- * Information about affiliations MUST be sent in all presence stanzas 
generated or reflected by the room and sent to occupants * 
+ * Information about affiliations MUST be sent in all presence stanzas 
generated or reflected by the room 
+ * and sent to occupants
  * 
  * @author The Apache MINA Project ([email protected])
  */
-...@speccompliant(spec="xep-0045", section="5.2", status= 
SpecCompliant.ComplianceStatus.FINISHED, coverage = 
SpecCompliant.ComplianceCoverage.COMPLETE)
+...@speccompliant(spec = "xep-0045", section = "5.2", status = 
SpecCompliant.ComplianceStatus.FINISHED, coverage = 
SpecCompliant.ComplianceCoverage.COMPLETE)
 public enum Affiliation {
 
-    Owner,
-    Admin,
-    Member,
-    Outcast,
-    None
+    Owner, Admin, Member, Outcast, None;
+
+    @Override
+    public String toString() {
+        return name().toLowerCase();
+    }
 }

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Conference.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Conference.java?rev=802586&r1=802585&r2=802586&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Conference.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Conference.java
 Sun Aug  9 20:32:14 2009
@@ -24,6 +24,7 @@
 import java.util.List;
 
 import org.apache.vysper.xmpp.addressing.Entity;
+import 
org.apache.vysper.xmpp.modules.extension.xep0045_muc.storage.InMemoryOccupantStorageProvider;
 import 
org.apache.vysper.xmpp.modules.extension.xep0045_muc.storage.InMemoryRoomStorageProvider;
 import 
org.apache.vysper.xmpp.modules.extension.xep0045_muc.storage.OccupantStorageProvider;
 import 
org.apache.vysper.xmpp.modules.extension.xep0045_muc.storage.RoomStorageProvider;
@@ -34,7 +35,6 @@
 import org.apache.vysper.xmpp.modules.servicediscovery.management.Item;
 import 
org.apache.vysper.xmpp.modules.servicediscovery.management.ItemRequestListener;
 import 
org.apache.vysper.xmpp.modules.servicediscovery.management.ServerInfoRequestListener;
-import 
org.apache.vysper.xmpp.modules.servicediscovery.management.ServiceDiscoveryRequestException;
 import org.apache.vysper.xmpp.protocol.NamespaceURIs;
 
 /**
@@ -47,7 +47,7 @@
     private String name;
 
     private RoomStorageProvider roomStorageProvider = new 
InMemoryRoomStorageProvider();
-    private OccupantStorageProvider occupantStorageProvider;
+    private OccupantStorageProvider occupantStorageProvider = new 
InMemoryOccupantStorageProvider();
     
     public Conference(String name) {
         if(name == null || name.trim().length() == 0) {
@@ -78,6 +78,14 @@
         return roomStorageProvider.findRoom(jid);
     }
     
+    public Room findOrCreateRoom(Entity jid, String name, RoomType... types) {
+        Room room = findRoom(jid);
+        if(room == null) {
+            room = createRoom(jid, name, types);
+        }
+        return room;
+    }
+    
     public OccupantStorageProvider getOccupantStorageProvider() {
         return occupantStorageProvider;
     }

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Occupant.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Occupant.java?rev=802586&r1=802585&r2=802586&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Occupant.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Occupant.java
 Sun Aug  9 20:32:14 2009
@@ -19,11 +19,55 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0045_muc.model;
 
+import org.apache.vysper.xmpp.addressing.Entity;
+
 /**
- * An occupant (user) in a conference
+ * An occupant (user) in a room
  *
  * @author The Apache MINA Project ([email protected])
  */
 public class Occupant {
+    
+    private Affiliation affiliation;
+    private Role role;
+    
+    private Entity jid;
+    private String name;
+    
+    public Occupant(Entity jid, String name, Affiliation affiliation, Role 
role) {
+        this.jid = jid;
+        this.name = name;
+        this.affiliation = affiliation;
+        this.role = role;
+    }
+
+    public Affiliation getAffiliation() {
+        return affiliation;
+    }
+
+    public void setAffiliation(Affiliation affiliation) {
+        this.affiliation = affiliation;
+    }
+
+    public Role getRole() {
+        return role;
+    }
+
+    public void setRole(Role role) {
+        this.role = role;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
 
+    public Entity getJid() {
+        return jid;
+    }
+    
+    
 }

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Role.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Role.java?rev=802586&r1=802585&r2=802586&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Role.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Role.java
 Sun Aug  9 20:32:14 2009
@@ -19,18 +19,30 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0045_muc.model;
 
+import java.util.EnumSet;
+
 import org.apache.vysper.compliance.SpecCompliant;
 
 /**
- * Roles are temporary in that they do not necessarily persist across a user's 
visits to the room and MAY change during the course of an occupant's visit to 
the room. An implementation MAY persist roles across visits and SHOULD do so 
for moderated rooms (since the distinction between visitor and participant is 
critical to the functioning of a moderated room).
+ * Roles are temporary in that they do not necessarily persist across a user's 
visits to the room and MAY 
+ * change during the course of an occupant's visit to the room. An 
implementation MAY persist roles across 
+ * visits and SHOULD do so for moderated rooms (since the distinction between 
visitor and participant is 
+ * critical to the functioning of a moderated room).
  * 
- * There is no one-to-one mapping between roles and affiliations (e.g., a 
member could be a participant or a visitor).
+ * There is no one-to-one mapping between roles and affiliations (e.g., a 
member could be a participant or 
+ * a visitor).
  * 
- * A moderator is the most powerful occupant within the context of the room, 
and can to some extent manage other occupants' roles in the room. A participant 
has fewer privileges than a moderator, although he or she always has the right 
to speak. A visitor is a more restricted role within the context of a moderated 
room, since visitors are not allowed to send messages to all occupants.
+ * A moderator is the most powerful occupant within the context of the room, 
and can to some extent manage 
+ * other occupants' roles in the room. A participant has fewer privileges than 
a moderator, although he or 
+ * she always has the right to speak. A visitor is a more restricted role 
within the context of a moderated 
+ * room, since visitors are not allowed to send messages to all occupants.
  * 
- * Roles are granted, revoked, and maintained based on the occupant's room 
nickname or full JID rather than bare JID. The privileges associated with these 
roles, as well as the actions that trigger changes in roles, are defined below.
+ * Roles are granted, revoked, and maintained based on the occupant's room 
nickname or full JID rather than 
+ * bare JID. The privileges associated with these roles, as well as the 
actions that trigger changes in roles, 
+ * are defined below.
  * 
- * Information about roles MUST be sent in all presence stanzas generated or 
reflected by the room and thus sent to occupants.
+ * Information about roles MUST be sent in all presence stanzas generated or 
reflected by the room and thus 
+ * sent to occupants.
  * 
  * @author The Apache MINA Project ([email protected])
  */
@@ -40,5 +52,32 @@
     Moderator,
     None,
     Participant,
-    Visitor
+    Visitor;
+    
+    @Override
+    public String toString() {
+        return name().toLowerCase();
+    }
+    
+    @SpecCompliant(spec="xep-0045", section="7.1.4", status= 
SpecCompliant.ComplianceStatus.FINISHED, coverage = 
SpecCompliant.ComplianceCoverage.COMPLETE)
+    public static Role getRole(Affiliation affiliation, EnumSet<RoomType> 
roomTypes) {
+        switch(affiliation) {
+        case Owner:
+        case Admin:
+            return Moderator;
+        case Member:
+            return Participant;
+        case None:
+            if(roomTypes.contains(RoomType.MembersOnly)) {
+                return None;
+            } else if(roomTypes.contains(RoomType.Moderated)) {
+                return Visitor;
+            } else {
+                return Participant;
+            }
+        default:
+            // no role for Outcast
+            return null;
+        }
+    }
 }

Modified: 
mina/sandbox/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/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java?rev=802586&r1=802585&r2=802586&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java
 Sun Aug  9 20:32:14 2009
@@ -21,8 +21,13 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.EnumSet;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.modules.servicediscovery.management.Feature;
@@ -48,7 +53,19 @@
     private Entity jid;
     private String name;
     
+    // keep in a map to allow for quick access
+    private Map<Entity, Occupant> occupants = new ConcurrentHashMap<Entity, 
Occupant>();
+    
     public Room(Entity jid, String name, RoomType... types) {
+        if(jid == null) {
+            throw new IllegalArgumentException("JID can not be null");
+        } else if(jid.getResource() != null) {
+            throw new IllegalArgumentException("JID must be bare");
+        }
+        if(name == null || name.trim().length() == 0) {
+            throw new IllegalArgumentException("Name can not be null or 
empty");
+        }
+        
         this.jid = jid;
         this.name = name;
         
@@ -73,7 +90,36 @@
     public String getName() {
         return name;
     }
+    
+    public EnumSet<RoomType> getRoomTypes() {
+        return roomTypes.clone();
+    }
+
+    public Occupant addOccupant(Entity occupantJid, String name) {
+        // TODO uses a default Affiliation.None, later to be looked up based 
on the user
+        Affiliation affiliation = Affiliation.None;
+        Role role = Role.getRole(affiliation, roomTypes);
+        Occupant occupant = new Occupant(occupantJid, name, affiliation, 
role); 
+        occupants.put(occupantJid, occupant);
+        return occupant;
+    }
 
+    
+    
+    public void removeOccupant(Entity occupantJid) {
+        occupants.remove(occupantJid);
+    }
+    
+    public Set<Occupant> getOccupants() {
+        Set<Occupant> set = new HashSet<Occupant>();
+        
+        for(Occupant occupant : occupants.values()) {
+            set.add(occupant);
+        }
+        
+        return Collections.unmodifiableSet(set);
+    }
+    
     public List<InfoElement> getInfosFor(InfoRequest request)
             throws ServiceDiscoveryRequestException {
         List<InfoElement> infoElements = new ArrayList<InfoElement>();

Added: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/storage/InMemoryOccupantStorageProvider.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/storage/InMemoryOccupantStorageProvider.java?rev=802586&view=auto
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/storage/InMemoryOccupantStorageProvider.java
 (added)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/storage/InMemoryOccupantStorageProvider.java
 Sun Aug  9 20:32:14 2009
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.vysper.xmpp.modules.extension.xep0045_muc.storage;
+
+
+
+/**
+ *
+ * @author The Apache MINA Project ([email protected])
+ */
+public class InMemoryOccupantStorageProvider implements 
OccupantStorageProvider {
+
+    public void initialize() {
+        // do nothing
+    }
+   
+}

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/AbstractDiscoTestCase.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/AbstractDiscoTestCase.java?rev=802586&r1=802585&r2=802586&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/AbstractDiscoTestCase.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/AbstractDiscoTestCase.java
 Sun Aug  9 20:32:14 2009
@@ -22,38 +22,25 @@
 import junit.framework.TestCase;
 
 import org.apache.vysper.xmpp.addressing.Entity;
-import org.apache.vysper.xmpp.addressing.EntityFormatException;
-import org.apache.vysper.xmpp.addressing.EntityImpl;
 import org.apache.vysper.xmpp.modules.Module;
 import org.apache.vysper.xmpp.modules.core.base.handler.IQHandler;
 import 
org.apache.vysper.xmpp.modules.servicediscovery.collection.ServiceCollector;
-import 
org.apache.vysper.xmpp.modules.servicediscovery.handler.DiscoInfoIQHandler;
 import org.apache.vysper.xmpp.protocol.ResponseStanzaContainer;
 import org.apache.vysper.xmpp.protocol.SessionStateHolder;
 import org.apache.vysper.xmpp.server.DefaultServerRuntimeContext;
 import org.apache.vysper.xmpp.server.TestSessionContext;
 import org.apache.vysper.xmpp.stanza.Stanza;
 import org.apache.vysper.xmpp.stanza.StanzaBuilder;
-import org.apache.vysper.xmpp.xmlfragment.Renderer;
 import org.apache.vysper.xmpp.xmlfragment.XMLElement;
-import org.apache.vysper.xmpp.xmlfragment.XMLSemanticError;
 
 /**
  * 
  * @author The Apache MINA Project ([email protected])
  */
 public abstract class AbstractDiscoTestCase extends TestCase {
-
-    protected static Entity parseUnchecked(String jid) {
-        try {
-            return EntityImpl.parse(jid);
-        } catch (EntityFormatException e) {
-            throw new RuntimeException(e);
-        }
-    }
     
-    protected static final Entity SERVER_JID = parseUnchecked("vysper.org");
-    protected static final Entity USER_JID = parseUnchecked("[email protected]");
+    protected static final Entity SERVER_JID = 
TestUtil.parseUnchecked("vysper.org");
+    protected static final Entity USER_JID = 
TestUtil.parseUnchecked("[email protected]");
 
     protected abstract Module getModule();
 
@@ -80,7 +67,6 @@
         ResponseStanzaContainer resultStanzaContainer = 
infoIQHandler.execute(request.getFinalStanza(), runtimeContext, false, new 
TestSessionContext(runtimeContext, new SessionStateHolder()), null);
         Stanza resultStanza = resultStanzaContainer.getResponseStanza();
 
-        System.out.println(new Renderer(resultStanza).getComplete());
         XMLElement queryElement = resultStanza.getFirstInnerElement();
         
         assertResponse(queryElement);

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCRoomInfoDiscoTestCase.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCRoomInfoDiscoTestCase.java?rev=802586&r1=802585&r2=802586&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCRoomInfoDiscoTestCase.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCRoomInfoDiscoTestCase.java
 Sun Aug  9 20:32:14 2009
@@ -35,7 +35,7 @@
  */
 public class MUCRoomInfoDiscoTestCase extends AbstractInfoDiscoTestCase {
     
-    private static final Entity ROOM_JID = parseUnchecked("[email protected]");
+    private static final Entity ROOM_JID = 
TestUtil.parseUnchecked("[email protected]");
     
     @Override
     protected Module getModule() {

Added: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/TestUtil.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/TestUtil.java?rev=802586&view=auto
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/TestUtil.java
 (added)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/TestUtil.java
 Sun Aug  9 20:32:14 2009
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.vysper.xmpp.modules.extension.xep0045_muc;
+
+import junit.framework.TestCase;
+
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityFormatException;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+
+/**
+ * 
+ * @author The Apache MINA Project ([email protected])
+ */
+public abstract class TestUtil extends TestCase {
+
+    public static Entity parseUnchecked(String jid) {
+        try {
+            return EntityImpl.parse(jid);
+        } catch (EntityFormatException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

Added: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCEnterRoomHandlerTestCase.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCEnterRoomHandlerTestCase.java?rev=802586&view=auto
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCEnterRoomHandlerTestCase.java
 (added)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCEnterRoomHandlerTestCase.java
 Sun Aug  9 20:32:14 2009
@@ -0,0 +1,175 @@
+package org.apache.vysper.xmpp.modules.extension.xep0045_muc.handler;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.delivery.StanzaReceiverQueue;
+import org.apache.vysper.xmpp.delivery.StanzaReceiverRelay;
+import org.apache.vysper.xmpp.modules.extension.xep0045_muc.TestUtil;
+import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Conference;
+import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Occupant;
+import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Room;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.apache.vysper.xmpp.protocol.ResponseStanzaContainer;
+import org.apache.vysper.xmpp.server.TestSessionContext;
+import org.apache.vysper.xmpp.stanza.PresenceStanza;
+import org.apache.vysper.xmpp.stanza.Stanza;
+import org.apache.vysper.xmpp.stanza.StanzaBuilder;
+import org.apache.vysper.xmpp.xmlfragment.XMLElement;
+
+/**
+ */
+public class MUCEnterRoomHandlerTestCase extends TestCase {
+    
+    private TestSessionContext sessionContext;
+
+    protected Entity room1Jid = TestUtil.parseUnchecked("[email protected]");
+    protected Entity room2Jid = TestUtil.parseUnchecked("[email protected]");
+
+    protected Entity room1JidWithNick = 
TestUtil.parseUnchecked("[email protected]/nick");
+    protected Entity room2JidWithNick = 
TestUtil.parseUnchecked("[email protected]/nick");
+    
+    protected Entity occupant1Jid = 
TestUtil.parseUnchecked("[email protected]");
+    protected Entity occupant2Jid = 
TestUtil.parseUnchecked("[email protected]");
+    protected MUCEnterRoomHandler handler;
+
+    private Conference conference;
+
+    private StanzaReceiverQueue occupant1Queue;
+
+    private StanzaReceiverQueue occupant2Queue;
+    
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        
+        sessionContext = 
TestSessionContext.createWithStanzaReceiverRelayAuthenticated();
+        sessionContext.setInitiatingEntity(occupant1Jid);
+        
+        StanzaReceiverRelay stanzaRelay = (StanzaReceiverRelay) 
sessionContext.getServerRuntimeContext().getStanzaRelay();
+        occupant1Queue = new StanzaReceiverQueue();
+        occupant2Queue = new StanzaReceiverQueue();
+        stanzaRelay.add(occupant1Jid, occupant1Queue);
+        stanzaRelay.add(occupant2Jid, occupant2Queue);
+        
+        conference = new Conference("foo");
+        conference.createRoom(room1Jid, "Room 1");
+        
+        handler = new MUCEnterRoomHandler(conference);
+    }
+
+    private Stanza enterRoom(Entity occupantJid, Entity roomJid) {
+        StanzaBuilder stanzaBuilder = 
StanzaBuilder.createPresenceStanza(occupantJid, roomJid, null, null, null, 
null);
+        
stanzaBuilder.startInnerElement("x").addNamespaceAttribute(NamespaceURIs.XEP0045_MUC).endInnerElement();
+
+        Stanza presenceStanza = stanzaBuilder.getFinalStanza();
+        ResponseStanzaContainer container = handler.execute(presenceStanza, 
sessionContext.getServerRuntimeContext(), true, sessionContext, null);
+        if(container != null) {
+            return container.getResponseStanza();
+        } else {
+            return null;
+        }
+    }
+    
+    public void testEnterExistingRoom() {
+        Room room = conference.findRoom(room1Jid);
+        assertEquals(0, room.getOccupants().size());
+
+        enterRoom(occupant1Jid, room1JidWithNick);
+
+        assertEquals(1, room.getOccupants().size());
+        Occupant occupant = room.getOccupants().iterator().next();
+        
+        assertEquals(occupant1Jid, occupant.getJid());
+        assertEquals("nick", occupant.getName());
+    }
+
+    public void testEnterNonExistingRoom() {
+        Room room = conference.findRoom(room2Jid);
+        assertNull(room);
+
+        enterRoom(occupant1Jid, room2JidWithNick);
+
+        room = conference.findRoom(room2Jid);
+        assertNotNull(room);
+        assertEquals(1, room.getOccupants().size());
+        Occupant occupant = room.getOccupants().iterator().next();
+        
+        assertEquals(occupant1Jid, occupant.getJid());
+        assertEquals("nick", occupant.getName());
+    }
+    
+    public void testEnterWithoutNick() {
+        // try entering without a nick
+        PresenceStanza response = (PresenceStanza) enterRoom(occupant1Jid, 
room1Jid);
+
+        assertNotNull(response);
+        assertEquals("presence", response.getName());
+        assertEquals(occupant1Jid, response.getTo());
+        assertEquals(room1Jid, response.getFrom());
+        assertEquals("error", response.getType());
+        
+        List<XMLElement> innerElements = response.getInnerElements();
+        
+        XMLElement xElement = innerElements.get(0);
+        assertEquals("x", xElement.getName());
+        assertEquals(NamespaceURIs.XEP0045_MUC, xElement.getNamespaceURI());
+
+        XMLElement errorElement = innerElements.get(1);
+        assertEquals("error", errorElement.getName());
+        assertEquals("modify", errorElement.getAttributeValue("type"));
+        
+        XMLElement jidMalformedElement = errorElement.getFirstInnerElement();
+        assertEquals("jid-malformed", jidMalformedElement.getName());
+        assertEquals(NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS, 
jidMalformedElement.getNamespaceURI());
+        
+    }
+    
+    public void testEnterRoomWithRelays() throws Exception {
+
+
+        // add one occupant to the room
+        Room room = conference.findOrCreateRoom(room1Jid, "Room 1");
+        room.addOccupant(occupant1Jid, "Some nick");
+        
+        // now, let user 2 enter room
+        enterRoom(occupant2Jid, room1JidWithNick);
+
+//        <presence
+//        from='[email protected]/firstwitch'
+//        to='[email protected]/pda'>
+//      <x xmlns='http://jabber.org/protocol/muc#user'>
+//        <item affiliation='owner' role='moderator'/>
+//      </x>
+//    </presence>
+
+        // verify stanzas to existing occupants on the new user
+        Stanza user2JoinedStanza = occupant1Queue.getNext();
+        // should be from room + nick name
+        assertEquals(room1Jid.getFullQualifiedName() + "/nick", 
user2JoinedStanza.getFrom().getFullQualifiedName());
+        // should be to the existing user
+        assertEquals(occupant1Jid, user2JoinedStanza.getTo());
+
+        // verify stanzas to the new user on all existing users, including 
himself with status=110 element
+        // own presence must be sent last
+        // assert the stanza from the already existing user
+        Stanza stanza = occupant2Queue.getNext();
+        assertNotNull(stanza);
+        assertEquals(room1Jid.getFullQualifiedName() + "/Some nick", 
stanza.getFrom().getFullQualifiedName());
+        assertEquals(occupant2Jid, stanza.getTo());
+
+        // assert stanza from the joining user, must have extra status=110 
element
+        stanza = occupant2Queue.getNext();
+        assertNotNull(stanza);
+        assertEquals(room1JidWithNick, stanza.getFrom());
+        assertEquals(occupant2Jid, stanza.getTo());
+        XMLElement statusElement = 
stanza.getFirstInnerElement().getSingleInnerElementsNamed("status");
+        assertNotNull(statusElement);
+        assertEquals("110", statusElement.getAttributeValue("code"));
+        
+    }
+}

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/ConferenceTestCase.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/ConferenceTestCase.java?rev=802586&r1=802585&r2=802586&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/ConferenceTestCase.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/ConferenceTestCase.java
 Sun Aug  9 20:32:14 2009
@@ -27,6 +27,7 @@
 
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.modules.extension.xep0045_muc.TestUtil;
 
 /**
  * 
@@ -34,16 +35,8 @@
  */
 public class ConferenceTestCase extends TestCase {
     
-    private Entity jid1;
-    private Entity jid2;
-    
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        
-        jid1 = EntityImpl.parse("[email protected]");
-        jid2 = EntityImpl.parse("[email protected]");
-    }
+    private Entity jid1 = TestUtil.parseUnchecked("[email protected]");
+    private Entity jid2 = TestUtil.parseUnchecked("[email protected]");
     
     public void testGetName() {
         Conference conference = new Conference("foo");

Added: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/RoomTestCase.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/RoomTestCase.java?rev=802586&view=auto
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/RoomTestCase.java
 (added)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/RoomTestCase.java
 Sun Aug  9 20:32:14 2009
@@ -0,0 +1,138 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.vysper.xmpp.modules.extension.xep0045_muc.model;
+
+import java.util.EnumSet;
+
+import junit.framework.TestCase;
+
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.modules.extension.xep0045_muc.TestUtil;
+import org.jivesoftware.smackx.workgroup.packet.RoomTransfer;
+
+/**
+ * 
+ * @author The Apache MINA Project ([email protected])
+ */
+public class RoomTestCase extends TestCase {
+    
+    private Entity roomJid1 = TestUtil.parseUnchecked("[email protected]");
+    private Entity roomJid2 = TestUtil.parseUnchecked("[email protected]");
+
+    private Entity occupantJid1 = TestUtil.parseUnchecked("[email protected]");
+    private Entity occupantJid2 = TestUtil.parseUnchecked("[email protected]");
+
+    public void testConstructor() {
+        Room room = new Room(roomJid1, "Room 1");
+        assertEquals(roomJid1, room.getJID());
+        assertEquals("Room 1", room.getName());
+        
+        EnumSet<RoomType> types = room.getRoomTypes();
+        assertTrue(types.contains(RoomType.NonAnonymous));
+        assertTrue(types.contains(RoomType.Open));
+        assertTrue(types.contains(RoomType.Public));
+        assertTrue(types.contains(RoomType.Temporary));
+        assertTrue(types.contains(RoomType.Unmoderated));
+        assertTrue(types.contains(RoomType.Unsecured));
+    }
+
+    public void testConstructorWithTypes() {
+        Room room = new Room(roomJid1, "Room 1", RoomType.Hidden, 
RoomType.Open);
+        assertEquals(roomJid1, room.getJID());
+        assertEquals("Room 1", room.getName());
+        
+        EnumSet<RoomType> types = room.getRoomTypes();
+        assertTrue(types.contains(RoomType.NonAnonymous));
+        assertTrue(types.contains(RoomType.Open));
+        // must be hidden
+        assertTrue(types.contains(RoomType.Hidden));
+        assertTrue(types.contains(RoomType.Temporary));
+        assertTrue(types.contains(RoomType.Unmoderated));
+        assertTrue(types.contains(RoomType.Unsecured));
+    }
+
+    public void testConstructorWithAntonymTypes() {
+        try {
+            new Room(roomJid1, "Room 1", RoomType.Hidden, RoomType.Public);
+            fail("Expects IllegalArgumentException");
+        } catch(IllegalArgumentException e) {
+            // ok
+        }
+    }
+    
+    public void testConstructorWithFullJID() {
+        try {
+            new Room(TestUtil.parseUnchecked("[email protected]/incorrect"), 
"Room 1");
+            fail("Expects IllegalArgumentException");
+        } catch(IllegalArgumentException e) {
+            // ok
+        }
+    }
+    
+    public void testConstructorWithNullJID() {
+        try {
+            new Room(null, "Room 1");
+            fail("Expects IllegalArgumentException");
+        } catch(IllegalArgumentException e) {
+            // ok
+        }
+    }
+    
+    
+    public void testConstructorWithNullName() {
+        try {
+            new Room(roomJid1, null);
+            fail("Expects IllegalArgumentException");
+        } catch(IllegalArgumentException e) {
+            // ok
+        }
+    }
+    
+    public void testConstructorWithWhitespaceName() {
+        try {
+            new Room(roomJid1, " \t ");
+            fail("Expects IllegalArgumentException");
+        } catch(IllegalArgumentException e) {
+            // ok
+        }
+    }
+    
+    public void testAddRemoveGetOccupant() {
+        Room room = new Room(roomJid1, "Room 1");
+        room.addOccupant(occupantJid1, "Nick 1");
+        
+        assertEquals(1, room.getOccupants().size());
+        
+        Occupant occupant = room.getOccupants().iterator().next();
+        assertEquals(occupantJid1, occupant.getJid());
+        assertEquals("Nick 1", occupant.getName());
+        
+        room.addOccupant(occupantJid2, "Nick 2");
+        assertEquals(2, room.getOccupants().size());
+        
+        room.removeOccupant(occupantJid1);
+
+        assertEquals(1, room.getOccupants().size());
+        
+        occupant = room.getOccupants().iterator().next();
+        assertEquals(occupantJid2, occupant.getJid());
+
+    }
+}


Reply via email to