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/06/22 22:48:44 UTC

svn commit: r787392 - in /mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub: ./ handler/ handler/owner/ model/

Author: mjakl
Date: Mon Jun 22 20:48:43 2009
New Revision: 787392

URL: http://svn.apache.org/viewvc?rev=787392&view=rev
Log:
Add JavaDocs and more SpecComplant annotations. Replace tabs with spaces. Touches VYSPER-77 and VYSPER-78.

Modified:
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/AbstractPublishSubscribeIQHandler.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PubSubPersistenceManager.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PublishSubscribeModule.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/SubscriberNotificationVisitor.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/SubscriberVisitor.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/AbstractPubSubGeneralHandler.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/ErrorStanzaGenerator.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubCreateNodeHandler.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubPublishHandler.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubSubscribeHandler.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubUnsubscribeHandler.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/AbstractPubSubOwnerHandler.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerConfigureNodeHandler.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerDeleteNodeHandler.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/CollectionNode.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/DuplicateNodeException.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/LeafNode.java
    mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/MultipleSubscriptionException.java

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/AbstractPublishSubscribeIQHandler.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/AbstractPublishSubscribeIQHandler.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/AbstractPublishSubscribeIQHandler.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/AbstractPublishSubscribeIQHandler.java Mon Jun 22 20:48:43 2009
@@ -28,37 +28,73 @@
 import org.apache.vysper.xmpp.xmlfragment.XMLElement;
 
 /**
- * Handles PubSub stanzas.
+ * This abstract class is the superclass of all pubsub (and related) handlers. It is responsible for correctly verifying whether a
+ * given Stanza is to be handled, or not.
  *
  * @author The Apache MINA Project (http://mina.apache.org)
  */
 @SpecCompliant(spec="xep-0060", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public abstract class AbstractPublishSubscribeIQHandler extends DefaultIQHandler {
-	
-	protected CollectionNode root;
-	protected UUIDGenerator idGenerator;
-	
-	public AbstractPublishSubscribeIQHandler(CollectionNode root) {
-		this.root = root;
-		this.idGenerator = new JVMBuiltinUUIDGenerator();
-	}
-	
-	@Override
-	protected boolean verifyNamespace(Stanza stanza) {
-		return verifyInnerNamespace(stanza, getNamespace());
-	}
-	
-	@Override
-	protected boolean verifyInnerElement(Stanza stanza) {
-        return verifyInnerElementWorker(stanza, "pubsub") 
-        	&& verifySingleElementParameter(stanza.getFirstInnerElement(), getWorkerElement());
-	}
-	
-	protected boolean verifySingleElementParameter(XMLElement pubsub, String element) {
-		return pubsub.getVerifier().subElementsPresentExact(1)
-			&& pubsub.getVerifier().subElementPresent(element);		
-	}
 
-	protected abstract String getNamespace();
-	protected abstract String getWorkerElement();
+    // the pubsub service itself is a collection node
+    protected CollectionNode root;
+    // we need to generate some IDs
+    protected UUIDGenerator idGenerator;
+
+    /**
+     * Initialize the handler with the given root CollectionNode.
+     * 
+     * @param root the one and only "root" CollectionNode
+     */
+    public AbstractPublishSubscribeIQHandler(CollectionNode root) {
+        this.root = root;
+        this.idGenerator = new JVMBuiltinUUIDGenerator();
+    }
+
+    /**
+     * Delegate the verification to DefaultIQHandler#verifyInnerNamespace(Stanza, String).
+     * 
+     * @see DefaultIQHandler#verifyNamespace(Stanza)
+     * @return true if the namespace of the inner element matches the pubsub namespace.
+     */
+    @Override
+    protected boolean verifyNamespace(Stanza stanza) {
+        return verifyInnerNamespace(stanza, getNamespace());
+    }
+
+    /**
+     * Checks whether the inner element of the stanza is a "pubsub" element and if the
+     * worker element (the element within the pubsub element) matches the one of the current class.
+     * 
+     * @param stanza the Stanza to be checked.
+     * @return true if this class is responsible for handling the stanza.
+     */
+    @Override
+    protected boolean verifyInnerElement(Stanza stanza) {
+        return verifyInnerElementWorker(stanza, "pubsub")
+        && verifySingleElementParameter(stanza.getFirstInnerElement(), getWorkerElement());
+    }
+
+    /**
+     * Verifies if there is only one inner element available and if it matches the element name given.
+     * @param pubsub the XMLElement to check
+     * @param element the name of the expected inner element.
+     * @return true if the name matches the only available inner element.
+     */
+    protected boolean verifySingleElementParameter(XMLElement pubsub, String element) {
+        return pubsub.getVerifier().subElementsPresentExact(1)
+        && pubsub.getVerifier().subElementPresent(element);
+    }
+
+    /**
+     * Implement this method to specify which namespace the pubsub element in the stanza should lie in.
+     * @return the namespace this class is expecting.
+     */
+    protected abstract String getNamespace();
+    
+    /**
+     * Implement this method to specify which inner element of pubsub element this class expects.
+     * @return the name of the inner element this class is expecting.
+     */
+    protected abstract String getWorkerElement();
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PubSubPersistenceManager.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PubSubPersistenceManager.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PubSubPersistenceManager.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PubSubPersistenceManager.java Mon Jun 22 20:48:43 2009
@@ -19,42 +19,121 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub;
 
+import org.apache.vysper.compliance.SpecCompliant;
 import org.apache.vysper.storage.StorageProvider;
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.LeafNode;
 import org.apache.vysper.xmpp.xmlfragment.XMLElement;
 
 /**
+ * This interface defines all methods a StorageProvider has to offer to be suitable
+ * for the pubsub-module.
+ * 
  * @author The Apache MINA Project (http://mina.apache.org)
  */
+@SpecCompliant(spec="xep-0060", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public interface PubSubPersistenceManager extends StorageProvider {
 
-	// CollectionNode methods
-	public LeafNode findNode(Entity jid);
-
-	public boolean containsNode(Entity jid);
-	
-	public void storeNode(Entity jid, LeafNode node);
-
-	// LeafNode methods (subscriptions)
-	public void addSubscriber(Entity nodeJID, String subscriptionID, Entity subscriber);
-
-	public boolean containsSubscriber(Entity nodeJID, Entity subscriber);
-
-	public boolean containsSubscriber(Entity nodeJID, String subscriptionId);
-
-	public Entity getSubscriber(Entity nodeJID, String subscriptionId);
-
-	public boolean removeSubscription(Entity nodeJID, String subscriptionId);
-
-	public boolean removeSubscriber(Entity nodeJID, Entity subscriber);
-
-	public int countSubscriptions(Entity nodeJID, Entity subscriber);
-
-	public int countSubscriptions(Entity nodeJID);
-
-	public void addMessage(Entity nodeJID, String messageID, XMLElement item);
-
-	public void accept(Entity nodeJID, SubscriberVisitor subscriberVisitor);
+    // CollectionNode methods
+    
+    /**
+     * Retrieve a node via its JID
+     * @param jid the JID of the node we're searching for
+     * @return the LeafNode if found, null otherwise.
+     */
+    public LeafNode findNode(Entity jid);
+
+    /**
+     * Checks whether the collection node contains a node with a certain JID.
+     * @param jid the JID we're checking for.
+     * @return true if the JID corresponds to a known node.
+     */
+    public boolean containsNode(Entity jid);
+
+    /**
+     * Stores a node under the specified JID.
+     * @param jid the JID for the node.
+     * @param node the LeafNode to be stored.
+     */
+    public void storeNode(Entity jid, LeafNode node);
+
+    // LeafNode methods (subscriptions)
+    /**
+     * Add a subscriber to the LeafNode.
+     * @param nodeJID the node JID to which the subscriber should be added.
+     * @param subscriptionID the ID for the subscription (multiple subscription ber subscriber).
+     * @param subscriber the JID of the subscriber.
+     */
+    public void addSubscriber(Entity nodeJID, String subscriptionID, Entity subscriber);
+
+    /**
+     * Checks if the node specified by nodeJID has a subscriber with the given JID.
+     * @param nodeJID the node to check.
+     * @param subscriber the JID of the subscriber.
+     * @return true if this JID is subscribed to the node.
+     */
+    public boolean containsSubscriber(Entity nodeJID, Entity subscriber);
+
+    /**
+     * Checks if the node specified by nodeJID has a subscriber with the given subscription ID.
+     * @param nodeJID the node to check.
+     * @param subscriptionId the subscription ID to check.
+     * @return true if there is a subscription with the given subscription ID.
+     */
+    public boolean containsSubscriber(Entity nodeJID, String subscriptionId);
+
+    /**
+     * Fetches the subscriber for a given subscription ID.
+     * @param nodeJID the JID of the node.
+     * @param subscriptionId the subscription ID we search for.
+     * @return the JID of the subscriber with this subscription ID
+     */
+    public Entity getSubscriber(Entity nodeJID, String subscriptionId);
+
+    /**
+     * Removes a subscription based on the subscription ID.
+     * @param nodeJID the node from which we remove the subscription.
+     * @param subscriptionId the ID of the subscription to remove.
+     * @return true if the subscription has been removed, false otherwise.
+     */
+    public boolean removeSubscription(Entity nodeJID, String subscriptionId);
+
+    /**
+     * Removes a subscription based on the JID of the subscriber.
+     * @param nodeJID the node from which we remove the subscription.
+     * @param subscriber the JID to remove.
+     * @return true if the subscription has been removed, false otherwise.
+     */
+    public boolean removeSubscriber(Entity nodeJID, Entity subscriber);
+
+    /**
+     * Count how many subscription a given JID has to a node
+     * @param nodeJID the node to check
+     * @param subscriber the subscriber JID to check
+     * @return the number of subscriptions.
+     */
+    public int countSubscriptions(Entity nodeJID, Entity subscriber);
+
+    /**
+     * Count how many subscriptions a given node has.
+     * @param nodeJID the JID of the node to check.
+     * @return the number of subscriptions (should return the number of subscription IDs, not subscribed JIDs).
+     */
+    public int countSubscriptions(Entity nodeJID);
+
+    /**
+     * Store a published message to a node.
+     * @param nodeJID the node to which we want to store the message.
+     * @param messageID the message ID for later retrieval.
+     * @param item the payload of the message.
+     */
+    public void addMessage(Entity nodeJID, String messageID, XMLElement item);
+
+    /**
+     * Call the SubscriberVisitor for each subscription of the given node.
+     * @param nodeJID the node we want to iterate.
+     * @param subscriberVisitor the SubscriberVisitor to call
+     */
+    public void accept(Entity nodeJID, SubscriberVisitor subscriberVisitor);
 
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PublishSubscribeModule.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PublishSubscribeModule.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PublishSubscribeModule.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/PublishSubscribeModule.java Mon Jun 22 20:48:43 2009
@@ -22,6 +22,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.vysper.compliance.SpecCompliant;
 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;
@@ -49,67 +50,94 @@
  *
  * @author The Apache MINA Project (http://mina.apache.org)
  */
+@SpecCompliant(spec="xep-0060", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public class PublishSubscribeModule extends DefaultDiscoAwareModule implements ServerInfoRequestListener {
 
-	CollectionNode root = null;
-	final Logger logger = LoggerFactory.getLogger(PublishSubscribeModule.class);
-	
-	/**
-	 * Default constructor takes care of the root-CollectionNode 
-	 */
-	public PublishSubscribeModule() {
-		this.root = new CollectionNode();
-	}
-	
-	@Override
-	public void initialize(ServerRuntimeContext serverRuntimeContext) {
-		super.initialize(serverRuntimeContext);
-		
+    CollectionNode root = null;
+    final Logger logger = LoggerFactory.getLogger(PublishSubscribeModule.class);
+
+    /**
+     * Default constructor takes care of the root-CollectionNode
+     */
+    public PublishSubscribeModule() {
+        this.root = new CollectionNode();
+    }
+
+    @Override
+    public void initialize(ServerRuntimeContext serverRuntimeContext) {
+        super.initialize(serverRuntimeContext);
+
         PubSubPersistenceManager persistenceManager = (PubSubPersistenceManager) serverRuntimeContext.getStorageProvider(PubSubPersistenceManager.class);
         if (persistenceManager == null) {
             logger.error("No persistency manager found");
             // TODO throw some exception - without PM we can't do anything useful
         } else {
-        	root.setPersistenceManager(persistenceManager);
+            root.setPersistenceManager(persistenceManager);
         }
-	}
-	
-	@Override
-	public String getName() {
-		return "XEP-0060 Publish-Subscribe";
-	}
-
-	@Override
-	public String getVersion() {
-		return "1.13rc3";
-	}
+    }
+
+    @Override
+    public String getName() {
+        return "XEP-0060 Publish-Subscribe";
+    }
+
+    @Override
+    public String getVersion() {
+        return "1.13rc3";
+    }
 
     @Override
     protected void addServerInfoRequestListeners(List<ServerInfoRequestListener> serverInfoRequestListeners) {
         serverInfoRequestListeners.add(this);
     }
-    
-	public List<InfoElement> getServerInfosFor(InfoRequest request)
-			throws ServiceDiscoveryRequestException {
+
+    /**
+     * Implements the getServerInfosFor method from the {@link ServerInfoRequestListener} interface.
+     * Makes this modules available via disco as "pubsub service" in the pubsub namespace.
+     * 
+     * @see ServerInfoRequestListener#getServerInfosFor(InfoRequest)
+     */
+    public List<InfoElement> getServerInfosFor(InfoRequest request)
+    throws ServiceDiscoveryRequestException {
         List<InfoElement> infoElements = new ArrayList<InfoElement>();
         infoElements.add(new Identity("pubsub", "service"));
         infoElements.add(new Feature(NamespaceURIs.XEP0060_PUBSUB));
         return infoElements;
-	}
-	
+    }
+
+    /**
+     * Registers the handlers for the various stanza types known to this pubsub implementation.
+     * 
+     * @see DefaultModule#addHandlerDictionaries(List<HandlerDictionary> dictionary)
+     */
     @Override
     protected void addHandlerDictionaries(List<HandlerDictionary> dictionary) {
+        addPubsubHandlers(dictionary);
+        addPubsubOwnerHandlers(dictionary);
+    }
+
+    /**
+     * Inserts the handlers for the pubsub#owner namespace into the HandlerDictionary.
+     * @param dictionary the list to which the handlers should be appended.
+     */
+    private void addPubsubOwnerHandlers(List<HandlerDictionary> dictionary) {
+        ArrayList<StanzaHandler> pubsubOwnerHandlers = new ArrayList<StanzaHandler>();
+        pubsubOwnerHandlers.add(new PubSubOwnerConfigureNodeHandler(root));
+        pubsubOwnerHandlers.add(new PubSubOwnerDeleteNodeHandler(root));
+        dictionary.add(new NamespaceHandlerDictionary(NamespaceURIs.XEP0060_PUBSUB_OWNER, pubsubOwnerHandlers));
+    }
+
+    /**
+     * Inserts the handlers for the pubsub namespace into the HandlerDictionary.
+     * @param dictionary the list to which the handlers should be appended.
+     */
+    private void addPubsubHandlers(List<HandlerDictionary> dictionary) {
         ArrayList<StanzaHandler> pubsubHandlers = new ArrayList<StanzaHandler>();
         pubsubHandlers.add(new PubSubSubscribeHandler(root));
         pubsubHandlers.add(new PubSubUnsubscribeHandler(root));
         pubsubHandlers.add(new PubSubPublishHandler(root));
         pubsubHandlers.add(new PubSubCreateNodeHandler(root));
         dictionary.add(new NamespaceHandlerDictionary(NamespaceURIs.XEP0060_PUBSUB, pubsubHandlers));
-        
-        ArrayList<StanzaHandler> pubsubOwnerHandlers = new ArrayList<StanzaHandler>();
-        pubsubOwnerHandlers.add(new PubSubOwnerConfigureNodeHandler(root));
-        pubsubOwnerHandlers.add(new PubSubOwnerDeleteNodeHandler(root));
-        dictionary.add(new NamespaceHandlerDictionary(NamespaceURIs.XEP0060_PUBSUB_OWNER, pubsubOwnerHandlers));
     }
 
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/SubscriberNotificationVisitor.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/SubscriberNotificationVisitor.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/SubscriberNotificationVisitor.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/SubscriberNotificationVisitor.java Mon Jun 22 20:48:43 2009
@@ -19,6 +19,7 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub;
 
+import org.apache.vysper.compliance.SpecCompliant;
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.delivery.DeliveryException;
 import org.apache.vysper.xmpp.delivery.DeliveryFailureStrategy;
@@ -30,32 +31,56 @@
 import org.apache.vysper.xmpp.xmlfragment.XMLElement;
 
 /**
+ * This visitor sends each visited entity the XMLElement specified via the constructor.
+ * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
+@SpecCompliant(spec="xep-0060", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public class SubscriberNotificationVisitor implements SubscriberVisitor {
 
-	private DeliveryFailureStrategy dfs = new IgnoreFailureStrategy();
-	private StanzaRelay stanzaRelay;
-	private XMLElement item;
-	
-	public SubscriberNotificationVisitor(StanzaRelay stanzaRelay, XMLElement item) {
-		this.stanzaRelay = stanzaRelay;
-		this.item = item;
-	}
-
-	public void visit(Entity nodeJID, Entity subscriber) {
-		Stanza event = createMessageEventStanza(nodeJID, subscriber, "en", item); // TODO extract the hardcoded "en"
-		// TODO filter sender of the item?
-		
-		try {
-			stanzaRelay.relay(subscriber, event, dfs);
-		} catch (DeliveryException e1) {
-			// TODO we don't care - do we?
-		}
-	}
-
-	private Stanza createMessageEventStanza(Entity from, Entity to, String lang, XMLElement item) {
+    // Ignore all failures during the delivery (fire and forget)
+    private DeliveryFailureStrategy dfs = new IgnoreFailureStrategy();
+    // The StanzaRelay we use to send the messages
+    private StanzaRelay stanzaRelay;
+    // The payload.
+    private XMLElement item;
+
+    /**
+     * Initialize the visitor with the StanzaRelay and Payload.
+     * @param stanzaRelay relay for sending the messages.
+     * @param item payload for the messages.
+     */
+    public SubscriberNotificationVisitor(StanzaRelay stanzaRelay, XMLElement item) {
+        this.stanzaRelay = stanzaRelay;
+        this.item = item;
+    }
+
+    /**
+     * Send each visited subscriber a notification with the configured payload included.
+     * 
+     * @param nodeJID the node from which the message comes from
+     * @param subscriber the receiver of the notification
+     */
+    public void visit(Entity nodeJID, Entity subscriber) {
+        Stanza event = createMessageEventStanza(nodeJID, subscriber, "en", item); // TODO extract the hardcoded "en"
+
+        try {
+            stanzaRelay.relay(subscriber, event, dfs);
+        } catch (DeliveryException e1) {
+            // TODO we don't care - do we?
+        }
+    }
+
+    /**
+     * Creates the stanza for notifying the subscriber including payload.
+     * 
+     * @param from the node JID which sends the notification
+     * @param to the receiver of the notification (subscriber)
+     * @param lang the language of the stanza text-content.
+     * @param item the payload as XMLElement
+     * @return the prepared Stanza object.
+     */
+    private Stanza createMessageEventStanza(Entity from, Entity to, String lang, XMLElement item) {
         StanzaBuilder stanzaBuilder = new StanzaBuilder("message");
         stanzaBuilder.addAttribute("from", from.getBareJID().getFullQualifiedName());
         stanzaBuilder.addAttribute("to", to.getFullQualifiedName());
@@ -63,6 +88,6 @@
         stanzaBuilder.startInnerElement("event", NamespaceURIs.XEP0060_PUBSUB_EVENT);
         stanzaBuilder.addPreparedElement(item);
         return stanzaBuilder.getFinalStanza();
-	}
+    }
 
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/SubscriberVisitor.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/SubscriberVisitor.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/SubscriberVisitor.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/SubscriberVisitor.java Mon Jun 22 20:48:43 2009
@@ -19,14 +19,24 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub;
 
+import org.apache.vysper.compliance.SpecCompliant;
 import org.apache.vysper.xmpp.addressing.Entity;
 
 /**
+ * The SubscriberVisitor is used to visit all subscriptions of a node.
+ * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
+@SpecCompliant(spec="xep-0060", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public interface SubscriberVisitor {
 
-	void visit(Entity nodeJID, Entity sub);
+    /**
+     * visit is part of the "visitor pattern" and should be used to iterate
+     * over all subscriptions of a node.
+     * 
+     * @param nodeJID the node JID of the subscription
+     * @param sub the subscriber JID
+     */
+    void visit(Entity nodeJID, Entity sub);
 
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/AbstractPubSubGeneralHandler.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/AbstractPubSubGeneralHandler.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/AbstractPubSubGeneralHandler.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/AbstractPubSubGeneralHandler.java Mon Jun 22 20:48:43 2009
@@ -19,6 +19,7 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler;
 
+import org.apache.vysper.compliance.SpecCompliant;
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.addressing.EntityImpl;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.AbstractPublishSubscribeIQHandler;
@@ -27,43 +28,48 @@
 import org.apache.vysper.xmpp.stanza.IQStanza;
 
 /**
+ * This class is the superclass for all stanzas within the pubsub namespace.
  * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
+@SpecCompliant(spec="xep-0060", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public abstract class AbstractPubSubGeneralHandler extends AbstractPublishSubscribeIQHandler {
 
-	ErrorStanzaGenerator errorStanzaGenerator = null;
-	
-	/**
-	 * @param root
-	 */
-	public AbstractPubSubGeneralHandler(CollectionNode root) {
-		super(root);
-		errorStanzaGenerator = new ErrorStanzaGenerator();
-	}
-
-	@Override
-	protected String getNamespace() {
-		return NamespaceURIs.XEP0060_PUBSUB;
-	}
-
-	/**
-	 * Extracts the node name from a given IQ stanza. The node attribute
-	 * takes precedence over the JID resource. The standard requires only
-	 * one of these addressing methods.
-	 * 
-	 * @param stanza the received IQStanza
-	 * @return the node
-	 */
-	protected Entity extractNodeJID(IQStanza stanza) {
-		String node = stanza.getFirstInnerElement().getAttributeValue("node");
-		if(node == null) {
-			return stanza.getTo();
-		} else {
-			Entity to = stanza.getTo();
-			return new EntityImpl(to.getNode(), to.getDomain(), node);
-		}
-	}
-	
+    // one ErrorStanzaGenerator available for all subclasses
+    protected ErrorStanzaGenerator errorStanzaGenerator = null;
+
+    /**
+     * @param root
+     */
+    public AbstractPubSubGeneralHandler(CollectionNode root) {
+        super(root);
+        errorStanzaGenerator = new ErrorStanzaGenerator();
+    }
+
+    /**
+     * @return the fixed pubsub namespace
+     */
+    @Override
+    protected String getNamespace() {
+        return NamespaceURIs.XEP0060_PUBSUB;
+    }
+
+    /**
+     * Extracts the node name from a given IQ stanza. The node attribute
+     * takes precedence over the JID resource. The standard requires only
+     * one of these addressing methods.
+     * 
+     * @param stanza the received IQStanza
+     * @return the node
+     */
+    protected Entity extractNodeJID(IQStanza stanza) {
+        String node = stanza.getFirstInnerElement().getAttributeValue("node");
+        if(node == null) {
+            return stanza.getTo();
+        } else {
+            Entity to = stanza.getTo();
+            return new EntityImpl(to.getNode(), to.getDomain(), node);
+        }
+    }
+
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/ErrorStanzaGenerator.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/ErrorStanzaGenerator.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/ErrorStanzaGenerator.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/ErrorStanzaGenerator.java Mon Jun 22 20:48:43 2009
@@ -26,85 +26,148 @@
 import org.apache.vysper.xmpp.stanza.StanzaBuilder;
 
 /**
+ * The ErrorStanzaGenerator is used to unify the creation of error stanzas across the pubsub
+ * module.
+ * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
 public class ErrorStanzaGenerator {
-	public Stanza generateJIDMalformedErrorStanza(Entity sender, Entity receiver, String iqStanzaID) {
-		StanzaBuilder error = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.ERROR, iqStanzaID);
-		error.startInnerElement("error");
-		error.addAttribute("type", "modify");
-		error.startInnerElement("jid-malformed", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS);
-		error.endInnerElement(); // jid-malformed
-		error.endInnerElement(); // error
-		return error.getFinalStanza();
-	}
-
-	public Stanza generateInsufficientPrivilegesErrorStanza(Entity sender, Entity receiver, String iqStanzaID) {
-		StanzaBuilder error = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.ERROR, iqStanzaID);
-		error.startInnerElement("error");
-		error.addAttribute("type", "auth");
-		error.startInnerElement("forbidden", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS);
-		error.endInnerElement(); // forbidden
-		error.endInnerElement(); // error
-		return error.getFinalStanza();
-	}
-
-	public Stanza generateNoSuchSubscriberErrorStanza(Entity sender, Entity receiver, String iqStanzaID) {
-		StanzaBuilder error = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.ERROR, iqStanzaID);
-		error.startInnerElement("error");
-		error.addAttribute("type", "cancel");
-		error.startInnerElement("unexpected-request", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS);
-		error.endInnerElement(); // unexpected-request
-		error.startInnerElement("not-subscribed", NamespaceURIs.XEP0060_PUBSUB_ERRORS);
-		error.endInnerElement(); // not-subscribed
-		error.endInnerElement(); // error
-		return error.getFinalStanza();
-	}
-
-	public Stanza generateSubIDRequiredErrorStanza(Entity sender, Entity receiver, String iqStanzaID) {
-		StanzaBuilder error = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.ERROR, iqStanzaID);
-		error.startInnerElement("error");
-		error.addAttribute("type", "modify");
-		error.startInnerElement("bad-request", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS);
-		error.endInnerElement(); // bad-request
-		error.startInnerElement("subid-required", NamespaceURIs.XEP0060_PUBSUB_ERRORS);
-		error.endInnerElement(); // subid-required
-		error.endInnerElement(); // error
-		return error.getFinalStanza();
-	}
-	
-	public Stanza generateNoNodeErrorStanza(Entity sender, Entity receiver, String iqStanzaID) {
-		StanzaBuilder error = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.ERROR, iqStanzaID);
-		error.startInnerElement("error");
-		error.addAttribute("type", "cancel");
-		error.startInnerElement("item-does-not-exist", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS);
-		error.endInnerElement(); // item-does-not-exist
-		error.endInnerElement(); // error
-		return error.getFinalStanza();
-	}
-
-	public Stanza generateSubIDNotValidErrorStanza(Entity sender, Entity receiver, String iqStanzaID) {
-		StanzaBuilder error = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.ERROR, iqStanzaID);
-		error.startInnerElement("error");
-		error.addAttribute("type", "modify");
-		error.startInnerElement("not-acceptable", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS);
-		error.endInnerElement(); // not-acceptable
-		error.startInnerElement("invalid-subid", NamespaceURIs.XEP0060_PUBSUB_ERRORS);
-		error.endInnerElement(); // invlaid-subid
-		error.endInnerElement(); // error
-		return error.getFinalStanza();
-	}
-	
-	public Stanza generateJIDDontMatchErrorStanza(Entity sender, Entity receiver, String iqStanzaID) {
-		StanzaBuilder error = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.ERROR, iqStanzaID);
-		error.startInnerElement("error");
-		error.addAttribute("type", "modify");
-		error.startInnerElement("bad-request", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS);
-		error.endInnerElement(); // bad-request
-		error.startInnerElement("invalid-jid", NamespaceURIs.XEP0060_PUBSUB_ERRORS);
-		error.endInnerElement(); // invalid-jid
-		error.endInnerElement(); // error
-		return error.getFinalStanza();
-	}
+    
+    /**
+     * Creates a "JID malformed" error stanza (not specific to the pubsub module).
+     * 
+     * @param sender who sent the erroneous request.
+     * @param receiver who was the recipient of the erroneous request.
+     * @param iqStanzaID the staza ID of the errorneous request.
+     * @return the generated stanza.
+     */
+    public Stanza generateJIDMalformedErrorStanza(Entity sender, Entity receiver, String iqStanzaID) {
+        StanzaBuilder error = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.ERROR, iqStanzaID);
+        error.startInnerElement("error");
+        error.addAttribute("type", "modify");
+        error.startInnerElement("jid-malformed", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS);
+        error.endInnerElement(); // jid-malformed
+        error.endInnerElement(); // error
+        return error.getFinalStanza();
+    }
+
+    /**
+     * Creates a "forbidden" error stanza (not specific to the pubsub module).
+     * 
+     * @param sender who sent the erroneous request.
+     * @param receiver who was the recipient of the erroneous request.
+     * @param iqStanzaID the staza ID of the errorneous request.
+     * @return the generated stanza.
+     */
+    public Stanza generateInsufficientPrivilegesErrorStanza(Entity sender, Entity receiver, String iqStanzaID) {
+        StanzaBuilder error = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.ERROR, iqStanzaID);
+        error.startInnerElement("error");
+        error.addAttribute("type", "auth");
+        error.startInnerElement("forbidden", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS);
+        error.endInnerElement(); // forbidden
+        error.endInnerElement(); // error
+        return error.getFinalStanza();
+    }
+
+    /**
+     * Create the "no such subscriber" error stanza. This is a combination of "unexpected-request" and
+     * "not-subscribed" error conditions (specific to pubsub).
+     * 
+     * @param sender who sent the erroneous request.
+     * @param receiver who was the recipient of the erroneous request.
+     * @param iqStanzaID the staza ID of the errorneous request.
+     * @return the generated stanza.
+     */
+    public Stanza generateNoSuchSubscriberErrorStanza(Entity sender, Entity receiver, String iqStanzaID) {
+        StanzaBuilder error = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.ERROR, iqStanzaID);
+        error.startInnerElement("error");
+        error.addAttribute("type", "cancel");
+        error.startInnerElement("unexpected-request", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS);
+        error.endInnerElement(); // unexpected-request
+        error.startInnerElement("not-subscribed", NamespaceURIs.XEP0060_PUBSUB_ERRORS);
+        error.endInnerElement(); // not-subscribed
+        error.endInnerElement(); // error
+        return error.getFinalStanza();
+    }
+
+    /**
+     * Create the "SubID required" error stanza. This is a combination of "bad-request" and
+     * "subid-required" error conditions (specific to pubsub).
+     * 
+     * @param sender who sent the erroneous request.
+     * @param receiver who was the recipient of the erroneous request.
+     * @param iqStanzaID the staza ID of the errorneous request.
+     * @return the generated stanza.
+     */
+    public Stanza generateSubIDRequiredErrorStanza(Entity sender, Entity receiver, String iqStanzaID) {
+        StanzaBuilder error = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.ERROR, iqStanzaID);
+        error.startInnerElement("error");
+        error.addAttribute("type", "modify");
+        error.startInnerElement("bad-request", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS);
+        error.endInnerElement(); // bad-request
+        error.startInnerElement("subid-required", NamespaceURIs.XEP0060_PUBSUB_ERRORS);
+        error.endInnerElement(); // subid-required
+        error.endInnerElement(); // error
+        return error.getFinalStanza();
+    }
+
+    /**
+     * Create the "no such node" error stanza (not specific to the pubsub module).
+     * 
+     * @param sender who sent the erroneous request.
+     * @param receiver who was the recipient of the erroneous request.
+     * @param iqStanzaID the staza ID of the errorneous request.
+     * @return the generated stanza.
+     */
+    public Stanza generateNoNodeErrorStanza(Entity sender, Entity receiver, String iqStanzaID) {
+        StanzaBuilder error = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.ERROR, iqStanzaID);
+        error.startInnerElement("error");
+        error.addAttribute("type", "cancel");
+        error.startInnerElement("item-does-not-exist", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS);
+        error.endInnerElement(); // item-does-not-exist
+        error.endInnerElement(); // error
+        return error.getFinalStanza();
+    }
+
+    /**
+     * Create the "SubID not valid" error stanza. This is a combination of "not-acceptable" and
+     * "invalid-subid" error conditions (specific to pubsub).
+     * 
+     * @param sender who sent the erroneous request.
+     * @param receiver who was the recipient of the erroneous request.
+     * @param iqStanzaID the staza ID of the errorneous request.
+     * @return the generated stanza.
+     */
+    public Stanza generateSubIDNotValidErrorStanza(Entity sender, Entity receiver, String iqStanzaID) {
+        StanzaBuilder error = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.ERROR, iqStanzaID);
+        error.startInnerElement("error");
+        error.addAttribute("type", "modify");
+        error.startInnerElement("not-acceptable", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS);
+        error.endInnerElement(); // not-acceptable
+        error.startInnerElement("invalid-subid", NamespaceURIs.XEP0060_PUBSUB_ERRORS);
+        error.endInnerElement(); // invlaid-subid
+        error.endInnerElement(); // error
+        return error.getFinalStanza();
+    }
+
+    /**
+     * Create the "JID don't match" error stanza. This is a combination of "bad-request" and
+     * "invalid-jid" error conditions (specific to pubsub).
+     * 
+     * @param sender who sent the erroneous request.
+     * @param receiver who was the recipient of the erroneous request.
+     * @param iqStanzaID the staza ID of the errorneous request.
+     * @return the generated stanza.
+     */
+    public Stanza generateJIDDontMatchErrorStanza(Entity sender, Entity receiver, String iqStanzaID) {
+        StanzaBuilder error = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.ERROR, iqStanzaID);
+        error.startInnerElement("error");
+        error.addAttribute("type", "modify");
+        error.startInnerElement("bad-request", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS);
+        error.endInnerElement(); // bad-request
+        error.startInnerElement("invalid-jid", NamespaceURIs.XEP0060_PUBSUB_ERRORS);
+        error.endInnerElement(); // invalid-jid
+        error.endInnerElement(); // error
+        return error.getFinalStanza();
+    }
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubCreateNodeHandler.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubCreateNodeHandler.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubCreateNodeHandler.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubCreateNodeHandler.java Mon Jun 22 20:48:43 2009
@@ -19,25 +19,32 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler;
 
