You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2008/11/27 17:16:13 UTC

svn commit: r721221 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/schemas/ rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ rt/frontend/jaxrs/src...

Author: sergeyb
Date: Thu Nov 27 08:16:12 2008
New Revision: 721221

URL: http://svn.apache.org/viewvc?rev=721221&view=rev
Log:
JAXRS : JSONProvider fixes, adding an option to share schema resources between JSON and JAXB providers

Added:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/schemas/
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/schemas/SchemaHandler.java   (with props)
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java   (with props)
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/ManyTags.java   (with props)
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/TagVO.java   (with props)
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/Tags.java   (with props)
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/bookid.xsd   (with props)
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json.txt   (with props)
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json_invalid.txt   (with props)
Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractAegisProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/Books.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java
    cxf/trunk/systests/src/test/resources/jaxrs/WEB-INF/beans.xml

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractAegisProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractAegisProvider.java?rev=721221&r1=721220&r2=721221&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractAegisProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractAegisProvider.java Thu Nov 27 08:16:12 2008
@@ -19,47 +19,27 @@
 
 package org.apache.cxf.jaxrs.provider;
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
-import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.WeakHashMap;
-import java.util.logging.Logger;
 
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.ext.ContextResolver;
 import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.MessageBodyWriter;
-import javax.xml.XMLConstants;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
 
 import org.apache.cxf.aegis.AegisContext;
