← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 15494: minor refactor to node render system

 

------------------------------------------------------------
revno: 15494
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Sun 2014-06-01 13:39:39 +0200
message:
  minor refactor to node render system
removed:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/JacksonJsonNodeRenderer.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeRenderer.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/StaXNodeRenderer.java
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeDeserializer.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeSerializer.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/JacksonJsonNodeSerializer.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/StAXNodeSerializer.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/node/
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/node/DefaultNodeService.java
modified:
  dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== removed file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/JacksonJsonNodeRenderer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/JacksonJsonNodeRenderer.java	2014-05-31 23:48:24 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/JacksonJsonNodeRenderer.java	1970-01-01 00:00:00 +0000
@@ -1,112 +0,0 @@
-package org.hisp.dhis.node;
-
-/*
- * Copyright (c) 2004-2014, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * Neither the name of the HISP project nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
- */
-
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonGenerator;
-import org.hisp.dhis.node.types.CollectionNode;
-import org.hisp.dhis.node.types.ComplexNode;
-import org.hisp.dhis.node.types.RootNode;
-import org.hisp.dhis.node.types.SimpleNode;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
- */
-public class JacksonJsonNodeRenderer implements NodeRenderer
-{
-    @Override
-    public void render( RootNode rootNode, OutputStream outputStream ) throws IOException
-    {
-        JsonFactory jsonFactory = new JsonFactory();
-        JsonGenerator generator = jsonFactory.createGenerator( outputStream );
-
-        renderRootNode( rootNode, generator );
-        generator.flush();
-    }
-
-    private void renderRootNode( RootNode rootNode, JsonGenerator generator ) throws IOException
-    {
-        generator.writeStartObject();
-
-        for ( Node node : rootNode.getNodes() )
-        {
-            dispatcher( node, generator );
-        }
-
-        generator.writeEndObject();
-    }
-
-    private void renderSimpleNode( SimpleNode simpleNode, JsonGenerator generator ) throws IOException
-    {
-        generator.writeObjectField( simpleNode.getName(), simpleNode.getValue() );
-    }
-
-    private void renderComplexNode( ComplexNode complexNode, JsonGenerator generator ) throws IOException
-    {
-        generator.writeObjectFieldStart( complexNode.getName() );
-
-        for ( Node node : complexNode.getNodes() )
-        {
-            dispatcher( node, generator );
-        }
-
-        generator.writeEndObject();
-    }
-
-    private void renderCollectionNode( CollectionNode collectionNode, JsonGenerator generator ) throws IOException
-    {
-        generator.writeArrayFieldStart( collectionNode.getName() );
-
-        for ( Node node : collectionNode.getNodes() )
-        {
-            dispatcher( node, generator );
-        }
-
-        generator.writeEndArray();
-    }
-
-    private void dispatcher( Node node, JsonGenerator generator ) throws IOException
-    {
-        switch ( node.getType() )
-        {
-            case SIMPLE:
-                renderSimpleNode( (SimpleNode) node, generator );
-                break;
-            case COMPLEX:
-                renderComplexNode( (ComplexNode) node, generator );
-                break;
-            case COLLECTION:
-                renderCollectionNode( (CollectionNode) node, generator );
-                break;
-        }
-    }
-}

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeDeserializer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeDeserializer.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeDeserializer.java	2014-06-01 11:39:39 +0000
@@ -0,0 +1,70 @@
+package org.hisp.dhis.node;
+
+/*
+ * Copyright (c) 2004-2014, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/*
+ * Copyright (c) 2004-2014, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+import org.hisp.dhis.node.types.RootNode;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public interface NodeDeserializer
+{
+    RootNode render( InputStream inputStream ) throws IOException;
+}

=== removed file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeRenderer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeRenderer.java	2014-05-31 23:48:24 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeRenderer.java	1970-01-01 00:00:00 +0000
@@ -1,42 +0,0 @@
-package org.hisp.dhis.node;
-
-/*
- * Copyright (c) 2004-2014, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * Neither the name of the HISP project nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
- */
-
-import org.hisp.dhis.node.types.RootNode;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
- */
-public interface NodeRenderer
-{
-    void render( RootNode rootNode, OutputStream outputStream ) throws IOException;
-}

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeSerializer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeSerializer.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeSerializer.java	2014-06-01 11:39:39 +0000
@@ -0,0 +1,44 @@
+package org.hisp.dhis.node;
+
+/*
+ * Copyright (c) 2004-2014, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+import org.hisp.dhis.node.types.RootNode;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public interface NodeSerializer
+{
+    void serialize( RootNode rootNode, OutputStream outputStream ) throws IOException;
+
+    String contentType();
+}

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeService.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/NodeService.java	2014-06-01 11:39:39 +0000
@@ -0,0 +1,42 @@
+package org.hisp.dhis.node;
+
+/*
+ * Copyright (c) 2004-2014, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+import org.hisp.dhis.node.types.RootNode;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public interface NodeService
+{
+    void serialize( RootNode rootNode, String contentType, OutputStream outputStream ) throws IOException;
+}

=== removed file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/StaXNodeRenderer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/StaXNodeRenderer.java	2014-06-01 00:03:15 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/StaXNodeRenderer.java	1970-01-01 00:00:00 +0000
@@ -1,174 +0,0 @@
-package org.hisp.dhis.node;
-
-/*
- * Copyright (c) 2004-2014, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * Neither the name of the HISP project nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
- */
-
-import org.hisp.dhis.node.types.CollectionNode;
-import org.hisp.dhis.node.types.ComplexNode;
-import org.hisp.dhis.node.types.RootNode;
-import org.hisp.dhis.node.types.SimpleNode;
-
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
- */
-public class StaXNodeRenderer implements NodeRenderer
-{
-    @Override
-    public void render( RootNode rootNode, OutputStream outputStream ) throws IOException
-    {
-        XMLOutputFactory factory = XMLOutputFactory.newInstance();
-        XMLStreamWriter writer;
-
-        try
-        {
-            writer = factory.createXMLStreamWriter( outputStream );
-            renderRootNode( rootNode, writer );
-            writer.flush();
-        }
-        catch ( XMLStreamException e )
-        {
-            throw new IOException( e.getMessage(), e.getCause() );
-        }
-    }
-
-    private void renderRootNode( RootNode rootNode, XMLStreamWriter writer ) throws IOException, XMLStreamException
-    {
-        writer.writeStartDocument( "UTF-8", "1.0" );
-
-        if ( rootNode.haveHint( NodeHint.Type.XML_NAMESPACE ) )
-        {
-            writer.writeStartElement( "", rootNode.getName(), (String) rootNode.getHint( NodeHint.Type.XML_NAMESPACE ).getValue() );
-        }
-        else
-        {
-            writer.writeStartElement( rootNode.getName() );
-        }
-
-        for ( Node node : rootNode.getNodes() )
-        {
-            dispatcher( node, writer );
-        }
-
-        writeEndElement( writer );
-        writer.writeEndDocument();
-    }
-
-    private void renderSimpleNode( SimpleNode simpleNode, XMLStreamWriter writer ) throws XMLStreamException
-    {
-        String value = String.format( "%s", simpleNode.getValue() );
-
-        writeStartElement( simpleNode, writer );
-        writer.writeCharacters( value );
-        writeEndElement( writer );
-    }
-
-    private void renderSimpleNodeAttribute( SimpleNode simpleNode, XMLStreamWriter writer ) throws XMLStreamException
-    {
-        String value = String.format( "%s", simpleNode.getValue() );
-
-        if ( simpleNode.haveHint( NodeHint.Type.XML_NAMESPACE ) )
-        {
-            writer.writeAttribute( "", String.valueOf( simpleNode.getHint( NodeHint.Type.XML_NAMESPACE ).getValue() ), simpleNode.getName(), value );
-        }
-        else
-        {
-            writer.writeAttribute( simpleNode.getName(), value );
-        }
-    }
-
-    private void renderComplexNode( ComplexNode complexNode, XMLStreamWriter writer ) throws XMLStreamException, IOException
-    {
-        writeStartElement( complexNode, writer );
-
-        for ( Node node : complexNode.getNodes() )
-        {
-            dispatcher( node, writer );
-        }
-
-        writeEndElement( writer );
-    }
-
-    private void renderCollectionNode( CollectionNode collectionNode, XMLStreamWriter writer ) throws XMLStreamException, IOException
-    {
-        writeStartElement( collectionNode, writer );
-
-        for ( Node node : collectionNode.getNodes() )
-        {
-            dispatcher( node, writer );
-        }
-
-        writeEndElement( writer );
-    }
-
-    private void dispatcher( Node node, XMLStreamWriter writer ) throws IOException, XMLStreamException
-    {
-        switch ( node.getType() )
-        {
-            case SIMPLE:
-                if ( node.haveHint( NodeHint.Type.XML_ATTRIBUTE ) &&
-                    (boolean) node.getHint( NodeHint.Type.XML_ATTRIBUTE ).getValue() )
-                {
-                    renderSimpleNodeAttribute( (SimpleNode) node, writer );
-                }
-                else
-                {
-                    renderSimpleNode( (SimpleNode) node, writer );
-                }
-                break;
-            case COMPLEX:
-                renderComplexNode( (ComplexNode) node, writer );
-                break;
-            case COLLECTION:
-                renderCollectionNode( (CollectionNode) node, writer );
-                break;
-        }
-    }
-
-    private void writeStartElement( Node node, XMLStreamWriter writer ) throws XMLStreamException
-    {
-        if ( node.haveHint( NodeHint.Type.XML_NAMESPACE ) )
-        {
-            writer.writeStartElement( "", node.getName(), String.valueOf( node.getHint( NodeHint.Type.XML_NAMESPACE ).getValue() ) );
-        }
-        else
-        {
-            writer.writeStartElement( node.getName() );
-        }
-    }
-
-    private void writeEndElement( XMLStreamWriter writer ) throws XMLStreamException
-    {
-        writer.writeEndElement();
-    }
-}

