You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by mj...@apache.org on 2009/08/06 11:36:41 UTC

svn commit: r801570 - in /mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src: main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/ main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/ main/java/org/apache...

Author: mjakl
Date: Thu Aug  6 09:36:40 2009
New Revision: 801570

URL: http://svn.apache.org/viewvc?rev=801570&view=rev
Log:
A user is now able to retrieve his/her affiliations to all nodes (retrieve-affiliations). This fixes VYSPER-171.

Added:
    mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/AffiliationItem.java
    mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/NodeAffiliationVisitor.java
    mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubRetrieveAffiliationsHandler.java
    mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubRetrieveAffiliationsTestCase.java
Modified:
    mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PubSubAffiliation.java
    mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PublishSubscribeModule.java
    mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/LeafNode.java
    mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/disco/PubSubDiscoInfoTestCase.java

Added: mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/AffiliationItem.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/AffiliationItem.java?rev=801570&view=auto
==============================================================================
--- mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/AffiliationItem.java (added)
+++ mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/AffiliationItem.java Thu Aug  6 09:36:40 2009
@@ -0,0 +1,53 @@
+/*
+ *  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.xep0060_pubsub;
+
+/**
+ * @author The Apache MINA Project (http://mina.apache.org)
+ */
+public class AffiliationItem {
+
+    protected String nodeName = null;
+    protected PubSubAffiliation affiliation = null;
+
+    /**
+     * Creates a new affiliation item with the supplied values.
+     * @param nodeName
+     * @param affil
+     */
+    public AffiliationItem(String nodeName, PubSubAffiliation affil) {
+        this.nodeName = nodeName;
+        this.affiliation = affil;
+    }
+
+    /**
+     * Returns the node of this affiliation.
+     */
+    public String getNodeName() {
+        return nodeName;
+    }
+
+    /**
+     * Returns the state of the affiliation.
+     */
+    public PubSubAffiliation getAffiliation() {
+        return affiliation;
+    }
+}

Modified: mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PubSubAffiliation.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PubSubAffiliation.java?rev=801570&r1=801569&r2=801570&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PubSubAffiliation.java (original)
+++ mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PubSubAffiliation.java Thu Aug  6 09:36:40 2009
@@ -26,9 +26,18 @@
  * @author The Apache MINA Project (http://mina.apache.org)
  */
 public enum PubSubAffiliation {
-    OUTCAST,
-    NONE,
-    MEMBER,
-    PUBLISHER,
-    OWNER
+    OUTCAST ("outcast"),
+    NONE ("none"),
+    MEMBER ("member"),
+    PUBLISHER ("publisher"),
+    OWNER ("owner");
+    
+    private final String xep0060Name;
+    private PubSubAffiliation(String name) {
+        this.xep0060Name = name;
+    }
+    
+    public String toString() {
+        return xep0060Name;
+    }
 }

Modified: mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PublishSubscribeModule.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PublishSubscribeModule.java?rev=801570&r1=801569&r2=801570&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PublishSubscribeModule.java (original)
+++ mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PublishSubscribeModule.java Thu Aug  6 09:36:40 2009
@@ -26,6 +26,7 @@
 import org.apache.vysper.xmpp.modules.DefaultDiscoAwareModule;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.PubSubCreateNodeHandler;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.PubSubPublishHandler;
+import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.PubSubRetrieveAffiliationsHandler;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.PubSubRetrieveSubscriptionsHandler;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.PubSubSubscribeHandler;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.PubSubUnsubscribeHandler;
@@ -212,6 +213,7 @@
         pubsubHandlers.add(new PubSubPublishHandler(serviceConfiguration));
         pubsubHandlers.add(new PubSubCreateNodeHandler(serviceConfiguration));
         pubsubHandlers.add(new PubSubRetrieveSubscriptionsHandler(serviceConfiguration));
+        pubsubHandlers.add(new PubSubRetrieveAffiliationsHandler(serviceConfiguration));
         dictionary.add(new NamespaceHandlerDictionary(NamespaceURIs.XEP0060_PUBSUB, pubsubHandlers));
     }
 }