-import org.apache.cxf.common.logging.LogUtils;
 
 public abstract class AbstractAegisProvider 
     implements MessageBodyReader<Object>, MessageBodyWriter<Object> {
     
-    private static final Logger LOG = LogUtils.getL7dLogger(AbstractAegisProvider.class);
-
-    private static final String CLASSPATH_PREFIX = "classpath:";
-        
     private static Map<Class<?>, AegisContext> classContexts = new WeakHashMap<Class<?>, AegisContext>();
     
     @Context protected ContextResolver<AegisContext> resolver;
-    private Schema schema;
     
     public boolean isWriteable(Class<?> type, Type genericType, Annotation[] anns, MediaType mt) {
         return isSupported(type, genericType, anns);
@@ -69,10 +49,6 @@
         return isSupported(type, genericType, annotations);
     }
 
-    public void setSchemas(List<String> locations) {
-        schema = createSchema(locations);    
-    }
-    
     public long getSize(Object o, Class<?> type, Type genericType, Annotation[] annotations, MediaType mt) {
         return -1;
     }
@@ -117,44 +93,4 @@
     protected boolean isSupported(Class<?> type, Type genericType, Annotation[] annotations) {
         return true;
     }
-    
-    private Schema createSchema(List<String> locations) {
-        
-        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-        Schema s = null;
-        try {
-            List<Source> sources = new ArrayList<Source>();
-            for (String loc : locations) {
-                InputStream is = null;
-                if (loc.startsWith(CLASSPATH_PREFIX)) {
-                    String path = loc.substring(CLASSPATH_PREFIX.length() + 1);
-                    is = getClass().getClassLoader().getResourceAsStream(path);
-                    if (is == null) {
-                        LOG.warning("No schema resource " + loc + " is available on classpath");
-                        return null;
-                    }
-                } else {
-                    File f = new File(loc);
-                    if (!f.exists()) {
-                        LOG.warning("No schema resource " + loc + " is available on local disk");
-                        return null;
-                    }
-                    is = new FileInputStream(f);
-                }
-                                
-                Reader r = new BufferedReader(
-                               new InputStreamReader(is, "UTF-8"));
-                sources.add(new StreamSource(r));
-            }
-            s = factory.newSchema(sources.toArray(new Source[]{}));
-        } catch (Exception ex) {
-            LOG.warning("Validation will be disabled, failed to create schema : " + ex.getMessage());
-        }
-        return s;
-        
-    }
-    
-    protected Schema getSchema() {
-        return schema;
-    }
 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java?rev=721221&r1=721220&r2=721221&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java Thu Nov 27 08:16:12 2008
@@ -19,27 +19,21 @@
 
 package org.apache.cxf.jaxrs.provider;
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.ResourceBundle;
 import java.util.WeakHashMap;
 import java.util.logging.Logger;
 
+import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.ContextResolver;
 import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.MessageBodyWriter;
-import javax.xml.XMLConstants;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
@@ -48,16 +42,14 @@
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.adapters.XmlAdapter;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
 import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
 
 import org.apache.cxf.common.i18n.BundleUtils;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.util.PackageUtils;
 import org.apache.cxf.jaxrs.utils.AnnotationUtils;
 import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler;
 
 public abstract class AbstractJAXBProvider 
     implements MessageBodyReader<Object>, MessageBodyWriter<Object> {
@@ -67,7 +59,6 @@
     private static final Logger LOG = LogUtils.getL7dLogger(AbstractJAXBProvider.class);
 
     private static final String CHARSET_PARAMETER = "charset"; 
-    private static final String CLASSPATH_PREFIX = "classpath:";
         
     private static Map<String, JAXBContext> packageContexts = new WeakHashMap<String, JAXBContext>();
     private static Map<Class<?>, JAXBContext> classContexts = new WeakHashMap<Class<?>, JAXBContext>();
@@ -85,8 +76,12 @@
         return isSupported(type, genericType, annotations);
     }
 
-    public void setSchemas(List<String> locations) {
-        schema = createSchema(locations);    
+    public void setSchemaLocations(List<String> locations) {
+        schema = SchemaHandler.createSchema(locations);    
+    }
+    
+    public void setSchema(Schema s) {
+        schema = s;    
     }
     
     public long getSize(Object o, Class<?> type, Type genericType, Annotation[] annotations, MediaType mt) {
@@ -223,43 +218,17 @@
         return obj;
     }
     
-    private Schema createSchema(List<String> locations) {
-        
-        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-        Schema s = null;
-        try {
-            List<Source> sources = new ArrayList<Source>();
-            for (String loc : locations) {
-                InputStream is = null;
-                if (loc.startsWith(CLASSPATH_PREFIX)) {
-                    String path = loc.substring(CLASSPATH_PREFIX.length() + 1);
-                    is = getClass().getClassLoader().getResourceAsStream(path);
-                    if (is == null) {
-                        LOG.warning("No schema resource " + loc + " is available on classpath");
-                        return null;
-                    }
-                } else {
-                    File f = new File(loc);
-                    if (!f.exists()) {
-                        LOG.warning("No schema resource " + loc + " is available on local disk");
-                        return null;
-                    }
-                    is = new FileInputStream(f);
-                }
-                                
-                Reader r = new BufferedReader(
-                               new InputStreamReader(is, "UTF-8"));
-                sources.add(new StreamSource(r));
-            }
-            s = factory.newSchema(sources.toArray(new Source[]{}));
-        } catch (Exception ex) {
-            LOG.warning("Validation will be disabled, failed to create schema : " + ex.getMessage());
-        }
-        return s;
-        
-    }
-    
     protected Schema getSchema() {
         return schema;
     }
+    
+    protected static void handleJAXBException(JAXBException e) {
+        Throwable t = e.getLinkedException() != null 
+            ? e.getLinkedException() : e.getCause() != null ? e.getCause() : e;
+        String message = new org.apache.cxf.common.i18n.Message("JAXB_EXCEPTION", 
+                             BUNDLE, t.getMessage()).toString();
+        Response r = Response.status(Response.Status.INTERNAL_SERVER_ERROR)
+            .type(MediaType.TEXT_PLAIN).entity(message).build();
+        throw new WebApplicationException(t, r);
+    }
 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java?rev=721221&r1=721220&r2=721221&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java Thu Nov 27 08:16:12 2008
@@ -33,7 +33,6 @@
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.Provider;
 import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
@@ -41,6 +40,8 @@
 import javax.xml.bind.Unmarshaller;
 import javax.xml.transform.stream.StreamSource;
 
+import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler;
+
 @Produces({"application/xml", "text/xml" })
 @Consumes({"application/xml", "text/xml" })
 @Provider
@@ -49,7 +50,11 @@
     private Map<String, Object> mProperties = new HashMap<String, Object>();
     
     public void setSchemas(List<String> locations) {
-        super.setSchemas(locations);
+        super.setSchemaLocations(locations);
+    }
+    
+    public void setSchemaHandler(SchemaHandler handler) {
+        super.setSchema(handler.getSchema());
     }
     
     public void setMarshallerProperties(Map<String, Object> marshallProperties) {
@@ -74,16 +79,12 @@
             }
             
         } catch (JAXBException e) {
-            Throwable t = e.getLinkedException() != null 
-                ? e.getLinkedException() : e.getCause() != null ? e.getCause() : e;
-            String message = new org.apache.cxf.common.i18n.Message("JAXB_EXCEPTION", 
-                                 BUNDLE, t.getMessage()).toString();
-            Response r = Response.status(Response.Status.INTERNAL_SERVER_ERROR)
-                .type(MediaType.TEXT_PLAIN).entity(message).build();
-            throw new WebApplicationException(t, r);
+            handleJAXBException(e);
         } catch (Exception e) {
             throw new WebApplicationException(e);        
         }
+        // unreachable
+        return null;
     }
 
     

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java?rev=721221&r1=721220&r2=721221&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java Thu Nov 27 08:16:12 2008
@@ -23,6 +23,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.OutputStreamWriter;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 import java.util.HashMap;
@@ -35,28 +36,47 @@
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.ext.Provider;
-import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
-import javax.xml.stream.XMLOutputFactory;
+import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
-import javax.xml.stream.XMLStreamWriter;
 