+import org.apache.vysper.compliance.SpecCompliant;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.CollectionNode;
 
 
 /**
+ * This handler is responsible for dealing with the "create" requests (in the pubsub namespace).
+ * Even though this sounds like a "owner" action, it actually lies within the general "pubsub" namespace.
+ * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
+@SpecCompliant(spec="xep-0060", section="8.1", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public class PubSubCreateNodeHandler extends AbstractPubSubGeneralHandler {
 
-	/**
-	 * @param root
-	 */
-	public PubSubCreateNodeHandler(CollectionNode root) {
-		super(root);
-	}
-
-	@Override
-	protected String getWorkerElement() {
-		return "create";
-	}
+    /**
+     * @param root
+     */
+    public PubSubCreateNodeHandler(CollectionNode root) {
+        super(root);
+    }
+
+    /**
+     * @return "create" as worker element.
+     */
+    @Override
+    protected String getWorkerElement() {
+        return "create";
+    }
 
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubPublishHandler.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubPublishHandler.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubPublishHandler.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubPublishHandler.java Mon Jun 22 20:48:43 2009
@@ -19,6 +19,7 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler;
 
+import org.apache.vysper.compliance.SpecCompliant;
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.addressing.EntityImpl;
 import org.apache.vysper.xmpp.delivery.StanzaRelay;
