Author: mjakl
Date: Sun Aug 23 22:00:08 2009
New Revision: 807022

URL: http://svn.apache.org/viewvc?rev=807022&view=rev
Log:
Implemented "Manage Affiliations". Added the ability to change affiliations 
(VYSPER-160), and made sure that the last owner cannot resign (VYSPER-161).

Added:
    
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerManageAffiliationsHandler.java
      - copied, changed from r807013, 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerRetrieveAffiliationsHandler.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/LastOwnerResignedException.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerModifyAffiliationsTestCase.java
      - copied, changed from r807013, 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerRetrieveAffiliationsTestCase.java
Removed:
    
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerRetrieveAffiliationsHandler.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/handler/ErrorStanzaGenerator.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/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/storageprovider/LeafNodeInMemoryStorageProvider.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/storageprovider/LeafNodeStorageProvider.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PubSubTests.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerRetrieveAffiliationsTestCase.java

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=807022&r1=807021&r2=807022&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
 Sun Aug 23 22:00:08 2009
@@ -40,4 +40,19 @@
     public String toString() {
         return xep0060Name;
     }
+
+    /**
+     * Returns the correct PubSubAffiliation object for the given string.
+     * The case will be ignored.
+     *
+     * @param name The name of the requested affiliation object.
+     * @return the affiliation object, NONE if not known.
+     */
+    public static PubSubAffiliation get(String name) {
+        if(name.equalsIgnoreCase(OUTCAST.toString())) return OUTCAST;
+        if(name.equalsIgnoreCase(MEMBER.toString())) return MEMBER;
+        if(name.equalsIgnoreCase(PUBLISHER.toString())) return PUBLISHER;
+        if(name.equalsIgnoreCase(OWNER.toString())) return OWNER;
+        return NONE;
+    }
 }

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/ErrorStanzaGenerator.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/ErrorStanzaGenerator.java?rev=807022&r1=807021&r2=807022&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/ErrorStanzaGenerator.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/ErrorStanzaGenerator.java
 Sun Aug 23 22:00:08 2009
@@ -141,6 +141,18 @@
     }
 
     /**
+     * Create a general error stanza (bad-request).
+     *
+     * @param sender who sent the erroneous request.
+     * @param receiver who was the recipient of the erroneous request.
+     * @param stanza the stanza of the erroneous request.
+     * @return the generated stanza.
+     */
+    public Stanza generateBadRequestErrorStanza(Entity sender, Entity 
receiver, IQStanza stanza) {
+        return errorResponses.getStanzaError(StanzaErrorCondition.BAD_REQUEST, 
stanza, StanzaErrorType.MODIFY, null, null, null);
+    }
+
+    /**
      * Create a conflict error stanza. For example if a node with an existing 
nodeID is to be created.
      * 
      * @param sender
@@ -165,4 +177,15 @@
         return element;
     }
 
+    /**
+     * Create a general error stanza (bad-request).
+     *
+     * @param sender who sent the erroneous request.
+     * @param receiver who was the recipient of the erroneous request.
+     * @param stanza the stanza of the erroneous request.
+     * @return the generated stanza.
+     */
+    public Stanza generateNotAcceptableErrorStanza(Entity sender, Entity 
receiver, IQStanza stanza) {
+        return 
errorResponses.getStanzaError(StanzaErrorCondition.NOT_ACCEPTABLE, stanza, 
StanzaErrorType.MODIFY, null, null, null);
+    }
 }

