/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * http://glassfish.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package org.glassfish.jersey.tests.e2e.entity; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.Set; import java.util.Stack; import java.util.TreeSet; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Application; import javax.ws.rs.core.GenericEntity; import javax.ws.rs.core.GenericType; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.ext.ContextResolver; import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.moxy.json.MoxyJsonConfig; import org.glassfish.jersey.moxy.json.MoxyJsonFeature; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.TestProperties; import org.glassfish.jersey.test.util.runner.ConcurrentRunner; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import static org.junit.Assert.assertEquals; /** * @author Pavel Bucek (pavel.bucek at oracle.com) */ @RunWith(ConcurrentRunner.class) public class JsonMoxyTest extends AbstractTypeTester { @Path("JAXBElementListResource") @Produces({"application/json"}) @Consumes({"application/json"}) public static class JAXBElementListResource extends AResource<List<JAXBElement<String>>> { } private List<JAXBElement<String>> getJAXBElementList() { return Arrays.asList(getJAXBElementArray()); } public static final class MoxyJsonConfigurationContextResolver implements ContextResolver<MoxyJsonConfig> { @Override public MoxyJsonConfig getContext(final Class<?> type) { final MoxyJsonConfig configuration = new MoxyJsonConfig(); configuration.setIncludeRoot(true); return configuration; } } @SuppressWarnings("unchecked") public void _testListOrArray(final boolean isList, final MediaType mt) { final Object in = isList ? getJAXBElementList() : getJAXBElementArray(); final GenericType gt = isList ? new GenericType<List<JAXBElement<String>>>() { } : new GenericType<JAXBElement<String>[]>() { }; final WebTarget target = target(isList ? "JAXBElementListResource" : "JAXBElementArrayResource"); final Object out = target.request(mt).post(Entity.entity(new GenericEntity(in, gt.getType()), mt), gt); final List<JAXBElement<String>> inList = isList ? ((List<JAXBElement<String>>) in) : Arrays.asList((JAXBElement<String>[]) in); final List<JAXBElement<String>> outList = isList ? ((List<JAXBElement<String>>) out) : Arrays .asList((JAXBElement<String>[]) out); assertEquals("Lengths differ", inList.size(), outList.size()); for (int i = 0; i < inList.size(); i++) { assertEquals("Names of elements at index " + i + " differ", inList.get(i).getName(), outList.get(i).getName()); assertEquals("Values of elements at index " + i + " differ", inList.get(i).getValue(), outList.get(i).getValue()); } } @Test public void testJAXBElementListJSONRepresentation() { _testListOrArray(true, MediaType.APPLICATION_JSON_TYPE); } @Path("JAXBElementArrayResource") @Produces({"application/json"}) @Consumes({"application/json"}) public static class JAXBElementArrayResource extends AResource<JAXBElement<String>[]> { } @SuppressWarnings("unchecked") private JAXBElement<String>[] getJAXBElementArray() { return new JAXBElement[] { new JAXBElement(QName.valueOf("element1"), String.class, "ahoj"), new JAXBElement(QName.valueOf("element2"), String.class, "nazdar") }; } @Test public void testJAXBElementArrayJSONRepresentation() { _testListOrArray(false, MediaType.APPLICATION_JSON_TYPE); } @Override protected Application configure() { enable(TestProperties.LOG_TRAFFIC); enable(TestProperties.DUMP_ENTITY); return ((ResourceConfig) super.configure()) .register(MoxyJsonFeature.class) .register(MoxyJsonConfigurationContextResolver.class); } @Override protected void configureClient(final ClientConfig config) { super.configureClient(config); config.register(MoxyJsonFeature.class); config.register(MoxyJsonConfigurationContextResolver.class); } @Path("JAXBElementBeanJSONResource") @Consumes("application/json") @Produces("application/json") public static class JAXBElementBeanJSONResource extends AResource<JAXBElement<String>> { } @Test public void testJAXBElementBeanJSONRepresentation() { final WebTarget target = target("JAXBElementBeanJSONResource"); final GenericType<JAXBElement<String>> genericType = new GenericType<JAXBElement<String>>() { }; final GenericEntity<JAXBElement<String>> jaxbElementGenericEntity = new GenericEntity<>( new JAXBElement<>(new QName("test"), String.class, "CONTENT"), genericType.getType()); final Response rib = target.request().post( Entity.entity(jaxbElementGenericEntity, "application/json")); // TODO: the following would not be needed if i knew how to workaround JAXBElement<String>.class literal final byte[] inBytes = getRequestEntity(); final byte[] outBytes = getEntityAsByteArray(rib); assertEquals(new String(outBytes), inBytes.length, outBytes.length); for (int i = 0; i < inBytes.length; i++) { if (inBytes[i] != outBytes[i]) { assertEquals("Index: " + i, inBytes[i], outBytes[i]); } } } @Path("JaxbBeanResourceJSON") @Produces("application/json") @Consumes("application/json") public static class JaxbBeanResourceJSON extends AResource<JaxbBean> { } @Test public void testJaxbBeanRepresentationJSON() { final WebTarget target = target("JaxbBeanResourceJSON"); final JaxbBean in = new JaxbBean("CONTENT"); final JaxbBean out = target.request().post(Entity.entity(in, "application/json"), JaxbBean.class); assertEquals(in.value, out.value); } @Path("JaxbBeanResourceJSONMediaType") @Produces("application/foo+json") @Consumes("application/foo+json") public static class JaxbBeanResourceJSONMediaType extends AResource<JaxbBean> { } @Test public void testJaxbBeanRepresentationJSONMediaType() { final WebTarget target = target("JaxbBeanResourceJSONMediaType"); final JaxbBean in = new JaxbBean("CONTENT"); final JaxbBean out = target.request().post(Entity.entity(in, "application/foo+json"), JaxbBean.class); assertEquals(in.value, out.value); } @Path("JAXBElementBeanResourceJSON") @Produces("application/json") @Consumes("application/json") public static class JAXBElementBeanResourceJSON extends AResource<JAXBElement<JaxbBeanType>> { } @Test public void testJAXBElementBeanRepresentationJSON() { final WebTarget target = target("JAXBElementBeanResourceJSON"); final JaxbBean in = new JaxbBean("CONTENT"); final JaxbBean out = target.request().post(Entity.entity(in, "application/json"), JaxbBean.class); assertEquals(in.value, out.value); } @Path("JAXBElementBeanResourceJSONMediaType") @Produces("application/foo+json") @Consumes("application/foo+json") public static class JAXBElementBeanResourceJSONMediaType extends AResource<JAXBElement<JaxbBeanType>> { } @Test public void testJAXBElementBeanRepresentationJSONMediaType() { final WebTarget target = target("JAXBElementBeanResourceJSONMediaType"); final JaxbBean in = new JaxbBean("CONTENT"); final JaxbBean out = target.request().post(Entity.entity(in, "application/foo+json"), JaxbBean.class); assertEquals(in.value, out.value); } @Path("JAXBTypeResourceJSON") @Produces("application/json") @Consumes("application/json") public static class JAXBTypeResourceJSON { @POST public JaxbBean post(final JaxbBeanType t) { return new JaxbBean(t.value); } } @Test public void testJAXBTypeRepresentationJSON() { final WebTarget target = target("JAXBTypeResourceJSON"); final JaxbBean in = new JaxbBean("CONTENT"); final JaxbBeanType out = target.request().post(Entity.entity(in, "application/json"), JaxbBeanType.class); assertEquals(in.value, out.value); } @Path("JAXBTypeResourceJSONMediaType") @Produces("application/foo+json") @Consumes("application/foo+json") public static class JAXBTypeResourceJSONMediaType { @POST public JaxbBean post(final JaxbBeanType t) { return new JaxbBean(t.value); } } @Test public void testJAXBTypeRepresentationJSONMediaType() { final WebTarget target = target("JAXBTypeResourceJSONMediaType"); final JaxbBean in = new JaxbBean("CONTENT"); final JaxbBeanType out = target.request().post(Entity.entity(in, "application/foo+json"), JaxbBeanType.class); assertEquals(in.value, out.value); } @Path("JAXBListResource") @Produces("application/xml") @Consumes("application/xml") public static class JAXBListResource { @POST public List<JaxbBean> post(final List<JaxbBean> l) { return l; } @POST @Path("set") public Set<JaxbBean> postSet(final Set<JaxbBean> l) { return l; } @POST @Path("queue") public Queue<JaxbBean> postQueue(final Queue<JaxbBean> l) { return l; } @POST @Path("stack") public Stack<JaxbBean> postStack(final Stack<JaxbBean> l) { return l; } @POST @Path("custom") public MyArrayList<JaxbBean> postCustom(final MyArrayList<JaxbBean> l) { return l; } @GET public Collection<JaxbBean> get() { final ArrayList<JaxbBean> l = new ArrayList<>(); l.add(new JaxbBean("one")); l.add(new JaxbBean("two")); l.add(new JaxbBean("three")); return l; } @POST @Path("type") public List<JaxbBean> postType(final Collection<JaxbBeanType> l) { final List<JaxbBean> beans = new ArrayList<>(); for (final JaxbBeanType t : l) { beans.add(new JaxbBean(t.value)); } return beans; } } @Path("JAXBListResourceMediaType") @Produces("application/foo+xml") @Consumes("application/foo+xml") public static class JAXBListResourceMediaType extends JAXBListResource { } @Path("JAXBListResourceJSON") @Produces("application/json") @Consumes("application/json") public static class JAXBListResourceJSON extends JAXBListResource { } @Test public void testJAXBListRepresentationJSONCollection() throws Exception { final WebTarget target = target("JAXBListResourceJSON"); final Collection<JaxbBean> a = target.request().get( new GenericType<Collection<JaxbBean>>() { }); Collection<JaxbBean> b = target.request().post(Entity.entity(new GenericEntity<Collection<JaxbBean>>(a) { }, "application/json"), new GenericType<Collection<JaxbBean>>() { }); assertEquals(a, b); b = target.path("type").request().post(Entity.entity(new GenericEntity<Collection<JaxbBean>>(a) { }, "application/json"), new GenericType<Collection<JaxbBean>>() { }); assertEquals(a, b); } @Test public void testJAXBListRepresentationJSONLinkedList() throws Exception { final WebTarget target = target("JAXBListResourceJSON"); Collection<JaxbBean> a = target.request().get( new GenericType<Collection<JaxbBean>>() { }); final Collection<JaxbBean> b; a = new LinkedList<>(a); b = target.path("queue").request().post(Entity.entity(new GenericEntity<Queue<JaxbBean>>((Queue<JaxbBean>) a) { }, "application/json"), new GenericType<Queue<JaxbBean>>() { }); assertEquals(a, b); } @Test public void testJAXBListRepresentationJSONSet() throws Exception { final WebTarget target = target("JAXBListResourceJSON"); Collection<JaxbBean> a = target.request().get( new GenericType<Collection<JaxbBean>>() { }); final Collection<JaxbBean> b; a = new HashSet<>(a); b = target.path("set").request().post(Entity.entity(new GenericEntity<Set<JaxbBean>>((Set<JaxbBean>) a) { }, "application/json"), new GenericType<Set<JaxbBean>>() { }); final Comparator<JaxbBean> c = new Comparator<JaxbBean>() { @Override public int compare(final JaxbBean t, final JaxbBean t1) { return t.value.compareTo(t1.value); } }; final TreeSet<JaxbBean> t1 = new TreeSet<>(c); final TreeSet<JaxbBean> t2 = new TreeSet<>(c); t1.addAll(a); t2.addAll(b); assertEquals(t1, t2); } @Test public void testJAXBListRepresentationJSONStack() throws Exception { final WebTarget target = target("JAXBListResourceJSON"); final Collection<JaxbBean> a = target.request().get( new GenericType<Collection<JaxbBean>>() { }); final Collection<JaxbBean> b; final Stack<JaxbBean> s = new Stack<>(); s.addAll(a); b = target.path("stack").request().post(Entity.entity(new GenericEntity<Stack<JaxbBean>>(s) { }, "application/json"), new GenericType<Stack<JaxbBean>>() { }); assertEquals(s, b); } @Test @Ignore("Until JERSEY-2825 is fixed.") public void testJAXBListRepresentationJSONArrayList() throws Exception { final WebTarget target = target("JAXBListResourceJSON"); Collection<JaxbBean> a = target.request().get(new GenericType<Collection<JaxbBean>>() {}); final Collection<JaxbBean> b; a = new MyArrayList<>(a); b = target.path("custom").request() .post(Entity.entity(new GenericEntity<MyArrayList<JaxbBean>>((MyArrayList<JaxbBean>) a) {}, "application/json"), new GenericType<MyArrayList<JaxbBean>>() {}); assertEquals(a, b); } @Path("JAXBListResourceJSONMediaType") @Produces("application/foo+json") @Consumes("application/foo+json") public static class JAXBListResourceJSONMediaType extends JAXBListResource { } @Test public void testJAXBListRepresentationJSONMediaType() throws Exception { final WebTarget target = target("JAXBListResourceJSONMediaType"); final Collection<JaxbBean> a = target.request().get( new GenericType<Collection<JaxbBean>>() { }); Collection<JaxbBean> b = target.request().post(Entity.entity(new GenericEntity<Collection<JaxbBean>>(a) { }, "application/foo+json"), new GenericType<Collection<JaxbBean>>() { }); assertEquals(a, b); b = target.path("type").request().post(Entity.entity(new GenericEntity<Collection<JaxbBean>>(a) { }, "application/foo+json"), new GenericType<Collection<JaxbBean>>() { }); assertEquals(a, b); } }