Added: mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/NodeAffiliationVisitor.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/NodeAffiliationVisitor.java?rev=801570&view=auto
==============================================================================
--- mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/NodeAffiliationVisitor.java (added)
+++ mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/NodeAffiliationVisitor.java Thu Aug  6 09:36:40 2009
@@ -0,0 +1,67 @@
+/*
+ *  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.xep0060_pubsub.handler;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.AffiliationItem;
+import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.NodeVisitor;
+import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.PubSubAffiliation;
+import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.LeafNode;
+
+/**
+ * @author The Apache MINA Project (http://mina.apache.org)
+ */
+public class NodeAffiliationVisitor implements NodeVisitor {
+
+    // bare jid to compare with
+    protected Entity bareJID = null;
+    // the list of user <-> node affiliation
+    protected List<AffiliationItem> affiliations = null;
+    
+    /**
+     * Creates a new node visitor to fetch all affiliations for the given user.
+     */
+    public NodeAffiliationVisitor(Entity entity) {
+        this.bareJID = entity.getBareJID();
+        this.affiliations = new ArrayList<AffiliationItem>();
+    }
+
+    /**
+     * Visit all nodes and get the affiliation of the requesting user.
+     */
+    public void visit(LeafNode ln) {
+        PubSubAffiliation affil = ln.getAffiliation(bareJID);
+        if(!affil.equals(PubSubAffiliation.NONE)) {
+            AffiliationItem ai = new AffiliationItem(ln.getName(), affil);
+            affiliations.add(ai);
+        }
+    }
+
+    /**
+     * Return the list of known affiliations (other than "NONE").
+     */
+    public List<AffiliationItem> getAffiliations() {
+        return affiliations;
+    }
+
+}

Added: mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubRetrieveAffiliationsHandler.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubRetrieveAffiliationsHandler.java?rev=801570&view=auto
==============================================================================
--- mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubRetrieveAffiliationsHandler.java (added)
+++ mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubRetrieveAffiliationsHandler.java Thu Aug  6 09:36:40 2009
@@ -0,0 +1,115 @@
+/*
+ *  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.xep0060_pubsub.handler;
+
+import java.util.List;
+
+import org.apache.vysper.compliance.SpecCompliant;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.AffiliationItem;
+import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.PubSubServiceConfiguration;
+import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.CollectionNode;
+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.IQStanzaType;
+import org.apache.vysper.xmpp.stanza.Stanza;
+import org.apache.vysper.xmpp.stanza.StanzaBuilder;
+
+
+/**
+ * This class handles the "affiliations" use cases for the "pubsub" namespace.
+ * 
+ * @author The Apache MINA Project (http://mina.apache.org)
+ */
+@SpecCompliant(spec="xep-0060", section="5.7", status= SpecCompliant.ComplianceStatus.FINISHED, coverage = SpecCompliant.ComplianceCoverage.PARTIAL)
+public class PubSubRetrieveAffiliationsHandler extends AbstractPubSubGeneralHandler {
+
+    /**
+     * @param serviceConfiguration
+     */
+    public PubSubRetrieveAffiliationsHandler(PubSubServiceConfiguration serviceConfiguration) {
+        super(serviceConfiguration);
+    }
+
+    /**
+     * @return "subscriptions" as worker element.
+     */
+    @Override
+    protected String getWorkerElement() {
+        return "affiliations";
+    }
+
+    /**
+     * This method takes care of handling the "affiliations" use-case
+     * 
+     * @return the appropriate response stanza
+     */
+    @Override
+    protected Stanza handleGet(IQStanza stanza,
+            ServerRuntimeContext serverRuntimeContext,
+            SessionContext sessionContext) {
+        Entity serverJID = serviceConfiguration.getServerJID();
+        CollectionNode root = serviceConfiguration.getRootNode();
+        
+        Entity sender = extractSenderJID(stanza, sessionContext);
+        String iqStanzaID = stanza.getAttributeValue("id");
+
+        StanzaBuilder sb = StanzaBuilder.createIQStanza(serverJID, sender, IQStanzaType.RESULT, iqStanzaID);
+        sb.startInnerElement("pubsub");
+        sb.addNamespaceAttribute(NamespaceURIs.XEP0060_PUBSUB);
+        
+        List<AffiliationItem> subscriptions = collectAffiliations(root, sender);
+
+        buildSuccessStanza(sb, subscriptions);
+
+        sb.endInnerElement(); // pubsub
+        return new IQStanza(sb.getFinalStanza());
+    }
+
+    /**
+     * Traverses through all nodes to collect all affiliations of the user.
+     * @return the list of subscriptions or an empty list.
+     */
+    private List<AffiliationItem> collectAffiliations(CollectionNode root, Entity sender) {
+        List<AffiliationItem> affiliations;
+        NodeAffiliationVisitor nodeAffiliationVisitor = new NodeAffiliationVisitor(sender);
+        root.acceptNodes(nodeAffiliationVisitor);
+        affiliations = nodeAffiliationVisitor.getAffiliations();
+        return affiliations;
+    }
+
+    /**
+     * This method adds the "affiliations" and eventual "affiliation" elements to the given StanzaBuilder.
+     */
+    private void buildSuccessStanza(StanzaBuilder sb, List<AffiliationItem> affiliations) {
+        sb.startInnerElement("affiliations");
+        
+        for(AffiliationItem s : affiliations) {
+            sb.startInnerElement("affiliation");
+            sb.addAttribute("node", s.getNodeName());
+            sb.addAttribute("affiliation", s.getAffiliation().toString());
+            sb.endInnerElement();
+        }
+        
+        sb.endInnerElement();
+    }
+}

