You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by be...@apache.org on 2008/04/08 18:16:26 UTC

svn commit: r645987 - in /labs/vysper/src: main/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistry.java test/java/org/apache/vysper/xmpp/resourcebinding/ test/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistryTestCase.java

Author: berndf
Date: Tue Apr  8 09:16:24 2008
New Revision: 645987

URL: http://svn.apache.org/viewvc?rev=645987&view=rev
Log:
[vysper] have a registry where we can identify sessions and bound resources (LABS-111)

Added:
    labs/vysper/src/test/java/org/apache/vysper/xmpp/resourcebinding/
    labs/vysper/src/test/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistryTestCase.java
Modified:
    labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistry.java

Modified: labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistry.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistry.java?rev=645987&r1=645986&r2=645987&view=diff
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistry.java (original)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistry.java Tue Apr  8 09:16:24 2008
@@ -19,27 +19,144 @@
 import org.apache.vysper.xmpp.server.SessionContext;
 import org.apache.vysper.xmpp.uuid.JVMBuiltinUUIDGenerator;
 import org.apache.vysper.xmpp.uuid.UUIDGenerator;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
 
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.Collections;
+import java.util.Map;
+import java.util.HashMap;
 
 /**
- * assigns and holds resource ids
+ * assigns and holds resource ids and their related session
  */
 public class ResourceRegistry {
     
     private UUIDGenerator resourceIdGenerator = new JVMBuiltinUUIDGenerator();
-    protected final List<String> boundResources = new ArrayList<String>();
+    
+    protected final Map<String, SessionContext> boundResources = new HashMap<String, SessionContext>();
+    protected final Map<Entity, List<String>> entityResources = new HashMap<Entity, List<String>>(); 
 
     public String bindSession(SessionContext sessionContext) {
+        if (sessionContext == null) throw new IllegalArgumentException("session context cannot be NULL");
+        if (sessionContext.getInitiatingEntity() == null) throw new IllegalStateException("session context must have a initiating entity set");
         String resourceId = resourceIdGenerator.create();
-        boundResources.add(resourceId);
+
+        synchronized (boundResources) {
+            synchronized (entityResources) {
+                boundResources.put(resourceId, sessionContext);
+
+                Entity initiatingEntity = sessionContext.getInitiatingEntity();
+                List<String> resourceList = getResourceList(initiatingEntity);
+                if (resourceList == null) {
+                    resourceList = new ArrayList<String>();
+                    entityResources.put(getBareEntity(initiatingEntity), resourceList);
+                }
+                resourceList.add(resourceId);
+            }
+        } 
+
         return resourceId;
     }
 
     public Iterator<String> boundResources() {
-        return Collections.unmodifiableList(boundResources).iterator();
+        return Collections.unmodifiableSet(boundResources.keySet()).iterator();
+    }
+
+    public void unbindResource(String resourceId) {
+        boundResources.remove(resourceId);
+    }
+
+    public void unbindSession(SessionContext unbindingSessionContext) {
+        if (unbindingSessionContext == null) return;
+
+        synchronized (boundResources) {
+            synchronized (entityResources) {
+                // collect all remove candidates
+                List<String> removeResourceIds = getResourcesForSession(unbindingSessionContext);
+
+                // actually remove from bound resources
+                for (String removeResourceId : removeResourceIds) {
+                    unbindResource(removeResourceId);
+                }
+
+                // actually remove from entity map
+                List<String> resourceList = getResourceList(unbindingSessionContext.getInitiatingEntity());
+                if (resourceList != null) {
+                    resourceList.remove(removeResourceIds);
+                }
+            }
+        }
+    }
+
+    protected List<String> getResourcesForSession(SessionContext sessionContext) {
+        if (sessionContext == null) return null;
+
+        List<String> resourceIds = new ArrayList<String>();
+        for (String resourceId : boundResources.keySet()) {
+            SessionContext visitedSessionContext = boundResources.get(resourceId);
+            if (visitedSessionContext != null && visitedSessionContext.getSessionId().equals(sessionContext.getSessionId())) {
+                resourceIds.add(resourceId);
+                // indeed continue iteration, session might have more than one resource bound. 
+            }
+        }
+        return resourceIds;
+    }
+
+    public SessionContext getSessionContext(String resourceId) {
+        return boundResources.get(resourceId);
+    }
+
+    private Entity getBareEntity(Entity entity) {
+        if (entity.getResource() == null) return entity; // bare already
+        return new EntityImpl(entity.getNode(), entity.getDomain(), null);
+    }
+
+    /**
+     * @param entity
+     * @return all resources bound to this entity modulo the entity's resource (if given)
+     */
+    private List<String> getResourceList(Entity entity) {
+        return entityResources.get(getBareEntity(entity));
+    }
+
+    /**
+     * retrieve IDs of all bound resources for this entity
+     */
+    public List<String> getBoundResources(Entity entity) {
+        return getBoundResources(entity, true);
+    }
+
+    /**
+     * retrieve IDs of all bound resources for this entity
+     */
+    public List<String> getBoundResources(Entity entity, boolean considerBareID) {
+        // all resources for the entity
+        List<String> resourceList = Collections.unmodifiableList(getResourceList(entity));
+        
+        // if resource should not be considered, return all resources
+        if (considerBareID || entity.getResource() == null) return resourceList;
+        // resource not contained, result is empty
+        if (!resourceList.contains(entity.getResource())) {
+            return Collections.emptyList();
+        }
+        // do we have a bound entity and want only their resource returned?
+        List<String> singleResult = new ArrayList<String>();
+        singleResult.add(entity.getResource());
+        return singleResult;
+    }
+
+
+    public List<SessionContext> getSessions(Entity entity) {
+        List<SessionContext> sessionContexts = new ArrayList<SessionContext>();
+        
+        List<String> boundResources = getBoundResources(entity, false);
+        for (String resourceId : boundResources) {
+            sessionContexts.add(getSessionContext(resourceId));
+        }
+        
+        return sessionContexts;
     }
 }

