You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by il...@apache.org on 2013/02/26 13:30:40 UTC

svn commit: r1450148 - in /cocoon/cocoon3/trunk: cocoon-archetype-parent/src/main/resources/archetype-resources/ cocoon-archetype-sample/src/main/resources/archetype-resources/ cocoon-optional/ cocoon-optional/src/main/java/org/apache/cocoon/optional/p...

Author: ilgrosso
Date: Tue Feb 26 12:30:40 2013
New Revision: 1450148

URL: http://svn.apache.org/r1450148
Log:
[COCOON3-122] #resolve

Added:
    cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/
    cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonGenerator.java   (with props)
    cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonSerializer.java   (with props)
    cocoon/cocoon3/trunk/cocoon-sample-webapp/src/test/java/org/apache/cocoon/it/JSONTest.java   (with props)
Modified:
    cocoon/cocoon3/trunk/cocoon-archetype-parent/src/main/resources/archetype-resources/pom.xml
    cocoon/cocoon3/trunk/cocoon-archetype-sample/src/main/resources/archetype-resources/pom.xml
    cocoon/cocoon3/trunk/cocoon-optional/pom.xml
    cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-generators.xml
    cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-serializers.xml
    cocoon/cocoon3/trunk/cocoon-sample/pom.xml
    cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/overview.html
    cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap
    cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/META-INF/cocoon/spring/cocoon-sample-sitemap-components-optional.xml
    cocoon/cocoon3/trunk/parent/pom.xml

Modified: cocoon/cocoon3/trunk/cocoon-archetype-parent/src/main/resources/archetype-resources/pom.xml
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-archetype-parent/src/main/resources/archetype-resources/pom.xml?rev=1450148&r1=1450147&r2=1450148&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-archetype-parent/src/main/resources/archetype-resources/pom.xml (original)
+++ cocoon/cocoon3/trunk/cocoon-archetype-parent/src/main/resources/archetype-resources/pom.xml Tue Feb 26 12:30:40 2013
@@ -306,9 +306,19 @@
         <version>4.3.1</version>
       </dependency>
       <dependency>
-	<groupId>org.apache.xmlgraphics</groupId>
-	<artifactId>xmlgraphics-commons</artifactId>
-	<version>1.5</version>
+        <groupId>com.thoughtworks.xstream</groupId>
+        <artifactId>xstream</artifactId>
+        <version>1.4.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jdom</groupId>
+        <artifactId>jdom</artifactId>
+        <version>1.1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.jettison</groupId>
+        <artifactId>jettison</artifactId>
+        <version>1.3.3</version>
       </dependency>
       <dependency>
 	<groupId>xalan</groupId>

Modified: cocoon/cocoon3/trunk/cocoon-archetype-sample/src/main/resources/archetype-resources/pom.xml
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-archetype-sample/src/main/resources/archetype-resources/pom.xml?rev=1450148&r1=1450147&r2=1450148&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-archetype-sample/src/main/resources/archetype-resources/pom.xml (original)
+++ cocoon/cocoon3/trunk/cocoon-archetype-sample/src/main/resources/archetype-resources/pom.xml Tue Feb 26 12:30:40 2013
@@ -116,6 +116,21 @@
       <version>4.3.1</version>
     </dependency>
     <dependency>
+      <groupId>com.thoughtworks.xstream</groupId>
+      <artifactId>xstream</artifactId>
+      <version>1.4.4</version>
+    </dependency>
+    <dependency>
+      <groupId>org.jdom</groupId>
+      <artifactId>jdom</artifactId>
+      <version>1.1.3</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.jettison</groupId>
+      <artifactId>jettison</artifactId>
+      <version>1.3.3</version>
+    </dependency>
+    <dependency>
       <groupId>org.apache.cocoon</groupId>
       <artifactId>cocoon-serializers-charsets</artifactId>
       <version>1.0.2</version>