@@ -35,80 +36,97 @@
 
 
 /**
+ * This class handles the "publish" use cases for the "pubsub" namespace.
+ * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
+@SpecCompliant(spec="xep-0060", section="7.1", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public class PubSubPublishHandler extends AbstractPubSubGeneralHandler {
 
-	/**
-	 * @param root
-	 */
-	public PubSubPublishHandler(CollectionNode root) {
-		super(root);
-	}
-
-	@Override
-	protected String getWorkerElement() {
-		return "publish";
-	}
-
-	@Override
-	protected Stanza handleSet(IQStanza stanza,
-			ServerRuntimeContext serverRuntimeContext,
-			SessionContext sessionContext) {
-		Entity sender = stanza.getFrom();
-		Entity receiver = stanza.getTo();
-
-		String iqStanzaID = stanza.getAttributeValue("id");
-		
-		StanzaBuilder sb = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.RESULT, iqStanzaID);
-		sb.startInnerElement("pubsub", NamespaceURIs.XEP0060_PUBSUB);
-		
-		XMLElement publish = stanza.getFirstInnerElement().getFirstInnerElement(); // pubsub/publish
-		String strNode = publish.getAttributeValue("node"); // MUST
-
-		XMLElement item = publish.getFirstInnerElement();
-		String strID = item.getAttributeValue("id"); // MAY
-		
-		Entity jid = new EntityImpl(receiver.getNode(), receiver.getDomain(), strNode);
-		LeafNode node = root.find(jid);
-		
-		if(node == null) {
-			//TODO node does not exist - error condition 3 (7.1.3)
-			return null;
-		}
-		
-		if(!node.isSubscribed(sender)) {
-			// TODO not enough privileges to publish - error condition 1 (7.1.3)
-			return null;
-		}
-		
-		if(strID == null) {
-			strID = idGenerator.create();
-			// wrap a new item element with the id attribute
-			StanzaBuilder itemBuilder = new StanzaBuilder("item");
-			itemBuilder.addAttribute("id", strID);
-			itemBuilder.addPreparedElement(item.getFirstInnerElement());
-			item = itemBuilder.getFinalStanza();
-		}
-		
-		StanzaRelay relay = serverRuntimeContext.getStanzaRelay();
-		node.publish(sender, relay, strID, item);
-		
-		buildSuccessStanza(sb, strNode, strID);
-		
-		sb.endInnerElement(); // pubsub
-		return new IQStanza(sb.getFinalStanza());
-	}
-	
-	private void buildSuccessStanza(StanzaBuilder sb, String node, String id) {
-		sb.startInnerElement("publish");
-		sb.addAttribute("node", node);
-		
-		sb.startInnerElement("item");
-		sb.addAttribute("id", id);
-		sb.endInnerElement();
-		
-		sb.endInnerElement();
-	}
+    /**
+     * @param root
+     */
+    public PubSubPublishHandler(CollectionNode root) {
+        super(root);
+    }
+
+    /**
+     * @return "publish" as worker element.
+     */
+    @Override
+    protected String getWorkerElement() {
+        return "publish";
+    }
+
+    /**
+     * This method takes care of handling the "publish" use-case including all (relevant) error conditions.
+     * 
+     * @return the appropriate response stanza (either success or some error condition).
+     */
+    @Override
+    protected Stanza handleSet(IQStanza stanza,
+            ServerRuntimeContext serverRuntimeContext,
+            SessionContext sessionContext) {
+        Entity sender = stanza.getFrom();
+        Entity receiver = stanza.getTo();
+
+        String iqStanzaID = stanza.getAttributeValue("id");
+
+        StanzaBuilder sb = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.RESULT, iqStanzaID);
+        sb.startInnerElement("pubsub", NamespaceURIs.XEP0060_PUBSUB);
+
+        XMLElement publish = stanza.getFirstInnerElement().getFirstInnerElement(); // pubsub/publish
+        String strNode = publish.getAttributeValue("node"); // MUST
+
+        XMLElement item = publish.getFirstInnerElement();
+        String strID = item.getAttributeValue("id"); // MAY
+
+        Entity jid = new EntityImpl(receiver.getNode(), receiver.getDomain(), strNode);
+        LeafNode node = root.find(jid);
+
+        if(node == null) {
+            //TODO node does not exist - error condition 3 (7.1.3)
+            return null;
+        }
+
+        if(!node.isSubscribed(sender)) {
+            // TODO not enough privileges to publish - error condition 1 (7.1.3)
+            return null;
+        }
+
+        if(strID == null) {
+            strID = idGenerator.create();
+            // wrap a new item element with the id attribute
+            StanzaBuilder itemBuilder = new StanzaBuilder("item");
+            itemBuilder.addAttribute("id", strID);
+            itemBuilder.addPreparedElement(item.getFirstInnerElement());
+            item = itemBuilder.getFinalStanza();
+        }
+
+        StanzaRelay relay = serverRuntimeContext.getStanzaRelay();
+        node.publish(sender, relay, strID, item);
+
+        buildSuccessStanza(sb, strNode, strID);
+
+        sb.endInnerElement(); // pubsub
+        return new IQStanza(sb.getFinalStanza());
+    }
+
+    /**
+     * This method adds the default "success" elements to the given StanzaBuilder.
+     * 
+     * @param sb the StanzaBuilder to add the success elements.
+     * @param node the node to which the message was published.
+     * @param id the id of the published message.
+     */
+    private void buildSuccessStanza(StanzaBuilder sb, String node, String id) {
+        sb.startInnerElement("publish");
+        sb.addAttribute("node", node);
+
+        sb.startInnerElement("item");
+        sb.addAttribute("id", id);
+        sb.endInnerElement();
+
+        sb.endInnerElement();
+    }
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubSubscribeHandler.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubSubscribeHandler.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubSubscribeHandler.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubSubscribeHandler.java Mon Jun 22 20:48:43 2009
@@ -19,6 +19,7 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler;
 
