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 2013/12/17 13:54:50 UTC

svn commit: r1551528 - in /cxf/trunk/rt/rs/extensions/providers/src: main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java test/java/org/apache/cxf/jaxrs/provider/dom4j/DOM4JProviderTest.java

Author: sergeyb
Date: Tue Dec 17 12:54:50 2013
New Revision: 1551528

URL: http://svn.apache.org/r1551528
Log:
Updating JSONProvider to check more properties on MessageContext

Modified:
    cxf/trunk/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java
    cxf/trunk/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/dom4j/DOM4JProviderTest.java

Modified: cxf/trunk/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java?rev=1551528&r1=1551527&r2=1551528&view=diff
==============================================================================
--- cxf/trunk/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java (original)
+++ cxf/trunk/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java Tue Dec 17 12:54:50 2013
@@ -60,6 +60,7 @@ import javax.xml.stream.XMLStreamWriter;
 
 import org.w3c.dom.Document;
 
+import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.io.CachedOutputStream;
 import org.apache.cxf.jaxrs.ext.MessageContext;
@@ -87,6 +88,10 @@ public class JSONProvider<T> extends Abs
     private static final String MAPPED_CONVENTION = "mapped";
     private static final String BADGER_FISH_CONVENTION = "badgerfish";
     private static final String DROP_ROOT_CONTEXT_PROPERTY = "drop.json.root.element";
+    private static final String ARRAY_KEYS_PROPERTY = "json.array.keys";
+    private static final String ROOT_IS_ARRAY_PROPERTY = "json.root.is.array";
+    private static final String DROP_ELEMENT_IN_XML_PROPERTY = "drop.xml.elements";
+    private static final String IGNORE_EMPTY_JSON_ARRAY_VALUES_PROPERTY = "ignore.empty.json.array.values";
     static {
         new SimpleConverter();
     }
@@ -505,11 +510,16 @@ public class JSONProvider<T> extends Abs
         if (BADGER_FISH_CONVENTION.equals(convention)) {
             return JSONUtils.createBadgerFishWriter(os);
         }
+        boolean dropElementsInXmlStreamProp = getBooleanJsonProperty(DROP_ELEMENT_IN_XML_PROPERTY, 
+                                                                     dropElementsInXmlStream);
         
-        boolean dropRootNeeded = isDropRootNeeded();
+        boolean dropRootNeeded = getBooleanJsonProperty(DROP_ROOT_CONTEXT_PROPERTY, dropRootElement);
+        boolean dropRootInXmlNeeded = dropRootNeeded && dropElementsInXmlStreamProp;
         
-        QName qname = actualClass == Document.class ? null : getQName(actualClass, genericType, actualObject);
-        if (qname != null && ignoreNamespaces && (isCollection || dropRootNeeded)) {        
+        QName qname = actualClass == Document.class 
+            ? org.apache.cxf.helpers.DOMUtils.getElementQName(((Document)actualObject).getDocumentElement()) 
+            : getQName(actualClass, genericType, actualObject);
+        if (qname != null && ignoreNamespaces && (isCollection || dropRootInXmlNeeded)) {        
             qname = new QName(qname.getLocalPart());
         }
         
@@ -518,48 +528,70 @@ public class JSONProvider<T> extends Abs
                                           writeXsiType && !ignoreNamespaces,
                                           attributesToElements,
                                           typeConverter);