Modified: cocoon/cocoon3/trunk/cocoon-optional/pom.xml
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-optional/pom.xml?rev=1450148&r1=1450147&r2=1450148&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-optional/pom.xml (original)
+++ cocoon/cocoon3/trunk/cocoon-optional/pom.xml Tue Feb 26 12:30:40 2013
@@ -102,11 +102,6 @@
       <optional>true</optional>
     </dependency>
     <dependency>
-      <groupId>org.apache.xmlgraphics</groupId>
-      <artifactId>xmlgraphics-commons</artifactId>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
       <groupId>org.apache.cocoon</groupId>
       <artifactId>cocoon-serializers-charsets</artifactId>
       <optional>true</optional>
@@ -136,6 +131,21 @@
       <artifactId>jaxb-impl</artifactId>
       <optional>true</optional>
     </dependency>
+    <dependency>
+      <groupId>com.thoughtworks.xstream</groupId>
+      <artifactId>xstream</artifactId>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.jdom</groupId>
+      <artifactId>jdom</artifactId>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.jettison</groupId>
+      <artifactId>jettison</artifactId>
+      <optional>true</optional>
+    </dependency>
 
     <!-- Test libraries -->
     <dependency>

Added: cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonGenerator.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonGenerator.java?rev=1450148&view=auto
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonGenerator.java (added)
+++ cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonGenerator.java Tue Feb 26 12:30:40 2013
@@ -0,0 +1,338 @@
+/*
+ * 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.cocoon.optional.pipeline.components.sax.json;
+
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.copy.HierarchicalStreamCopier;
+import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
+import com.thoughtworks.xstream.io.xml.JDomWriter;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import org.apache.cocoon.pipeline.ProcessingException;
+import org.apache.cocoon.pipeline.SetupException;
+import org.apache.cocoon.pipeline.caching.CacheKey;
+import org.apache.cocoon.pipeline.caching.TimestampURLCacheKey;
+import org.apache.cocoon.pipeline.component.CachingPipelineComponent;
+import org.apache.cocoon.pipeline.component.Starter;
+import org.apache.cocoon.pipeline.util.StringRepresentation;
+import org.apache.cocoon.pipeline.util.URLConnectionUtils;
+import org.apache.cocoon.sax.AbstractSAXGenerator;
+import org.apache.cocoon.sax.AbstractSAXProducer;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.output.SAXOutputter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Generate SAX events from a JSON input. Only JSON data with single root are accepted.
+ */
+public class JsonGenerator extends AbstractSAXGenerator implements CachingPipelineComponent {
+
+    /**
+     * Logger.
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(JsonGenerator.class);
+
+    private transient Starter generator;
+
+    public JsonGenerator() {
+        this((URL) null);
+    }
+
+    public JsonGenerator(final byte[] bytes) {
+        super();
+        this.generator = new JsonGenerator.ByteArrayGenerator(bytes == null ? null : bytes.clone());
+    }
+
+    public JsonGenerator(final byte[] bytes, final String encoding) {
+        super();
+        this.generator = new JsonGenerator.ByteArrayGenerator(bytes == null ? null : bytes.clone(), encoding);
+    }
+
+    public JsonGenerator(final File file) {
+        super();
+        this.generator = new JsonGenerator.FileGenerator(file);
+    }
+
+    public JsonGenerator(final InputStream inputStream) {
+        super();
+        this.generator = new JsonGenerator.InputStreamGenerator(inputStream);
+    }
+
+    public JsonGenerator(final String xmlString) {
+        super();
+        this.generator = new JsonGenerator.StringGenerator(xmlString);
+    }
+
+    public JsonGenerator(final URL url) {
+        super();
+        this.generator = new JsonGenerator.URLGenerator(url);
+    }
+
+    @Override
+    public CacheKey constructCacheKey() {
+        return this.generator instanceof CachingPipelineComponent
+                ? ((CachingPipelineComponent) this.generator).constructCacheKey()
+                : null;
+    }
+
+    @Override
+    public void execute() {
+        this.generator.execute();
+    }
+
+    private void doExecute(final HierarchicalStreamReader xstreamReader) {
+        final JDomWriter jdomWriter = new JDomWriter();
+        new HierarchicalStreamCopier().copy(xstreamReader, jdomWriter);
+        @SuppressWarnings("unchecked")
+        final List<Element> topLevelNodes = jdomWriter.getTopLevelNodes();
+        if (topLevelNodes == null || topLevelNodes.size() != 1) {
+            throw new ProcessingException("Multiple or no root nodes not supported");
+        }
+
+        try {
+            new SAXOutputter(JsonGenerator.this.getSAXConsumer()).output(topLevelNodes.iterator().next());
+        } catch (JDOMException e) {
+            throw new ProcessingException("Can't ", e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.apache.cocoon.sax.AbstractSAXProducer#setConfiguration(java.util.Map)
+     */
+    @Override
+    public void setConfiguration(final Map<String, ? extends Object> configuration) {
+        ((JsonGenerator.URLGenerator) this.generator).setSource((URL) configuration.get("source"));
+    }
+
+    @Override
+    public String toString() {
+        return StringRepresentation.buildString(this, "internalGenerator=" + this.generator);
+    }
+
+    private class ByteArrayGenerator extends AbstractSAXGenerator {
+
+        private final transient byte[] bytes;
+
+        private final transient String encoding;
+
+        public ByteArrayGenerator(final byte[] bytes) {
+            this(bytes, null);
+        }
+
+        public ByteArrayGenerator(final byte[] bytes, final String encoding) {
+            super();
+            if (bytes == null) {
+                throw new SetupException("A byte array has to be passed.");
+            }
+
+            this.bytes = bytes.clone();
+            this.encoding = encoding;
+        }
+
+        @Override
+        public void execute() {
+            LOG.debug("Using a byte array as source to produce SAX events.");
+
+
+            if (this.encoding == null) {
+                JsonGenerator.this.doExecute(
+                        new JettisonMappedXmlDriver().createReader(
+                        new ByteArrayInputStream(this.bytes)));
+            } else {
+                try {
+                    JsonGenerator.this.doExecute(
+                            new JettisonMappedXmlDriver().createReader(
+                            new StringReader(new String(this.bytes, this.encoding))));
+                } catch (UnsupportedEncodingException e) {
+                    throw new ProcessingException("The encoding " + this.encoding + " is not supported.", e);
+                }
+            }
+        }
+
+        @Override
+        public String toString() {
+            return StringRepresentation.buildString(this,
+                    "bytes=" + Arrays.toString(this.bytes), "encoding=" + this.encoding);
+        }
+    }
+
+    private class FileGenerator extends AbstractSAXGenerator implements CachingPipelineComponent {
+
+        private final transient File file;
+
+        public FileGenerator(final File file) {
+            super();
+            if (file == null) {
+                throw new SetupException("A file has to be passed.");
+            }
+
+            this.file = file;
+        }
+
+        /**
+         * {@inheritDoc}
+         *
+         * @see org.apache.cocoon.pipeline.component.CachingPipelineComponent #constructCacheKey()
+         */
+        @Override
+        public CacheKey constructCacheKey() {
+            if (this.file == null) {
+                throw new SetupException(this.getClass().getSimpleName() + " has no file.");
+            }
+
+            CacheKey cacheKey = null;
+            try {
+                cacheKey = new TimestampURLCacheKey(this.file.toURI().toURL(), this.file.lastModified());
+            } catch (MalformedURLException e) {
+                LOG.error("Can't construct cache key. "
+                        + "Error while converting to " + this.file + " to URL", e);
+            }
+
+            return cacheKey;
+        }
+
+        @Override
+        public void execute() {
+            LOG.debug("Using file {} as source to produce SAX events.", this.file.getAbsolutePath());
+
+            JsonGenerator.this.doExecute(new JettisonMappedXmlDriver().createReader(this.file));
+        }
+
+        @Override
+        public String toString() {
+            return StringRepresentation.buildString(this, "file=" + this.file);
+        }
+    }
+
+    private class InputStreamGenerator extends AbstractSAXGenerator {
+
+        private final transient InputStream inputStream;
+
+        public InputStreamGenerator(final InputStream inputStream) {
+            super();
+            if (inputStream == null) {
+                throw new SetupException("An input stream has to be passed.");
+            }
+
+            this.inputStream = inputStream;
+        }
+
+        @Override
+        public void execute() {
+            LOG.debug("Using input stream {} as source to produce SAX events.", this.inputStream);
+
+            JsonGenerator.this.doExecute(new JettisonMappedXmlDriver().createReader(this.inputStream));
+        }
+
+        @Override
+        public String toString() {
+            return StringRepresentation.buildString(this, "inputStream=" + this.inputStream);
+        }
+    }
+
+    private class StringGenerator extends AbstractSAXProducer
+            implements Starter {
+
+        private final transient String jsonString;
+
+        public StringGenerator(final String jsonString) {
+            super();
+            if (jsonString == null) {
+                throw new SetupException("A JSON string has to be passed.");
+            }
+
+            this.jsonString = jsonString;
+        }
+
+        /**
+         * {@inheritDoc}
+         *
+         * @see org.apache.cocoon.pipeline.component.Starter#execute()
+         */
+        @Override
+        public void execute() {
+            LOG.debug("Using a string to produce SAX events.");
+
+            JsonGenerator.this.doExecute(new JettisonMappedXmlDriver().createReader(new StringReader(this.jsonString)));
+        }
+
+        @Override
+        public String toString() {
+            return StringRepresentation.buildString(this, "xmlString=" + this.jsonString);
+        }
+    }
+
+    private class URLGenerator extends AbstractSAXGenerator
+            implements CachingPipelineComponent {
+
+        private transient URL source;
+
+        public URLGenerator(final URL source) {
+            super();
+            this.source = source;
+        }
+
+        /**
+         * {@inheritDoc}
+         *
+         * @see org.apache.cocoon.pipeline.component.CachingPipelineComponent #constructCacheKey()
+         */
+        @Override
+        public CacheKey constructCacheKey() {
+            return new TimestampURLCacheKey(this.source, URLConnectionUtils.getLastModified(this.source));
+        }
+
+        /**
+         * {@inheritDoc}
+         *
+         * @see org.apache.cocoon.pipeline.component.Starter#execute()
+         */
+        @Override
+        public void execute() {
+            if (this.source == null) {
+                throw new ProcessingException(this.getClass().getSimpleName() + " has no source.");
+            }
+
+            LOG.debug("Using the URL {} to produce SAX events.", this.source.toExternalForm());
+
+            JsonGenerator.this.doExecute(new JettisonMappedXmlDriver().createReader(this.source));
+        }
+
+        public void setSource(final URL source) {
+            this.source = source;
+        }
+
+        @Override
+        public String toString() {
+            return StringRepresentation.buildString(this, "source=" + this.source);
+        }
+    }
+}