=== added directory 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers'
=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/JacksonJsonNodeSerializer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/JacksonJsonNodeSerializer.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/JacksonJsonNodeSerializer.java	2014-06-01 11:39:39 +0000
@@ -0,0 +1,124 @@
+package org.hisp.dhis.node.serializers;
+
+/*
+ * Copyright (c) 2004-2014, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+import org.hisp.dhis.node.Node;
+import org.hisp.dhis.node.NodeSerializer;
+import org.hisp.dhis.node.types.CollectionNode;
+import org.hisp.dhis.node.types.ComplexNode;
+import org.hisp.dhis.node.types.RootNode;
+import org.hisp.dhis.node.types.SimpleNode;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+@Component
+public class JacksonJsonNodeSerializer implements NodeSerializer
+{
+    public static final String CONTENT_TYPE = "application/json";
+
+    @Override
+    public String contentType()
+    {
+        return CONTENT_TYPE;
+    }
+
+    @Override
+    public void serialize( RootNode rootNode, OutputStream outputStream ) throws IOException
+    {
+        JsonFactory jsonFactory = new JsonFactory();
+        JsonGenerator generator = jsonFactory.createGenerator( outputStream );
+
+        renderRootNode( rootNode, generator );
+    }
+
+    private void renderRootNode( RootNode rootNode, JsonGenerator generator ) throws IOException
+    {
+        generator.writeStartObject();
+
+        for ( Node node : rootNode.getNodes() )
+        {
+            dispatcher( node, generator );
+            generator.flush();
+        }
+
+        generator.writeEndObject();
+    }
+
+    private void renderSimpleNode( SimpleNode simpleNode, JsonGenerator generator ) throws IOException
+    {
+        generator.writeObjectField( simpleNode.getName(), simpleNode.getValue() );
+    }
+
+    private void renderComplexNode( ComplexNode complexNode, JsonGenerator generator ) throws IOException
+    {
+        generator.writeObjectFieldStart( complexNode.getName() );
+
+        for ( Node node : complexNode.getNodes() )
+        {
+            dispatcher( node, generator );
+        }
+
+        generator.writeEndObject();
+    }
+
+    private void renderCollectionNode( CollectionNode collectionNode, JsonGenerator generator ) throws IOException
+    {
+        generator.writeArrayFieldStart( collectionNode.getName() );
+
+        for ( Node node : collectionNode.getNodes() )
+        {
+            dispatcher( node, generator );
+        }
+
+        generator.writeEndArray();
+    }
+
+    private void dispatcher( Node node, JsonGenerator generator ) throws IOException
+    {
+        switch ( node.getType() )
+        {
+            case SIMPLE:
+                renderSimpleNode( (SimpleNode) node, generator );
+                break;
+            case COMPLEX:
+                renderComplexNode( (ComplexNode) node, generator );
+                break;
+            case COLLECTION:
+                renderCollectionNode( (CollectionNode) node, generator );
+                break;
+        }
+    }
+}

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/StAXNodeSerializer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/StAXNodeSerializer.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/StAXNodeSerializer.java	2014-06-01 11:39:39 +0000
@@ -0,0 +1,180 @@
+package org.hisp.dhis.node.serializers;
+
+/*
+ * Copyright (c) 2004-2014, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+import org.hisp.dhis.node.Node;
+import org.hisp.dhis.node.NodeHint;
+import org.hisp.dhis.node.NodeSerializer;
+import org.hisp.dhis.node.types.CollectionNode;
+import org.hisp.dhis.node.types.ComplexNode;
+import org.hisp.dhis.node.types.RootNode;
+import org.hisp.dhis.node.types.SimpleNode;
+import org.springframework.stereotype.Component;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+@Component
+public class StAXNodeSerializer implements NodeSerializer
+{
+    public static final String CONTENT_TYPE = "application/xml";
+
+    @Override
+    public String contentType()
+    {
+        return CONTENT_TYPE;
+    }
+
+    @Override
+    public void serialize( RootNode rootNode, OutputStream outputStream ) throws IOException
+    {
+        XMLOutputFactory factory = XMLOutputFactory.newInstance();
+        XMLStreamWriter writer;
+
+        try
+        {
+            writer = factory.createXMLStreamWriter( outputStream );
+            renderRootNode( rootNode, writer );
+        }
+        catch ( XMLStreamException e )
+        {
+            throw new IOException( e.getMessage(), e.getCause() );
+        }
+    }
+
+    private void renderRootNode( RootNode rootNode, XMLStreamWriter writer ) throws IOException, XMLStreamException
+    {
+        writer.writeStartDocument( "UTF-8", "1.0" );
+
+        writeStartElement( rootNode, writer );
+
+        for ( Node node : rootNode.getNodes() )
+        {
+            dispatcher( node, writer );
+            writer.flush();
+        }
+
+        writeEndElement( writer );
+        writer.writeEndDocument();
+    }
+
+    private void renderSimpleNode( SimpleNode simpleNode, XMLStreamWriter writer ) throws XMLStreamException
+    {
+        String value = String.format( "%s", simpleNode.getValue() );
+
+        writeStartElement( simpleNode, writer );
+        writer.writeCharacters( value );
+        writeEndElement( writer );
+    }
+
+    private void renderSimpleNodeAttribute( SimpleNode simpleNode, XMLStreamWriter writer ) throws XMLStreamException
+    {
+        String value = String.format( "%s", simpleNode.getValue() );
+
+        if ( simpleNode.haveHint( NodeHint.Type.XML_NAMESPACE ) )
+        {
+            writer.writeAttribute( "", String.valueOf( simpleNode.getHint( NodeHint.Type.XML_NAMESPACE ).getValue() ), simpleNode.getName(), value );
+        }
+        else
+        {
+            writer.writeAttribute( simpleNode.getName(), value );
+        }
+    }
+
+    private void renderComplexNode( ComplexNode complexNode, XMLStreamWriter writer ) throws XMLStreamException, IOException
+    {
+        writeStartElement( complexNode, writer );
+
+        for ( Node node : complexNode.getNodes() )
+        {
+            dispatcher( node, writer );
+        }
+
+        writeEndElement( writer );
+    }
+
+    private void renderCollectionNode( CollectionNode collectionNode, XMLStreamWriter writer ) throws XMLStreamException, IOException
+    {
+        writeStartElement( collectionNode, writer );
+
+        for ( Node node : collectionNode.getNodes() )
+        {
+            dispatcher( node, writer );
+        }
+
+        writeEndElement( writer );
+    }
+
+    private void dispatcher( Node node, XMLStreamWriter writer ) throws IOException, XMLStreamException
+    {
+        switch ( node.getType() )
+        {
+            case SIMPLE:
+                if ( node.haveHint( NodeHint.Type.XML_ATTRIBUTE ) &&
+                    (boolean) node.getHint( NodeHint.Type.XML_ATTRIBUTE ).getValue() )
+                {
+                    renderSimpleNodeAttribute( (SimpleNode) node, writer );
+                }
+                else
+                {
+                    renderSimpleNode( (SimpleNode) node, writer );
+                }
+                break;
+            case COMPLEX:
+                renderComplexNode( (ComplexNode) node, writer );
+                break;
+            case COLLECTION:
+                renderCollectionNode( (CollectionNode) node, writer );
+                break;
+        }
+    }
+
+    private void writeStartElement( Node node, XMLStreamWriter writer ) throws XMLStreamException
+    {
+        if ( node.haveHint( NodeHint.Type.XML_NAMESPACE ) )
+        {
+            writer.writeStartElement( "", node.getName(), String.valueOf( node.getHint( NodeHint.Type.XML_NAMESPACE ).getValue() ) );
+        }
+        else
+        {
+            writer.writeStartElement( node.getName() );
+        }
+    }
+
+    private void writeEndElement( XMLStreamWriter writer ) throws XMLStreamException
+    {
+        writer.writeEndElement();
+    }
+}

=== added directory 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/node'
=== added file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/node/DefaultNodeService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/node/DefaultNodeService.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/node/DefaultNodeService.java	2014-06-01 11:39:39 +0000
@@ -0,0 +1,72 @@
+package org.hisp.dhis.node;
+
+/*
+ * Copyright (c) 2004-2014, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.hisp.dhis.node.types.RootNode;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.annotation.PostConstruct;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class DefaultNodeService implements NodeService
+{
+    @Autowired( required = false )
+    private List<NodeSerializer> nodeSerializers = Lists.newArrayList();
+
+    private Map<String, NodeSerializer> nodeSerializerMap = Maps.newHashMap();
+
+    @PostConstruct
+    private void init()
+    {
+        for ( NodeSerializer nodeSerializer : nodeSerializers )
+        {
+            nodeSerializerMap.put( nodeSerializer.contentType(), nodeSerializer );
+        }
+    }
+
+    @Override
+    public void serialize( RootNode rootNode, String contentType, OutputStream outputStream ) throws IOException
+    {
+        if ( !nodeSerializerMap.containsKey( contentType ) )
+        {
+            return;
+        }
+
+        NodeSerializer nodeSerializer = nodeSerializerMap.get( contentType );
+        nodeSerializer.serialize( rootNode, outputStream );
+    }
+}

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2014-05-27 02:41:16 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2014-06-01 11:39:39 +0000
@@ -5,9 +5,11 @@
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd";>
 
-  <context:component-scan base-package="org.hisp.dhis.schema.descriptors" />
-
-  <context:component-scan base-package="org.hisp.dhis.calendar.impl" />
+  <context:component-scan base-package="org.hisp.dhis.schema" />
+
+  <context:component-scan base-package="org.hisp.dhis.calendar" />
+
+  <context:component-scan base-package="org.hisp.dhis.node" />
 
   <bean id="org.hisp.dhis.calendar.CalendarService" class="org.hisp.dhis.calendar.DefaultCalendarService" />
 
@@ -17,6 +19,8 @@
 
   <bean id="org.hisp.dhis.acl.AclService" class="org.hisp.dhis.acl.DefaultAclService" />
 
+  <bean id="org.hisp.dhis.node.NodeService" class="org.hisp.dhis.node.DefaultNodeService" />
+
   <!-- Store definitions -->
 
   <bean id="smsCommandService" class="org.hisp.dhis.smscommand.DefaultSMSCommandService">