You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by be...@apache.org on 2010/04/27 21:39:49 UTC

svn commit: r938616 - in /mina/vysper/trunk: demo/pubsub/client/src/main/java/org/apache/vysper/demo/pubsub/client/ server/core/src/main/java/org/apache/vysper/xmpp/delivery/ server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/ s...

Author: berndf
Date: Tue Apr 27 19:39:48 2010
New Revision: 938616

URL: http://svn.apache.org/viewvc?rev=938616&view=rev
Log:
VYSPER-201: component handlers now managed by separate lookup subclass. distinguish between component and server-addressed stanzas, properly handle component-addressed and all other kinds of IQ stanzas, incl. disco IQs.

Added:
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/AbstractStanzaHandlerLookup.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/ComponentStanzaHandlerLookup.java
Modified:
    mina/vysper/trunk/demo/pubsub/client/src/main/java/org/apache/vysper/demo/pubsub/client/PubsubClientModel.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/delivery/StanzaRelayBroker.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandler.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookup.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/DefaultServerRuntimeContext.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/Component.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/ComponentStanzaProcessor.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/stanza/StanzaBuilder.java
    mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookupTestCase.java

Modified: mina/vysper/trunk/demo/pubsub/client/src/main/java/org/apache/vysper/demo/pubsub/client/PubsubClientModel.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/demo/pubsub/client/src/main/java/org/apache/vysper/demo/pubsub/client/PubsubClientModel.java?rev=938616&r1=938615&r2=938616&view=diff
==============================================================================
--- mina/vysper/trunk/demo/pubsub/client/src/main/java/org/apache/vysper/demo/pubsub/client/PubsubClientModel.java (original)
+++ mina/vysper/trunk/demo/pubsub/client/src/main/java/org/apache/vysper/demo/pubsub/client/PubsubClientModel.java Tue Apr 27 19:39:48 2010
@@ -105,6 +105,7 @@ public class PubsubClientModel {
     }
 
     public boolean login() {
+        XMPPConnection.DEBUG_ENABLED = false;
         try {
             connection = connect(username, password, hostname);
         } catch (XMPPException e) {
@@ -113,7 +114,7 @@ public class PubsubClientModel {
             return false;
         }
         
-        pubsubMgr = new PubSubManager(connection);
+        pubsubMgr = new PubSubManager(connection, "pubsub.vysper.org");
         return true;
     }
 
@@ -129,7 +130,17 @@ public class PubsubClientModel {
 
         try {
             discoverNodes(lookup);
+        } catch (XMPPException e) {
+            e.printStackTrace();
+        }
+
+        try {
             discoverSubscriptions(lookup);
+        } catch (XMPPException e) {
+            e.printStackTrace();
+        }
+
+        try {
             discoverAffiliations(lookup);
         } catch (XMPPException e) {
             e.printStackTrace();

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/delivery/StanzaRelayBroker.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/delivery/StanzaRelayBroker.java?rev=938616&r1=938615&r2=938616&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/delivery/StanzaRelayBroker.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/delivery/StanzaRelayBroker.java Tue Apr 27 19:39:48 2010
@@ -57,7 +57,11 @@ public class StanzaRelayBroker implement
     }
 
     public void relay(Entity receiver, Stanza stanza, DeliveryFailureStrategy deliveryFailureStrategy) throws DeliveryException {
-        if (receiver == null || !receiver.isNodeSet()) {
+
+        boolean toServerTLD = receiver == null ||
+                              (!receiver.isNodeSet() && serverRuntimeContext.getServerEnitity().getDomain().equals(receiver.getDomain()));
+        boolean toComponent = !toServerTLD && !receiver.isNodeSet();
+        if (toServerTLD) {
             // TODO handle by server
 
             // TODO if received <message/> from another server 'to' MUST be set

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandler.java?rev=938616&r1=938615&r2=938616&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandler.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandler.java Tue Apr 27 19:39:48 2010
@@ -42,9 +42,10 @@ public class RelayingIQHandler extends I
 
     @Override
     protected Stanza executeIQLogic(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, boolean outboundStanza, SessionContext sessionContext) {
-        // only handle IQs which are not directed to the server.
+        // only handle IQs which are not directed to the server (vysper.org).
         // in the case where an IQ is send to the server, StanzaHandlerLookup.getIQHandler is responsible for
         // looking it up and we shouldn't have been come here in the first place.
+        // but we might will relay to a component (chat.vysper.org)
         Entity to = stanza.getTo();
         if (to == null || to.equals(sessionContext.getServerJID())) {
             return ServerErrorResponses.getInstance().getStanzaError(StanzaErrorCondition.FEATURE_NOT_IMPLEMENTED, stanza,
@@ -56,20 +57,24 @@ public class RelayingIQHandler extends I
 
         if (outboundStanza) {
             try {
+                boolean toComponent = !to.isNodeSet() && !to.isResourceSet();
+                
                 Entity from = stanza.getFrom();
                 if (from == null || !from.isResourceSet()) {
                     from = new EntityImpl(sessionContext.getInitiatingEntity(), serverRuntimeContext.getResourceRegistry().getUniqueResourceForSession(sessionContext));
                 }
 
                 // determine if the is a matching subscription...
-                boolean isFromContact;
-                try {
-                    isFromContact = rosterManager.retrieve(from.getBareJID()).getEntry(to.getBareJID()).hasFrom();
-                } catch (Exception e) {
-                    isFromContact = false;
+                boolean isFromContact = false;
+                if (!toComponent) {
+                    try {
+                        isFromContact = rosterManager.retrieve(from.getBareJID()).getEntry(to.getBareJID()).hasFrom();
+                    } catch (Exception e) {
+                        isFromContact = false;
+                    }
                 }
-                // ...otherwise relaying is denied
-                if (!isFromContact) {
+                // deny relaying if neither isFromContact nor toComponent
+                if (!isFromContact && !toComponent) {
                     return ServerErrorResponses.getInstance().getStanzaError(StanzaErrorCondition.SERVICE_UNAVAILABLE, stanza,
                             StanzaErrorType.CANCEL,
                             null, null, null);
@@ -84,16 +89,19 @@ public class RelayingIQHandler extends I
             // write inbound stanza to the user
 
             Entity from = stanza.getFrom();
-            
-            // determine if the is a matching subscription...
-            boolean isToContact;
-            try {
-                isToContact = rosterManager.retrieve(to.getBareJID()).getEntry(from.getBareJID()).hasTo();
-            } catch (Exception e) {
-                isToContact = false;
+            boolean fromComponent = (from != null) && (!from.isNodeSet()) && (!from.isResourceSet());
+
+            // determine if 'from' is a component or a matching subscription...
+            boolean isToContact = false;
+            if (!fromComponent) {
+                try {
+                    isToContact = rosterManager.retrieve(to.getBareJID()).getEntry(from.getBareJID()).hasTo();
+                } catch (Exception e) {
+                    isToContact = false;
+                }
             }
             // ...otherwise relaying is denied
-            if (!isToContact) {
+            if (!isToContact && !fromComponent) {
                 return ServerErrorResponses.getInstance().getStanzaError(StanzaErrorCondition.SERVICE_UNAVAILABLE, stanza,
                         StanzaErrorType.CANCEL,
                         null, null, null);

Added: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/AbstractStanzaHandlerLookup.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/AbstractStanzaHandlerLookup.java?rev=938616&view=auto
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/AbstractStanzaHandlerLookup.java (added)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/AbstractStanzaHandlerLookup.java Tue Apr 27 19:39:48 2010
@@ -0,0 +1,61 @@
+/*
+ *  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.protocol;
+
+import org.apache.vysper.xml.fragment.XMLElement;
+import org.apache.vysper.xmpp.stanza.Stanza;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * basic facility to collect and query a set of namespace-based handlers 
+ */
+public abstract class AbstractStanzaHandlerLookup {
+    protected Map<String, NamespaceHandlerDictionary> namespaceDictionaries = new LinkedHashMap<String, NamespaceHandlerDictionary>();
+
+    public void addDictionary(NamespaceHandlerDictionary namespaceHandlerDictionary) {
+        String namespace = namespaceHandlerDictionary.getNamespaceURI();
+        if (namespaceDictionaries.containsKey(namespace)) throw new IllegalArgumentException("dictionary already exists covering namespace " + namespace);
+        namespaceDictionaries.put(namespace, namespaceHandlerDictionary);
+    }
+
+    public abstract StanzaHandler getHandler(Stanza stanza);
+
+    /**
+     * tries to find the handler by trying
+     * 1. value of xmlElement's XMLNS attribute, if unique
+     * 2. xmlElements namespace, if the element name has a namespace prefix
+     */
+    protected StanzaHandler getHandlerForElement(Stanza stanza, XMLElement xmlElement) {
+
+        String namespace = xmlElement.getNamespaceURI();
+        NamespaceHandlerDictionary namespaceHandlerDictionary = namespaceDictionaries.get(namespace);
+
+        // another try to get a dictionary
+        if (namespaceHandlerDictionary == null) {
+            namespace = xmlElement.getNamespacePrefix();
+            namespaceHandlerDictionary = namespaceDictionaries.get(namespace);
+        }
+        if (namespaceHandlerDictionary != null) return namespaceHandlerDictionary.get(stanza);
+
+        return null;
+    }
+}

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookup.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookup.java?rev=938616&r1=938615&r2=938616&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookup.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookup.java Tue Apr 27 19:39:48 2010
@@ -19,9 +19,6 @@
  */
 package org.apache.vysper.xmpp.protocol;
 
-import java.util.LinkedHashMap;
-import java.util.Map;
-
 import org.apache.vysper.xml.fragment.XMLElement;
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.modules.core.base.handler.IQHandler;
@@ -30,6 +27,7 @@ import org.apache.vysper.xmpp.modules.co
 import org.apache.vysper.xmpp.modules.core.base.handler.StreamStartHandler;
 import org.apache.vysper.xmpp.modules.core.base.handler.XMLPrologHandler;
 import org.apache.vysper.xmpp.modules.core.im.handler.PresenceHandler;
+import org.apache.vysper.xmpp.server.ServerRuntimeContext;
 import org.apache.vysper.xmpp.stanza.Stanza;
 import org.apache.vysper.xmpp.stanza.XMPPCoreStanza;
 
@@ -42,19 +40,16 @@ import org.apache.vysper.xmpp.stanza.XMP
  *
  * @author The Apache MINA Project (dev@mina.apache.org)
  */
-public class StanzaHandlerLookup {
-
-    private Map<String, NamespaceHandlerDictionary> namespaceDictionaries = new LinkedHashMap<String, NamespaceHandlerDictionary>();
+public class StanzaHandlerLookup extends AbstractStanzaHandlerLookup {
 
     private IQHandler iqHandler = new RelayingIQHandler();
     private MessageHandler messageHandler = new MessageHandler();
     private PresenceHandler presenceHandler = new PresenceHandler();
     private static final ServiceUnavailableStanzaErrorHandler SERVICE_UNAVAILABLE_STANZA_ERROR_HANDLER = new ServiceUnavailableStanzaErrorHandler();
+    protected ServerRuntimeContext serverRuntimeContext;
 
-    public void addDictionary(NamespaceHandlerDictionary namespaceHandlerDictionary) {
-        String namespace = namespaceHandlerDictionary.getNamespaceURI();
-        if (namespaceDictionaries.containsKey(namespace)) throw new IllegalArgumentException("dictionary already exists covering namespace " + namespace);
-        namespaceDictionaries.put(namespace, namespaceHandlerDictionary);
+    public StanzaHandlerLookup(ServerRuntimeContext serverRuntimeContext) {
+        this.serverRuntimeContext = serverRuntimeContext;
     }
 
     /**
@@ -62,6 +57,7 @@ public class StanzaHandlerLookup {
      * @param stanza
      * @return NULL, if no handler could be
      */
+    @Override
     public StanzaHandler getHandler(Stanza stanza) {
         if (stanza == null) return null;
 
@@ -80,7 +76,10 @@ public class StanzaHandlerLookup {
             // d. an evil forged stanza
             // e. some extension we don't know yet
             // ...so we delegate:
-            return getHandlerForElement(stanza, stanza);
+            StanzaHandler stanzaHandler = getHandlerForElement(stanza, stanza);
+            // ... and if we could not resolve and it's a core stanza, we can safely return an error
+            if (stanzaHandler == null && XMPPCoreStanza.getWrapper(stanza) != null) return SERVICE_UNAVAILABLE_STANZA_ERROR_HANDLER;
+            return stanzaHandler;
         }
     }
 
@@ -96,38 +95,27 @@ public class StanzaHandlerLookup {
         StanzaHandler handlerForElement = null;
 
         Entity to = stanza.getTo();
-        boolean isAddressedToServer = (to == null || (!to.isNodeSet() && !to.isResourceSet()));
-        
-        if (isAddressedToServer && stanza.getVerifier().subElementsPresentExact(1)) {
-            XMLElement firstInnerElement = stanza.getFirstInnerElement();
-            handlerForElement = getHandlerForElement(stanza, firstInnerElement);
-            return handlerForElement;
-        } else {
-            // if no specialized handler can be identified, return general handler
-            return iqHandler;
-        }
-    }
-
-    /**
-     * tries to find the handler by trying
-     * 1. value of xmlElement's XMLNS attribute, if unique
-     * 2. xmlElements namespace, if the element name has a namespace prefix
-     */
-    private StanzaHandler getHandlerForElement(Stanza stanza, XMLElement xmlElement) {
+        Entity serverEntity = (serverRuntimeContext == null) ? null : serverRuntimeContext.getServerEnitity();
+        boolean isAddressedToServerOrComponent = (to == null || (!to.isNodeSet() && !to.isResourceSet()));
+        boolean isAddressedToComponent = (to != null) && isAddressedToServerOrComponent && serverEntity != null && (!serverEntity.equals(to));
+        boolean isAddressedToServer = (to == null) || (isAddressedToServerOrComponent && !isAddressedToComponent);
+
+        // The following cases must be properly handled:
+        // 1. IQ disco stanza always handled by disco subsystem, not addressee
+        // 2. to = someone@vysper.org => relay
+        // 3. to = vysper.org => service unavailable
+        // 4. to = component.vysper.org => relay
 
-        String namespace = xmlElement.getNamespaceURI();
-        NamespaceHandlerDictionary namespaceHandlerDictionary = namespaceDictionaries.get(namespace);
+        // if no specialized handler can be identified, return general handler (relay)
+        StanzaHandler resolvedHandler = null;
 
-        // another try to get a dictionary
-        if (namespaceHandlerDictionary == null) {
-            namespace = xmlElement.getNamespacePrefix();
-            namespaceHandlerDictionary = namespaceDictionaries.get(namespace);
+        if (stanza.getVerifier().subElementsPresentExact(1)) {
+            XMLElement firstInnerElement = stanza.getFirstInnerElement();
+            handlerForElement = getHandlerForElement(stanza, firstInnerElement);
+            if (handlerForElement != null) resolvedHandler = handlerForElement;
+            if (resolvedHandler == null && isAddressedToServer && XMPPCoreStanza.getWrapper(stanza) != null) resolvedHandler = SERVICE_UNAVAILABLE_STANZA_ERROR_HANDLER;
         }
-        if (namespaceHandlerDictionary != null) return namespaceHandlerDictionary.get(stanza);
-
-        if (XMPPCoreStanza.getWrapper(stanza) != null) return SERVICE_UNAVAILABLE_STANZA_ERROR_HANDLER;
-
-        return null;
+        if (resolvedHandler == null) resolvedHandler = iqHandler;
+        return resolvedHandler;
     }
-
 }

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/DefaultServerRuntimeContext.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/DefaultServerRuntimeContext.java?rev=938616&r1=938615&r2=938616&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/DefaultServerRuntimeContext.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/DefaultServerRuntimeContext.java Tue Apr 27 19:39:48 2010
@@ -129,7 +129,7 @@ public class DefaultServerRuntimeContext
         this.serverEntity = serverEntity;
         this.stanzaRelay = stanzaRelay;
         this.resourceRegistry = new ResourceRegistry();
-        this.stanzaHandlerLookup = new StanzaHandlerLookup();
+        this.stanzaHandlerLookup = new StanzaHandlerLookup(this);
     }
 
     public DefaultServerRuntimeContext(Entity serverEntity, StanzaRelay stanzaRelay, StorageProviderRegistry storageProviderRegistry) {

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/Component.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/Component.java?rev=938616&r1=938615&r2=938616&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/Component.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/Component.java Tue Apr 27 19:39:48 2010
@@ -27,8 +27,17 @@ import org.apache.vysper.xmpp.protocol.S
  * components have a dedicated context in which they receive stanzas 
  */
 public interface Component {
-    
+
+    /**
+     * the subdomain this component should become available under.
+     * example: subdomain = 'chat' + server domain = 'vysper.org' => 'chat.vysper.org'
+     * @return
+     */
     String getSubdomain();
-    
+
+    /**
+     * retrieve the stanza processor for the component
+     * @return
+     */
     StanzaProcessor getStanzaProcessor();
 }

Added: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/ComponentStanzaHandlerLookup.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/ComponentStanzaHandlerLookup.java?rev=938616&view=auto
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/ComponentStanzaHandlerLookup.java (added)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/ComponentStanzaHandlerLookup.java Tue Apr 27 19:39:48 2010
@@ -0,0 +1,60 @@
+/*
+ *  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.server.components;
+
+import org.apache.vysper.xml.fragment.XMLElement;
+import org.apache.vysper.xmpp.protocol.AbstractHandlerDictionary;
+import org.apache.vysper.xmpp.protocol.AbstractStanzaHandlerLookup;
+import org.apache.vysper.xmpp.protocol.StanzaHandler;
+import org.apache.vysper.xmpp.stanza.Stanza;
+
+/**
+ * look up a component's handler for a stanza 
+ */
+public class ComponentStanzaHandlerLookup extends AbstractStanzaHandlerLookup {
+
+    private static class ComponentHandlerDictionary extends AbstractHandlerDictionary {
+
+        public ComponentHandlerDictionary() {
+            super();
+        }
+    }
+
+    protected ComponentHandlerDictionary defaultHandlers = new ComponentHandlerDictionary();
+    
+    public void addDefaultHandler(StanzaHandler stanzaHandler) {
+        defaultHandlers.register(stanzaHandler);
+    }
+    
+    @Override
+    public StanzaHandler getHandler(Stanza stanza) {
+
+        XMLElement firstInnerElement = stanza;
+        if (stanza.getVerifier().subElementsPresentExact(1)) {
+            firstInnerElement = stanza.getFirstInnerElement();
+        }
+
+        StanzaHandler stanzaHandler = getHandlerForElement(stanza, firstInnerElement);
+
+        if (stanzaHandler == null) stanzaHandler = defaultHandlers.get(stanza);
+
+        return stanzaHandler;
+    }
+}

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/ComponentStanzaProcessor.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/ComponentStanzaProcessor.java?rev=938616&r1=938615&r2=938616&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/ComponentStanzaProcessor.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/server/components/ComponentStanzaProcessor.java Tue Apr 27 19:39:48 2010
@@ -19,13 +19,7 @@
  */
 package org.apache.vysper.xmpp.server.components;
 
-import org.apache.vysper.xmpp.protocol.StanzaProcessor;
-import org.apache.vysper.xmpp.protocol.SessionStateHolder;
-import org.apache.vysper.xmpp.protocol.AbstractHandlerDictionary;
-import org.apache.vysper.xmpp.protocol.StanzaHandler;
-import org.apache.vysper.xmpp.protocol.ProtocolException;
-import org.apache.vysper.xmpp.protocol.ResponseStanzaContainer;
-import org.apache.vysper.xmpp.protocol.ResponseWriter;
+import org.apache.vysper.xmpp.protocol.*;
 import org.apache.vysper.xmpp.server.ServerRuntimeContext;
 import org.apache.vysper.xmpp.server.SessionContext;
 import org.apache.vysper.xmpp.stanza.Stanza;
@@ -37,32 +31,29 @@ import org.apache.vysper.xmpp.delivery.f
  */
 public class ComponentStanzaProcessor implements StanzaProcessor {
 
-    private static class ComponentHandlerDictionary extends AbstractHandlerDictionary {
-
-        public ComponentHandlerDictionary() {
-            super();
-        }
-    }
-
     protected ServerRuntimeContext serverRuntimeContext;
     
-    protected ComponentHandlerDictionary handlers = new ComponentHandlerDictionary();
+    protected ComponentStanzaHandlerLookup componentStanzaHandlerLookup = new ComponentStanzaHandlerLookup();
 
     public ComponentStanzaProcessor(ServerRuntimeContext serverRuntimeContext) {
         this.serverRuntimeContext = serverRuntimeContext;
     }
     
     public void addHandler(StanzaHandler stanzaHandler) {
-        handlers.register(stanzaHandler);
+        componentStanzaHandlerLookup.addDefaultHandler(stanzaHandler);
     }
     
+    public void addDictionary(NamespaceHandlerDictionary namespaceHandlerDictionary) {
+        componentStanzaHandlerLookup.addDictionary(namespaceHandlerDictionary);
+    }
+
     public void processStanza(ServerRuntimeContext serverRuntimeContext, SessionContext sessionContext, Stanza stanza, SessionStateHolder sessionStateHolder) {
         if (stanza == null) throw new RuntimeException("cannot process NULL stanzas");
 
         XMPPCoreStanza xmppStanza = XMPPCoreStanza.getWrapper(stanza);
         if (xmppStanza == null) throw new RuntimeException("cannot process only: IQ, message or presence");
 
-        StanzaHandler stanzaHandler = handlers.get(xmppStanza);
+        StanzaHandler stanzaHandler = componentStanzaHandlerLookup.getHandler(xmppStanza);
 
         if (stanzaHandler == null) {
             unhandledStanza(stanza);
@@ -79,7 +70,7 @@ public class ComponentStanzaProcessor im
         if (responseStanzaContainer != null && responseStanzaContainer.getResponseStanza() != null) {
             Stanza responseStanza = responseStanzaContainer.getResponseStanza();
             try {
-                IgnoreFailureStrategy failureStrategy = new IgnoreFailureStrategy(); // TODO call back MUC module
+                IgnoreFailureStrategy failureStrategy = new IgnoreFailureStrategy(); // TODO call back module
                 serverRuntimeContext.getStanzaRelay().relay(responseStanza.getTo(), responseStanza, failureStrategy);
             } catch (DeliveryException e) {
                 throw new RuntimeException(e);

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/stanza/StanzaBuilder.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/stanza/StanzaBuilder.java?rev=938616&r1=938615&r2=938616&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/stanza/StanzaBuilder.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/stanza/StanzaBuilder.java Tue Apr 27 19:39:48 2010
@@ -89,6 +89,10 @@ public class StanzaBuilder extends Abstr
         return stanzaBuilder;
     }
 
+    public static StanzaBuilder createDirectReply(XMPPCoreStanza original, boolean fromIsServerOnly, IQStanzaType type) {
+        return createDirectReply(original, fromIsServerOnly, type == null ? null : type.value());
+    }
+
     public static StanzaBuilder createDirectReply(XMPPCoreStanza original, boolean fromIsServerOnly, String type) {
         if (original == null) throw new IllegalArgumentException();
 

Modified: mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookupTestCase.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookupTestCase.java?rev=938616&r1=938615&r2=938616&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookupTestCase.java (original)
+++ mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookupTestCase.java Tue Apr 27 19:39:48 2010
@@ -87,7 +87,7 @@ public class StanzaHandlerLookupTestCase
     }
 
     private StanzaHandlerLookup initStanzaHandlerLookup() {
-        return new StanzaHandlerLookup();
+        return new StanzaHandlerLookup(null);
     }
 
     public void testLookupCoreHandlerServerNS() {
@@ -148,7 +148,7 @@ public class StanzaHandlerLookupTestCase
 
         stanza = buildStanza("testFAIL", "test:namespace:OK");
         handler = stanzaHandlerLookup.getHandler(stanza);
-        assertNull("handler not found for name", handler);
+        assertTrue("handler not found for name", handler instanceof ServiceUnavailableStanzaErrorHandler);
 
         stanza = buildStanza("testOK", "test:namespace:OK");
         handler = stanzaHandlerLookup.getHandler(stanza);