Modified: mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/LeafNode.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/LeafNode.java?rev=801570&r1=801569&r2=801570&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/LeafNode.java (original)
+++ mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/LeafNode.java Thu Aug  6 09:36:40 2009
@@ -230,6 +230,7 @@
         infoElements.add(PubsubFeatures.PUBLISH.getFeature());
         infoElements.add(PubsubFeatures.SUBSCRIBE.getFeature());
         infoElements.add(PubsubFeatures.RETRIEVE_SUBSCRIPTIONS.getFeature());
+        infoElements.add(PubsubFeatures.RETRIEVE_AFFILIATIONS.getFeature());
         return infoElements;
     }
 
@@ -276,4 +277,13 @@
         PubSubAffiliation affiliation = this.storage.getAffiliation(name, sender);
         return affiliation.compareTo(requestedAffiliation) >= 0;
     }
+
+    /**
+     * Returns the affiliation for the given bareJID.
+     * @param bareJID
+     * @return All affiliations ("NONE" if no other affiliation is known).
+     */
+    public PubSubAffiliation getAffiliation(Entity bareJID) {
+        return this.storage.getAffiliation(name, bareJID);
+    }
 }

Modified: mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/disco/PubSubDiscoInfoTestCase.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/disco/PubSubDiscoInfoTestCase.java?rev=801570&r1=801569&r2=801570&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/disco/PubSubDiscoInfoTestCase.java (original)
+++ mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/disco/PubSubDiscoInfoTestCase.java Thu Aug  6 09:36:40 2009
@@ -120,6 +120,7 @@
                 , PubsubFeatures.PUBLISH.toString()
                 , PubsubFeatures.SUBSCRIBE.toString()
                 , PubsubFeatures.RETRIEVE_SUBSCRIPTIONS.toString()
+                , PubsubFeatures.RETRIEVE_AFFILIATIONS.toString()
                 };
         XMLElement[] elementList = collectFeatures(inner, featuresList);
         