+import org.apache.vysper.compliance.SpecCompliant;
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.addressing.EntityFormatException;
 import org.apache.vysper.xmpp.addressing.EntityImpl;
@@ -35,74 +36,91 @@
 
 
 /**
+ * This class handles the "subscribe" use cases for the "pubsub" namespace.
+ * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
+@SpecCompliant(spec="xep-0060", section="6.1", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public class PubSubSubscribeHandler extends AbstractPubSubGeneralHandler {
 
-	/**
-	 * @param root
-	 */
-	public PubSubSubscribeHandler(CollectionNode root) {
-		super(root);
-	}
-
-	@Override
-	protected String getWorkerElement() {
-		return "subscribe";
-	}
-
-	@Override
-	protected Stanza handleSet(IQStanza stanza,
-			ServerRuntimeContext serverRuntimeContext,
-			SessionContext sessionContext) {
-		Entity sender = stanza.getFrom();
-		Entity receiver = stanza.getTo();
-		Entity subJID = null;
-
-		String iqStanzaID = stanza.getAttributeValue("id");
-		
-		StanzaBuilder sb = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.RESULT, iqStanzaID);
-		sb.startInnerElement("pubsub", NamespaceURIs.XEP0060_PUBSUB);
-		
-		XMLElement sub = stanza.getFirstInnerElement().getFirstInnerElement(); // pubsub/subscribe
-		String strSubJID = sub.getAttributeValue("jid"); // MUST
-		
-		try {
-			subJID = EntityImpl.parse(strSubJID);
-		} catch (EntityFormatException e) {
-			return errorStanzaGenerator.generateJIDMalformedErrorStanza(sender, receiver, iqStanzaID);
-		}
-		
-		if(!sender.getBareJID().equals(subJID.getBareJID())) {
-			// error condition 1 (6.1.3)
-			return errorStanzaGenerator.generateJIDDontMatchErrorStanza(sender, receiver, iqStanzaID);
-		}
-		
-		Entity nodeJID = extractNodeJID(stanza);
-		LeafNode node = root.find(nodeJID);
-		
-		if(node == null) {
-			// no such node (error condition 11 (6.1.3))
-			return errorStanzaGenerator.generateNoNodeErrorStanza(sender, receiver, iqStanzaID);
-		}
-		
-		String id = idGenerator.create();
-		node.subscribe(id, subJID);
-		
-		buildSuccessStanza(sb, nodeJID, strSubJID, id);
-		
-		sb.endInnerElement(); // pubsub
-		return new IQStanza(sb.getFinalStanza());
-	}
-
-	
-	private void buildSuccessStanza(StanzaBuilder sb, Entity node, String jid, String subid) {
-		sb.startInnerElement("subscription");
-		sb.addAttribute("node", node.getResource());
-		sb.addAttribute("jid", jid);
-		sb.addAttribute("subid", subid);
-		sb.addAttribute("subscription", "subscribed");
-		sb.endInnerElement();
-	}
+    /**
+     * @param root
+     */
+    public PubSubSubscribeHandler(CollectionNode root) {
+        super(root);
+    }
+
+    /**
+     * @return "subscribe" as worker element.
+     */
+    @Override
+    protected String getWorkerElement() {
+        return "subscribe";
+    }
+
+    /**
+     * This method takes care of handling the "subscribe" use-case including all (relevant) error conditions.
+     * 
+     * @return the appropriate response stanza (either success or some error condition).
+     */
+    @Override
+    protected Stanza handleSet(IQStanza stanza,
+            ServerRuntimeContext serverRuntimeContext,
+            SessionContext sessionContext) {
+        Entity sender = stanza.getFrom();
+        Entity receiver = stanza.getTo();
+        Entity subJID = null;
+
+        String iqStanzaID = stanza.getAttributeValue("id");
+
+        StanzaBuilder sb = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.RESULT, iqStanzaID);
+        sb.startInnerElement("pubsub", NamespaceURIs.XEP0060_PUBSUB);
+
+        XMLElement sub = stanza.getFirstInnerElement().getFirstInnerElement(); // pubsub/subscribe
+        String strSubJID = sub.getAttributeValue("jid"); // MUST
+
+        try {
+            subJID = EntityImpl.parse(strSubJID);
+        } catch (EntityFormatException e) {
+            return errorStanzaGenerator.generateJIDMalformedErrorStanza(sender, receiver, iqStanzaID);
+        }
+
+        if(!sender.getBareJID().equals(subJID.getBareJID())) {
+            // error condition 1 (6.1.3)
+            return errorStanzaGenerator.generateJIDDontMatchErrorStanza(sender, receiver, iqStanzaID);
+        }
+
+        Entity nodeJID = extractNodeJID(stanza);
+        LeafNode node = root.find(nodeJID);
+
+        if(node == null) {
+            // no such node (error condition 11 (6.1.3))
+            return errorStanzaGenerator.generateNoNodeErrorStanza(sender, receiver, iqStanzaID);
+        }
+
+        String id = idGenerator.create();
+        node.subscribe(id, subJID);
+
+        buildSuccessStanza(sb, nodeJID, strSubJID, id);
+
+        sb.endInnerElement(); // pubsub
+        return new IQStanza(sb.getFinalStanza());
+    }
+
+    /**
+     * This method adds the default "success" elements to the given StanzaBuilder.
+     * 
+     * @param sb the StanzaBuilder to add the success elements.
+     * @param node the node the user wanted to subscribe to.
+     * @param jid the jid of the subscriber.
+     * @param subid the subscription id for the given JID.
+     */
+    private void buildSuccessStanza(StanzaBuilder sb, Entity node, String jid, String subid) {
+        sb.startInnerElement("subscription");
+        sb.addAttribute("node", node.getResource());
+        sb.addAttribute("jid", jid);
+        sb.addAttribute("subid", subid);
+        sb.addAttribute("subscription", "subscribed");
+        sb.endInnerElement();
+    }
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubUnsubscribeHandler.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubUnsubscribeHandler.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubUnsubscribeHandler.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/PubSubUnsubscribeHandler.java Mon Jun 22 20:48:43 2009
@@ -19,6 +19,7 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler;
 
