You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by ng...@apache.org on 2011/03/05 23:45:11 UTC

svn commit: r1078382 - in /mina/vysper/trunk: nbxml/src/main/java/org/apache/vysper/xml/decoder/ nbxml/src/main/java/org/apache/vysper/xml/fragment/ nbxml/src/test/java/org/apache/vysper/xml/fragment/ server/core/src/main/java/org/apache/vysper/xmpp/mo...

Author: ngn
Date: Sat Mar  5 22:45:10 2011
New Revision: 1078382

URL: http://svn.apache.org/viewvc?rev=1078382&view=rev
Log:
Adding unit tests
Fixing bug where escaped private storage data was returned (VYSPER-269)
Fixing bug where a 0 was interpreted as true for data forms (VYSPER-270)
Fixing bug where a stream error rather than IQ error was returned for private storage (VYSPER-271)

Added:
    mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/DocumentContentHandler.java
    mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMLElementListener.java
    mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/
    mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataIQHandlerTestCase.java
    mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataModuleTestCase.java
    mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/servicediscovery/ServiceDiscoveryModuleTestCase.java
    mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/stanza/dataforms/DataFormParserTestCase.java
Modified:
    mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPContentHandler.java
    mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPDecoder.java
    mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/fragment/XMLElement.java
    mina/vysper/trunk/nbxml/src/test/java/org/apache/vysper/xml/fragment/XMLElementTestCase.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataIQHandler.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/stanza/dataforms/DataFormParser.java

