diff --git a/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java b/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java index 29d45f00c5..5e61ed6965 100644 --- a/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java +++ b/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java @@ -35,7 +35,11 @@ package sonia.scm.net.ahc; import com.google.common.io.ByteSource; +import org.codehaus.jackson.map.AnnotationIntrospector; +import org.codehaus.jackson.map.DeserializationConfig; import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector; +import org.codehaus.jackson.xc.JaxbAnnotationIntrospector; import sonia.scm.plugin.ext.Extension; import sonia.scm.util.IOUtil; @@ -47,9 +51,6 @@ import java.io.IOException; import java.io.InputStream; import javax.ws.rs.core.MediaType; -import org.codehaus.jackson.map.AnnotationIntrospector; -import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector; -import org.codehaus.jackson.xc.JaxbAnnotationIntrospector; /** * {@link ContentTransformer} for json. The {@link JsonContentTransformer} uses @@ -62,18 +63,26 @@ import org.codehaus.jackson.xc.JaxbAnnotationIntrospector; public class JsonContentTransformer implements ContentTransformer { + /** + * Constructs a new {@link JsonContentTransformer}. + * + */ public JsonContentTransformer() { this.mapper = new ObjectMapper(); + + // allow jackson and jaxb annotations AnnotationIntrospector jackson = new JacksonAnnotationIntrospector(); AnnotationIntrospector jaxb = new JaxbAnnotationIntrospector(); - AnnotationIntrospector pair = new AnnotationIntrospector.Pair(jackson, jaxb); - this.mapper.setAnnotationIntrospector(pair); + + this.mapper.setAnnotationIntrospector(new AnnotationIntrospector.Pair(jackson, jaxb)); + + // do not fail on unknown json properties + this.mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); } - - - + //~--- methods -------------------------------------------------------------- + /** * {@inheritDoc} */ @@ -138,8 +147,7 @@ public class JsonContentTransformer implements ContentTransformer @Override public boolean isResponsible(Class type, String contentType) { - return MediaType.valueOf(contentType).isCompatible( - MediaType.APPLICATION_JSON_TYPE); + return MediaType.valueOf(contentType).isCompatible(MediaType.APPLICATION_JSON_TYPE); } //~--- fields --------------------------------------------------------------- diff --git a/scm-webapp/src/test/java/sonia/scm/net/ahc/JsonContentTransformerTest.java b/scm-webapp/src/test/java/sonia/scm/net/ahc/JsonContentTransformerTest.java index 1828c5ccf2..1a11390993 100644 --- a/scm-webapp/src/test/java/sonia/scm/net/ahc/JsonContentTransformerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/net/ahc/JsonContentTransformerTest.java @@ -1,10 +1,10 @@ /** * Copyright (c) 2014, Sebastian Sdorra * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, @@ -13,7 +13,7 @@ * 3. Neither the name of SCM-Manager; nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -24,31 +24,57 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * http://bitbucket.org/sdorra/scm-manager - * + * */ + + package sonia.scm.net.ahc; +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Charsets; import com.google.common.io.ByteSource; +import com.google.common.io.CharSource; + +import org.junit.Test; + +import static org.junit.Assert.*; + +import static org.mockito.Mockito.*; + +//~--- JDK imports ------------------------------------------------------------ + import java.io.IOException; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; -import org.junit.Test; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; /** * * @author Sebastian Sdorra */ -public class JsonContentTransformerTest { +public class JsonContentTransformerTest +{ + /** + * Method description + * + */ + @Test + public void testDoNotFailOnUnknownProperties() { + ByteSource bs = ByteSource.wrap("{\"value\": \"test\", \"other\": \"test2\"}".getBytes(Charsets.UTF_8)); + TestObject obj = transformer.unmarshall(TestObject.class, bs); + assertEquals("test", obj.value); + } - private final JsonContentTransformer transformer = new JsonContentTransformer(); - + /** + * Method description + * + */ @Test public void testIsResponsible() { @@ -56,37 +82,87 @@ public class JsonContentTransformerTest { assertTrue(transformer.isResponsible(String.class, "application/json;charset=UTF-8")); assertFalse(transformer.isResponsible(String.class, "text/plain")); } - + + /** + * Method description + * + * + * @throws IOException + */ @Test - public void testMarshallAndUnmarshall() throws IOException{ + public void testMarshallAndUnmarshall() throws IOException + { ByteSource bs = transformer.marshall(new TestObject("test")); TestObject to = transformer.unmarshall(TestObject.class, bs); + assertEquals("test", to.value); } - + + /** + * Method description + * + * + * @throws IOException + */ @Test(expected = ContentTransformerException.class) - public void testUnmarshallIOException() throws IOException{ + public void testUnmarshallIOException() throws IOException + { ByteSource bs = mock(ByteSource.class); + when(bs.openBufferedStream()).thenThrow(IOException.class); transformer.unmarshall(String.class, bs); } - - private static class TestObject2 {} - + + //~--- inner classes -------------------------------------------------------- + + /** + * Class description + * + * + * @version Enter version here..., 15/10/21 + * @author Enter your name here... + */ @XmlRootElement(name = "test") @XmlAccessorType(XmlAccessType.FIELD) - private static class TestObject { - - private String value; + private static class TestObject + { - public TestObject() - { - } - + /** + * Constructs ... + * + */ + public TestObject() {} + + /** + * Constructs ... + * + * + * @param value + */ public TestObject(String value) { this.value = value; } - + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private String value; } -} \ No newline at end of file + + + /** + * Class description + * + * + * @version Enter version here..., 15/10/21 + * @author Enter your name here... + */ + private static class TestObject2 {} + + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private final JsonContentTransformer transformer = new JsonContentTransformer(); +}