Added: labs/vysper/src/test/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistryTestCase.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/test/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistryTestCase.java?rev=645987&view=auto
==============================================================================
--- labs/vysper/src/test/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistryTestCase.java (added)
+++ labs/vysper/src/test/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistryTestCase.java Tue Apr  8 09:16:24 2008
@@ -0,0 +1,151 @@
+/***********************************************************************
+ * Copyright (c) 2006-2007 The Apache Software Foundation.             *
+ * All rights reserved.                                                *
+ * ------------------------------------------------------------------- *
+ * Licensed 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.resourcebinding;
+
+import junit.framework.TestCase;
+import org.apache.vysper.xmpp.server.TestSessionContext;
+import org.apache.vysper.xmpp.server.SessionContext;
+import org.apache.vysper.xmpp.protocol.SessionStateHolder;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.addressing.EntityFormatException;
+
+import java.util.List;
+
+/**
+ */
+public class ResourceRegistryTestCase extends TestCase {
+    
+    protected ResourceRegistry resourceRegistry = new ResourceRegistry();
+
+    private TestSessionContext createSessionContext(Entity entity) {
+        SessionStateHolder sessionStateHolder = new SessionStateHolder();
+        TestSessionContext sessionContext = new TestSessionContext(sessionStateHolder);
+        sessionContext.setInitiatingEntity(entity);
+        return sessionContext;
+    }
+
+    public void testSessionNotWellDefinedForResourceBinding() {
+        TestSessionContext sessionContext = createSessionContext(null);
+        assertNull(sessionContext.getInitiatingEntity());
+        try {
+            resourceRegistry.bindSession(sessionContext);
+            fail("do not accept sessions with no initiating entity");
+        } catch (IllegalStateException _) {
+            // test succeeded
+        }
+    }
+    
+    public void testAddSession() throws EntityFormatException {
+        TestSessionContext sessionContext = createSessionContext(EntityImpl.parse("me@test"));
+        String resourceId = resourceRegistry.bindSession(sessionContext);
+        assertNotNull(resourceId);
+        List<String> resourceList = resourceRegistry.getResourcesForSession(sessionContext);
+        assertEquals(1, resourceList.size());
+        assertTrue(resourceList.contains(resourceId));
+    }
+
+    public void testAddMultipleSession() throws EntityFormatException {
+        TestSessionContext sessionContext1 = createSessionContext(EntityImpl.parse("me1@test"));
+        String resourceId1 = resourceRegistry.bindSession(sessionContext1);
+        TestSessionContext sessionContext2 = createSessionContext(EntityImpl.parse("me2@test"));
+        String resourceId2 = resourceRegistry.bindSession(sessionContext2);
+        assertNotNull(resourceId2);
+        List<String> resourceList = resourceRegistry.getResourcesForSession(sessionContext1);
+        assertEquals(1, resourceList.size());
+        assertTrue(resourceList.contains(resourceId1));
+        resourceList = resourceRegistry.getResourcesForSession(sessionContext2);
+        assertEquals(1, resourceList.size());
+        assertTrue(resourceList.contains(resourceId2));
+        
+        assertEquals(resourceRegistry.getSessionContext(resourceId1), sessionContext1);
+        assertEquals(resourceRegistry.getSessionContext(resourceId2), sessionContext2);
+    }
+    
+    public void testAddOneEntityMultipleResources() throws EntityFormatException {
+        EntityImpl entity = EntityImpl.parse("me@test");
+        
+        TestSessionContext sessionContext1 = createSessionContext(entity);
+        String resourceId1 = resourceRegistry.bindSession(sessionContext1);
+        
+        TestSessionContext sessionContext2 = createSessionContext(entity);
+        String resourceId2 = resourceRegistry.bindSession(sessionContext2);
+        
+        assertNotNull(resourceId1);
+        assertNotNull(resourceId2);
+        
+        List<String> resourceList = resourceRegistry.getBoundResources(entity);
+        assertEquals(2, resourceList.size());
+        assertTrue(resourceList.contains(resourceId1));
+        assertTrue(resourceList.contains(resourceId2));
+
+        List<SessionContext> sessionList = resourceRegistry.getSessions(entity);
+        assertEquals(2, resourceList.size());
+        assertTrue(sessionList.contains(sessionContext1));
+        assertTrue(sessionList.contains(sessionContext2));
+    }
+
+    public void testAddOneEntityMultipleResources_TolerateResourceIds() throws EntityFormatException {
+        EntityImpl entity = EntityImpl.parse("me@test");
+        
+        TestSessionContext sessionContext1 = createSessionContext(EntityImpl.parse("me@test/xy"));
+        String resourceId1 = resourceRegistry.bindSession(sessionContext1);
+        
+        TestSessionContext sessionContext2 = createSessionContext(EntityImpl.parse("me@test/ab"));
+        String resourceId2 = resourceRegistry.bindSession(sessionContext2);
+        
+        assertNotNull(resourceId1);
+        assertNotNull(resourceId2);
+        
+        List<String> resourceList = resourceRegistry.getBoundResources(entity);
+        assertEquals(2, resourceList.size());
+        assertTrue(resourceList.contains(resourceId1));
+        assertTrue(resourceList.contains(resourceId2));
+
+        List<SessionContext> sessionList = resourceRegistry.getSessions(entity);
+        assertEquals(2, resourceList.size());
+        assertTrue(sessionList.contains(sessionContext1));
+        assertTrue(sessionList.contains(sessionContext2));
+    }
+
+    public void testSameEntityMultipleResources() throws EntityFormatException {
+        EntityImpl entity = EntityImpl.parse("me@test");
+        
+        TestSessionContext sessionContext1 = createSessionContext(entity);
+        String resourceId1 = resourceRegistry.bindSession(sessionContext1);
+        
+        TestSessionContext sessionContext2 = createSessionContext(entity);
+        String resourceId2 = resourceRegistry.bindSession(sessionContext2);
+        
+        // resource ids are different
+        assertFalse(resourceId1.equals(resourceId2));
+    }
+    
+    public void testUnbindSimple() throws EntityFormatException {
+        EntityImpl entity = EntityImpl.parse("me@test");
+        
+        TestSessionContext sessionContext1 = createSessionContext(entity);
+        String resourceId1 = resourceRegistry.bindSession(sessionContext1);
+        assertEquals(sessionContext1, resourceRegistry.getSessionContext(resourceId1));
+        
+        resourceRegistry.unbindResource(resourceId1);
+        
+        assertNull(resourceRegistry.getSessionContext(resourceId1));
+        assertEquals(0, resourceRegistry.getBoundResources(entity).size());
+    }
+    
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org