Propchange: cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonGenerator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonGenerator.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonGenerator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonSerializer.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonSerializer.java?rev=1450148&view=auto
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonSerializer.java (added)
+++ cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonSerializer.java Tue Feb 26 12:30:40 2013
@@ -0,0 +1,62 @@
+/*
+ * 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.cocoon.optional.pipeline.components.sax.json;
+
+import com.thoughtworks.xstream.io.copy.HierarchicalStreamCopier;
+import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
+import com.thoughtworks.xstream.io.xml.JDomReader;
+import java.util.Map;
+import org.apache.cocoon.pipeline.caching.CacheKey;
+import org.apache.cocoon.pipeline.caching.SimpleCacheKey;
+import org.apache.cocoon.pipeline.component.CachingPipelineComponent;
+import org.apache.cocoon.sax.AbstractSAXSerializer;
+import org.jdom.input.SAXHandler;
+
+/**
+ * Serialize SAX events into a JSON string.
+ */
+public class JsonSerializer extends AbstractSAXSerializer implements CachingPipelineComponent {
+
+    private static final String JSON_UTF_8 = "application/json;charset=utf-8";
+
+    private SAXHandler saxHandler;
+
+    @Override
+    public String getContentType() {
+        return JSON_UTF_8;
+    }
+
+    @Override
+    public void setup(final Map<String, Object> inputParameters) {
+        this.saxHandler = new SAXHandler();
+        this.setContentHandler(this.saxHandler);
+    }
+
+    @Override
+    public void finish() {
+        new HierarchicalStreamCopier().copy(
+                new JDomReader(this.saxHandler.getDocument()),
+                new JettisonMappedXmlDriver().createWriter(this.getOutputStream()));
+    }
+
+    @Override
+    public CacheKey constructCacheKey() {
+        return new SimpleCacheKey();
+    }
+}