+import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler;
+import org.codehaus.jettison.AbstractXMLStreamWriter;
+import org.codehaus.jettison.mapped.Configuration;
+import org.codehaus.jettison.mapped.MappedNamespaceConvention;
 import org.codehaus.jettison.mapped.MappedXMLInputFactory;
-import org.codehaus.jettison.mapped.MappedXMLOutputFactory;
+import org.codehaus.jettison.mapped.MappedXMLStreamWriter;
 
 @Produces("application/json")
 @Consumes("application/json")
 @Provider
 public final class JSONProvider extends AbstractJAXBProvider  {
     
+    private static final String JAXB_DEFAULT_NAMESPACE = "##default";
+    private static final String JAXB_DEFAULT_NAME = "##default";
+    
     private Map<String, String> namespaceMap = new HashMap<String, String>();
+    private boolean serializeAsArray;
+    private List<String> arrayKeys;
     
     public void setSchemas(List<String> locations) {
-        super.setSchemas(locations);
+        super.setSchemaLocations(locations);
+    }
+    
+    public void setSchemaHandler(SchemaHandler handler) {
+        super.setSchema(handler.getSchema());
+    }
+    
+    public void setSerializeAsArray(boolean asArray) {
+        this.serializeAsArray = asArray;
+    }
+    
+    public void setArrayKeys(List<String> keys) {
+        this.arrayKeys = keys;
     }
     
     public void setNamespaceMap(Map<String, String> namespaceMap) {
@@ -69,8 +89,7 @@
         
         try {
             Class<?> theType = getActualType(type, genericType);
-            JAXBContext context = getJAXBContext(theType, genericType);
-            Unmarshaller unmarshaller = context.createUnmarshaller();
+            Unmarshaller unmarshaller = createUnmarshaller(theType, genericType);
             
             MappedXMLInputFactory factory = new MappedXMLInputFactory(namespaceMap);
             XMLStreamReader xsw = factory.createXMLStreamReader(is);
@@ -83,12 +102,14 @@
             return response;
             
         } catch (JAXBException e) {
-            throw new WebApplicationException(e);         
+            handleJAXBException(e);
         } catch (XMLStreamException e) {
             throw new WebApplicationException(e);
         } catch (Exception e) {
             throw new WebApplicationException(e);
-        } 
+        }
+        // unreachable
+        return null;
     }
 
     public void writeTo(Object obj, Class<?> cls, Type genericType, Annotation[] anns,  
@@ -103,8 +124,22 @@
             }
             Marshaller ms = createMarshaller(actualObject, actualClass, genericType, m);
 
-            XMLOutputFactory factory = new MappedXMLOutputFactory(namespaceMap);
-            XMLStreamWriter xsw = factory.createXMLStreamWriter(os);            
+            Configuration c = new Configuration(namespaceMap);
+            MappedNamespaceConvention convention = new MappedNamespaceConvention(c);
+            AbstractXMLStreamWriter xsw = new MappedXMLStreamWriter(
+                                               convention, 
+                                               new OutputStreamWriter(os, "UTF-8"));
+            if (serializeAsArray) {
+                if (arrayKeys != null) {
+                    for (String key : arrayKeys) {
+                        xsw.seriliazeAsArray(key);
+                    }
+                } else {
+                    String key = getKey(convention, cls);
+                    xsw.seriliazeAsArray(key);
+                }
+            }
+                        
             ms.marshal(actualObject, xsw);
             xsw.close();
             
