You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2012/07/23 19:11:19 UTC

svn commit: r1364715 - in /cxf/branches/2.5.x-fixes: parent/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/ systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/

Author: dkulp
Date: Mon Jul 23 17:11:18 2012
New Revision: 1364715

URL: http://svn.apache.org/viewvc?rev=1364715&view=rev
Log:
Merged revisions 1364549 via  git cherry-pick from
https://svn.apache.org/repos/asf/cxf/branches/2.6.x-fixes

........
  r1364549 | sergeyb | 2012-07-23 05:15:50 -0400 (Mon, 23 Jul 2012) | 9 lines

  Merged revisions 1364548 via svnmerge from
  https://svn.apache.org/repos/asf/cxf/trunk

  ........
    r1364548 | sergeyb | 2012-07-23 10:10:29 +0100 (Mon, 23 Jul 2012) | 1 line

    [CXF-4439] Update to Jettison 1.3.2
  ........

........

Added:
    cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json_duplicate.txt
Modified:
    cxf/branches/2.5.x-fixes/parent/pom.xml
    cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
    cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java
    cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java

Modified: cxf/branches/2.5.x-fixes/parent/pom.xml
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/parent/pom.xml?rev=1364715&r1=1364714&r2=1364715&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/parent/pom.xml (original)
+++ cxf/branches/2.5.x-fixes/parent/pom.xml Mon Jul 23 17:11:18 2012
@@ -101,7 +101,7 @@
         <cxf.xmlschema.version>2.0.2</cxf.xmlschema.version>
         <cxf.jibx.version>1.2.4.5</cxf.jibx.version>
         <cxf.axiom.version>1.2.10</cxf.axiom.version>
-        <cxf.jettison.version>1.3.1</cxf.jettison.version>
+        <cxf.jettison.version>1.3.2</cxf.jettison.version>
         <cxf.wss4j.version>1.6.7-SNAPSHOT</cxf.wss4j.version>
         <cxf.joda.time.version>1.6.2</cxf.joda.time.version>
         <cxf.opensaml.version>2.5.1</cxf.opensaml.version>

Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java?rev=1364715&r1=1364714&r2=1364715&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java (original)
+++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java Mon Jul 23 17:11:18 2012
@@ -61,14 +61,18 @@ import org.w3c.dom.Document;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.io.CachedOutputStream;
 import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.ext.Nullable;
+import org.apache.cxf.jaxrs.provider.AbstractJAXBProvider;
+import org.apache.cxf.jaxrs.provider.json.utils.JSONUtils;
+import org.apache.cxf.jaxrs.utils.AnnotationUtils;
 import org.apache.cxf.jaxrs.utils.HttpUtils;
 import org.apache.cxf.jaxrs.utils.InjectionUtils;
 import org.apache.cxf.jaxrs.utils.JAXBUtils;
 import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler;
 import org.apache.cxf.message.MessageUtils;
-import org.apache.cxf.staxutils.DepthExceededStaxException;
 import org.apache.cxf.staxutils.StaxUtils;
 import org.apache.cxf.staxutils.W3CDOMStreamWriter;
+import org.codehaus.jettison.JSONSequenceTooLargeException;
 import org.codehaus.jettison.mapped.Configuration;
 import org.codehaus.jettison.mapped.SimpleConverter;
 import org.codehaus.jettison.mapped.TypeConverter;