+import org.apache.vysper.compliance.SpecCompliant;
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.addressing.EntityFormatException;
 import org.apache.vysper.xmpp.addressing.EntityImpl;
@@ -36,79 +37,89 @@
 
 
 /**
+ * This class handles the "unsubscribe" use cases for the "pubsub" namespace.
+ * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
+@SpecCompliant(spec="xep-0060", section="6.2", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public class PubSubUnsubscribeHandler extends AbstractPubSubGeneralHandler {
 
-	/**
-	 * @param root
-	 */
-	public PubSubUnsubscribeHandler(CollectionNode root) {
-		super(root);
-	}
-
-	@Override
-	protected String getWorkerElement() {
-		return "unsubscribe";
-	}
-	
-	@Override
-	protected Stanza handleSet(IQStanza stanza,
-			ServerRuntimeContext serverRuntimeContext,
-			SessionContext sessionContext) {
-		Entity sender = stanza.getFrom();
-		Entity receiver = stanza.getTo();
-		Entity subJID = null;
-		
-		String iqStanzaID = stanza.getAttributeValue("id");
-		
-		StanzaBuilder sb = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.RESULT, iqStanzaID);
-		sb.startInnerElement("pubsub", NamespaceURIs.XEP0060_PUBSUB);
-		
-		XMLElement unsub = stanza.getFirstInnerElement().getFirstInnerElement(); // pubsub/unsubscribe
-		String strSubJID = unsub.getAttributeValue("jid"); // MUST
-		String strSubID = unsub.getAttributeValue("subid"); // SHOULD (req. for more than one subscription)
-		
-		try {
-			subJID = EntityImpl.parse(strSubJID);
-		} catch (EntityFormatException e) {
-			// return error stanza... (general error)
-			return errorStanzaGenerator.generateJIDMalformedErrorStanza(sender, receiver, iqStanzaID);
-		}
-		
-		if(!sender.getBareJID().equals(subJID.getBareJID())) {
-			// insufficient privileges (error condition 3 (6.2.3))
-			return errorStanzaGenerator.generateInsufficientPrivilegesErrorStanza(sender, receiver, iqStanzaID);
-		}
-				
-		Entity nodeJID = extractNodeJID(stanza);
-		LeafNode node = root.find(nodeJID);
-		
-		if(node == null) {
-			// no such node (error condition 4 (6.2.3))
-			return errorStanzaGenerator.generateNoNodeErrorStanza(sender, receiver, iqStanzaID);
-		}
-		
-		if(strSubID == null) {
-			try {
-				if(node.unsubscribe(subJID) == false) {
-					// has no subscription (6.2.3.2)
-					return errorStanzaGenerator.generateNoSuchSubscriberErrorStanza(sender, receiver, iqStanzaID);
-				}
-			} catch(MultipleSubscriptionException e) {
-				// error case 6.2.3.1
-				return errorStanzaGenerator.generateSubIDRequiredErrorStanza(sender, receiver, iqStanzaID);
-			}
-		} else {
-			if(node.unsubscribe(strSubID, subJID) == false) {
-				// subID not valid (6.2.3.5)
-				return errorStanzaGenerator.generateSubIDNotValidErrorStanza(sender, receiver, iqStanzaID);
-			}
-		}
-		
-		sb.endInnerElement(); // pubsub
-		return new IQStanza(sb.getFinalStanza());
-	}
-	
+    /**
+     * @param root
+     */
+    public PubSubUnsubscribeHandler(CollectionNode root) {
+        super(root);
+    }
+
+    /**
+     * @return "unsubscribe" as worker element.
+     */
+    @Override
+    protected String getWorkerElement() {
+        return "unsubscribe";
+    }
+
+    /**
+     * This method takes care of handling the "unsubscribe" use-case including all (relevant) error conditions.
+     * 
+     * @return the appropriate response stanza (either success or some error condition).
+     */
+    @Override
+    protected Stanza handleSet(IQStanza stanza,
+            ServerRuntimeContext serverRuntimeContext,
+            SessionContext sessionContext) {
+        Entity sender = stanza.getFrom();
+        Entity receiver = stanza.getTo();
+        Entity subJID = null;
+
+        String iqStanzaID = stanza.getAttributeValue("id");
+
+        StanzaBuilder sb = StanzaBuilder.createIQStanza(receiver, sender, IQStanzaType.RESULT, iqStanzaID);
+        sb.startInnerElement("pubsub", NamespaceURIs.XEP0060_PUBSUB);
+
+        XMLElement unsub = stanza.getFirstInnerElement().getFirstInnerElement(); // pubsub/unsubscribe
+        String strSubJID = unsub.getAttributeValue("jid"); // MUST
+        String strSubID = unsub.getAttributeValue("subid"); // SHOULD (req. for more than one subscription)
+
+        try {
+            subJID = EntityImpl.parse(strSubJID);
+        } catch (EntityFormatException e) {
+            // return error stanza... (general error)
+            return errorStanzaGenerator.generateJIDMalformedErrorStanza(sender, receiver, iqStanzaID);
+        }
+
+        if(!sender.getBareJID().equals(subJID.getBareJID())) {
+            // insufficient privileges (error condition 3 (6.2.3))
+            return errorStanzaGenerator.generateInsufficientPrivilegesErrorStanza(sender, receiver, iqStanzaID);
+        }
+
+        Entity nodeJID = extractNodeJID(stanza);
+        LeafNode node = root.find(nodeJID);
+
+        if(node == null) {
+            // no such node (error condition 4 (6.2.3))
+            return errorStanzaGenerator.generateNoNodeErrorStanza(sender, receiver, iqStanzaID);
+        }
+
+        if(strSubID == null) {
+            try {
+                if(node.unsubscribe(subJID) == false) {
+                    // has no subscription (6.2.3.2)
+                    return errorStanzaGenerator.generateNoSuchSubscriberErrorStanza(sender, receiver, iqStanzaID);
+                }
+            } catch(MultipleSubscriptionException e) {
+                // error case 6.2.3.1
+                return errorStanzaGenerator.generateSubIDRequiredErrorStanza(sender, receiver, iqStanzaID);
+            }
+        } else {
+            if(node.unsubscribe(strSubID, subJID) == false) {
+                // subID not valid (6.2.3.5)
+                return errorStanzaGenerator.generateSubIDNotValidErrorStanza(sender, receiver, iqStanzaID);
+            }
+        }
+
+        sb.endInnerElement(); // pubsub
+        return new IQStanza(sb.getFinalStanza());
+    }
+
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/AbstractPubSubOwnerHandler.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/AbstractPubSubOwnerHandler.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/AbstractPubSubOwnerHandler.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/AbstractPubSubOwnerHandler.java Mon Jun 22 20:48:43 2009
@@ -19,28 +19,33 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.owner;
 