@@ -115,7 +150,33 @@
         }
     }
 
-    
+    private String getKey(MappedNamespaceConvention convention, Class<?> cls) {
+        String key = null;
+        
+        XmlRootElement root = cls.getAnnotation(XmlRootElement.class);
+        if (root != null) {
+            
+            String namespace = root.namespace();
+            if (JAXB_DEFAULT_NAMESPACE.equals(namespace)) {
+                namespace = "";
+            }
+            
+            String prefix = namespaceMap.get(namespace);
+            if (prefix == null) {
+                prefix = "";
+            }
+            
+            String name = root.name();
+            if (JAXB_DEFAULT_NAME.equals(name)) {
+                name = cls.getSimpleName();
+            }
+            key = convention.createKey(prefix, namespace, name);
+            
+        } else {
+            key = convention.createKey("", "", cls.getSimpleName());
+        }
+        return key;
+    }
     
     
 }

Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/schemas/SchemaHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/schemas/SchemaHandler.java?rev=721221&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/schemas/SchemaHandler.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/schemas/SchemaHandler.java Thu Nov 27 08:16:12 2008
@@ -0,0 +1,94 @@
+/**
+ * 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.cxf.jaxrs.utils.schemas;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.apache.cxf.common.logging.LogUtils;
+
+public class SchemaHandler {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(SchemaHandler.class);
+    private static final String CLASSPATH_PREFIX = "classpath:";
+    
+    private Schema schema;
+    
+    public SchemaHandler() {
+        
+    }
+    
+    public void setSchemas(List<String> locations) {
+        schema = createSchema(locations);
+    }
+    
+    public Schema getSchema() {
+        return schema;
+    }
+    
+    public static Schema createSchema(List<String> locations) {
+        
+        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+        Schema s = null;
+        try {
+            List<Source> sources = new ArrayList<Source>();
+            for (String loc : locations) {
+                InputStream is = null;
+                if (loc.startsWith(CLASSPATH_PREFIX)) {
+                    String path = loc.substring(CLASSPATH_PREFIX.length() + 1);
+                    is = SchemaHandler.class.getClassLoader().getResourceAsStream(path);
+                    if (is == null) {
+                        LOG.warning("No schema resource " + loc + " is available on classpath");
+                        return null;
+                    }
+                } else {
+                    File f = new File(loc);
+                    if (!f.exists()) {
+                        LOG.warning("No schema resource " + loc + " is available on local disk");
+                        return null;
+                    }
+                    is = new FileInputStream(f);
+                }
+                                
+                Reader r = new BufferedReader(
+                               new InputStreamReader(is, "UTF-8"));
+                sources.add(new StreamSource(r));
+            }
+            s = factory.newSchema(sources.toArray(new Source[]{}));
+        } catch (Exception ex) {
+            LOG.warning("Validation will be disabled, failed to create schema : " + ex.getMessage());
+        }
+        return s;
+        
+    }
+}

Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/schemas/SchemaHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/schemas/SchemaHandler.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java?rev=721221&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java Thu Nov 27 08:16:12 2008
@@ -0,0 +1,100 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Collections;
+
+import javax.ws.rs.core.MediaType;
+
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.jaxrs.resources.ManyTags;
+import org.apache.cxf.jaxrs.resources.TagVO;
+import org.apache.cxf.jaxrs.resources.Tags;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class JSONProviderTest extends Assert {
+
+    @Test
+    public void testWriteToListWithManyValues() throws Exception {
+        JSONProvider p = new JSONProvider();
+        Tags tags = new Tags();
+        tags.addTag(createTag("a", "b"));
+        tags.addTag(createTag("c", "d"));
+        
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        
+        p.writeTo(tags, (Class)Tags.class, Tags.class, Tags.class.getAnnotations(), 
+                  MediaType.APPLICATION_JSON_TYPE, new MetadataMap<String, Object>(), os);
+        
+        String s = os.toString();
+        System.out.println(s);
+        assertEquals(
+            "{\"Tags\":{\"list\":[{\"group\":\"b\",\"name\":\"a\"},{\"group\":\"d\",\"name\":\"c\"}]}}",
+            s);
+    }
+    
+    @Test
+    public void testWriteToListWithSingleValue() throws Exception {
+        JSONProvider p = new JSONProvider();
+        p.setSerializeAsArray(true);
+        Tags tags = new Tags();
+        tags.addTag(createTag("a", "b"));
+        
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        
+        p.writeTo(tags, (Class)Tags.class, Tags.class, Tags.class.getAnnotations(), 
+                  MediaType.APPLICATION_JSON_TYPE, new MetadataMap<String, Object>(), os);
+        
+        String s = os.toString();
+        System.out.println(s);
+        assertEquals(
+            "{\"Tags\":{\"list\":[{\"group\":\"b\",\"name\":\"a\"}]}}",
+            s);
+    }
+    
+    @Test
+    public void testManyTags() throws Exception {
+        JSONProvider p = new JSONProvider();
+        p.setSerializeAsArray(true);
+        p.setArrayKeys(Collections.singletonList("tags"));
+        
+        Tags tags = new Tags();
+        tags.addTag(createTag("a", "b"));
+        ManyTags many = new ManyTags();
+        many.setTags(tags);
+        
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        
+        p.writeTo(many, (Class)ManyTags.class, ManyTags.class, ManyTags.class.getAnnotations(), 
+                  MediaType.APPLICATION_JSON_TYPE, new MetadataMap<String, Object>(), os);
+        
+        String s = os.toString();
+        System.out.println(s);
+        assertEquals(
+            "{\"ManyTags\":{\"tags\":{\"list\":[{\"group\":\"b\",\"name\":\"a\"}]}}}",
+            s);
+    }
+    
+    private TagVO createTag(String name, String group) {
+        return new TagVO(name, group);
+    }
+}

Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/ManyTags.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/ManyTags.java?rev=721221&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/ManyTags.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/ManyTags.java Thu Nov 27 08:16:12 2008
@@ -0,0 +1,39 @@
+/**
+ * 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.cxf.jaxrs.resources;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "ManyTags")
+public class ManyTags {
+    private Tags tags;
+    
+    public ManyTags() {
+        
+    }
+    
+    public void setTags(Tags t) {
+        tags = t;
+    }
+    
+    public Tags getTags() {
+        return tags;
+    }
+    
+}

Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/ManyTags.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/ManyTags.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/TagVO.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/TagVO.java?rev=721221&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/TagVO.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/TagVO.java Thu Nov 27 08:16:12 2008
@@ -0,0 +1,51 @@
+/**
+ * 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.cxf.jaxrs.resources;
+
+public class TagVO {
+    private String name;
+    private String group;
+    
+    public TagVO() { 
+        
+    }
+    
+    public TagVO(String name, String group) {
+        this.name = name;
+        this.group = group;
+    }
+    
+    public void setName(String n) {
+        this.name = n;
+    }
+    
+    public void setGroup(String g) {
+        this.group = g;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public String getGroup() {
+        return group;
+    }
+    
+}

Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/TagVO.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/TagVO.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/Tags.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/Tags.java?rev=721221&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/Tags.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/Tags.java Thu Nov 27 08:16:12 2008
@@ -0,0 +1,43 @@
+/**
+ * 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.cxf.jaxrs.resources;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "Tags")
+public class Tags {
+    @XmlElement
+    private List<TagVO> list = new ArrayList<TagVO>();
+    
+    public Tags() {
+        
+    }
+    
+    public Tags(List<TagVO> tags) {
+        list.addAll(tags);
+    }
+    
+    public void addTag(TagVO tag) {
+        list.add(tag);
+    }
+}

Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/Tags.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/Tags.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java?rev=721221&r1=721220&r2=721221&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java Thu Nov 27 08:16:12 2008
@@ -289,6 +289,24 @@
 
         return r;
     }
+    
+    @DELETE
+    @Path("/books/id")
+    public Response deleteWithQuery(@QueryParam("value") @DefaultValue("-1") int id) {
+        if (id != 123) {
+            throw new WebApplicationException();
+        }
+        Book b = books.get(new Long(id));
+
+        Response r;
+        if (b != null) {
+            r = Response.ok().build();
+        } else {
+            r = Response.notModified().build();
+        }
+
+        return r;
+    }
 
     @POST
     @Path("/booksplain")

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java?rev=721221&r1=721220&r2=721221&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java Thu Nov 27 08:16:12 2008
@@ -23,6 +23,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
@@ -48,6 +49,12 @@
     }
     
     @GET
+    @Path("/books/list/{id}")
+    public Books getBookAsJsonList(@PathParam("id") Long id) {
+        return new Books(books.get(id));
+    }
+    
+    @GET
     @Path("/books/{id}")
     public Book getBookById(@PathParam("id") Long id) {
         return books.get(id);
@@ -88,6 +95,7 @@
 
     @POST
     @Path("books/convert")
+    @Consumes({"application/xml", "application/json" })
     @Produces("application/xml")
     public Book convertBook(Book2 book) {
         // how to have Book2 populated ?
@@ -97,6 +105,8 @@
         return b;
     }
     
+    
+    
     final void init() {
         Book book = new Book();
         book.setId(mainId);

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/Books.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/Books.java?rev=721221&r1=721220&r2=721221&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/Books.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/Books.java Thu Nov 27 08:16:12 2008
@@ -19,20 +19,27 @@
 
 package org.apache.cxf.systest.jaxrs;
 
-import javax.xml.bind.annotation.XmlElement;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 
 @XmlRootElement(name = "Books")
+@XmlAccessorType(XmlAccessType.FIELD)
 public class Books {
 
-    @XmlElement
-    private Book b;
+    private List<Book> books = new ArrayList<Book>();
+    
+    public Books() {
+    }
     
     public Books(Book b) {
-        this.b = b;
+        books.add(b);
     }
 
     public Book getBook() {
-        return b;
+        return books.size() == 0 ? null : books.get(0);
     }
 }

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java?rev=721221&r1=721220&r2=721221&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java Thu Nov 27 08:16:12 2008
@@ -25,6 +25,7 @@
 import java.net.URLConnection;
 
 import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.DeleteMethod;
 import org.apache.commons.httpclient.methods.FileRequestEntity;
 import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.commons.httpclient.methods.PostMethod;
@@ -497,6 +498,40 @@
     }
     
     @Test
+    public void testDeleteBook() throws Exception {
+        String endpointAddress =
+            "http://localhost:9080/bookstore/books/123"; 
+
+        DeleteMethod post = new DeleteMethod(endpointAddress);
+        HttpClient httpclient = new HttpClient();
+        
+        try {
+            int result = httpclient.executeMethod(post);
+            assertEquals(200, result);
+        } finally {
+            // Release current connection to the connection pool once you are done
+            post.releaseConnection();
+        }  
+    }
+    
+    @Test
+    public void testDeleteBookByQuery() throws Exception {
+        String endpointAddress =
+            "http://localhost:9080/bookstore/books/id?value=123"; 
+
+        DeleteMethod post = new DeleteMethod(endpointAddress);
+        HttpClient httpclient = new HttpClient();
+        
+        try {
+            int result = httpclient.executeMethod(post);
+            assertEquals(200, result);
+        } finally {
+            // Release current connection to the connection pool once you are done
+            post.releaseConnection();
+        }  
+    }
+    
+    @Test
     public void testGetCDsJSON() throws Exception {
         String endpointAddress =
             "http://localhost:9080/bookstore/cds"; 

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java?rev=721221&r1=721220&r2=721221&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java Thu Nov 27 08:16:12 2008
@@ -47,98 +47,125 @@
         String endpointAddress =
             "http://localhost:9080/bookstore/bookinfo?"
                                + "param1=12&param2=3"; 
-        getBook(endpointAddress);
+        getBook(endpointAddress, "resources/expected_get_book123json.txt");
     }
     
     @Test
     public void testGetBook123() throws Exception {
         String endpointAddress =
             "http://localhost:9080/bookstore/books/123"; 
-        getBook(endpointAddress); 
+        getBook(endpointAddress, "resources/expected_get_book123json.txt"); 
+    }
+    
+    @Test
+    public void testGetBookAsArray() throws Exception {
+        URL url = new URL("http://localhost:9080/bookstore/books/list/123");
+        URLConnection connect = url.openConnection();
+        connect.addRequestProperty("Accept", "application/json");
+        InputStream in = connect.getInputStream();           
+
+        assertEquals("{\"Books\":{\"books\":[{\"id\":123,\"name\":\"CXF in Action\"}]}}", 
+                     getStringFromInputStream(in)); 
+        
     }
     
     @Test
     public void testGetBookWithEncodedQueryValue() throws Exception {
         String endpointAddress =
             "http://localhost:9080/bookstore/booksquery?id=12%2B3"; 
-        getBook(endpointAddress); 
+        getBook(endpointAddress, "resources/expected_get_book123json.txt"); 
     }
     
     @Test
     public void testGetBookWithEncodedPathValue() throws Exception {
         String endpointAddress =
             "http://localhost:9080/bookstore/id=12%2B3"; 
-        getBook(endpointAddress); 
+        getBook(endpointAddress, "resources/expected_get_book123json.txt"); 
     }
     
     @Test
     public void testGetDefaultBook() throws Exception {
         String endpointAddress =
             "http://localhost:9080/bookstore"; 
-        getBook(endpointAddress); 
+        getBook(endpointAddress, "resources/expected_get_book123json.txt"); 
     }
 
-    private void getBook(String endpointAddress) throws Exception {
+    private void getBook(String endpointAddress, String resource) throws Exception {
         URL url = new URL(endpointAddress);
         URLConnection connect = url.openConnection();
         connect.addRequestProperty("Accept", "application/json");
         InputStream in = connect.getInputStream();           
 
-        InputStream expected = getClass()
-            .getResourceAsStream("resources/expected_get_book123json.txt");
-
+        InputStream expected = getClass().getResourceAsStream(resource);
         assertEquals(getStringFromInputStream(expected), getStringFromInputStream(in));
     }
     
     @Test
-    public void testAddInvalidBook() throws Exception {
+    public void testAddInvalidXmlBook() throws Exception {
         
-        String endpointAddress =
-            "http://localhost:9080/bookstore/books/convert";
-        
-        File input = new File(getClass().getResource("resources/add_book.txt").toURI());         
-        PostMethod post = new PostMethod(endpointAddress);
-        post.setRequestHeader("Content-Type", "application/xml");
-        RequestEntity entity = new FileRequestEntity(input, "text/xml; charset=ISO-8859-1");
-        post.setRequestEntity(entity);
-        HttpClient httpclient = new HttpClient();
+        doPost("http://localhost:9080/bookstore/books/convert",
+               500,
+               "application/xml",
+               "resources/add_book.txt",
+               null);
+                
+    }
+    
+    @Test
+    public void testAddInvalidJsonBook() throws Exception {
         
-        try {
-            int result = httpclient.executeMethod(post);
-            assertEquals(500, result);
-            assertTrue(post.getResponseBodyAsString().contains("JAXBException"));
-        } finally {
-            // Release current connection to the connection pool once you are done
-            post.releaseConnection();
-        }
+        doPost("http://localhost:9080/bookstore/books/convert",
+               500,
+               "application/json",
+               "resources/add_book2json_invalid.txt",
+               null);
                 
     }
     
     @Test
-    public void testAddValidBook() throws Exception {
+    public void testAddValidXmlBook() throws Exception {
         
-        String endpointAddress =
-            "http://localhost:9080/bookstore/books/convert";
+        doPost("http://localhost:9080/bookstore/books/convert",
+               200,
+               "application/xml",
+               "resources/add_book2.txt",
+               "resources/expected_get_book123.txt");
+                
+    }
+    
+    @Test
+    public void testAddValidBookJson() throws Exception {
+        doPost("http://localhost:9080/bookstore/books/convert",
+               200,
+               "application/json",
+               "resources/add_book2json.txt",
+               "resources/expected_get_book123.txt");
+    }
+    
+    private void doPost(String endpointAddress, int expectedStatus, String contentType,
+                        String inResource, String expectedResource) throws Exception {
         
-        File input = new File(getClass().getResource("resources/add_book2.txt").toURI());         
+        File input = new File(getClass().getResource(inResource).toURI());         
         PostMethod post = new PostMethod(endpointAddress);
-        post.setRequestHeader("Content-Type", "application/xml");
+        post.setRequestHeader("Content-Type", contentType);
         RequestEntity entity = new FileRequestEntity(input, "text/xml");
         post.setRequestEntity(entity);
         HttpClient httpclient = new HttpClient();
         
         try {
             int result = httpclient.executeMethod(post);
-            assertEquals(200, result);
+            assertEquals(expectedStatus, result);
             
-            InputStream expected = getClass().getResourceAsStream("resources/expected_get_book123.txt");
-            
-            assertEquals(getStringFromInputStream(expected), post.getResponseBodyAsString());
+            if (expectedStatus != 500) {
+                InputStream expected = getClass().getResourceAsStream(expectedResource);
+                assertEquals(getStringFromInputStream(expected), post.getResponseBodyAsString());
+            } else {
+                assertTrue(post.getResponseBodyAsString().contains("JAXBException"));
+            }
         } finally {
             // Release current connection to the connection pool once you are done
             post.releaseConnection();
         }
-                
     }
     
     private String getStringFromInputStream(InputStream in) throws Exception {        

Added: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/bookid.xsd
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/bookid.xsd?rev=721221&view=auto
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/bookid.xsd (added)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/bookid.xsd Thu Nov 27 08:16:12 2008
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.example.org/books/id" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.example.org/books/id">
+  
+
+     <simpleType name="bid">
+       <restriction base="xs:long"/>
+     </simpleType>
+  </schema>

Propchange: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/bookid.xsd
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/bookid.xsd
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json.txt
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json.txt?rev=721221&view=auto
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json.txt (added)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json.txt Thu Nov 27 08:16:12 2008
@@ -0,0 +1 @@
+{"b.Book":{"b.name":"CXF in Action","b.id":123}}
\ No newline at end of file

Propchange: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json_invalid.txt
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json_invalid.txt?rev=721221&view=auto
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json_invalid.txt (added)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json_invalid.txt Thu Nov 27 08:16:12 2008
@@ -0,0 +1 @@
+{"Book":{"name":"CXF in Action","id":123}}
\ No newline at end of file

Propchange: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json_invalid.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json_invalid.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cxf/trunk/systests/src/test/resources/jaxrs/WEB-INF/beans.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/resources/jaxrs/WEB-INF/beans.xml?rev=721221&r1=721220&r2=721221&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/resources/jaxrs/WEB-INF/beans.xml (original)
+++ cxf/trunk/systests/src/test/resources/jaxrs/WEB-INF/beans.xml Thu Nov 27 08:16:12 2008
@@ -26,10 +26,13 @@
   http://cxf.apache.org/simple http://cxf.apache.org/schemas/simple.xsd"-->
 <beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xmlns:util="http://www.springframework.org/schema/util"
   xmlns:jaxrs="http://cxf.apache.org/jaxrs"
   xsi:schemaLocation="
 http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans.xsd
+http://www.springframework.org/schema/util 
+http://www.springframework.org/schema/util/spring-util-2.0.xsd
 http://cxf.apache.org/jaxrs
 http://cxf.apache.org/schemas/jaxrs.xsd">
 
@@ -44,17 +47,38 @@
     </jaxrs:serviceBeans>		   
     <jaxrs:providers>
        <ref bean="jaxbProvider"/>
-       
+       <ref bean="jsonProvider"/>
     </jaxrs:providers>
     
   </jaxrs:server>
 
   <bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
-      <property name="schemas">
-        <list>
-           <value>classpath:/org/apache/cxf/systest/jaxrs/book.xsd</value>
-        </list>
-      </property>
+      <property name="schemaHandler" ref="schemaHolder"/>
+  </bean>
+  
+  <bean id="schemaHolder" class="org.apache.cxf.jaxrs.utils.schemas.SchemaHandler">
+      <property name="schemas" ref="theSchemas"/>
+  </bean>
+  
+  <util:list id="theSchemas">
+    <value>classpath:/org/apache/cxf/systest/jaxrs/bookid.xsd</value>
+    <value>classpath:/org/apache/cxf/systest/jaxrs/book.xsd</value>
+  </util:list>
+  
+  <util:map id="jsonNamespaceMap" map-class="java.util.Hashtable">
+       <entry key="http://www.example.org/books" value="b"/>
+  </util:map> 
+  
+  <util:list id="jsonKeys">
+    <value>Books</value>
+  </util:list>
+  
+  <bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.JSONProvider">
+      <property name="namespaceMap" ref="jsonNamespaceMap"/> 
+      <property name="schemaHandler" ref="schemaHolder"/>
+
+      <property name="serializeAsArray" value="true"/> 
+      <property name="arrayKeys" ref="jsonKeys"/>
   </bean>
 </beans>
 <!-- END SNIPPET: beans -->