Author: sergeyb Date: Thu Jun 27 09:40:06 2013 New Revision: 1497264 URL: http://svn.apache.org/r1497264 Log: Merged revisions 1496500 via svnmerge from https://svn.apache.org/repos/asf/cxf/branches/2.7.x-fixes
................ r1496500 | sergeyb | 2013-06-25 15:49:16 +0100 (Tue, 25 Jun 2013) | 9 lines Merged revisions 1496496 via svnmerge from https://svn.apache.org/repos/asf/cxf/trunk ........ r1496496 | sergeyb | 2013-06-25 15:45:00 +0100 (Tue, 25 Jun 2013) | 1 line [CXF-5090] Starting to update to Jettison 1.3.4 ........ ................ Modified: cxf/branches/2.6.x-fixes/ (props changed) cxf/branches/2.6.x-fixes/parent/pom.xml cxf/branches/2.6.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java cxf/branches/2.6.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/utils/JSONUtils.java cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/json/JSONProviderTest.java cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/resources/Book.java Propchange: cxf/branches/2.6.x-fixes/ ------------------------------------------------------------------------------ Merged /cxf/branches/2.7.x-fixes:r1496500 Merged /cxf/trunk:r1496496 Propchange: cxf/branches/2.6.x-fixes/ ------------------------------------------------------------------------------ Binary property 'svnmerge-integrated' - no diff available. Modified: cxf/branches/2.6.x-fixes/parent/pom.xml URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/parent/pom.xml?rev=1497264&r1=1497263&r2=1497264&view=diff ============================================================================== --- cxf/branches/2.6.x-fixes/parent/pom.xml (original) +++ cxf/branches/2.6.x-fixes/parent/pom.xml Thu Jun 27 09:40:06 2013 @@ -121,7 +121,7 @@ <cxf.jaxb.xjc.version>${cxf.jaxb21.xjc.version}</cxf.jaxb.xjc.version> <cxf.jdom.version>1.0</cxf.jdom.version> - <cxf.jettison.version>1.3.3</cxf.jettison.version> + <cxf.jettison.version>1.3.4</cxf.jettison.version> <cxf.jetty.osgi.version>[7.2,8.2)</cxf.jetty.osgi.version> <cxf.jetty.version>7.5.4.v20111024</cxf.jetty.version> <cxf.jibx.version>1.2.4.5</cxf.jibx.version> @@ -1801,6 +1801,12 @@ </build> </profile> </profiles> + <repositories> + <repository> + <id>jettison</id> + <url>https://nexus.codehaus.org/content/repositories/orgcodehausjettison-021/</url> + </repository> + </repositories> </project> Modified: cxf/branches/2.6.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java?rev=1497264&r1=1497263&r2=1497264&view=diff ============================================================================== --- cxf/branches/2.6.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java (original) +++ cxf/branches/2.6.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java Thu Jun 27 09:40:06 2013 @@ -720,10 +720,11 @@ public abstract class AbstractJAXBProvid } protected XMLStreamWriter createTransformWriterIfNeeded(XMLStreamWriter writer, - OutputStream os) { + OutputStream os, + boolean dropAtXmlLevel) { return TransformUtils.createTransformWriterIfNeeded(writer, os, outElementsMap, - outDropElements, + dropAtXmlLevel ? outDropElements : null, outAppendMap, attributesToElements, null); Modified: cxf/branches/2.6.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java?rev=1497264&r1=1497263&r2=1497264&view=diff ============================================================================== --- cxf/branches/2.6.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java (original) +++ cxf/branches/2.6.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java Thu Jun 27 09:40:06 2013 @@ -548,7 +548,7 @@ public class JAXBElementProvider<T> exte if (writer == null && os == null) { writer = getStreamHandlerFromCurrentMessage(XMLStreamWriter.class); } - return createTransformWriterIfNeeded(writer, os); + return createTransformWriterIfNeeded(writer, os, true); } protected void marshalToOutputStream(Marshaller ms, Object obj, OutputStream os, MediaType mt) Modified: cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java?rev=1497264&r1=1497263&r2=1497264&view=diff ============================================================================== --- cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java (original) +++ cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java Thu Jun 27 09:40:06 2013 @@ -32,6 +32,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.List; @@ -58,6 +59,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; @@ -98,6 +100,7 @@ public class JSONProvider<T> extends Abs private String wrapperName; private Map<String, String> wrapperMap; private boolean dropRootElement; + private boolean dropElementsInXmlStream = true; private boolean dropCollectionWrapperElement; private boolean ignoreMixedContent; private boolean writeXsiType = true; @@ -106,6 +109,8 @@ public class JSONProvider<T> extends Abs private String convention = MAPPED_CONVENTION; private TypeConverter typeConverter; private boolean attributesToElements; + private boolean writeNullAsString = true; + private boolean readNullAsEmptyString = true; @Override public void setAttributesToElements(boolean value) { @@ -270,8 +275,12 @@ public class JSONProvider<T> extends Abs if (BADGER_FISH_CONVENTION.equals(convention)) { reader = JSONUtils.createBadgerFishReader(is); } else { - reader = JSONUtils.createStreamReader(is, readXsiType, namespaceMap, - primitiveArrayKeys, getDepthProperties()); + reader = JSONUtils.createStreamReader(is, + readXsiType, + namespaceMap, + primitiveArrayKeys, + readNullAsEmptyString, + getDepthProperties()); } reader = createTransformReaderIfNeeded(reader, is); @@ -490,26 +499,40 @@ public class JSONProvider<T> extends Abs protected XMLStreamWriter createWriter(Object actualObject, Class<?> actualClass, Type genericType, String enc, OutputStream os, boolean isCollection) throws Exception { - QName qname = getQName(actualClass, genericType, actualObject); - if (qname != null && ignoreNamespaces && (isCollection || dropRootElement)) { - qname = new QName(qname.getLocalPart()); - } if (BADGER_FISH_CONVENTION.equals(convention)) { return JSONUtils.createBadgerFishWriter(os); } + + boolean dropRootNeeded = isDropRootNeeded(); + QName qname = getQName(actualClass, genericType, actualObject); + if (qname != null && ignoreNamespaces && (isCollection || dropRootNeeded)) { + qname = new QName(qname.getLocalPart()); + } + Configuration config = JSONUtils.createConfiguration(namespaceMap, writeXsiType && !ignoreNamespaces, attributesToElements, typeConverter); - + if (!dropElementsInXmlStream && super.outDropElements != null) { + config.setIgnoredElements(outDropElements); + } + config.setWriteNullAsString(writeNullAsString); + config.setDropRootElement(dropRootElement && !dropElementsInXmlStream); + if (ignoreNamespaces && serializeAsArray && arrayKeys == null) { + arrayKeys = CastUtils.cast((List<?>)Collections.singletonList(qname.getLocalPart())); + } XMLStreamWriter writer = JSONUtils.createStreamWriter(os, qname, writeXsiType && !ignoreNamespaces, config, serializeAsArray, arrayKeys, - isCollection || dropRootElement); + isCollection || dropRootNeeded); writer = JSONUtils.createIgnoreMixedContentWriterIfNeeded(writer, ignoreMixedContent); writer = JSONUtils.createIgnoreNsWriterIfNeeded(writer, ignoreNamespaces); - return createTransformWriterIfNeeded(writer, os); + return createTransformWriterIfNeeded(writer, os, dropElementsInXmlStream); + } + + protected boolean isDropRootNeeded() { + return dropRootElement && dropElementsInXmlStream; } protected void marshal(Object actualObject, Class<?> actualClass, @@ -554,4 +577,16 @@ public class JSONProvider<T> extends Abs this.primitiveArrayKeys = primitiveArrayKeys; } + public void setDropElementsInXmlStream(boolean drop) { + this.dropElementsInXmlStream = drop; + } + + public void setWriteNullAsString(boolean writeNullAsString) { + this.writeNullAsString = writeNullAsString; + } + + public void setReadNullAsEmptyString(boolean readNullAsString) { + this.readNullAsEmptyString = readNullAsString; + } + } Modified: cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/utils/JSONUtils.java URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/utils/JSONUtils.java?rev=1497264&r1=1497263&r2=1497264&view=diff ============================================================================== --- cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/utils/JSONUtils.java (original) +++ cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/utils/JSONUtils.java Thu Jun 27 09:40:06 2013 @@ -137,12 +137,13 @@ public final class JSONUtils { public static XMLStreamReader createStreamReader(InputStream is, boolean readXsiType, ConcurrentHashMap<String, String> namespaceMap) throws Exception { - return createStreamReader(is, readXsiType, namespaceMap, null, null); + return createStreamReader(is, readXsiType, namespaceMap, null, true, null); } public static XMLStreamReader createStreamReader(InputStream is, boolean readXsiType, ConcurrentHashMap<String, String> namespaceMap, List<String> primitiveArrayKeys, + boolean readNullAsString, DocumentDepthProperties depthProps) throws Exception { if (readXsiType) { namespaceMap.putIfAbsent(XSI_URI, XSI_PREFIX); @@ -152,6 +153,7 @@ public final class JSONUtils { conf.setPrimitiveArrayKeys( new HashSet<String>(primitiveArrayKeys)); } + conf.setReadNullAsEmptyString(readNullAsString); XMLInputFactory factory = depthProps != null ? new JettisonMappedReaderFactory(conf, depthProps) : new MappedXMLInputFactory(conf); Modified: cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/json/JSONProviderTest.java URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/json/JSONProviderTest.java?rev=1497264&r1=1497263&r2=1497264&view=diff ============================================================================== --- cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/json/JSONProviderTest.java (original) +++ cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/json/JSONProviderTest.java Thu Jun 27 09:40:06 2013 @@ -22,6 +22,7 @@ package org.apache.cxf.jaxrs.provider.js import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.io.OutputStream; import java.io.StringReader; import java.lang.annotation.Annotation; import java.lang.reflect.Method; @@ -53,11 +54,13 @@ import javax.xml.bind.annotation.XmlMixe import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.bind.annotation.XmlType; +import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import javax.xml.transform.stream.StreamSource; import org.w3c.dom.Document; +import org.apache.cxf.common.util.StringUtils; import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.helpers.DOMUtils; import org.apache.cxf.jaxrs.impl.MetadataMap; @@ -70,6 +73,7 @@ import org.apache.cxf.jaxrs.resources.Ta import org.apache.cxf.jaxrs.resources.TagVO2; import org.apache.cxf.jaxrs.resources.Tags; import org.apache.cxf.jaxrs.resources.jaxb.Book2; +import org.apache.cxf.staxutils.DelegatingXMLStreamWriter; import org.apache.cxf.staxutils.StaxUtils; import org.junit.Assert; @@ -112,6 +116,18 @@ public class JSONProviderTest extends As } @Test + public void testReadNullStringAsNull() throws Exception { + + String input = "{\"Book\":{\"id\":123,\"name\":\"null\"}}"; + + JSONProvider<Book> provider = new JSONProvider<Book>(); + Book theBook = provider.readFrom(Book.class, null, null, + null, null, new ByteArrayInputStream(input.getBytes())); + assertEquals(123L, theBook.getId()); + assertEquals("", theBook.getName()); + } + + @Test public void testReadEmbeddedArray() throws Exception { String input = "{\"store\":" @@ -194,6 +210,102 @@ public class JSONProviderTest extends As } @Test + public void testWriteCollectionAsPureArray() throws Exception { + JSONProvider<ReportDefinition> provider + = new JSONProvider<ReportDefinition>(); + provider.setSerializeAsArray(true); + provider.setDropRootElement(true); + provider.setDropElementsInXmlStream(false); + ReportDefinition r = new ReportDefinition(); + r.setReportName("report"); + r.addParameterDefinition(new ParameterDefinition("param")); + + Method m = ReportService.class.getMethod("findReport", new Class<?>[]{}); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + provider.writeTo(r, m.getReturnType(), m.getGenericReturnType(), + new Annotation[0], MediaType.APPLICATION_JSON_TYPE, + new MetadataMap<String, Object>(), bos); + assertTrue(bos.toString().startsWith("[{\"parameterList\":")); + } + + @Test + public void testWriteCollectionAsPureArray2() throws Exception { + JSONProvider<ReportDefinition> provider + = new JSONProvider<ReportDefinition>(); + provider.setSerializeAsArray(true); + provider.setOutDropElements(Collections.singletonList("reportDefinition")); + provider.setDropElementsInXmlStream(false); + ReportDefinition r = new ReportDefinition(); + r.setReportName("report"); + r.addParameterDefinition(new ParameterDefinition("param")); + + Method m = ReportService.class.getMethod("findReport", new Class<?>[]{}); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + provider.writeTo(r, m.getReturnType(), m.getGenericReturnType(), + new Annotation[0], MediaType.APPLICATION_JSON_TYPE, + new MetadataMap<String, Object>(), bos); + assertTrue(bos.toString().startsWith("[{\"parameterList\":")); + } + + @Test + public void testWriteBeanNoRootAtJsonLevel() throws Exception { + JSONProvider<Book> provider = new JSONProvider<Book>(); + provider.setDropRootElement(true); + provider.setDropElementsInXmlStream(false); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + provider.writeTo(new Book("cxf", 123), Book.class, Book.class, + new Annotation[0], MediaType.APPLICATION_JSON_TYPE, + new MetadataMap<String, Object>(), bos); + assertTrue(bos.toString().contains("\"name\":\"cxf\"")); + assertTrue(bos.toString().contains("\"id\":123")); + assertFalse(bos.toString().startsWith("{\"Book\":")); + } + + @Test + public void testWriteBeanIgnorePropertyAtJsonLevel() throws Exception { + JSONProvider<Book> provider = new JSONProvider<Book>(); + provider.setOutDropElements(Collections.singletonList("id")); + provider.setDropElementsInXmlStream(false); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + provider.writeTo(new Book("cxf", 123), Book.class, Book.class, + new Annotation[0], MediaType.APPLICATION_JSON_TYPE, + new MetadataMap<String, Object>(), bos); + assertTrue(bos.toString().contains("\"name\":\"cxf\"")); + assertFalse(bos.toString().contains("\"id\":123")); + assertTrue(bos.toString().startsWith("{\"Book\":")); + } + + @Test + public void testWriteNullValueAsString() throws Exception { + doTestWriteNullValue(true); + } + @Test + public void testWriteNullValueAsNull() throws Exception { + doTestWriteNullValue(false); + } + + private void doTestWriteNullValue(boolean nullAsString) throws Exception { + JSONProvider<Book> provider = new JSONProvider<Book>() { + protected XMLStreamWriter createWriter(Object actualObject, Class<?> actualClass, + Type genericType, String enc, OutputStream os, boolean isCollection) throws Exception { + return new NullWriter( + super.createWriter(actualObject, actualClass, genericType, enc, os, isCollection)); + } + }; + provider.setWriteNullAsString(nullAsString); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + provider.writeTo(new Book("cxf", 123), Book.class, Book.class, + new Annotation[0], MediaType.APPLICATION_JSON_TYPE, + new MetadataMap<String, Object>(), bos); + if (nullAsString) { + assertTrue(bos.toString().contains("\"state\":\"null\"")); + } else { + assertTrue(bos.toString().contains("\"state\":null")); + } + } + + @Test public void testWriteCollectionParameterDef() throws Exception { doTestWriteCollectionParameterDef(false); @@ -801,6 +913,21 @@ public class JSONProviderTest extends As } @Test + public void testWriteArrayAndNamespaceOnObject() throws Exception { + JSONProvider<TagVO2> p = new JSONProvider<TagVO2>(); + p.setIgnoreNamespaces(true); + p.setSerializeAsArray(true); + TagVO2 tag = new TagVO2("a", "b"); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + + p.writeTo(tag, TagVO2.class, TagVO2.class, TagVO2.class.getAnnotations(), + MediaType.APPLICATION_JSON_TYPE, new MetadataMap<String, Object>(), os); + + String s = os.toString(); + assertEquals("{\"thetag\":[{\"group\":\"b\",\"name\":\"a\"}]}", s); + } + + @Test public void testWriteUsingNaturalNotation() throws Exception { JSONProvider<Post> p = new JSONProvider<Post>(); p.setSerializeAsArray(true); @@ -1408,6 +1535,7 @@ public class JSONProviderTest extends As interface ReportService { List<ReportDefinition> findAllReports(); + ReportDefinition findReport(); } @@ -1465,4 +1593,18 @@ public class JSONProviderTest extends As parameterList.add(parameterDefinition); } } + + private static class NullWriter extends DelegatingXMLStreamWriter { + public NullWriter(XMLStreamWriter writer) { + super(writer); + } + + public void writeCharacters(String text) throws XMLStreamException { + if (StringUtils.isEmpty(text.trim())) { + super.writeCharacters(null); + } else { + super.writeCharacters(text); + } + } + } } Modified: cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/resources/Book.java URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/resources/Book.java?rev=1497264&r1=1497263&r2=1497264&view=diff ============================================================================== --- cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/resources/Book.java (original) +++ cxf/branches/2.6.x-fixes/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/resources/Book.java Thu Jun 27 09:40:06 2013 @@ -20,6 +20,7 @@ package org.apache.cxf.jaxrs.resources; import javax.ws.rs.GET; +import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlSeeAlso; @@ -27,6 +28,7 @@ import javax.xml.bind.annotation.XmlSeeA @XmlRootElement(name = "Book") @XmlSeeAlso({SuperBook.class }) public class Book implements Comparable<Book> { + private String name; private long id; @@ -38,6 +40,7 @@ public class Book implements Comparable< this.id = id; } + @XmlElement(nillable = true) public void setName(String n) { name = n; }