@@ -199,6 +203,14 @@ public class JSONProvider extends Abstra
         MultivaluedMap<String, String> headers, InputStream is) 
         throws IOException {
         
+        if (isPayloadEmpty()) {
+            if (AnnotationUtils.getAnnotation(anns, Nullable.class) != null) {
+                return null;
+            } else {
+                reportEmptyContentLength();
+            }
+        }
+        
         try {
             InputStream realStream = getInputStream(type, genericType, is);
             if (Document.class.isAssignableFrom(type)) {
@@ -234,10 +246,12 @@ public class JSONProvider extends Abstra
             
         } catch (JAXBException e) {
             handleJAXBException(e, true);
-        } catch (DepthExceededStaxException e) {
-            throw new WebApplicationException(413);
         } catch (XMLStreamException e) {
-            handleXMLStreamException(e, true); 
+            if (e.getCause() instanceof JSONSequenceTooLargeException) {
+                throw new WebApplicationException(413);
+            } else {
+                handleXMLStreamException(e, true);
+            }
         } catch (WebApplicationException e) {
             throw e;
         } catch (Exception e) {

Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java?rev=1364715&r1=1364714&r2=1364715&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java (original)
+++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java Mon Jul 23 17:11:18 2012
@@ -18,8 +18,6 @@
  */
 package org.apache.cxf.jaxrs.provider;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
@@ -42,22 +40,16 @@ import javax.xml.stream.XMLStreamWriter;
 import org.apache.cxf.common.WSDLConstants;
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.staxutils.DelegatingXMLStreamWriter;
-import org.apache.cxf.staxutils.DepthExceededStaxException;
 import org.apache.cxf.staxutils.DepthXMLStreamReader;
 import org.apache.cxf.staxutils.DocumentDepthProperties;
 import org.apache.cxf.staxutils.transform.IgnoreNamespacesWriter;
-import org.codehaus.jettison.AbstractXMLInputFactory;
 import org.codehaus.jettison.AbstractXMLStreamWriter;
 import org.codehaus.jettison.badgerfish.BadgerFishXMLInputFactory;
 import org.codehaus.jettison.badgerfish.BadgerFishXMLOutputFactory;
-import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
 import org.codehaus.jettison.json.JSONTokener;
 import org.codehaus.jettison.mapped.Configuration;
 import org.codehaus.jettison.mapped.MappedNamespaceConvention;
 import org.codehaus.jettison.mapped.MappedXMLInputFactory;
-import org.codehaus.jettison.mapped.MappedXMLStreamReader;
 import org.codehaus.jettison.mapped.MappedXMLStreamWriter;
 import org.codehaus.jettison.mapped.TypeConverter;
 
@@ -88,7 +80,7 @@ public final class JSONUtils {
                                                      List<String> arrayKeys,
                                                      boolean dropRootElement) throws Exception {
         
-        MappedNamespaceConvention convention = new PrefixRespectingMappedNamespaceConvention(config);
+        MappedNamespaceConvention convention = new MappedNamespaceConvention(config);
         AbstractXMLStreamWriter xsw = new MappedXMLStreamWriter(
                                             convention, 
                                             new OutputStreamWriter(os, UTF8));
@@ -159,213 +151,17 @@ public final class JSONUtils {
         return new JettisonReader(namespaceMap, factory.createXMLStreamReader(is));
     }
     
-    private static class JettisonMappedReaderFactory extends AbstractXMLInputFactory {
-        private static final int INPUT_BUF_SIZE = 4096;
-        private MappedNamespaceConvention convention;
+    private static class JettisonMappedReaderFactory extends MappedXMLInputFactory {
         private DocumentDepthProperties depthProps;
         public JettisonMappedReaderFactory(Map<?, ?> nstojns, DocumentDepthProperties depthProps) {
-            convention = new MappedNamespaceConvention(new Configuration(nstojns));
+            super(nstojns);
             this.depthProps = depthProps;
         }
-        @Override
-        public XMLStreamReader createXMLStreamReader(JSONTokener tokener) throws XMLStreamException {
-            try {
-                JSONObject root = new JettisonJSONObject(tokener, depthProps);
-                return new MappedXMLStreamReader(root, convention);
-            } catch (JSONException e) {
-                throw new XMLStreamException(e);
-            }
-        } 
-        private String readAll(InputStream in, String encoding)
-            throws IOException {
-            
-            final byte[] buffer = new byte[INPUT_BUF_SIZE];
-            ByteArrayOutputStream bos = null;
-            while (true) {
-                int count = in.read(buffer);
-                if (count < 0) { // EOF
-                    break;
-                }
-                if (bos == null) {
-                    int cap;
-                    if (count < 64) {
-                        cap = 64;
-                    } else if (count == INPUT_BUF_SIZE) {
-                        // Let's assume there's more coming, not just this chunk
-                        cap = INPUT_BUF_SIZE * 4;
-                    } else {
-                        cap = count;
-                    }
-                    bos = new ByteArrayOutputStream(cap);
-                }
-                bos.write(buffer, 0, count);
-            }
-            return (bos == null) ? "" : bos.toString(encoding);
-        }
-        public XMLStreamReader createXMLStreamReader(InputStream is, String charset) 
-            throws XMLStreamException {
-            /* !!! This is not really correct: should (try to) auto-detect
-             * encoding, since JSON only allows 3 Unicode-based variants.
-             * For now it's ok to default to UTF-8 though.
-             */
-            if (charset == null) {
-                charset = "UTF-8";
-            }
-            try {
-                String doc = readAll(is, charset);
-                return createXMLStreamReader(new JettisonJSONTokener(doc, depthProps));
-            } catch (IOException e) {
-                throw new XMLStreamException(e);
-            }
+        protected JSONTokener createNewJSONTokener(String doc) {
+            return new JSONTokener(doc, depthProps.getInnerElementCountThreshold());
         }
     }
 
-    private static class JettisonJSONTokener extends JSONTokener {
-        private DocumentDepthProperties depthProps;
-        public JettisonJSONTokener(String s, DocumentDepthProperties depthProps) {
-            super(s);
-            this.depthProps = depthProps;
-        }
-        public Object nextValue() throws JSONException {
-            char c = nextClean();
-            switch (c) {
-            case '"':
-            case '\'':
-                return nextString(c);
-            case '{':
-                back();
-                return new JettisonJSONObject(this, depthProps);
-            case '[':
-                back();
-                return new JSONArray(this);
-            default:    
-            }
-
-            return finalize(c);
-        }
-        private Object finalize(char c) throws JSONException { 
-            StringBuffer sb = new StringBuffer();
-            char b = c;
-            while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
-                sb.append(c);
-                c = next();
-            }
-            back();
-
-            String s = sb.toString().trim();
-            if (s.length() == 0) {
-                throw new JSONException("Missing value.");
-            }
-            Object res = null;
-            if (s.equalsIgnoreCase("true")) {
-                res = Boolean.TRUE;
-            } else if (s.equalsIgnoreCase("false")) {
-                res = Boolean.FALSE;
-            } else if (s.equalsIgnoreCase("null")) {
-                res = JSONObject.NULL;
-            }
-            if (res != null) {
-                return res;
-            }
-            if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') {
-                if (b == '0') {
-                    if (s.length() > 2 && (s.charAt(1) == 'x' || s.charAt(1) == 'X')) {
-                        try {
-                            res = new Integer(Integer.parseInt(s.substring(2),
-                                    16));
-                        } catch (Exception e) {
-                            /* Ignore the error */
-                        }
-                    } else {
-                        try {
-                            res = new Integer(Integer.parseInt(s, 8));
-                        } catch (Exception e) {
-                            /* Ignore the error */
-                        }
-                    }
-                }
-                if (res == null) {
-                    try {
-                        res = new Integer(s);
-                    } catch (Exception e) {
-                        try {
-                            res = new Long(s);
-                        } catch (Exception f) {
-                            try {
-                                res = new Double(s);
-                            }  catch (Exception g) {
-                                res = s;
-                            }
-                        }
-                    }
-                }
-                if (res != null) {
-                    return res;
-                }
-            }
-            return s;
-        }
-    }
-    
-    private static class JettisonJSONObject extends JSONObject {
-        private static final long serialVersionUID = 9016458891093343731L;
-        private int threshold;
-        
-        public JettisonJSONObject(JSONTokener x, DocumentDepthProperties depthProps) 
-            throws JSONException {
-            this.threshold = depthProps.getElementCountThreshold() != -1 
-                ? depthProps.getElementCountThreshold() : depthProps.getInnerElementCountThreshold();
-            String key;
-            char c;
-            if (x.nextClean() != '{') {
-                throw x.syntaxError("A JSONObject text must begin with '{'");
-            }
-            for (;;) {
-                c = x.nextClean();
-                switch (c) {
-                case 0:
-                    throw x.syntaxError("A JSONObject text must end with '}'");
-                case '}':
-                    return;
-                default:
-                    x.back();
-                    key = x.nextValue().toString();
-                }
-
-                c = x.nextClean();
-                if (c == '=') {
-                    if (x.next() != '>') {
-                        x.back();
-                    }
-                } else if (c != ':') {
-                    throw x.syntaxError("Expected a ':' after a key");
-                }
-                put(key, x.nextValue()); //NOPMD
-                switch (x.nextClean()) {
-                case ';':
-                case ',':
-                    if (x.nextClean() == '}') {
-                        return;
-                    }
-                    x.back();
-                    break;
-                case '}':
-                    return;
-                default:
-                    throw new JSONException("Expected a ',' or '}'");
-                }
-            }
-        }
-        public JSONObject put(String key, Object value) throws JSONException {
-            JSONObject obj = super.put(key, value);
-            if (threshold != -1 && super.length() >= threshold) {
-                throw new DepthExceededStaxException();
-            }
-            return obj;
-            
-        }
-    }
-    
     private static class JettisonReader extends DepthXMLStreamReader {
         private Map<String, String> namespaceMap;
         public JettisonReader(Map<String, String> nsMap,

Modified: cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java?rev=1364715&r1=1364714&r2=1364715&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java (original)
+++ cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java Mon Jul 23 17:11:18 2012
@@ -623,6 +623,18 @@ public class JAXRSClientServerSpringBook
                "resources/expected_get_book123.txt");
     }
     
+    @Test
+    public void testAddInvalidBookDuplicateElementJson() throws Exception {
+        WebClient wc = WebClient.create("http://localhost:" + PORT + "/the/bookstore/books/convert");
+        wc.type("application/json");
+        InputStream is = getClass().getResourceAsStream("resources/add_book2json_duplicate.txt");
+        assertNotNull(is);
+        Response r = wc.post(is);
+        assertEquals(400, r.getStatus());
+        String content = IOUtils.readStringFromStream((InputStream)r.getEntity());
+        assertTrue(content.contains("Invalid content was found starting with element 'id'"));
+    }
+    
     private void doPost(String endpointAddress, int expectedStatus, String contentType,
                         String inResource, String expectedResource) throws Exception {
         

Added: cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json_duplicate.txt
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json_duplicate.txt?rev=1364715&view=auto
==============================================================================
--- cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json_duplicate.txt (added)
+++ cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/add_book2json_duplicate.txt Mon Jul 23 17:11:18 2012
@@ -0,0 +1 @@
+{"b.Book":{"b.name":"CXF in Action","b.id":123,"b.id":124}}
\ No newline at end of file