Propchange: cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonSerializer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonSerializer.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/json/JsonSerializer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-generators.xml
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-generators.xml?rev=1450148&r1=1450147&r2=1450148&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-generators.xml (original)
+++ cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-generators.xml Tue Feb 26 12:30:40 2013
@@ -10,26 +10,46 @@
 
       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.
- -->
+ 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.
+-->
 <!-- $Id: cocoon-optional-fop.xml 712183 2008-11-07 16:24:12Z reinhard $ -->
-<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+<beans xmlns="http://www.springframework.org/schema/beans" 
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans 
+                           http://www.springframework.org/schema/beans/spring-beans.xsd">
 
-  <bean name="generator:dir" class="org.apache.cocoon.optional.pipeline.components.sax.directory.DirectoryGenerator" scope="prototype" />
-  <bean name="generator:html" class="org.apache.cocoon.optional.pipeline.components.sax.neko.NekoGenerator" scope="prototype" />
-  <bean name="generator:csv" class="org.apache.cocoon.optional.pipeline.components.sax.csv.CSVGenerator" scope="prototype" />
-  <bean name="generator:calendar" class="org.apache.cocoon.optional.pipeline.components.sax.calendar.CalendarGenerator" scope="prototype" />
-  <bean name="generator:log4j" class="org.apache.cocoon.optional.pipeline.components.sax.generator.AddRootElementGenerator" scope="prototype">
+  <bean name="generator:dir" 
+        class="org.apache.cocoon.optional.pipeline.components.sax.directory.DirectoryGenerator" 
+        scope="prototype" />
+
+  <bean name="generator:html" 
+        class="org.apache.cocoon.optional.pipeline.components.sax.neko.NekoGenerator" 
+        scope="prototype" />
+
+  <bean name="generator:csv" 
+        class="org.apache.cocoon.optional.pipeline.components.sax.csv.CSVGenerator" 
+        scope="prototype" />
+
+  <bean name="generator:calendar" 
+        class="org.apache.cocoon.optional.pipeline.components.sax.calendar.CalendarGenerator" 
+        scope="prototype" />
+
+  <bean name="generator:log4j" 
+        class="org.apache.cocoon.optional.pipeline.components.sax.generator.AddRootElementGenerator" 
+        scope="prototype">
     <property name="encoding" value="UTF-8"/>
     <property name="localName" value="events"/>
     <property name="prefix" value="log4j"/>
     <property name="namespace" value="http://jakarta.apache.org/log4j/"/>
   </bean>
 