Added: mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubRetrieveAffiliationsTestCase.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubRetrieveAffiliationsTestCase.java?rev=801570&view=auto
==============================================================================
--- mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubRetrieveAffiliationsTestCase.java (added)
+++ mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubRetrieveAffiliationsTestCase.java Thu Aug  6 09:36:40 2009
@@ -0,0 +1,121 @@
+/*
+ *  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.xep0060_pubsub.handler;
+
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.modules.core.base.handler.IQHandler;
+import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.AbstractPublishSubscribeTestCase;
+import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.LeafNode;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.apache.vysper.xmpp.protocol.ResponseStanzaContainer;
+import org.apache.vysper.xmpp.stanza.IQStanza;
+import org.apache.vysper.xmpp.stanza.IQStanzaType;
+import org.apache.vysper.xmpp.stanza.Stanza;
+import org.apache.vysper.xmpp.stanza.StanzaBuilder;
+import org.apache.vysper.xmpp.xmlfragment.XMLElement;
+
+/**
+ * @author The Apache MINA Project (http://mina.apache.org)
+ */
+public class PubSubRetrieveAffiliationsTestCase extends AbstractPublishSubscribeTestCase {
+    protected LeafNode n1 = null;
+    protected LeafNode n2 = null;
+    protected LeafNode n3 = null;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        
+        n1 = new LeafNode(serviceConfiguration, "Node1", "Node 1 used for testing purposes", client);
+        n2 = new LeafNode(serviceConfiguration, "Node2", "Node 2 used for testing purposes", client);
+        n3 = new LeafNode(serviceConfiguration, "Node3", "Node 3 used for testing purposes", client);
+        
+        root.add(n1);
+        root.add(n2);
+        root.add(n3);
+    }
+    
+    @Override
+    protected IQHandler getHandler() {
+        return new PubSubRetrieveAffiliationsHandler(serviceConfiguration);
+    }
+
+    @Override
+    protected AbstractStanzaGenerator getDefaultStanzaGenerator() {
+        return new DefaultRetrieveAffiliationsStanzaGenerator();
+    }
+
+    public void testNoAffiliations() {
+        Entity client2 = new EntityImpl("yoda", "starwars.com", null);
+        
+        AbstractStanzaGenerator sg = getDefaultStanzaGenerator();
+        Stanza stanza = sg.getStanza(client2, pubsubService, "id123", null);
+        ResponseStanzaContainer result = sendStanza(stanza, true);
+        
+        assertTrue(result.hasResponse());
+        
+        IQStanza response = new IQStanza(result.getResponseStanza());
+        assertEquals(IQStanzaType.RESULT.value(),response.getType());
+        XMLElement sub = response.getFirstInnerElement().getFirstInnerElement();
+        assertEquals("affiliations", sub.getName());
+        assertEquals(0, sub.getInnerElements().size()); // there should be no affiliations
+    }
+    
+    public void testSomeAffiliations() {
+        AbstractStanzaGenerator sg = getDefaultStanzaGenerator();
+        
+        Stanza stanza = sg.getStanza(client, pubsubService, "4711", null);
+        ResponseStanzaContainer result = sendStanza(stanza, true);
+        
+        assertTrue(result.hasResponse());
+        
+        IQStanza response = new IQStanza(result.getResponseStanza());
+        assertEquals(IQStanzaType.RESULT.value(),response.getType());
+        XMLElement sub = response.getFirstInnerElement().getFirstInnerElement();
+        assertEquals("affiliations", sub.getName());
+        assertEquals(3, sub.getInnerElements().size());
+        
+        for(XMLElement e : sub.getInnerElements()) {
+            assertEquals("owner", e.getAttributeValue("affiliation"));
+        }
+        
+    }
+
+    class DefaultRetrieveAffiliationsStanzaGenerator extends AbstractStanzaGenerator {
+        @Override
+        protected StanzaBuilder buildInnerElement(Entity client, Entity pubsub, StanzaBuilder sb, String node) {
+            sb.startInnerElement("affiliations");
+            sb.endInnerElement();
+            return sb;
+        }
+
+        @Override
+        protected String getNamespace() {
+            return NamespaceURIs.XEP0060_PUBSUB;
+        }
+
+        @Override
+        protected IQStanzaType getStanzaType() {
+            return IQStanzaType.GET;
+        }
+    }
+
+}