-        if (!dropElementsInXmlStream && super.outDropElements != null) {
+        if (!dropElementsInXmlStreamProp && super.outDropElements != null) {
             config.setIgnoredElements(outDropElements);
         }
         if (!writeNullAsString) {
             config.setWriteNullAsString(writeNullAsString);
         }
-        if (ignoreEmptyArrayValues) {
-            config.setIgnoreEmptyArrayValues(ignoreEmptyArrayValues);
+        boolean ignoreEmpty = getBooleanJsonProperty(IGNORE_EMPTY_JSON_ARRAY_VALUES_PROPERTY, ignoreEmptyArrayValues);
+        if (ignoreEmpty) {
+            config.setIgnoreEmptyArrayValues(ignoreEmpty);
         }
         
         
-        boolean dropRootInJsonStream = dropRootElement && !dropElementsInXmlStream;
+        boolean dropRootInJsonStream = dropRootNeeded && !dropElementsInXmlStreamProp;
         if (dropRootInJsonStream) {
             config.setDropRootElement(true);
         }
-        if (ignoreNamespaces && serializeAsArray && (arrayKeys == null || dropRootInJsonStream)) {
-            if (arrayKeys == null) {
-                arrayKeys = new LinkedList<String>();
+         
+        List<String> theArrayKeys = getArrayKeys();
+        boolean rootIsArray = isRootArray(theArrayKeys);
+        
+        if (ignoreNamespaces && rootIsArray && (theArrayKeys == null || dropRootInJsonStream)) {
+            if (theArrayKeys == null) {
+                theArrayKeys = new LinkedList<String>();
             } else if (dropRootInJsonStream) {
-                arrayKeys = new LinkedList<String>(arrayKeys);
+                theArrayKeys = new LinkedList<String>(theArrayKeys);
+            }
+            if (qname != null) {
+                theArrayKeys.add(qname.getLocalPart());
             }
-            arrayKeys.add(qname.getLocalPart());
         }
         
         XMLStreamWriter writer = JSONUtils.createStreamWriter(os, qname, 
-             writeXsiType && !ignoreNamespaces, config, serializeAsArray, arrayKeys,
-             isCollection || dropRootNeeded);
+             writeXsiType && !ignoreNamespaces, config, rootIsArray, theArrayKeys,
+             isCollection || dropRootInXmlNeeded);
         writer = JSONUtils.createIgnoreMixedContentWriterIfNeeded(writer, ignoreMixedContent);
         writer = JSONUtils.createIgnoreNsWriterIfNeeded(writer, ignoreNamespaces);
-        return createTransformWriterIfNeeded(writer, os, dropElementsInXmlStream);
+        return createTransformWriterIfNeeded(writer, os, dropElementsInXmlStreamProp);
     }
     
-    protected boolean isDropRootNeeded() {
+    protected List<String> getArrayKeys() {
+        MessageContext mc = getContext();
+        if (mc != null) {
+            Object prop = mc.get(ARRAY_KEYS_PROPERTY);
+            if (prop instanceof List) {
+                return CastUtils.cast((List<?>)prop);
+            }
+        }
+        return arrayKeys;
+    }
+    
+    protected boolean isRootArray(List<String> theArrayKeys) {
+        return theArrayKeys != null ? true : getBooleanJsonProperty(ROOT_IS_ARRAY_PROPERTY, serializeAsArray);
+    }
+    
+    
+    protected boolean getBooleanJsonProperty(String name, boolean defaultValue) {
         MessageContext mc = getContext();
         if (mc != null) {
-            Object prop = mc.get(DROP_ROOT_CONTEXT_PROPERTY);
+            Object prop = mc.get(name);
             if (prop != null) {
-                // means the property has been set explicitly
                 return MessageUtils.isTrue(prop);
             }
         }
-        return dropRootElement && dropElementsInXmlStream;
+        return defaultValue;
     }
     
     protected void marshal(Object actualObject, Class<?> actualClass, 

Modified: cxf/trunk/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/dom4j/DOM4JProviderTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/dom4j/DOM4JProviderTest.java?rev=1551528&r1=1551527&r2=1551528&view=diff
==============================================================================
--- cxf/trunk/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/dom4j/DOM4JProviderTest.java (original)
+++ cxf/trunk/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/dom4j/DOM4JProviderTest.java Tue Dec 17 12:54:50 2013
@@ -108,7 +108,6 @@ public class DOM4JProviderTest extends A
                    new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE, new MetadataMap<String, Object>(),
                    bos);
         String str = bos.toString();
-        // starts with the xml PI
         assertEquals("{\"a\":\"\"}", str);
     }
     
@@ -123,10 +122,31 @@ public class DOM4JProviderTest extends A
                    new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE, new MetadataMap<String, Object>(),
                    bos);
         String str = bos.toString();
-        // starts with the xml PI
         assertEquals("{\"a\":\"\"}", str);
     }
     
+    @Test
+    public void testWriteJSONAsArray() throws Exception {
+        org.dom4j.Document dom = readXML(MediaType.APPLICATION_XML_TYPE, "<root><a>1</a></root>");
+        DOM4JProvider p = new DOM4JProvider();
+        
+        ProviderFactory factory = ServerProviderFactory.getInstance();
+        JSONProvider<Object> provider = new JSONProvider<Object>();
+        provider.setSerializeAsArray(true);
+        provider.setDropRootElement(true);
+        provider.setDropElementsInXmlStream(false);
+        provider.setIgnoreNamespaces(true);
+        factory.registerUserProvider(provider);
+        p.setProviders(new ProvidersImpl(createMessage(factory)));
+        
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        p.writeTo(dom, org.dom4j.Document.class, org.dom4j.Document.class, 
+                   new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE, new MetadataMap<String, Object>(),
+                   bos);
+        String str = bos.toString();
+        assertEquals("[{\"a\":1}]", str);
+    }
+    
     private Message createMessage() {
         ProviderFactory factory = ServerProviderFactory.getInstance();
         Message m = new MessageImpl();
@@ -156,6 +176,9 @@ public class DOM4JProviderTest extends A
         provider.setDropRootElement(true);
         provider.setIgnoreNamespaces(true);
         factory.registerUserProvider(provider);
+        return createMessage(factory);
+    }
+    private Message createMessage(ProviderFactory factory) {
         Message m = new MessageImpl();
         m.put("org.apache.cxf.http.case_insensitive_queries", false);
         Exchange e = new ExchangeImpl();