+import org.apache.vysper.compliance.SpecCompliant;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.AbstractPublishSubscribeIQHandler;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.CollectionNode;
 import org.apache.vysper.xmpp.protocol.NamespaceURIs;
 
 /**
+ * The AbstractPubSubOwnerHandler class is the superclass for all owner-related
+ * pubsub handlers. This means all stanzas in the pubsub#owner namespace.
  * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
-public abstract class AbstractPubSubOwnerHandler extends
-		AbstractPublishSubscribeIQHandler {
+@SpecCompliant(spec="xep-0060", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
+public abstract class AbstractPubSubOwnerHandler extends AbstractPublishSubscribeIQHandler {
 
-	/**
-	 * @param root
-	 */
-	public AbstractPubSubOwnerHandler(CollectionNode root) {
-		super(root);
-	}
+    /**
+     * @param root
+     */
+    public AbstractPubSubOwnerHandler(CollectionNode root) {
+        super(root);
+    }
 
-	@Override
-	protected String getNamespace() {
-		return NamespaceURIs.XEP0060_PUBSUB_OWNER;
-	}
+    /**
+     * @return the pubsub#owner namespace.
+     */
+    @Override
+    protected String getNamespace() {
+        return NamespaceURIs.XEP0060_PUBSUB_OWNER;
+    }
 
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerConfigureNodeHandler.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerConfigureNodeHandler.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerConfigureNodeHandler.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerConfigureNodeHandler.java Mon Jun 22 20:48:43 2009
@@ -19,25 +19,32 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.owner;
 