+  <bean name="generator:json" 
+        class="org.apache.cocoon.optional.pipeline.components.sax.json.JsonGenerator" 
+        scope="prototype" />
+
 </beans>

Modified: cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-serializers.xml
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-serializers.xml?rev=1450148&r1=1450147&r2=1450148&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-serializers.xml (original)
+++ cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-serializers.xml Tue Feb 26 12:30:40 2013
@@ -34,4 +34,8 @@
   <bean name="serializer:ehtml" 
         class="org.apache.cocoon.optional.servlet.components.sax.serializers.EncodingHTMLSerializer" 
         scope="prototype" />
+  
+  <bean name="serializer:json" 
+          class="org.apache.cocoon.optional.pipeline.components.sax.json.JsonSerializer" 
+          scope="prototype" />
 </beans>

Added: cocoon/cocoon3/trunk/cocoon-sample-webapp/src/test/java/org/apache/cocoon/it/JSONTest.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sample-webapp/src/test/java/org/apache/cocoon/it/JSONTest.java?rev=1450148&view=auto
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sample-webapp/src/test/java/org/apache/cocoon/it/JSONTest.java (added)
+++ cocoon/cocoon3/trunk/cocoon-sample-webapp/src/test/java/org/apache/cocoon/it/JSONTest.java Tue Feb 26 12:30:40 2013
@@ -0,0 +1,49 @@
+/*
+ * 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.cocoon.it;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+
+public class JSONTest extends CocoonHtmlUnitTestCase {
+
+    @Test
+    public void testSerializeAsJSON() throws Exception {
+        this.loadResponse("json/xml2json");
+        assertEquals(200, this.response.getStatusCode());
+        assertTrue(this.response.getContentType().startsWith("application/json"));
+
+        final String json = IOUtils.toString(this.response.getContentAsStream());
+        assertFalse(json.isEmpty());
+    }
+
+    @Test
+    public void testGenerateFromJSON() throws Exception {
+        this.loadResponse("json/json2xml");
+        assertEquals(200, this.response.getStatusCode());
+        assertEquals("text/xml", this.response.getContentType());
+
+        final String xml = IOUtils.toString(this.response.getContentAsStream());
+        assertFalse(xml.isEmpty());
+    }
+}

Propchange: cocoon/cocoon3/trunk/cocoon-sample-webapp/src/test/java/org/apache/cocoon/it/JSONTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/cocoon3/trunk/cocoon-sample-webapp/src/test/java/org/apache/cocoon/it/JSONTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: cocoon/cocoon3/trunk/cocoon-sample-webapp/src/test/java/org/apache/cocoon/it/JSONTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cocoon/cocoon3/trunk/cocoon-sample/pom.xml
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sample/pom.xml?rev=1450148&r1=1450147&r2=1450148&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sample/pom.xml (original)
+++ cocoon/cocoon3/trunk/cocoon-sample/pom.xml Tue Feb 26 12:30:40 2013
@@ -92,6 +92,18 @@
       <artifactId>avalon-framework-impl</artifactId>
     </dependency>
     <dependency>
+      <groupId>com.thoughtworks.xstream</groupId>
+      <artifactId>xstream</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.jdom</groupId>
+      <artifactId>jdom</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.jettison</groupId>
+      <artifactId>jettison</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.apache.cocoon</groupId>
       <artifactId>cocoon-serializers-charsets</artifactId>
     </dependency>

Modified: cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/overview.html
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/overview.html?rev=1450148&r1=1450147&r2=1450148&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/overview.html (original)
+++ cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/overview.html Tue Feb 26 12:30:40 2013
@@ -173,6 +173,13 @@
           <li><a href="fop/test.pdf">PDF</a>: Create a PDF document by using Apache FOP.</li>
         </ul>
       </section>
+      <section id="json">
+        <h2>JSON</h2>
+        <ul>
+          <li><a href="json/xml2json">JSON</a>: Serialize pipeline to JSON string.</li>
+          <li><a href="json/json2xml">JSON</a>: Generate SAX events from JSON string.</li>
+        </ul>
+      </section>
       <section id="encoding-serializers">
         <h2>Encoding Serializers</h2>
         <ul>
@@ -198,7 +205,7 @@
     <nav>
       <ul>
         <li><a href="#map-read" target="_self">map:read</a></li>
-        <li><a href="#sax-pipelines" target="_self">Sax Pipelines</a></li>
+        <li><a href="#sax-pipelines" target="_self">SAX Pipelines</a></li>
         <li><a href="#stax-pipelines" target="_self">StAX Pipelines</a></li>
         <li><a href="#caching" target="_self">Caching</a></li>
         <li><a href="#error-handling" target="_self">Error handling</a></li>
@@ -213,7 +220,8 @@
         <li><a href="#xslt" target="_self">XSLT</a></li>
         <li><a href="#sitemap-rest-controller" target="_self">Sitemap REST Controller</a></li>
         <li><a href="#jaxrs-rest-controller" target="_self">JAX-RS REST Controller</a></li>
-        <li><a href="#fop" target="_self">fop</a></li>
+        <li><a href="#fop" target="_self">FOP</a></li>
+        <li><a href="#json" target="_self">JSON</a></li>
         <li><a href="#encoding-serializers" target="_self">Encoding Serializers</a></li>
         <li><a href="#cocoon-wicket-integration" target="_self">Cocoon-Wicket integration</a></li>
         <li><a href="#stringtemplate" target="_self">StringTemplate</a></li>

Modified: cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap?rev=1450148&r1=1450147&r2=1450148&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap (original)
+++ cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap Tue Feb 26 12:30:40 2013
@@ -569,6 +569,21 @@
       </map:match>
     </map:pipeline>
 
+    <!-- JSON -->
+    <map:pipeline>
+      <map:match equals="json/xml2json">
+        <map:generate src="sax-pipeline/simple.xml" />
+        <map:transform src="sax-pipeline/simple.xslt">
+          <map:parameter name="myParam" value="1" />
+        </map:transform>
+        <map:serialize type="json"/>
+      </map:match>
+      <map:match equals="json/json2xml">
+        <map:generate type="json" src="servlet:/json/xml2json" />
+        <map:serialize/>
+      </map:match>
+    </map:pipeline>
+
     <!-- Cocoon Wicket integration -->
     <map:pipeline type="noncaching">
       <map:match wildcard="wicket/**">

Modified: cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/META-INF/cocoon/spring/cocoon-sample-sitemap-components-optional.xml
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/META-INF/cocoon/spring/cocoon-sample-sitemap-components-optional.xml?rev=1450148&r1=1450147&r2=1450148&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/META-INF/cocoon/spring/cocoon-sample-sitemap-components-optional.xml (original)
+++ cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/META-INF/cocoon/spring/cocoon-sample-sitemap-components-optional.xml Tue Feb 26 12:30:40 2013
@@ -10,18 +10,22 @@
 
       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.
- -->
+ 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.
+-->
 <!-- $Id$ -->
-<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+<beans xmlns="http://www.springframework.org/schema/beans" 
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans 
+                           http://www.springframework.org/schema/beans/spring-beans.xsd">
 
   <import resource="classpath:META-INF/cocoon/spring-optional/cocoon-optional-fop.xml" />
   
+  <import resource="classpath:META-INF/cocoon/spring-optional/cocoon-optional-generators.xml" />
+
   <import resource="classpath:META-INF/cocoon/spring-optional/cocoon-optional-serializers.xml" />
 </beans>

Modified: cocoon/cocoon3/trunk/parent/pom.xml
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/parent/pom.xml?rev=1450148&r1=1450147&r2=1450148&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/parent/pom.xml (original)
+++ cocoon/cocoon3/trunk/parent/pom.xml Tue Feb 26 12:30:40 2013
@@ -466,9 +466,19 @@
         <version>4.3.1</version>
       </dependency>
       <dependency>
-        <groupId>org.apache.xmlgraphics</groupId>
-        <artifactId>xmlgraphics-commons</artifactId>
-        <version>1.5</version>
+        <groupId>com.thoughtworks.xstream</groupId>
+        <artifactId>xstream</artifactId>
+        <version>1.4.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jdom</groupId>
+        <artifactId>jdom</artifactId>
+        <version>1.1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.jettison</groupId>
+        <artifactId>jettison</artifactId>
+        <version>1.3.3</version>
       </dependency>
       <dependency>
         <groupId>xalan</groupId>