Copied: 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerManageAffiliationsHandler.java
 (from r807013, 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerRetrieveAffiliationsHandler.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/owner/PubSubOwnerManageAffiliationsHandler.java?p2=mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerManageAffiliationsHandler.java&p1=mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerRetrieveAffiliationsHandler.java&r1=807013&r2=807022&rev=807022&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerRetrieveAffiliationsHandler.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerManageAffiliationsHandler.java
 Sun Aug 23 22:00:08 2009
@@ -22,12 +22,12 @@
 import org.apache.vysper.compliance.SpecCompliance;
 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.CollectingMemberAffiliationVisitor;
-import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.PubSubPrivilege;
-import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.PubSubServiceConfiguration;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.addressing.EntityFormatException;
+import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.*;
 import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.CollectionNode;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.LeafNode;
+import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.LastOwnerResignedException;
 import org.apache.vysper.xmpp.protocol.NamespaceURIs;
 import org.apache.vysper.xmpp.server.ServerRuntimeContext;
 import org.apache.vysper.xmpp.server.SessionContext;
@@ -35,6 +35,7 @@
 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;
 
 import java.util.List;
 
@@ -45,14 +46,14 @@
  * @author The Apache MINA Project (http://mina.apache.org)
  */
 @SpecCompliant(spec="xep-0060", section="8.9", status= 
SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = 
SpecCompliant.ComplianceCoverage.PARTIAL)
-public class PubSubOwnerRetrieveAffiliationsHandler extends 
AbstractPubSubOwnerHandler {
+public class PubSubOwnerManageAffiliationsHandler extends 
AbstractPubSubOwnerHandler {
 
     /**
      * Creates a new handler with the supplied configuration object.
      *
      * @param serviceConfiguration configuration object to use.
      */
-    public PubSubOwnerRetrieveAffiliationsHandler(PubSubServiceConfiguration 
serviceConfiguration) {
+    public PubSubOwnerManageAffiliationsHandler(PubSubServiceConfiguration 
serviceConfiguration) {
         super(serviceConfiguration);
     }
 
@@ -110,6 +111,69 @@
     }
 
     /**
+     * This method takes care of handling the "affiliations" use-case 
including all (relevant) error conditions.
+     *
+     * @return the appropriate response stanza (either success or some error 
condition).
+     */
+    @Override
+    @SpecCompliance(compliant = {
+            @SpecCompliant(spec="xep-0060", section="8.9.2.2", status= 
SpecCompliant.ComplianceStatus.FINISHED, coverage = 
SpecCompliant.ComplianceCoverage.PARTIAL)
+            , @SpecCompliant(spec="xep-0060", section="8.9.2.3.3", status= 
SpecCompliant.ComplianceStatus.FINISHED, coverage = 
SpecCompliant.ComplianceCoverage.COMPLETE)
+            , @SpecCompliant(spec="xep-0060", section="8.9.2.3.4", status= 
SpecCompliant.ComplianceStatus.FINISHED, coverage = 
SpecCompliant.ComplianceCoverage.COMPLETE)
+        })
+    protected Stanza handleSet(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_OWNER);
+
+        String nodeName = extractNodeName(stanza);
+        LeafNode node = root.find(nodeName);
+
+        if(node == null) {
+            return errorStanzaGenerator.generateNoNodeErrorStanza(sender, 
serverJID, stanza);
+        }
+
+        if(!node.isAuthorized(sender, PubSubPrivilege.MANAGE_AFFILIATIONS)) {
+            return 
errorStanzaGenerator.generateInsufficientPrivilegesErrorStanza(sender, 
serverJID, stanza);
+        }
+
+
+        XMLElement affiliationElement = null;
+        try {
+            
if(stanza.getFirstInnerElement().getFirstInnerElement().getInnerElements().size()
 != 1) {
+                return 
errorStanzaGenerator.generateNotAcceptableErrorStanza(serverJID, sender, 
stanza);
+            }
+
+            affiliationElement = 
stanza.getFirstInnerElement().getFirstInnerElement().getFirstInnerElement();
+
+            Entity userJID = null;
+            try {
+                userJID = 
EntityImpl.parse(affiliationElement.getAttributeValue("jid"));
+            } catch (EntityFormatException e) {
+                return 
errorStanzaGenerator.generateJIDMalformedErrorStanza(serverJID, sender, 
stanza); // TODO not defined in the standard(?)
+            }
+
+            PubSubAffiliation newAffiliation = 
PubSubAffiliation.get(affiliationElement.getAttributeValue("affiliation"));
+            node.setAffiliation(userJID, newAffiliation);
+        } catch(LastOwnerResignedException e) {
+            // if the last owner tries to resign.
+            return 
errorStanzaGenerator.generateNotAcceptableErrorStanza(serverJID, sender, 
stanza);
+        } catch(Throwable t) { // possible null-pointer
+            return 
errorStanzaGenerator.generateBadRequestErrorStanza(serverJID, sender, stanza); 
// TODO not defined in the standard(?)
+        }
+
+        sb.endInnerElement();
+        return new IQStanza(sb.getFinalStanza());
+    }
+
+    /**
      * Creates the stanza to be sent for successful requests.
      */
     private void buildSuccessStanza(StanzaBuilder sb, LeafNode node, 
List<AffiliationItem> affiliations) {

Added: 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/LastOwnerResignedException.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/LastOwnerResignedException.java?rev=807022&view=auto
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/LastOwnerResignedException.java
 (added)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/LastOwnerResignedException.java
 Sun Aug 23 22:00:08 2009
@@ -0,0 +1,39 @@
+/*
+ *  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.model;
+
+/**
+ * This exception is thrown if the last owner of a node tries to resign.
+ * @author The Apache MINA Project (http://mina.apache.org)
+ */
+public class LastOwnerResignedException extends Exception {
+
+    private static final long serialVersionUID = 4689474856848548356L;
+
+    /**
+     * Initializes the exception with a free-form string.
+     *
+     * @param description further details about the exception.
+     */
+    public LastOwnerResignedException(String description) {
+        super(description);
+    }
+
+}

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=807022&r1=807021&r2=807022&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
 Sun Aug 23 22:00:08 2009
@@ -79,7 +79,11 @@
         this.title = title;
         this.storage = serviceConfiguration.getLeafNodeStorageProvider();
         this.storage.initialize(this);
-        this.addOwner(creator);
+        try {
+            this.setAffiliation(creator, PubSubAffiliation.OWNER);
+        } catch (LastOwnerResignedException e) {
+            // won't happen
+        }
     }
 
     /**
@@ -268,8 +272,8 @@
      * 
      * @param owner
      */
-    public void addOwner(Entity owner) {
-        this.storage.addOwner(name,owner);
+    public void setAffiliation(Entity owner, PubSubAffiliation affiliation) 
throws LastOwnerResignedException {
+        this.storage.setAffiliation(name, owner, affiliation);
     }
 
     /**
@@ -285,10 +289,10 @@
 
     /**
      * Returns the affiliation for the given bareJID.
-     * @param bareJID
+     * @param entity the entity for which the affiliation should be returned.
      * @return All affiliations ("NONE" if no other affiliation is known).
      */
-    public PubSubAffiliation getAffiliation(Entity bareJID) {
-        return this.storage.getAffiliation(name, bareJID);
+    public PubSubAffiliation getAffiliation(Entity entity) {
+        return this.storage.getAffiliation(name, entity);
     }
 }

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/storageprovider/LeafNodeInMemoryStorageProvider.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/storageprovider/LeafNodeInMemoryStorageProvider.java?rev=807022&r1=807021&r2=807022&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/storageprovider/LeafNodeInMemoryStorageProvider.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/storageprovider/LeafNodeInMemoryStorageProvider.java
 Sun Aug 23 22:00:08 2009
@@ -30,6 +30,7 @@
 import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.MemberAffiliationVisitor;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.LeafNode;
 import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.PayloadItem;
+import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.LastOwnerResignedException;
 import org.apache.vysper.xmpp.xmlfragment.XMLElement;
 
 /**
@@ -183,10 +184,37 @@
      * Add the entity to the owner list of the given node.
      * The owner is stored as bare JID.
      */
-    public void addOwner(String nodeName, Entity owner) {
+    public void setAffiliation(String nodeName, Entity entity, 
PubSubAffiliation affiliation) throws LastOwnerResignedException {
         Map<Entity, PubSubAffiliation> affils = 
this.nodeAffiliations.get(nodeName);
-        Entity bareOwner = owner.getBareJID();
-        affils.put(bareOwner, PubSubAffiliation.OWNER);
+        Entity bareJID = entity.getBareJID();
+
+        if(getAffiliation(nodeName, bareJID).equals(PubSubAffiliation.OWNER)
+                && !affiliation.equals(PubSubAffiliation.OWNER)
+                && countAffiliations(nodeName, PubSubAffiliation.OWNER) == 1) {
+            throw new 
LastOwnerResignedException(bareJID.getFullQualifiedName() + " tried to resign 
from " + nodeName);
+        }
+
+        if(affiliation.equals(PubSubAffiliation.NONE)) {
+            affils.remove(bareJID); // NONE affiliations are not stored.
+        } else {
+            affils.put(bareJID, affiliation);
+        }
+    }
+
+    /**
+     * Calculates how many users with the given affiliation are present for 
this node.
+     * @param nodeName the node to check
+     * @param affiliation to count
+     * @return the number of owners.
+     */
+    private int countAffiliations(String nodeName, PubSubAffiliation 
affiliation) {
+        Map<Entity, PubSubAffiliation> affils = 
this.nodeAffiliations.get(nodeName);
+        int i = 0;
+        for(PubSubAffiliation a : affils.values()) {
+            if(a.equals(affiliation))
+                ++i;
+        }
+        return i;
     }
 
     /**

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/storageprovider/LeafNodeStorageProvider.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/storageprovider/LeafNodeStorageProvider.java?rev=807022&r1=807021&r2=807022&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/storageprovider/LeafNodeStorageProvider.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/storageprovider/LeafNodeStorageProvider.java
 Sun Aug 23 22:00:08 2009
@@ -26,6 +26,7 @@
 import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.SubscriberVisitor;
 import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.MemberAffiliationVisitor;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.LeafNode;
+import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.LastOwnerResignedException;
 import org.apache.vysper.xmpp.xmlfragment.XMLElement;
 
 /**
@@ -143,7 +144,7 @@
      * Add the entity to the owner list of the given node.
      * @param owner
      */
-    public void addOwner(String nodeName, Entity owner);
+    public void setAffiliation(String nodeName, Entity owner, 
PubSubAffiliation affiliation) throws LastOwnerResignedException;
 
     /**
      * Returns the affiliation of the entity to the node identified by 
nodeName.

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PubSubTests.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/PubSubTests.java?rev=807022&r1=807021&r2=807022&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PubSubTests.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PubSubTests.java
 Sun Aug 23 22:00:08 2009
@@ -32,6 +32,7 @@
 import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.owner.PubSubConfigureNodeTestCase;
 import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.owner.PubSubDeleteNodeTestCase;
 import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.owner.PubSubOwnerRetrieveAffiliationsTestCase;
+import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.owner.PubSubOwnerModifyAffiliationsTestCase;
 import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.CollectionNodeTestCase;
 import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.LeafNodeTestCase;
 
@@ -49,6 +50,7 @@
         suite.addTestSuite(PubSubDeleteNodeTestCase.class);
         suite.addTestSuite(PubSubConfigureNodeTestCase.class);
         suite.addTestSuite(PubSubOwnerRetrieveAffiliationsTestCase.class);
+        suite.addTestSuite(PubSubOwnerModifyAffiliationsTestCase.class);
 
         suite.addTestSuite(PubSubCreateNodeTestCase.class);
         suite.addTestSuite(PubSubPublishTestCase.class);

Copied: 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerModifyAffiliationsTestCase.java
 (from r807013, 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerRetrieveAffiliationsTestCase.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/owner/PubSubOwnerModifyAffiliationsTestCase.java?p2=mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerModifyAffiliationsTestCase.java&p1=mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerRetrieveAffiliationsTestCase.java&r1=807013&r2=807022&rev=807022&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerRetrieveAffiliationsTestCase.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerModifyAffiliationsTestCase.java
 Sun Aug 23 22:00:08 2009
@@ -23,6 +23,7 @@
 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.PubSubAffiliation;
 import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.AbstractStanzaGenerator;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.LeafNode;
 import org.apache.vysper.xmpp.protocol.NamespaceURIs;
@@ -38,36 +39,37 @@
 /**
  * @author The Apache MINA Project (http://mina.apache.org)
  */
-public class PubSubOwnerRetrieveAffiliationsTestCase extends 
AbstractPublishSubscribeTestCase {
+public class PubSubOwnerModifyAffiliationsTestCase extends 
AbstractPublishSubscribeTestCase {
     protected LeafNode n1 = null;
+    protected Entity client2 = null;
+    protected Entity client3 = null;
 
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        Entity client2 = new EntityImpl("user1", "vysper.org", null);
-        Entity client3 = new EntityImpl("user2", "vysper.org", null);;
+        client2 = new EntityImpl("user1", "vysper.org", null);
+        client3 = new EntityImpl("user2", "vysper.org", null);
 
         n1 = new LeafNode(serviceConfiguration, "Node1", "Node 1 used for 
testing purposes", client);
-        n1.addOwner(client2);
-        n1.addOwner(client3);
-
+        n1.setAffiliation(client2, PubSubAffiliation.MEMBER);
+        
         root.add(n1);
     }
 
     @Override
     protected IQHandler getHandler() {
-        return new 
PubSubOwnerRetrieveAffiliationsHandler(serviceConfiguration);
+        return new PubSubOwnerManageAffiliationsHandler(serviceConfiguration);
     }
 
     @Override
     protected AbstractStanzaGenerator getDefaultStanzaGenerator() {
-        return new DefaultRetrieveAffiliationsStanzaGenerator("Node1");
+        return new DefaultModifyAffiliationsStanzaGenerator("Node1", client3, 
PubSubAffiliation.PUBLISHER);
     }
 
-    public void testRetrieveAffiliationsNoAuth() {
+    public void testModifyAffiliationsNoAuth() {
         Entity client2 = new EntityImpl("yoda", "starwars.com", null);
 
-        AbstractStanzaGenerator sg = new 
DefaultRetrieveAffiliationsStanzaGenerator("Node1");
+        AbstractStanzaGenerator sg = new 
DefaultModifyAffiliationsStanzaGenerator("Node1", client, 
PubSubAffiliation.MEMBER);
         Stanza stanza = sg.getStanza(client2, pubsubService, "id123", null);
         ResponseStanzaContainer result = sendStanza(stanza, true);
 
@@ -88,11 +90,11 @@
         assertEquals(NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS, 
errorContent.get(0).getNamespaceURI());
     }
 
-    public void testRetrieveAffiliationsNoSuchNode() throws Exception {
+    public void testModifyAffiliationsNoSuchNode() throws Exception {
         String testNode = "test";
         assertNull(root.find(testNode));
 
-        AbstractStanzaGenerator sg = new 
DefaultRetrieveAffiliationsStanzaGenerator("test");
+        AbstractStanzaGenerator sg = new 
DefaultModifyAffiliationsStanzaGenerator("test", client, 
PubSubAffiliation.MEMBER);
         Stanza stanza = sg.getStanza(client, pubsubService, "id123", testNode);
         ResponseStanzaContainer result = sendStanza(stanza, true);
         assertTrue(result.hasResponse());
@@ -111,7 +113,11 @@
         assertEquals(NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS, 
errorContent.get(0).getNamespaceURI());
     }
 
-    public void testRetrieveAffiliations() {
+    public void testModifyAffiliations() {
+        assertEquals(PubSubAffiliation.OWNER, n1.getAffiliation(client));
+        assertEquals(PubSubAffiliation.MEMBER, n1.getAffiliation(client2));
+        assertEquals(PubSubAffiliation.NONE, n1.getAffiliation(client3));
+
         AbstractStanzaGenerator sg = getDefaultStanzaGenerator();
 
         Stanza stanza = sg.getStanza(client, pubsubService, "4711", null);
@@ -121,26 +127,80 @@
 
         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());
+        assertEquals("4711", response.getAttributeValue("id")); // IDs must 
match
 
-        for(XMLElement e : sub.getInnerElements()) {
-            assertEquals("owner", e.getAttributeValue("affiliation"));
-        }
+        assertEquals(PubSubAffiliation.OWNER, n1.getAffiliation(client));
+        assertEquals(PubSubAffiliation.MEMBER, n1.getAffiliation(client2));
+        assertEquals(PubSubAffiliation.PUBLISHER, n1.getAffiliation(client3));
+    }
+
+    public void testModifyAffiliationsRemoveOne() {
+        assertEquals(PubSubAffiliation.OWNER, n1.getAffiliation(client));
+        assertEquals(PubSubAffiliation.MEMBER, n1.getAffiliation(client2));
+        assertEquals(PubSubAffiliation.NONE, n1.getAffiliation(client3));
+
+        DefaultModifyAffiliationsStanzaGenerator sg = new 
DefaultModifyAffiliationsStanzaGenerator(n1.getName(), client2, 
PubSubAffiliation.NONE);
+
+        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());
+        assertEquals("4711", response.getAttributeValue("id")); // IDs must 
match
+
+        assertEquals(PubSubAffiliation.OWNER, n1.getAffiliation(client));
+        assertEquals(PubSubAffiliation.NONE, n1.getAffiliation(client2));
+        assertEquals(PubSubAffiliation.NONE, n1.getAffiliation(client3));
+    }
+
+    public void testModifyAffiliationsRemoveLastOwner() {
+        assertEquals(PubSubAffiliation.OWNER, n1.getAffiliation(client));
+        assertEquals(PubSubAffiliation.MEMBER, n1.getAffiliation(client2));
+        assertEquals(PubSubAffiliation.NONE, n1.getAffiliation(client3));
+
+        DefaultModifyAffiliationsStanzaGenerator sg = new 
DefaultModifyAffiliationsStanzaGenerator(n1.getName(), client, 
PubSubAffiliation.NONE);
+
+        Stanza stanza = sg.getStanza(client, pubsubService, "4711", null);
+        ResponseStanzaContainer result = sendStanza(stanza, true);
+
+        assertTrue(result.hasResponse());
+
+        IQStanza response = new IQStanza(result.getResponseStanza());
+        assertEquals(IQStanzaType.ERROR.value(),response.getType());
+
+        assertEquals("4711", response.getAttributeValue("id")); // IDs must 
match
+
+        XMLElement error = response.getInnerElementsNamed("error").get(0); 
//jump directly to the error part
+        assertEquals("error", error.getName());
+        assertEquals("modify", error.getAttributeValue("type"));
+        assertEquals("not-acceptable", error.getFirstInnerElement().getName());
+
+        assertEquals(PubSubAffiliation.OWNER, n1.getAffiliation(client));
+        assertEquals(PubSubAffiliation.MEMBER, n1.getAffiliation(client2));
+        assertEquals(PubSubAffiliation.NONE, n1.getAffiliation(client3));
     }
 
-    class DefaultRetrieveAffiliationsStanzaGenerator extends 
AbstractStanzaGenerator {
+    class DefaultModifyAffiliationsStanzaGenerator extends 
AbstractStanzaGenerator {
         private String node;
+        private Entity jid;
+        private PubSubAffiliation affiliation;
 
-        public DefaultRetrieveAffiliationsStanzaGenerator(String nodeName) {
+        public DefaultModifyAffiliationsStanzaGenerator(String nodeName, 
Entity jid, PubSubAffiliation affiliation) {
             this.node = nodeName;
+            this.jid = jid;
+            this.affiliation = affiliation;
         }
 
         @Override
         protected StanzaBuilder buildInnerElement(Entity client, Entity 
pubsub, StanzaBuilder sb, String node) {
             sb.startInnerElement("affiliations");
             sb.addAttribute("node", this.node);
+            sb.startInnerElement("affiliation");
+            sb.addAttribute("jid", this.jid.getFullQualifiedName());
+            sb.addAttribute("affiliation", this.affiliation.toString());
+            sb.endInnerElement();
             sb.endInnerElement();
             return sb;
         }
@@ -152,7 +212,7 @@
 
         @Override
         protected IQStanzaType getStanzaType() {
-            return IQStanzaType.GET;
+            return IQStanzaType.SET;
         }
     }
 

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerRetrieveAffiliationsTestCase.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/owner/PubSubOwnerRetrieveAffiliationsTestCase.java?rev=807022&r1=807021&r2=807022&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerRetrieveAffiliationsTestCase.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0060-pubsub/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerRetrieveAffiliationsTestCase.java
 Sun Aug 23 22:00:08 2009
@@ -23,6 +23,7 @@
 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.PubSubAffiliation;
 import 
org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.AbstractStanzaGenerator;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.LeafNode;
 import org.apache.vysper.xmpp.protocol.NamespaceURIs;
@@ -45,18 +46,18 @@
     public void setUp() throws Exception {
         super.setUp();
         Entity client2 = new EntityImpl("user1", "vysper.org", null);
-        Entity client3 = new EntityImpl("user2", "vysper.org", null);;
+        Entity client3 = new EntityImpl("user2", "vysper.org", null);
 
         n1 = new LeafNode(serviceConfiguration, "Node1", "Node 1 used for 
testing purposes", client);
-        n1.addOwner(client2);
-        n1.addOwner(client3);
+        n1.setAffiliation(client2, PubSubAffiliation.OWNER);
+        n1.setAffiliation(client3, PubSubAffiliation.OWNER);
 
         root.add(n1);
     }
 
     @Override
     protected IQHandler getHandler() {
-        return new 
PubSubOwnerRetrieveAffiliationsHandler(serviceConfiguration);
+        return new PubSubOwnerManageAffiliationsHandler(serviceConfiguration);
     }
 
     @Override


Reply via email to