+import org.apache.vysper.compliance.SpecCompliant;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.CollectionNode;
 
 
 /**
+ * This class handles the configure node part of the XEP-0060 specification. This means
+ * all stanzas with "configure" within the pubsub#owner namespace.
+ * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
+@SpecCompliant(spec="xep-0060", section="8.2", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public class PubSubOwnerConfigureNodeHandler extends AbstractPubSubOwnerHandler {
 
-	/**
-	 * @param root
-	 */
-	public PubSubOwnerConfigureNodeHandler(CollectionNode root) {
-		super(root);
-	}
-
-	@Override
-	protected String getWorkerElement() {
-		return "configure";
-	}
+    /**
+     * @param root
+     */
+    public PubSubOwnerConfigureNodeHandler(CollectionNode root) {
+        super(root);
+    }
+
+    /**
+     * @return "configure" as worker element.
+     */
+    @Override
+    protected String getWorkerElement() {
+        return "configure";
+    }
 
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerDeleteNodeHandler.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerDeleteNodeHandler.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerDeleteNodeHandler.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/handler/owner/PubSubOwnerDeleteNodeHandler.java Mon Jun 22 20:48:43 2009
@@ -19,25 +19,31 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.handler.owner;
 
+import org.apache.vysper.compliance.SpecCompliant;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model.CollectionNode;
 
 
 /**
+ * This class is responsible for handling all "delete" stanzas within the pubsub#owner namespace.
+ * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
+@SpecCompliant(spec="xep-0060", section="8.4", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public class PubSubOwnerDeleteNodeHandler extends AbstractPubSubOwnerHandler {
 
-	/**
-	 * @param root
-	 */
-	public PubSubOwnerDeleteNodeHandler(CollectionNode root) {
-		super(root);
-	}
-
-	@Override
-	protected String getWorkerElement() {
-		return "delete";
-	}
+    /**
+     * @param root
+     */
+    public PubSubOwnerDeleteNodeHandler(CollectionNode root) {
+        super(root);
+    }
+
+    /**
+     * @return "delete" as worker element.
+     */
+    @Override
+    protected String getWorkerElement() {
+        return "delete";
+    }
 
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/CollectionNode.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/CollectionNode.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/CollectionNode.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/CollectionNode.java Mon Jun 22 20:48:43 2009
@@ -19,40 +19,66 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model;
 
+import org.apache.vysper.compliance.SpecCompliant;
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.NullPersistenceManager;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.PubSubPersistenceManager;
 
 /**
+ * A collection node is a special pubsub node containing only other nodes. Either more CollectionNodes or
+ * LeafNodes or both.
+ * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
+@SpecCompliant(spec="xep-0060", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public class CollectionNode {
-	
-	protected PubSubPersistenceManager storage;
-	
-	public CollectionNode() {
-		storage = new NullPersistenceManager();
-	}
-	
-	public LeafNode find(Entity jid) {
-		return storage.findNode(jid);
-	}
-	
-	public LeafNode createNode(Entity jid) throws DuplicateNodeException {
-		if(storage.containsNode(jid)) {
-			throw new DuplicateNodeException(jid.getFullQualifiedName() + " already present");
-		}
-		
-		LeafNode node = new LeafNode(jid);
-		node.setPersistenceManager(storage);
-		
-		storage.storeNode(jid, node);
-		
-		return node;
-	}
-
-	public void setPersistenceManager(PubSubPersistenceManager persistenceManager) {
-		storage = persistenceManager;
-	}
+
+    // the persistence manager for storing and retrieving node-info
+    protected PubSubPersistenceManager storage;
+
+    /**
+     * Initializes the CollectionNode
+     */
+    public CollectionNode() {
+        storage = new NullPersistenceManager();
+    }
+
+    /**
+     * Search for a given node via its JID. We currently only support a flat hierachy, so no
+     * other node types are available ATM.
+     * 
+     * @return the LeafNode for the JID
+     */
+    public LeafNode find(Entity jid) {
+        return storage.findNode(jid);
+    }
+
+    /**
+     * Creates a new node under the given JID.
+     * 
+     * @param jid the JID of the new node.
+     * @return the newly created LeafNode.
+     * @throws DuplicateNodeException if the JID is already taken.
+     */
+    public LeafNode createNode(Entity jid) throws DuplicateNodeException {
+        if(storage.containsNode(jid)) {
+            throw new DuplicateNodeException(jid.getFullQualifiedName() + " already present");
+        }
+
+        LeafNode node = new LeafNode(jid);
+        node.setPersistenceManager(storage);
+
+        storage.storeNode(jid, node);
+
+        return node;
+    }
+
+    /**
+     * Change the persistency manager.
+     * 
+     * @param persistenceManager the new persitency manager.
+     */
+    public void setPersistenceManager(PubSubPersistenceManager persistenceManager) {
+        storage = persistenceManager;
+    }
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/DuplicateNodeException.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/DuplicateNodeException.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/DuplicateNodeException.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/DuplicateNodeException.java Mon Jun 22 20:48:43 2009
@@ -19,15 +19,25 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model;
 