Added: mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/DocumentContentHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/DocumentContentHandler.java?rev=1078382&view=auto
==============================================================================
--- mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/DocumentContentHandler.java (added)
+++ mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/DocumentContentHandler.java Sat Mar  5 22:45:10 2011
@@ -0,0 +1,171 @@
+/*
+ *  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.xml.decoder;
+
+import org.apache.vysper.xml.fragment.Renderer;
+import org.apache.vysper.xml.fragment.XMLElement;
+import org.apache.vysper.xml.fragment.XMLElementBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * SAX content handler for the purpose of emitting a complete XML document
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ */
+public class DocumentContentHandler implements ContentHandler {
+
+    private Logger log = LoggerFactory.getLogger(DocumentContentHandler.class);
+
+    private XMLElementBuilder builder;
+
+    private int depth = 0;
+
+    private XMLElementListener listener;
+
+    public XMLElementListener getListener() {
+        return listener;
+    }
+
+    public void setListener(XMLElementListener listener) {
+        this.listener = listener;
+    }
+
+    public DocumentContentHandler() {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        // TODO handle start and length
+        if (builder != null) {
+            builder.addText(new String(ch));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+        depth--;
+        if (depth == 0) {
+            // complete document, emit
+            emit();
+        } else {
+            builder.endInnerElement();
+        }
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+        // increase element depth
+        depth++;
+        if (builder == null) {
+            builder = new XMLElementBuilder(localName, uri, extractPrefix(qName), null, null);
+        } else {
+            builder.startInnerElement(localName, uri);
+        }
+
+        for (int i = 0; i < atts.getLength(); i++) {
+            builder.addAttribute(atts.getURI(i), atts.getLocalName(i), atts.getValue(i));
+        }
+    }
+
+    private void emit() {
+        XMLElement element = builder.build();
+
+        if (log.isDebugEnabled()) {
+            log.debug("Decoder writing stanza: {}", new Renderer(element).getComplete());
+        }
+
+        if (listener != null) {
+            listener.element(element);
+        }
+
+        builder = null;
+    }
+
+    private String extractPrefix(String qname) {
+        int index = qname.indexOf(':');
+        if (index > -1) {
+            return qname.substring(0, index);
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void endDocument() throws SAXException { /* ignore */
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void startPrefixMapping(String prefix, String uri) throws SAXException { /* ignore */
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void endPrefixMapping(String prefix) throws SAXException { /* ignore */
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { /* ignore */
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void processingInstruction(String target, String data) throws SAXException { /* ignore */
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setDocumentLocator(Locator locator) { /* ignore */
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void skippedEntity(String name) throws SAXException { /* ignore */
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void startDocument() throws SAXException {
+        depth = 0;
+        builder = null;
+    }
+}

Added: mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMLElementListener.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMLElementListener.java?rev=1078382&view=auto
==============================================================================
--- mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMLElementListener.java (added)
+++ mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMLElementListener.java Sat Mar  5 22:45:10 2011
@@ -0,0 +1,26 @@
+/*
+ *  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.xml.decoder;
+
+import org.apache.vysper.xml.fragment.XMLElement;
+
+public interface XMLElementListener {
+    void element(XMLElement element);
+}
\ No newline at end of file

Modified: mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPContentHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPContentHandler.java?rev=1078382&r1=1078381&r2=1078382&view=diff
==============================================================================
--- mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPContentHandler.java (original)
+++ mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPContentHandler.java Sat Mar  5 22:45:10 2011
@@ -46,20 +46,16 @@ public class XMPPContentHandler implemen
 
     private int depth = 0;
 
-    private StanzaListener listener;
+    private XMLElementListener listener;
 
-    public StanzaListener getListener() {
+    public XMLElementListener getListener() {
         return listener;
     }
 
-    public void setListener(StanzaListener listener) {
+    public void setListener(XMLElementListener listener) {
         this.listener = listener;
     }
 
-    public static interface StanzaListener {
-        void stanza(XMLElement element);
-    }
-
     public XMPPContentHandler() {
     }
 
@@ -85,7 +81,7 @@ public class XMPPContentHandler implemen
         depth--;
         if (depth == 1) {
             // complete stanza, emit
-            emitStanza();
+            emit();
         } else if (depth == 0) {
             // end stream:stream element
             // TODO handle
@@ -113,11 +109,11 @@ public class XMPPContentHandler implemen
 
         if (depth == 1) {
             // outer stream:stream element, needs to be dispatched right away
-            emitStanza();
+            emit();
         }
     }
 
-    private void emitStanza() {
+    private void emit() {
         XMLElement element = builder.build();
 
         if (log.isDebugEnabled()) {
@@ -125,7 +121,7 @@ public class XMPPContentHandler implemen
         }
 
         if (listener != null) {
-            listener.stanza(element);
+            listener.element(element);
         }
 
         builder = null;

Modified: mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPDecoder.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPDecoder.java?rev=1078382&r1=1078381&r2=1078382&view=diff
==============================================================================
--- mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPDecoder.java (original)
+++ mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPDecoder.java Sat Mar  5 22:45:10 2011
@@ -24,7 +24,6 @@ import org.apache.mina.core.session.IoSe
 import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
 import org.apache.mina.filter.codec.ProtocolDecoderOutput;
 import org.apache.vysper.charset.CharsetUtil;
-import org.apache.vysper.xml.decoder.XMPPContentHandler.StanzaListener;
 import org.apache.vysper.xml.fragment.XMLElement;
 import org.apache.vysper.xml.sax.NonBlockingXMLReader;
 import org.apache.vysper.xml.sax.impl.DefaultNonBlockingXMLReader;
@@ -52,14 +51,14 @@ public class XMPPDecoder extends Cumulat
         this.builderFactory = builderFactory;
     }
 
-    public static class MinaStanzaListener implements StanzaListener {
+    public static class MinaStanzaListener implements XMLElementListener {
         private ProtocolDecoderOutput protocolDecoder;
 
         public MinaStanzaListener(ProtocolDecoderOutput protocolDecoder) {
             this.protocolDecoder = protocolDecoder;
         }
 
-        public void stanza(XMLElement element) {
+        public void element(XMLElement element) {
             if (element.getName().equals("stream")) {
                 // reset the reader 
             }

Modified: mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/fragment/XMLElement.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/fragment/XMLElement.java?rev=1078382&r1=1078381&r2=1078382&view=diff
==============================================================================
--- mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/fragment/XMLElement.java (original)
+++ mina/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xml/fragment/XMLElement.java Sat Mar  5 22:45:10 2011
@@ -26,6 +26,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Pattern;
 
 /**
  * an immutable xml element specialized for XMPP.
@@ -73,14 +74,26 @@ public class XMLElement implements XMLFr
     public XMLElement(String namespaceURI, String name, String namespacePrefix, List<Attribute> attributes,
             List<XMLFragment> innerFragments, Map<String, String> namespaces) {
         this.namespaceURI = namespaceURI == null ? Namespaces.DEFAULT_NAMESPACE_URI : namespaceURI;
+
+        if(namespacePrefix != null && namespacePrefix.length() > 0) {
+            if(!isValidName(namespacePrefix) || namespacePrefix.contains(":")) throw new IllegalArgumentException("Invalid XML element namespace prefix");
+        }
         this.namespacePrefix = namespacePrefix == null ? Namespaces.DEFAULT_NAMESPACE_PREFIX : namespacePrefix;
+        
+        if(name == null || !isValidName(name)) throw new IllegalArgumentException("Invalid XML element name");
         this.name = name;
         this.attributes = (attributes == null) ? Collections.EMPTY_LIST : Collections.unmodifiableList(attributes);
         this.namespaces = (namespaces == null) ? Collections.EMPTY_MAP : Collections.unmodifiableMap(namespaces);
         this.innerFragments = (innerFragments == null) ? Collections.EMPTY_LIST : Collections
                 .unmodifiableList(innerFragments);
-        if (name == null)
-            throw new IllegalArgumentException("XMLElement name cannot be null");
+    }
+    
+    private static final String NAME_START_CHAR = "A-Za-z\\_\\:";
+    private static final String NAME_CHAR = NAME_START_CHAR + "\\-\\.0-9";
+    private static final Pattern namePattern = Pattern.compile("[" + NAME_START_CHAR + "][" + NAME_CHAR + "]*");
+    private boolean isValidName(String name) {
+        // TODO add additional char ranges
+        return namePattern.matcher(name).matches();
     }
 
     public String getName() {
@@ -217,7 +230,7 @@ public class XMLElement implements XMLFr
     }
 
     /**
-     * collects all inner elements named as given parameter
+     * collects all inner elements named as given parameter. Namespace UIR is ignored.
      * @param name - must not be NULL
      */
     public List<XMLElement> getInnerElementsNamed(String name) {

Modified: mina/vysper/trunk/nbxml/src/test/java/org/apache/vysper/xml/fragment/XMLElementTestCase.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/nbxml/src/test/java/org/apache/vysper/xml/fragment/XMLElementTestCase.java?rev=1078382&r1=1078381&r2=1078382&view=diff
==============================================================================
--- mina/vysper/trunk/nbxml/src/test/java/org/apache/vysper/xml/fragment/XMLElementTestCase.java (original)
+++ mina/vysper/trunk/nbxml/src/test/java/org/apache/vysper/xml/fragment/XMLElementTestCase.java Sat Mar  5 22:45:10 2011
@@ -157,6 +157,15 @@ public class XMLElementTestCase extends 
         }
     }
 
+    public void testPrefixWithColon() {
+        try {
+            new XMLElementBuilder("message", "http://example.com", "pre:fix");
+            fail("Must throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // ok
+        }
+    }
+    
     public void testLanguageMapping() {
 
         XMLElement xmlElement = new XMLElementBuilder("message", "jabber:test").addText("t1").startInnerElement("body")

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataIQHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataIQHandler.java?rev=1078382&r1=1078381&r2=1078382&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataIQHandler.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataIQHandler.java Sat Mar  5 22:45:10 2011
@@ -19,14 +19,23 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0049_privatedata;
 
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.mina.core.buffer.IoBuffer;
+import org.apache.vysper.charset.CharsetUtil;
 import org.apache.vysper.compliance.SpecCompliant;
-import org.apache.vysper.xml.fragment.Attribute;
+import org.apache.vysper.xml.decoder.DocumentContentHandler;
+import org.apache.vysper.xml.decoder.XMLElementListener;
 import org.apache.vysper.xml.fragment.Renderer;
 import org.apache.vysper.xml.fragment.XMLElement;
+import org.apache.vysper.xml.sax.NonBlockingXMLReader;
+import org.apache.vysper.xml.sax.impl.DefaultNonBlockingXMLReader;
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.modules.core.base.handler.DefaultIQHandler;
 import org.apache.vysper.xmpp.protocol.NamespaceURIs;
-import org.apache.vysper.xmpp.protocol.StreamErrorCondition;
 import org.apache.vysper.xmpp.server.ServerRuntimeContext;
 import org.apache.vysper.xmpp.server.SessionContext;
 import org.apache.vysper.xmpp.server.response.ServerErrorResponses;
@@ -36,6 +45,8 @@ import org.apache.vysper.xmpp.stanza.Sta
 import org.apache.vysper.xmpp.stanza.StanzaBuilder;
 import org.apache.vysper.xmpp.stanza.StanzaErrorCondition;
 import org.apache.vysper.xmpp.stanza.StanzaErrorType;
+import org.apache.vysper.xmpp.stanza.XMPPCoreStanza;
+import org.xml.sax.SAXException;
 
 /**
  * @author The Apache MINA Project (dev@mina.apache.org)
@@ -50,13 +61,8 @@ public class PrivateDataIQHandler extend
     }
 
     @Override
-    protected boolean verifyNamespace(Stanza stanza) {
-        return verifyInnerNamespace(stanza, NamespaceURIs.PRIVATE_DATA);
-    }
-
-    @Override
     protected boolean verifyInnerElement(Stanza stanza) {
-        return verifyInnerElementWorker(stanza, "query");
+        return verifyInnerElementWorker(stanza, "query") && verifyInnerNamespace(stanza, NamespaceURIs.PRIVATE_DATA);
     }
 
     @Override
@@ -70,8 +76,8 @@ public class PrivateDataIQHandler extend
 
         // Not null, and not addressed to itself
         if (to != null && !to.getBareJID().equals(sessionContext.getInitiatingEntity().getBareJID())) {
-            return ServerErrorResponses.getStreamError(StreamErrorCondition.BAD_FORMAT, null,
-                    "Private data only modifiable by the owner", null);
+            return ServerErrorResponses.getStanzaError(StanzaErrorCondition.FORBIDDEN, stanza,
+                    StanzaErrorType.CANCEL, 403, "Private data only modifiable by the owner", null, null);
         }
 
         XMLElement queryElement = stanza.getFirstInnerElement();
@@ -83,20 +89,16 @@ public class PrivateDataIQHandler extend
                     StanzaErrorType.MODIFY, "query's child element is missing", null, null);
         }
         XMLElement x = queryElement.getFirstInnerElement();
-        String ns = x.getAttribute("xmlns").getValue();
-        if (ns == null) {
-            return ServerErrorResponses.getStanzaError(StanzaErrorCondition.NOT_ACCEPTABLE, stanza,
-                    StanzaErrorType.MODIFY, "no namespace", null, null);
-        }
+        String ns = x.getNamespaceURI();
 
-        // No persistancy Manager
+        // No persistance Manager
         if (persistenceManager == null) {
             return ServerErrorResponses.getStanzaError(StanzaErrorCondition.INTERNAL_SERVER_ERROR,
                     stanza, StanzaErrorType.WAIT, "internal storage inaccessible", null, null);
         }
 
         String queryKey = getKey(x);
-        String queryContent = new Renderer(queryElement).getComplete();
+        String queryContent = new Renderer(x).getComplete();
         boolean success = persistenceManager.setPrivateData(from, queryKey, queryContent);
 
         if (success) {
@@ -116,8 +118,8 @@ public class PrivateDataIQHandler extend
 
         // Not null, and not addressed to itself
         if (to != null && !to.getBareJID().equals(sessionContext.getInitiatingEntity().getBareJID())) {
-            return ServerErrorResponses.getStreamError(StreamErrorCondition.BAD_FORMAT, null,
-                    "can only view your data", null);
+            return ServerErrorResponses.getStanzaError(StanzaErrorCondition.FORBIDDEN, stanza,
+                    StanzaErrorType.CANCEL, 403, "can only view your data", null, null);
         }
 
         XMLElement queryElement = stanza.getFirstInnerElement();
@@ -129,8 +131,7 @@ public class PrivateDataIQHandler extend
 
         // No persistancy Manager
         if (persistenceManager == null) {
-            return ServerErrorResponses.getStanzaError(StanzaErrorCondition.INTERNAL_SERVER_ERROR,
-                    stanza, StanzaErrorType.WAIT, "internal storage inaccessible", null, null);
+            return buildInteralStorageError(stanza);
         }
 
         String queryKey = getKey(x);
@@ -138,18 +139,46 @@ public class PrivateDataIQHandler extend
 
         StanzaBuilder stanzaBuilder = StanzaBuilder.createIQStanza(stanza.getTo(), stanza.getFrom(),
                 IQStanzaType.RESULT, stanza.getID());
-        if (privateDataXML == null) {
-            stanzaBuilder.startInnerElement(x.getName(), x.getNamespaceURI());
-            for (Attribute a : x.getAttributes()) {
-                stanzaBuilder.addAttribute(a);
+
+        stanzaBuilder.startInnerElement("query", NamespaceURIs.PRIVATE_DATA);
+        if (privateDataXML != null) {
+            try {
+                XMLElement elm = parseDocument(privateDataXML);
+                stanzaBuilder.addPreparedElement(elm);
+            } catch (Exception e) {
+                return buildInteralStorageError(stanza);
             }
-            stanzaBuilder.endInnerElement();
         } else {
-            stanzaBuilder.addText(privateDataXML);
+            stanzaBuilder.addPreparedElement(x);
         }
         return stanzaBuilder.build();
     }
+    
+    private Stanza buildInteralStorageError(XMPPCoreStanza stanza) {
+        return ServerErrorResponses.getStanzaError(StanzaErrorCondition.INTERNAL_SERVER_ERROR,
+                stanza, StanzaErrorType.WAIT, "internal storage inaccessible", null, null);
+    }
+
+    private XMLElement parseDocument(String xml) throws IOException, SAXException {
+        NonBlockingXMLReader reader = new DefaultNonBlockingXMLReader();
+
+        DocumentContentHandler contentHandler = new DocumentContentHandler();
+        reader.setContentHandler(contentHandler);
+
+        final List<XMLElement> documents = new ArrayList<XMLElement>();
+        
+        contentHandler.setListener(new XMLElementListener() {
+            public void element(XMLElement element) {
+                documents.add(element);
+            }
+        });
+
+        IoBuffer buffer = IoBuffer.wrap(xml.getBytes(Charset.forName("UTF-8")));
+        reader.parse(buffer, CharsetUtil.UTF8_DECODER);
 
+        return documents.get(0);
+    }
+    
     /**
      * Create a property name that is unique for this query. eg this XMLElement:
      * <storage xmlns="storage:bookmarks"> is converted into this string:
@@ -159,7 +188,7 @@ public class PrivateDataIQHandler extend
         StringBuilder queryKey = new StringBuilder();
         queryKey.append(x.getName());
         queryKey.append("-");
-        queryKey.append(x.getAttribute("xmlns").getValue());
+        queryKey.append(x.getNamespaceURI());
 
         // Some characters are not valid for property names
         for (int i = 0; i < queryKey.length(); i++) {

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/stanza/dataforms/DataFormParser.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/stanza/dataforms/DataFormParser.java?rev=1078382&r1=1078381&r2=1078382&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/stanza/dataforms/DataFormParser.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/stanza/dataforms/DataFormParser.java Sat Mar  5 22:45:10 2011
@@ -23,6 +23,7 @@ import org.apache.vysper.xml.fragment.XM
 import org.apache.vysper.xml.fragment.XMLText;
 import org.apache.vysper.xmpp.addressing.EntityFormatException;
 import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -52,7 +53,7 @@ public class DataFormParser {
                 value = valueAsString;
                 break;
             case BOOLEAN:
-                value = "0".equals(valueAsString) || "true".equals(valueAsString);
+                value = "1".equals(valueAsString) || "true".equals(valueAsString);
                 break;
             case JID_MULTI:
             case JID_SINGLE:
@@ -75,7 +76,7 @@ public class DataFormParser {
     public Map<String, Object> extractFieldValues() throws IllegalArgumentException {
         Map<String,Object> map = new LinkedHashMap<String, Object>();
 
-        for (XMLElement fields : form.getInnerElementsNamed("field")) {
+        for (XMLElement fields : form.getInnerElementsNamed("field", NamespaceURIs.JABBER_X_DATA)) {
             final String varName = fields.getAttributeValue("var");
             final String typeName = fields.getAttributeValue("type");
             String valueAsString = null;
@@ -92,7 +93,7 @@ public class DataFormParser {
             boolean isMulti = Field.Type.isMulti(fieldType);
 
             List<Object> values = isMulti ? new ArrayList<Object>() : null;
-            for (XMLElement valueCandidates : fields.getInnerElementsNamed("value")) {
+            for (XMLElement valueCandidates : fields.getInnerElementsNamed("value", NamespaceURIs.JABBER_X_DATA)) {
                 final XMLText firstInnerText = valueCandidates.getFirstInnerText();
                 if (firstInnerText != null) valueAsString = firstInnerText.getText();
                 Object value;

Added: mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataIQHandlerTestCase.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataIQHandlerTestCase.java?rev=1078382&view=auto
==============================================================================
--- mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataIQHandlerTestCase.java (added)
+++ mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataIQHandlerTestCase.java Sat Mar  5 22:45:10 2011
@@ -0,0 +1,352 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.vysper.xmpp.modules.extension.xep0049_privatedata;
+
+import junit.framework.Assert;
+
+import org.apache.vysper.StanzaAssert;
+import org.apache.vysper.xml.fragment.Renderer;
+import org.apache.vysper.xml.fragment.XMLElement;
+import org.apache.vysper.xml.fragment.XMLElementBuilder;
+import org.apache.vysper.xml.fragment.XMLSemanticError;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.apache.vysper.xmpp.protocol.SessionStateHolder;
+import org.apache.vysper.xmpp.server.ServerRuntimeContext;
+import org.apache.vysper.xmpp.server.SessionContext;
+import org.apache.vysper.xmpp.stanza.IQStanza;
+import org.apache.vysper.xmpp.stanza.IQStanzaType;
+import org.apache.vysper.xmpp.stanza.Stanza;
+import org.apache.vysper.xmpp.stanza.StanzaBuilder;
+import org.apache.vysper.xmpp.state.resourcebinding.BindException;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ */
+public class PrivateDataIQHandlerTestCase {
+
+    private static final String NS = "http://example.com";
+    private static final Entity FROM = EntityImpl.parseUnchecked("from@vysper.org");
+    private static final Entity TO = EntityImpl.parseUnchecked("vysper.org");
+
+    private static final String KEY = "foo-http-//example.com";
+    
+    private ServerRuntimeContext serverRuntimeContext = Mockito.mock(ServerRuntimeContext.class);
+    private SessionContext sessionContext = Mockito.mock(SessionContext.class);
+    private SessionStateHolder sessionStateHolder = new SessionStateHolder();
+    private PrivateDataPersistenceManager persistenceManager = Mockito.mock(PrivateDataPersistenceManager.class);
+    
+    private IQStanza verifyStanza = (IQStanza) IQStanza.getWrapper(buildStanza());
+    
+    private PrivateDataIQHandler handler = new PrivateDataIQHandler();
+    
+    @Before
+    public void before() {
+        Mockito.when(sessionContext.getInitiatingEntity()).thenReturn(FROM);
+        
+        Mockito.when(persistenceManager.getPrivateData(FROM, KEY)).thenReturn("<bar xmlns=\"http://example.com\" />");
+        
+        handler.setPersistenceManager(persistenceManager);
+    }
+    
+    
+    private Stanza buildStanza() {
+        return buildStanza("iq", NamespaceURIs.JABBER_CLIENT, "query", NamespaceURIs.PRIVATE_DATA);
+    }
+
+    private Stanza buildStanza(String name, String namespaceUri) {
+        return buildStanza(name, namespaceUri, "query", NamespaceURIs.PRIVATE_DATA);
+    }
+    
+    private Stanza buildStanza(String name, String namespaceUri, String innerName, String innerNamespaceUri) {
+        return new StanzaBuilder(name, namespaceUri)
+            .addAttribute("type", "get")
+            .addAttribute("id", "1")
+            .startInnerElement(innerName, innerNamespaceUri)
+            .build();
+    }
+    
+    @Test
+    public void nameMustBeIq() {
+        Assert.assertEquals("iq", handler.getName());
+    }
+
+    @Test
+    public void verifyNullStanza() {
+        Assert.assertFalse(handler.verify(null));
+    }
+
+    @Test
+    public void verifyInvalidName() {
+        Assert.assertFalse(handler.verify(buildStanza("dummy", NamespaceURIs.JABBER_CLIENT)));
+    }
+
+    @Test
+    public void verifyInvalidNamespace() {
+        Assert.assertFalse(handler.verify(buildStanza("iq", "dummy")));
+    }
+
+    @Test
+    public void verifyNullNamespace() {
+        Assert.assertFalse(handler.verify(buildStanza("iq", null)));
+    }
+
+    @Test
+    public void verifyNullInnerNamespace() {
+        Assert.assertFalse(handler.verify(buildStanza("iq", NamespaceURIs.JABBER_CLIENT, "query", null)));
+    }
+
+    @Test
+    public void verifyInvalidInnerNamespace() {
+        Assert.assertFalse(handler.verify(buildStanza("iq", NamespaceURIs.JABBER_CLIENT, "query", "dummy")));
+    }
+    
+    @Test
+    public void verifyInvalidInnerName() {
+        Assert.assertFalse(handler.verify(buildStanza("iq", NamespaceURIs.JABBER_CLIENT, "dummy", NamespaceURIs.PRIVATE_DATA)));
+    }
+
+    @Test
+    public void verifyMissingInnerElement() {
+        Stanza stanza = new StanzaBuilder("iq", NamespaceURIs.JABBER_CLIENT).build();
+        Assert.assertFalse(handler.verify(stanza));
+    }
+    
+    @Test
+    public void verifyValidStanza() {
+        Assert.assertTrue(handler.verify(verifyStanza));
+    }
+
+    @Test
+    public void sessionIsRequired() {
+        Assert.assertTrue(handler.isSessionRequired());
+    }
+
+    @Test
+    public void handleGet() throws BindException, XMLSemanticError {
+        Stanza request = StanzaBuilder.createIQStanza(FROM, FROM, IQStanzaType.GET, "id1")
+            .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+            .startInnerElement("foo", NS)
+            .build();
+        
+        Stanza response = handler.execute(request, serverRuntimeContext, true, sessionContext, sessionStateHolder).getResponseStanza();
+
+        Stanza expected = StanzaBuilder.createIQStanza(FROM, FROM, IQStanzaType.RESULT, "id1")
+            .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+            .startInnerElement("bar", NS)
+            .build();
+        
+        StanzaAssert.assertEquals(expected, response);
+    }
+    
+    @Test
+    public void handleGetNonExisting() throws BindException, XMLSemanticError {
+        Stanza request = StanzaBuilder.createIQStanza(FROM, FROM, IQStanzaType.GET, "id1")
+        .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+        .startInnerElement("dummy", NS)
+        .addAttribute("attr", "attrval")
+        .build();
+        
+        Stanza response = handler.execute(request, serverRuntimeContext, true, sessionContext, sessionStateHolder).getResponseStanza();
+        
+        Stanza expected = StanzaBuilder.createIQStanza(FROM, FROM, IQStanzaType.RESULT, "id1")
+        .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+        .startInnerElement("dummy", NS)
+        .addAttribute("attr", "attrval")
+        .build();
+        
+        StanzaAssert.assertEquals(expected, response);
+    }
+    
+    @Test
+    public void handleGetWithoutInnerElement() throws BindException, XMLSemanticError {
+        Stanza request = StanzaBuilder.createIQStanza(FROM, FROM, IQStanzaType.GET, "id1")
+            .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+            .build();
+        
+        Stanza response = handler.execute(request, serverRuntimeContext, true, sessionContext, sessionStateHolder).getResponseStanza();
+
+        Stanza expected = StanzaBuilder.createIQStanza(TO, FROM, IQStanzaType.ERROR, "id1")
+            .startInnerElement("query", NamespaceURIs.PRIVATE_DATA).endInnerElement()
+            .startInnerElement("error", NamespaceURIs.JABBER_CLIENT)
+            .addAttribute("type", "modify")
+            .startInnerElement("not-acceptable", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS)
+            .build();
+            
+        StanzaAssert.assertEquals(expected, response);
+    }
+
+    @Test
+    public void handleGetForOtherUser() throws BindException, XMLSemanticError {
+        Entity other = EntityImpl.parseUnchecked("other@vysper.org");
+        
+        Stanza request = StanzaBuilder.createIQStanza(FROM, other, IQStanzaType.GET, "id1")
+            .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+            .build();
+        
+        Stanza response = handler.execute(request, serverRuntimeContext, true, sessionContext, sessionStateHolder).getResponseStanza();
+        
+        Stanza expected = StanzaBuilder.createIQStanza(TO, FROM, IQStanzaType.ERROR, "id1")
+        .startInnerElement("query", NamespaceURIs.PRIVATE_DATA).endInnerElement()
+        .startInnerElement("error", NamespaceURIs.JABBER_CLIENT)
+        .addAttribute("type", "cancel")
+        .addAttribute("code", "403")
+        .startInnerElement("forbidden", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS)
+        .build();
+        
+        StanzaAssert.assertEquals(expected, response);
+    }
+    
+    @Test
+    public void handleGetWithoutPersitenceManager() throws BindException, XMLSemanticError {
+        handler.setPersistenceManager(null);
+        
+        Stanza request = StanzaBuilder.createIQStanza(FROM, FROM, IQStanzaType.GET, "id1")
+        .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+        .startInnerElement("foo", NS)
+        .build();
+        
+        Stanza response = handler.execute(request, serverRuntimeContext, true, sessionContext, sessionStateHolder).getResponseStanza();
+        
+        Stanza expected = StanzaBuilder.createIQStanza(TO, FROM, IQStanzaType.ERROR, "id1")
+        .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+        .startInnerElement("foo", NS).endInnerElement()
+        .endInnerElement()
+        .startInnerElement("error", NamespaceURIs.JABBER_CLIENT)
+        .addAttribute("type", "wait")
+        .startInnerElement("internal-server-error", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS)
+        .build();
+        
+        StanzaAssert.assertEquals(expected, response);
+    }
+
+    @Test
+    public void handleSet() throws BindException, XMLSemanticError {
+        XMLElement stored = new XMLElementBuilder("foo", NS)
+            .startInnerElement("fez", NS)
+            .build();
+        
+        String storedXml = new Renderer(stored).getComplete();
+        
+        Mockito.when(persistenceManager.setPrivateData(FROM, KEY, storedXml)).thenReturn(true);
+        
+        Stanza request = StanzaBuilder.createIQStanza(FROM, FROM, IQStanzaType.SET, "id1")
+            .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+            .addPreparedElement(stored)
+            .build();
+        
+        Stanza response = handler.execute(request, serverRuntimeContext, true, sessionContext, sessionStateHolder).getResponseStanza();
+
+        Stanza expected = StanzaBuilder.createIQStanza(null, FROM, IQStanzaType.RESULT, "id1")
+            .build();
+        
+        StanzaAssert.assertEquals(expected, response);
+
+        Mockito.verify(persistenceManager).setPrivateData(FROM, KEY, storedXml);
+    }
+
+    @Test
+    public void handleSetWithoutPersistenceManager() throws BindException, XMLSemanticError {
+        handler.setPersistenceManager(null);
+        
+        Stanza request = StanzaBuilder.createIQStanza(FROM, FROM, IQStanzaType.SET, "id1")
+            .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+            .startInnerElement("foo", NS)
+            .build();
+        
+        Stanza response = handler.execute(request, serverRuntimeContext, true, sessionContext, sessionStateHolder).getResponseStanza();
+
+        Stanza expected = StanzaBuilder.createIQStanza(TO, FROM, IQStanzaType.ERROR, "id1")
+            .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+            .startInnerElement("foo", NS).endInnerElement()
+            .endInnerElement()
+            .startInnerElement("error", NamespaceURIs.JABBER_CLIENT)
+            .addAttribute("type", "wait")
+            .startInnerElement("internal-server-error", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS)
+            .build();
+        
+        StanzaAssert.assertEquals(expected, response);
+    }
+
+    @Test
+    public void handleSetForOtherUser() throws BindException, XMLSemanticError {
+        Entity other = EntityImpl.parseUnchecked("other@vysper.org");
+        
+        Stanza request = StanzaBuilder.createIQStanza(FROM, other, IQStanzaType.SET, "id1")
+            .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+            .startInnerElement("foo", NS)
+            .build();
+        
+        Stanza response = handler.execute(request, serverRuntimeContext, true, sessionContext, sessionStateHolder).getResponseStanza();
+        
+        Stanza expected = StanzaBuilder.createIQStanza(TO, FROM, IQStanzaType.ERROR, "id1")
+        .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+        .startInnerElement("foo", NS).endInnerElement()
+        .endInnerElement()
+        .startInnerElement("error", NamespaceURIs.JABBER_CLIENT)
+        .addAttribute("type", "cancel")
+        .addAttribute("code", "403")
+        .startInnerElement("forbidden", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS)
+        .build();
+        
+        StanzaAssert.assertEquals(expected, response);
+    }
+
+    @Test
+    public void handleSetWithoutInnerElement() throws BindException, XMLSemanticError {
+        Stanza request = StanzaBuilder.createIQStanza(FROM, FROM, IQStanzaType.SET, "id1")
+            .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+            .build();
+        
+        Stanza response = handler.execute(request, serverRuntimeContext, true, sessionContext, sessionStateHolder).getResponseStanza();
+
+        Stanza expected = StanzaBuilder.createIQStanza(TO, FROM, IQStanzaType.ERROR, "id1")
+            .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+            .endInnerElement()
+            .startInnerElement("error", NamespaceURIs.JABBER_CLIENT)
+            .addAttribute("type", "modify")
+            .startInnerElement("not-acceptable", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_STANZAS)
+            .build();
+            
+        StanzaAssert.assertEquals(expected, response);
+    }
+
+    @Test
+    public void handleSetFailedPersisting() throws BindException, XMLSemanticError {
+        // persistence manager mock will always default to return false
+        
+        Stanza request = StanzaBuilder.createIQStanza(FROM, FROM, IQStanzaType.SET, "id1")
+            .startInnerElement("query", NamespaceURIs.PRIVATE_DATA)
+            .startInnerElement("foo", NS)
+            .build();
+        
+        Stanza response = handler.execute(request, serverRuntimeContext, true, sessionContext, sessionStateHolder).getResponseStanza();
+
+        Stanza expected = StanzaBuilder.createIQStanza(null, FROM, IQStanzaType.ERROR, "id1")
+            .build();
+        
+        StanzaAssert.assertEquals(expected, response);
+    }
+
+
+}

Added: mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataModuleTestCase.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataModuleTestCase.java?rev=1078382&view=auto
==============================================================================
--- mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataModuleTestCase.java (added)
+++ mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0049_privatedata/PrivateDataModuleTestCase.java Sat Mar  5 22:45:10 2011
@@ -0,0 +1,89 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.vysper.xmpp.modules.extension.xep0049_privatedata;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.apache.vysper.xmpp.modules.servicediscovery.management.Feature;
+import org.apache.vysper.xmpp.modules.servicediscovery.management.InfoElement;
+import org.apache.vysper.xmpp.modules.servicediscovery.management.InfoRequest;
+import org.apache.vysper.xmpp.modules.servicediscovery.management.ServerInfoRequestListener;
+import org.apache.vysper.xmpp.modules.servicediscovery.management.ServiceDiscoveryRequestException;
+import org.apache.vysper.xmpp.protocol.HandlerDictionary;
+import org.apache.vysper.xmpp.protocol.NamespaceHandlerDictionary;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.junit.Test;
+
+/**
+ */
+public class PrivateDataModuleTestCase {
+
+    private PrivateDataModule module = new PrivateDataModule();
+    
+    @Test
+    public void nameMustBeProvided() {
+        Assert.assertNotNull(module.getName());
+    }
+
+    @Test
+    public void versionMustBeProvided() {
+        Assert.assertNotNull(module.getVersion());
+    }
+    
+    @Test
+    public void getServerInfosFor() throws ServiceDiscoveryRequestException {
+        List<ServerInfoRequestListener> serverInfoRequestListeners = new ArrayList<ServerInfoRequestListener>();
+        
+        module.addServerInfoRequestListeners(serverInfoRequestListeners);
+        
+        Assert.assertEquals(1, serverInfoRequestListeners.size());
+        
+        List<InfoElement> infoElements = serverInfoRequestListeners.get(0).getServerInfosFor(new InfoRequest(null, null, null, null));
+        
+        Assert.assertEquals(1, infoElements.size());
+        Assert.assertTrue(infoElements.get(0) instanceof Feature);
+        Assert.assertEquals(NamespaceURIs.PRIVATE_DATA, ((Feature)infoElements.get(0)).getVar());
+    }
+
+    @Test
+    public void getServerInfosForWithNode() throws ServiceDiscoveryRequestException {
+        List<ServerInfoRequestListener> serverInfoRequestListeners = new ArrayList<ServerInfoRequestListener>();
+        module.addServerInfoRequestListeners(serverInfoRequestListeners);
+        Assert.assertEquals(1, serverInfoRequestListeners.size());
+        
+        Assert.assertNull(serverInfoRequestListeners.get(0).getServerInfosFor(new InfoRequest(null, null, "node", null)));
+    }
+    
+    @Test
+    public void addHandlerDictionaries() {
+        List<HandlerDictionary> dictionaries = new ArrayList<HandlerDictionary>();
+        
+        module.addHandlerDictionaries(dictionaries);
+        
+        Assert.assertEquals(1, dictionaries.size());
+        Assert.assertTrue(dictionaries.get(0) instanceof NamespaceHandlerDictionary);
+        NamespaceHandlerDictionary namespaceHandlerDictionary = (NamespaceHandlerDictionary) dictionaries.get(0);
+        
+        Assert.assertEquals(NamespaceURIs.PRIVATE_DATA, namespaceHandlerDictionary.getNamespaceURI());
+    }
+}

Added: mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/servicediscovery/ServiceDiscoveryModuleTestCase.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/servicediscovery/ServiceDiscoveryModuleTestCase.java?rev=1078382&view=auto
==============================================================================
--- mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/servicediscovery/ServiceDiscoveryModuleTestCase.java (added)
+++ mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/servicediscovery/ServiceDiscoveryModuleTestCase.java Sat Mar  5 22:45:10 2011
@@ -0,0 +1,57 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.vysper.xmpp.modules.servicediscovery;
+
+import junit.framework.Assert;
+
+import org.apache.vysper.xmpp.modules.servicediscovery.collection.ServiceCollector;
+import org.apache.vysper.xmpp.modules.servicediscovery.management.ServiceDiscoveryRequestException;
+import org.junit.Test;
+
+/**
+ */
+public class ServiceDiscoveryModuleTestCase {
+
+    private ServiceDiscoveryModule module = new ServiceDiscoveryModule();
+    
+    @Test
+    public void nameMustBeProvided() {
+        Assert.assertNotNull(module.getName());
+    }
+
+    @Test
+    public void versionMustBeProvided() {
+        Assert.assertNotNull(module.getVersion());
+    }
+    
+    @Test
+    public void getHandlerDictionaries() throws ServiceDiscoveryRequestException {
+        Assert.assertEquals(2, module.getHandlerDictionaries().size());
+        Assert.assertTrue(module.getHandlerDictionaries().get(0) instanceof ServiceDiscoveryInfoDictionary);
+        Assert.assertTrue(module.getHandlerDictionaries().get(1) instanceof ServiceDiscoveryItemDictionary);
+    }
+
+    @Test
+    public void getServerServices() throws ServiceDiscoveryRequestException {
+        Assert.assertEquals(1, module.getServerServices().size());
+        Assert.assertTrue(module.getServerServices().get(0) instanceof ServiceCollector);
+    }
+
+}

Added: mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/stanza/dataforms/DataFormParserTestCase.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/stanza/dataforms/DataFormParserTestCase.java?rev=1078382&view=auto
==============================================================================
--- mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/stanza/dataforms/DataFormParserTestCase.java (added)
+++ mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/stanza/dataforms/DataFormParserTestCase.java Sat Mar  5 22:45:10 2011
@@ -0,0 +1,159 @@
+/*
+ *  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.stanza.dataforms;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.vysper.xml.fragment.Renderer;
+import org.apache.vysper.xml.fragment.XMLElement;
+import org.apache.vysper.xml.fragment.XMLElementBuilder;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class DataFormParserTestCase {
+
+    private static final Entity E1 = EntityImpl.parseUnchecked("user1@vysper.org");
+    private static final Entity E2 = EntityImpl.parseUnchecked("user2@vysper.org");
+    
+    @Test
+    public void noType() {
+        assertSingleValue(null, "val1", "val1");
+    }
+    
+    @Test
+    public void textSingle() {
+        assertSingleValue("text-single", "val1", "val1");
+    }
+    
+    @Test
+    public void textPrivate() {
+        assertSingleValue("text-private", "val1", "val1");
+    }
+    
+    @Test
+    public void hidden() {
+        assertSingleValue("hidden", "val1", "val1");
+    }
+    
+    @Test
+    public void fixed() {
+        assertSingleValue("fixed", "val1", "val1");
+    }
+    
+    @Test
+    public void listSingle() {
+        assertSingleValue("list-single", "val1", "val1");
+    }
+    
+    @Test
+    public void jidSingle() {
+        assertSingleValue("jid-single", E1.getFullQualifiedName(), E1);
+    }
+    
+    @Test
+    public void booleanFalse() {
+        assertSingleValue("boolean", "false", Boolean.FALSE);
+    }
+    
+    @Test
+    public void booleanTrue() {
+        assertSingleValue("boolean", "true", Boolean.TRUE);
+    }
+    
+    @Test
+    public void boolean1() {
+        assertSingleValue("boolean", "1", Boolean.TRUE);
+    }
+    
+    @Test
+    public void boolean0() {
+        assertSingleValue("boolean", "0", Boolean.FALSE);
+    }
+    
+    @Test
+    public void textMulti() {
+        assertMultiValue("text-multi", Arrays.asList("val1", "val2"), Arrays.asList((Object)"val1", "val2"));
+    }
+    
+    @Test
+    public void listMulti() {
+        assertMultiValue("list-multi", Arrays.asList("val1", "val2"), Arrays.asList((Object)"val1", "val2"));
+    }
+    
+    @Test
+    public void jidMulti() {
+        assertMultiValue("jid-multi", Arrays.asList(E1.getFullQualifiedName(), E2.getFullQualifiedName()), Arrays.asList((Object)E1, E2));
+    }
+    
+    @Test(expected=IllegalArgumentException.class)
+    public void invalidFieldType() {
+        assertSingleValue("dummy", null, null);
+    }
+    
+    private void assertSingleValue(String type, String value, Object expectedValue) {
+        XMLElementBuilder builder = new XMLElementBuilder("x", NamespaceURIs.JABBER_X_DATA)
+            .startInnerElement("field", NamespaceURIs.JABBER_X_DATA)
+            .addAttribute("var", "fie1");
+        
+        if(type != null) builder.addAttribute("type", type);
+        
+        builder.startInnerElement("value", NamespaceURIs.JABBER_X_DATA)
+            .addText(value);
+        
+        XMLElement elm = builder.build(); 
+        
+        DataFormParser parser = new DataFormParser(elm);
+        
+        Map<String, Object> values = parser.extractFieldValues();
+        
+        Assert.assertEquals(1, values.size());
+        Assert.assertEquals(expectedValue, values.get("fie1"));
+        
+    }
+
+    private void assertMultiValue(String type, List<String> values, List<Object> expectedValues) {
+        XMLElementBuilder builder = new XMLElementBuilder("x", NamespaceURIs.JABBER_X_DATA)
+        .startInnerElement("field", NamespaceURIs.JABBER_X_DATA)
+        .addAttribute("var", "fie1");
+        
+        if(type != null) builder.addAttribute("type", type);
+        
+        
+        for(String value : values) {
+            builder.startInnerElement("value", NamespaceURIs.JABBER_X_DATA);
+            builder.addText(value);
+            builder.endInnerElement();
+        }
+        
+        XMLElement elm = builder.build(); 
+        
+        DataFormParser parser = new DataFormParser(elm);
+        
+        Map<String, Object> actualValues = parser.extractFieldValues();
+        
+        Assert.assertEquals(1, actualValues.size());
+        Assert.assertEquals(expectedValues, actualValues.get("fie1"));
+    }
+}