Author: berndf
Date: Tue Sep  1 12:16:21 2009
New Revision: 809995

URL: http://svn.apache.org/viewvc?rev=809995&view=rev
Log:
VYSPER-6: add tests and fixes

Added:
    
mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/im/handler/DirectedPresenceHandlerTestCase.java
      - copied, changed from r809880, 
mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceAvailUpdateOutHandlerTestCase.java
Modified:
    
mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceAvailabilityHandler.java

Modified: 
mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceAvailabilityHandler.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceAvailabilityHandler.java?rev=809995&r1=809994&r2=809995&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceAvailabilityHandler.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceAvailabilityHandler.java
 Tue Sep  1 12:16:21 2009
@@ -55,6 +55,8 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * handling presence stanzas related to availability
@@ -63,6 +65,8 @@
  */
 public class PresenceAvailabilityHandler extends 
AbstractPresenceSpecializedHandler {
 
+    protected static final String DIRECTED_PRESENCE_MAP = 
"DIRECTED_PRESENCE_MAP_";
+    
     final Logger logger = 
LoggerFactory.getLogger(PresenceAvailabilityHandler.class);
 
     /**
@@ -171,6 +175,13 @@
             contacts.add(rosterContact.getJid());
         }
 
+        // broadcast unavailable to all directed-presence contacts
+        Set<Entity> entitySet = getDirectedPresenceMap(sessionContext, user);
+        if (entitySet != null) {
+            contacts.addAll(entitySet);
+            entitySet.clear(); // and un-record them
+        }
+
         // broadcast presence notification to all resources of
         // current entity.
         List<String> resources = registry.getAvailableResources(user);
@@ -287,22 +298,50 @@
                                                           Entity user,
                                                           ResourceRegistry 
registry, 
                                                           final boolean 
unvailable) {
+        final Entity to = presenceStanza.getTo();
+        Entity from = presenceStanza.getFrom();
+        
         Stanza redirectDirectedStanza = presenceStanza;
-        if (presenceStanza.getFrom() == null) {
-            EntityImpl from = new 
EntityImpl(sessionContext.getInitiatingEntity(), 
registry.getUniqueResourceForSession(sessionContext));
+        if (from == null || !from.isResourceSet()) {
+            from = new EntityImpl(sessionContext.getInitiatingEntity(), 
registry.getUniqueResourceForSession(sessionContext));
             redirectDirectedStanza = 
StanzaBuilder.createForwardStanza(presenceStanza, from, null);
         }
 
+        Set<Entity> dpMap = getDirectedPresenceMap(sessionContext, from);
+
+        boolean isFromContact;
         try {
-            
serverRuntimeContext.getStanzaRelay().relay(presenceStanza.getTo(), 
redirectDirectedStanza, new IgnoreFailureStrategy());
+            isFromContact = 
rosterManager.retrieve(from.getBareJID()).getEntry(to.getBareJID()).hasFrom();
+        } catch (Exception e) {
+            isFromContact = false;
+        }
+        boolean IsTOAvailable = 
!ResourceState.isAvailable(registry.getResourceState(from.getResource()));
+
+        if (unvailable) {
+            dpMap.remove(to);
+        } else {
+            if (!isFromContact || !IsTOAvailable) dpMap.add(to);
+        }
+
+        try {
+            serverRuntimeContext.getStanzaRelay().relay(to, 
redirectDirectedStanza, new IgnoreFailureStrategy());
         } catch (DeliveryException e) {
-            e.printStackTrace();  //To change body of catch statement use File 
| Settings | File Templates.
+            logger.warn("relaying directed presence failed. from = " + from + 
", to = " + to);
         }
 
-        logger.warn("directed presence is not yet fully implemented");
         return null;
     }
-    
+
+    private Set<Entity> getDirectedPresenceMap(SessionContext sessionContext, 
Entity from) {
+        String mapKey = DIRECTED_PRESENCE_MAP + from.getResource();
+        Set<Entity> directedPresenceMap = 
(Set<Entity>)sessionContext.getAttribute(mapKey);
+        if (directedPresenceMap == null) {
+            directedPresenceMap = new HashSet<Entity>();
+            sessionContext.putAttribute(mapKey, directedPresenceMap);
+        }
+        return directedPresenceMap;
+    }
+
     @SpecCompliant(spec = "RFC3921bis-08", section = "4.5.3")
     private PresenceStanza handleInboundUnavailable(PresenceStanza 
presenceStanza, 
                                                     ServerRuntimeContext 
serverRuntimeContext, 

Copied: 
mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/im/handler/DirectedPresenceHandlerTestCase.java
 (from r809880, 
mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceAvailUpdateOutHandlerTestCase.java)
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/im/handler/DirectedPresenceHandlerTestCase.java?p2=mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/im/handler/DirectedPresenceHandlerTestCase.java&p1=mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceAvailUpdateOutHandlerTestCase.java&r1=809880&r2=809995&rev=809995&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceAvailUpdateOutHandlerTestCase.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/im/handler/DirectedPresenceHandlerTestCase.java
 Tue Sep  1 12:16:21 2009
@@ -21,76 +21,98 @@
 package org.apache.vysper.xmpp.modules.core.im.handler;
 
 import org.apache.vysper.xmpp.addressing.EntityFormatException;
+import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.delivery.StanzaReceiverRelay;
 import org.apache.vysper.xmpp.stanza.Stanza;
 import org.apache.vysper.xmpp.stanza.StanzaBuilder;
 import org.apache.vysper.xmpp.stanza.XMPPCoreStanza;
+import org.apache.vysper.xmpp.stanza.PresenceStanza;
+import org.apache.vysper.xmpp.stanza.PresenceStanzaType;
 import org.apache.vysper.xmpp.state.resourcebinding.BindException;
 import org.apache.vysper.xmpp.state.resourcebinding.ResourceState;
+import org.apache.vysper.xmpp.server.SessionState;
+
+import java.util.Set;
 
 /**
  */
-public class PresenceAvailUpdateOutHandlerTestCase extends 
PresenceHandlerBaseTestCase {
+public class DirectedPresenceHandlerTestCase extends 
PresenceHandlerBaseTestCase {
 
     protected PresenceHandler handler = new PresenceHandler();
 
     public void testUpdatedPresence() throws BindException, 
EntityFormatException {
         StanzaReceiverRelay receiverRelay = (StanzaReceiverRelay) 
sessionContext.getServerRuntimeContext().getStanzaRelay();
+        setResourceState(initiatingUser.getBoundResourceId(), 
ResourceState.AVAILABLE_INTERESTED);
 
         // at first, initial presence
-        XMPPCoreStanza initialPresence = 
XMPPCoreStanza.getWrapper(StanzaBuilder.createPresenceStanza(initiatingUser.getEntityFQ(),
 null, null, null, null, null).getFinalStanza());
+        XMPPCoreStanza initialPresence = 
XMPPCoreStanza.getWrapper(StanzaBuilder.createPresenceStanza(initiatingUser.getEntityFQ(),
 unrelatedUser.getEntityFQ(), null, null, null, null).getFinalStanza());
         handler.executeCore(initialPresence, 
sessionContext.getServerRuntimeContext(), true, sessionContext);
         assertTrue(0 < receiverRelay.getCountDelivered());
+
+        // directed presence has been recorded internally
+        Set<Entity> map = 
(Set<Entity>)sessionContext.getAttribute("DIRECTED_PRESENCE_MAP_" + 
initiatingUser.getBoundResourceId());
+        assertNotNull(map);
+        assertEquals(map.iterator().next(), unrelatedUser.getEntityFQ());
+
+        Stanza directedPresence = unrelatedUser.getNextStanza();
+        assertNotNull(directedPresence); 
+        assertTrue(PresenceStanza.isOfType(directedPresence)); // is presence
+        PresenceStanza presenceStanza = new PresenceStanza(directedPresence);
+        assertEquals(initiatingUser.getEntityFQ(), presenceStanza.getFrom());
+
         resetRecordedStanzas(); // purge recorded 
-        assertTrue(0 == receiverRelay.getCountDelivered());
-        
-        // send update now
-        final String showValue = "chatty";
-        
-        XMPPCoreStanza updatePresence = 
XMPPCoreStanza.getWrapper(StanzaBuilder.createPresenceStanza(initiatingUser.getEntityFQ(),
 null, null, null, showValue, null).getFinalStanza());
-        handler.executeCore(updatePresence, 
sessionContext.getServerRuntimeContext(), true, sessionContext);
-        // check resource state 
-        assertEquals(ResourceState.AVAILABLE, getResourceState());
 
-        // 3 presence update broadcasts to same session + 2 presence to 
subscribers
-        assertEquals(3+2, ((StanzaReceiverRelay) 
sessionContext.getServerRuntimeContext().getStanzaRelay()).getCountDelivered());
-        
-        //
-        // check presence broadcasts to resources of same session (self, 
interested & available)
-        //
-        
-        Stanza initiatorNotification = initiatingUser.getNextStanza();
-        assertNotNull(initiatorNotification);
-        assertTrue(checkPresence(initiatorNotification, null, 
initiatingUser.getEntityFQ(), showValue));
-        
assertTrue(initiatorNotification.getVerifier().toAttributeEquals(initiatingUser.getEntityFQ().getFullQualifiedName()));
-        
-        Stanza availableResourceNotification = 
anotherAvailableUser.getNextStanza();
-        assertNotNull(availableResourceNotification);
-        assertTrue(checkPresence(availableResourceNotification, null, 
initiatingUser.getEntityFQ(), showValue));
-        
assertTrue(availableResourceNotification.getVerifier().toAttributeEquals(anotherAvailableUser.getEntityFQ().getFullQualifiedName()));
-        assertNull(anotherAvailableUser.getNextStanza()); // no more stanzas
-        
-        Stanza interestedResourceNotification = 
anotherInterestedUser.getNextStanza();
-        assertNotNull(interestedResourceNotification);
-        assertTrue(checkPresence(interestedResourceNotification, null, 
initiatingUser.getEntityFQ(), showValue));
-        
assertTrue(interestedResourceNotification.getVerifier().toAttributeEquals(initiatingUser.getEntity().getFullQualifiedName()
 + "/" + anotherInterestedUser.getBoundResourceId()));
-        assertNull(anotherInterestedUser.getNextStanza()); // no more stanzas
-        
-        assertNull(anotherInterestedNotAvailUser.getNextStanza()); // no 
stanza at all
+        // directed unavailable presence 
+        XMPPCoreStanza directedUnvailPresence = 
XMPPCoreStanza.getWrapper(StanzaBuilder.createPresenceStanza(initiatingUser.getEntityFQ(),
 unrelatedUser.getEntityFQ(), null, PresenceStanzaType.UNAVAILABLE, null, 
null).getFinalStanza());
+        handler.executeCore(directedUnvailPresence, 
sessionContext.getServerRuntimeContext(), true, sessionContext);
+        assertTrue(0 < receiverRelay.getCountDelivered());
 
-        //
-        // check other presences
-        //        
+        // directed presence has been recorded internally
+        map = 
(Set<Entity>)sessionContext.getAttribute("DIRECTED_PRESENCE_MAP_" + 
initiatingUser.getBoundResourceId());
+        assertTrue(map.size() == 0);
+        ResourceState resourceState = 
sessionContext.getServerRuntimeContext().getResourceRegistry().getResourceState(initiatingUser.getBoundResourceId());
+        assertTrue(ResourceState.isAvailable(resourceState));
+
+        Stanza directedUnavailPresence = unrelatedUser.getNextStanza();
+        assertNotNull(directedUnavailPresence); 
+        assertTrue(PresenceStanza.isOfType(directedUnavailPresence)); // is 
presence
+        presenceStanza = new PresenceStanza(directedUnavailPresence);
+        assertEquals(initiatingUser.getEntityFQ(), presenceStanza.getFrom());
+        assertEquals(PresenceStanzaType.UNAVAILABLE, 
presenceStanza.getPresenceType());
         
-        assertNull(unrelatedUser.getNextStanza()); // does not sent pres to 
everybody arbitrarily
-        assertTrue(checkPresence(subscribed_FROM.getNextStanza(), null, 
initiatingUser.getEntityFQ(), showValue)); // pres sent to FROM contacts
-        assertNull(subscribed_FROM.getNextStanza()); // no second stanza sent 
to FROMs
-
-        // initial pres and pres probe might come in different order
-        assertTrue(checkPresence(subscribed_BOTH.getNextStanza(), null, 
initiatingUser.getEntityFQ(), showValue)); // pres sent to BOTH contacts
-        assertNull(subscribed_BOTH.getNextStanza()); // no second stanza 
(especially probe) sent to BOTHs
-
-        assertNull(subscribed_TO.getNextStanza()); // pres (especially probe)  
NOT sent to TO contacts
     }
+    public void testUnavailableForDirectedPresences() throws BindException, 
EntityFormatException {
+        StanzaReceiverRelay receiverRelay = (StanzaReceiverRelay) 
sessionContext.getServerRuntimeContext().getStanzaRelay();
+        setResourceState(initiatingUser.getBoundResourceId(), 
ResourceState.AVAILABLE_INTERESTED);
+
+        // at first, initial presence
+        XMPPCoreStanza initialPresence = 
XMPPCoreStanza.getWrapper(StanzaBuilder.createPresenceStanza(initiatingUser.getEntityFQ(),
 unrelatedUser.getEntityFQ(), null, null, null, null).getFinalStanza());
+        handler.executeCore(initialPresence, 
sessionContext.getServerRuntimeContext(), true, sessionContext);
+
+        // directed presence has been recorded internally
+        Set<Entity> map = 
(Set<Entity>)sessionContext.getAttribute("DIRECTED_PRESENCE_MAP_" + 
initiatingUser.getBoundResourceId());
+        assertEquals(map.iterator().next(), unrelatedUser.getEntityFQ());
 
-}
+        resetRecordedStanzas(); // purge recorded 
+
+        // GENERAL unavailable presence 
+        XMPPCoreStanza generalUnavailable = 
XMPPCoreStanza.getWrapper(StanzaBuilder.createPresenceStanza(initiatingUser.getEntityFQ(),
 null, null, PresenceStanzaType.UNAVAILABLE, null, null).getFinalStanza());
+        handler.executeCore(generalUnavailable, 
sessionContext.getServerRuntimeContext(), true, sessionContext);
+        assertTrue(0 < receiverRelay.getCountDelivered());
+        ResourceState resourceState = 
sessionContext.getServerRuntimeContext().getResourceRegistry().getResourceState(initiatingUser.getBoundResourceId());
+        assertFalse(ResourceState.isAvailable(resourceState));
+
+        // directed presence has been recorded internally
+        map = 
(Set<Entity>)sessionContext.getAttribute("DIRECTED_PRESENCE_MAP_" + 
initiatingUser.getBoundResourceId());
+        assertEquals(0, map.size());
+
+        Stanza directedUnavailPresence = unrelatedUser.getNextStanza();
+        assertNotNull(directedUnavailPresence); 
+        assertTrue(PresenceStanza.isOfType(directedUnavailPresence)); // is 
presence
+        PresenceStanza presenceStanza = new 
PresenceStanza(directedUnavailPresence);
+        assertEquals(initiatingUser.getEntityFQ(), presenceStanza.getFrom());
+        assertEquals(PresenceStanzaType.UNAVAILABLE, 
presenceStanza.getPresenceType());
+        
+    }
+    
+}
\ No newline at end of file


Reply via email to