+import org.apache.vysper.compliance.SpecCompliant;
+
 /**
+ * This exception is used to deal with the case that a new node should
+ * be created with a JID already taken by some other node.
+ * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
+@SpecCompliant(spec="xep-0060", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public class DuplicateNodeException extends Exception {
 
-	private static final long serialVersionUID = 4689474856848508356L;
+    private static final long serialVersionUID = 4689474856848508356L;
 
-	public DuplicateNodeException(String description) {
-		super(description);
-	}
+    /**
+     * Initializes the exception with a free-form string.
+     * 
+     * @param description further details about the exception.
+     */
+    public DuplicateNodeException(String description) {
+        super(description);
+    }
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/LeafNode.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/LeafNode.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/LeafNode.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/LeafNode.java Mon Jun 22 20:48:43 2009
@@ -19,6 +19,7 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model;
 
+import org.apache.vysper.compliance.SpecCompliant;
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.delivery.StanzaRelay;
 import org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.NullPersistenceManager;
@@ -27,70 +28,129 @@
 import org.apache.vysper.xmpp.xmlfragment.XMLElement;
 
 /**
+ * This class is the model for leaf nodes. Leaf nodes contain messages and subscribers in various
+ * forms.
  * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
+@SpecCompliant(spec="xep-0060", status= SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.UNSUPPORTED)
 public class LeafNode {
-	
-	protected Entity jid;
-	protected PubSubPersistenceManager storage = new NullPersistenceManager();
-	
-	/**
-	 * Creates a new LeafNode with the specified JID.
-	 * @param persistenceManager the persistence manager for loading additional information
-	 * @param jid the JID of the node 
-	 */
-	public LeafNode(Entity jid) {
-		this.jid = jid;
-	}
-	
-	public void setPersistenceManager(PubSubPersistenceManager persistenceManager) {
-		this.storage = persistenceManager;
-	}
-	
-	public void subscribe(String id, Entity subscriber) {
-		storage.addSubscriber(jid, id, subscriber);
-	}
-	
-	public boolean isSubscribed(Entity subscriber) {
-		return storage.containsSubscriber(jid, subscriber);
-	}
-	
-	public boolean isSubscribed(String subscriptionID) {
-		return storage.containsSubscriber(jid, subscriptionID);
-	}
-	
-	public boolean unsubscribe(String subscriptionID, Entity subscriber) {
-		Entity sub = storage.getSubscriber(jid, subscriptionID);
-
-		if(sub != null && sub.equals(subscriber)) {
-			return storage.removeSubscription(jid, subscriptionID);
-		}
-		return false;
-	}
-	
-	public boolean unsubscribe(Entity subscriber) throws MultipleSubscriptionException {
-		if(countSubscriptions(subscriber) > 1) {
-			throw new MultipleSubscriptionException("Ambigous unsubscription request");
-		}
-		return storage.removeSubscriber(jid, subscriber);
-	}
-	
-	public int countSubscriptions(Entity subscriber) {
-		return storage.countSubscriptions(jid, subscriber);
-	}
-
-	public int countSubscriptions() {
-		return storage.countSubscriptions(jid);
-	}
-
-	public void publish(Entity sender, StanzaRelay relay, String messageID, XMLElement item) {
-		storage.addMessage(jid, messageID, item);
-		sendMessageToSubscriber(relay, item);
-	}
-	
-	protected void sendMessageToSubscriber(StanzaRelay stanzaRelay, XMLElement item) {
-		storage.accept(jid, new SubscriberNotificationVisitor(stanzaRelay, item));
-	}
+
+    // the jid of the node
+    protected Entity jid;
+    // the persistency manager for storing and retrieving node information.
+    protected PubSubPersistenceManager storage = new NullPersistenceManager();
+
+    /**
+     * Creates a new LeafNode with the specified JID.
+     * @param jid the JID of the node
+     */
+    public LeafNode(Entity jid) {
+        this.jid = jid;
+    }
+
+    /**
+     * Changes the persistenceManager.
+     * @param persistenceManager the new persistence manager.
+     */
+    public void setPersistenceManager(PubSubPersistenceManager persistenceManager) {
+        this.storage = persistenceManager;
+    }
+
+    /**
+     * Add a new subscriber with the given id.
+     * @param id subscription ID
+     * @param subscriber the subscriber
+     */
+    public void subscribe(String id, Entity subscriber) {
+        storage.addSubscriber(jid, id, subscriber);
+    }
+
+    /**
+     * Check whether a JID is already subscribed
+     * @param subscriber the JID to check
+     * @return true if the JID is already subscribed
+     */
+    public boolean isSubscribed(Entity subscriber) {
+        return storage.containsSubscriber(jid, subscriber);
+    }
+
+    /**
+     * Check whether if we already have a subscription with the given ID
+     * @param subscriptionID the ID to check for.
+     * @return true if a subscription with this ID is present.
+     */
+    
+    public boolean isSubscribed(String subscriptionID) {
+        return storage.containsSubscriber(jid, subscriptionID);
+    }
+
+    /**
+     * Remove a subscription of a JID with a given subscription ID.
+     * @param subscriptionID the subscription ID of the JID.
+     * @param subscriber the JID of the subscriber.
+     * @return true if the subscription has been removed, false otherwise.
+     */
+    public boolean unsubscribe(String subscriptionID, Entity subscriber) {
+        Entity sub = storage.getSubscriber(jid, subscriptionID);
+
+        if(sub != null && sub.equals(subscriber)) {
+            return storage.removeSubscription(jid, subscriptionID);
+        }
+        return false;
+    }
+
+    /**
+     * Remove a subscription solely with the subscription JID, if more than one subscription
+     * with this JID is present an exception will be thrown.
+     * 
+     * @param subscriber the JID to unsubscribe.
+     * @return true if the subscription has been removed.
+     * @throws MultipleSubscriptionException if more than one subscription with this JID is present.
+     */
+    public boolean unsubscribe(Entity subscriber) throws MultipleSubscriptionException {
+        if(countSubscriptions(subscriber) > 1) {
+            throw new MultipleSubscriptionException("Ambigous unsubscription request");
+        }
+        return storage.removeSubscriber(jid, subscriber);
+    }
+
+    /**
+     * Returns the number of subscriptions with the given JID.
+     * @param subscriber the JID to count.
+     * @return number of subscriptions.
+     */
+    public int countSubscriptions(Entity subscriber) {
+        return storage.countSubscriptions(jid, subscriber);
+    }
+
+    /**
+     * Returns the total number of subscriptions (based on the subscriptions IDs, not the JIDs).
+     * @return number of subscriptions.
+     */
+    public int countSubscriptions() {
+        return storage.countSubscriptions(jid);
+    }
+
+    /**
+     * Publish an item to this node.
+     * @param sender the sender of the message (publisher).
+     * @param relay the relay for sending the messages.
+     * @param messageID the ID of the published message.
+     * @param item the payload of the message.
+     */
+    public void publish(Entity sender, StanzaRelay relay, String messageID, XMLElement item) {
+        storage.addMessage(jid, messageID, item);
+        sendMessageToSubscriber(relay, item);
+    }
+
+    /**
+     * Sends a message to each subscriber of the node.
+     * 
+     * @param stanzaRelay the relay for sending the notifications.
+     * @param item the payload of the message.
+     */
+    protected void sendMessageToSubscriber(StanzaRelay stanzaRelay, XMLElement item) {
+        storage.accept(jid, new SubscriberNotificationVisitor(stanzaRelay, item));
+    }
 }

Modified: mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/MultipleSubscriptionException.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/MultipleSubscriptionException.java?rev=787392&r1=787391&r2=787392&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/MultipleSubscriptionException.java (original)
+++ mina/sandbox/vysper/trunk/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0060_pubsub/model/MultipleSubscriptionException.java Mon Jun 22 20:48:43 2009
@@ -20,14 +20,21 @@
 package org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.model;
 
 /**
+ * This exception should be used to deal with the unsubscription of a JID
+ * if more than one subscription with this JID is present.
+ * 
  * @author The Apache MINA Project (http://mina.apache.org)
- *
  */
 public class MultipleSubscriptionException extends Exception {
 
-	private static final long serialVersionUID = 4386083322266436191L;
+    private static final long serialVersionUID = 4386083322266436191L;
 
-	public MultipleSubscriptionException(String description) {
-		super(description);
-	}
+    /**
+     * Initializes the exception with a free-form string.
+     * 
+     * @param description further details about the exception.
+     */
+    public MultipleSubscriptionException(String description) {
+        super(description);
+    }
 }