/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*******************************************************************************/
package org.apache.wink.server.internal.providers.entity;
import java.io.StringReader;
import java.util.Collections;
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.core.MediaType;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
import javax.xml.namespace.QName;
import org.apache.wink.common.annotations.Asset;
import org.apache.wink.common.model.json.JSONUtils;
import org.apache.wink.common.model.synd.SyndEntry;
import org.apache.wink.common.model.synd.SyndFeed;
import org.apache.wink.common.model.synd.SyndText;
import org.apache.wink.server.internal.servlet.MockServletInvocationTest;
import org.apache.wink.test.mock.MockRequestConstructor;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
public class JsonProviderTest extends MockServletInvocationTest {
@Override
protected Class<?>[] getClasses() {
return new Class<?>[] {TestResource.class};
}
private static final SyndFeed SYND_FEED = new SyndFeed(new SyndText("title"), "id");
private static final SyndEntry SYND_ENTRY =
new SyndEntry(
new SyndText("entry title"),
"entry:id");
private static final String JSON_FEED =
"{\"feed\": {\n" + " \"@xmlns\": {\"$\": \"http:\\/\\/www.w3.org\\/2005\\/Atom\"},\n"
+ " \"id\": {\n"
+ " \"@xmlns\": {\"$\": \"http:\\/\\/www.w3.org\\/2005\\/Atom\"},\n"
+ " \"$\": \"id\"\n"
+ " },\n"
+ " \"title\": {\n"
+ " \"@type\": \"text\",\n"
+ " \"@xmlns\": {\"$\": \"http:\\/\\/www.w3.org\\/2005\\/Atom\"},\n"
+ " \"$\": \"title\"\n"
+ " }\n"
+ "}}";
private static final String JSON =
"{\"entry\": {\n" + " \"id\": {\"$\": \"entry:id\"},\n"
+ " \"title\": {\n"
+ " \"@type\": \"text\",\n"
+ " \"$\": \"entry title\"\n"
+ " }\n"
+ "}}";
private static final String JSON_ARRAY = "[" + JSON + ", {\"test\":\"ing\"}]";
private static final String JSON_AS_ATOM_ENTRY =
"{\"entry\": {\n" + " \"@xmlns\": {\"$\": \"http:\\/\\/www.w3.org\\/2005\\/Atom\"},\n"
+ " \"id\": {\n"
+ " \"@xmlns\": {\"$\": \"http:\\/\\/www.w3.org\\/2005\\/Atom\"},\n"
+ " \"$\": \"entry:id\"\n"
+ " },\n"
+ " \"title\": {\n"
+ " \"@type\": \"text\",\n"
+ " \"@xmlns\": {\"$\": \"http:\\/\\/www.w3.org\\/2005\\/Atom\"},\n"
+ " \"$\": \"entry title\"\n"
+ " }\n"
+ "}}";
private void compairJsonContent(final String expected, final String actual)
throws JSONException {
JSONObject result = JSONUtils.objectForString(actual);
JSONObject want = JSONUtils.objectForString(expected);
assertTrue(JSONUtils.equals(want, result));
}
@Path("test")
public static class TestResource {
@GET
@Path("json")
@Produces("application/json")
public JSONObject getJson() throws Exception {
return new JSONObject(JSON);
}
@POST
@Path("json")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public JSONObject postJson(JSONObject object) throws Exception {
return object.put("foo", "bar");
}
@GET
@Path("jsonarray")
@Produces(MediaType.APPLICATION_JSON)
public JSONArray getJsonArray() throws Exception {
return new JSONArray(JSON_ARRAY);
}
@POST
@Path("jsonarray")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public JSONArray postJson(JSONArray array) throws Exception {
return array.put(Collections.singletonMap("foo", "bar"));
}
@GET
@Path("jsonfeed")
@Produces("application/json")
public SyndFeed getJsonFeed() throws Exception {
return SYND_FEED;
}
@GET
@Path("jaxb")
@Produces("application/json")
public Entry getJAXB() throws Exception {
Entry entry = TestJAXBAsset.getJAXBEntry();
return entry;
}
@GET
@Path("jaxbelement")
@Produces("application/json")
public JAXBElement<Entry> getJAXBElement() throws Exception {
Entry entry = TestJAXBAsset.getJAXBEntry();
return new JAXBElement<Entry>(new QName("entry"), Entry.class, entry);
}
@GET
@Path("atom")
@Produces("application/json")
public SyndEntry getAtom() throws Exception {
return SYND_ENTRY;
}
@GET
@Path("jsonasset")
@Produces("application/json")
public TestJsonAsset getJsonAsset() throws Exception {
return new TestJsonAsset();
}
@GET
@Path("atomasset")
@Produces("application/json")
public TestOtherMediaTypeAsset getAtomAsset() throws Exception {
return new TestOtherMediaTypeAsset();
}
@GET
@Path("jaxbasset")
@Produces("application/json")
public TestJAXBAsset getJAXBAsset() throws Exception {
return new TestJAXBAsset();
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Entry", propOrder = {"id", "title"})
@XmlRootElement(name = "entry")
public static class Entry {
@XmlElement(name = "id")
public String id;
@XmlElementRef
public Title title;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Title", propOrder = {"type"})
@XmlRootElement(name = "title")
public static class Title {
@XmlAttribute(name = "type")
public String type;
@XmlValue
public String value;
}
@Asset
public static class TestJsonAsset {
@Produces(MediaType.APPLICATION_JSON)
public JSONObject getJSONObject() {
try {
return new JSONObject(JSON);
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
}
@Asset
public static class TestOtherMediaTypeAsset {
public MediaType getJsonXmlMediaType() {
return MediaType.APPLICATION_XML_TYPE;
}
@Produces(MediaType.APPLICATION_JSON)
public Entry getJAXB() {
return TestJAXBAsset.getJAXBEntry();
}
@Consumes(MediaType.APPLICATION_JSON)
public void setJAXB(Entry jaxbObject) {
fail("json does not support read");
}
}
@Asset
public static class TestJAXBAsset {
public static Entry getJAXBEntry() {
Title title = new Title();
title.type = "text";
title.value = "entry title";
Entry entry = new Entry();
entry.id = "entry:id";
entry.title = title;
return entry;
}
@Produces(MediaType.APPLICATION_JSON)
public Entry getJAXB() {
return getJAXBEntry();
}
@Consumes(MediaType.APPLICATION_JSON)
public void setJAXB(Entry entry) {
fail("setJAXB shouldn't be called for Json");
}
}
public void testGetJson() throws Exception {
MockHttpServletRequest request =
MockRequestConstructor.constructMockRequest("GET", "/test/json", "application/json");
MockHttpServletResponse response = invoke(request);
assertEquals(200, response.getStatus());
compairJsonContent(JSON, response.getContentAsString());
}
public void testPostJson() throws Exception {
MockHttpServletRequest request =
MockRequestConstructor.constructMockRequest("POST",
"/test/json",
"application/json",
MediaType.APPLICATION_JSON,
JSON.getBytes());
MockHttpServletResponse response = invoke(request);
assertEquals(200, response.getStatus());
JSONObject result = JSONUtils.objectForString(response.getContentAsString());
JSONObject want = JSONUtils.objectForString(JSON).put("foo", "bar");
assertTrue(JSONUtils.equals(want, result));
}
public void testGetJsonArray() throws Exception {
MockHttpServletRequest request =
MockRequestConstructor.constructMockRequest("GET",
"/test/jsonarray",
"application/json");
MockHttpServletResponse response = invoke(request);
assertEquals(200, response.getStatus());
JSONArray result =
new JSONArray(new JSONTokener(new StringReader(response.getContentAsString())));
JSONArray want = new JSONArray(JSON_ARRAY);
assertTrue(JSONUtils.equals(want, result));
}
public void testPostJsonArray() throws Exception {
MockHttpServletRequest request =
MockRequestConstructor.constructMockRequest("POST",
"/test/jsonarray",
"application/json",
MediaType.APPLICATION_JSON,
JSON_ARRAY.getBytes());
MockHttpServletResponse response = invoke(request);
assertEquals(200, response.getStatus());
JSONArray result =
new JSONArray(new JSONTokener(new StringReader(response.getContentAsString())));
JSONArray want = new JSONArray(JSON_ARRAY).put(Collections.singletonMap("foo", "bar"));
assertTrue(JSONUtils.equals(want, result));
}
public void testGetJsonFeed() throws Exception {
MockHttpServletRequest request =
MockRequestConstructor
.constructMockRequest("GET", "/test/jsonfeed", "application/json");
MockHttpServletResponse response = invoke(request);
assertEquals(200, response.getStatus());
compairJsonContent(JSON_FEED, response.getContentAsString());
}
public void testGetJsonFromJAXB() throws Exception {
MockHttpServletRequest request =
MockRequestConstructor.constructMockRequest("GET", "/test/jaxb", "application/json");
MockHttpServletResponse response = invoke(request);
assertEquals(200, response.getStatus());
compairJsonContent(JSON, response.getContentAsString());
}
public void testGetJsonFromJAXBElement() throws Exception {
MockHttpServletRequest request =
MockRequestConstructor.constructMockRequest("GET",
"/test/jaxbelement",
"application/json");
MockHttpServletResponse response = invoke(request);
assertEquals(200, response.getStatus());
compairJsonContent(JSON, response.getContentAsString());
}
public void testGetJsonFromAtom() throws Exception {
MockHttpServletRequest request =
MockRequestConstructor.constructMockRequest("GET", "/test/atom", "application/json");
MockHttpServletResponse response = invoke(request);
assertEquals(200, response.getStatus());
compairJsonContent(JSON_AS_ATOM_ENTRY, response.getContentAsString());
}
public void testGetJsonAsset() throws Exception {
MockHttpServletRequest request =
MockRequestConstructor.constructMockRequest("GET",
"/test/jsonasset",
"application/json");
MockHttpServletResponse response = invoke(request);
assertEquals(200, response.getStatus());
compairJsonContent(JSON, response.getContentAsString());
}
public void testGetJAXBAsset() throws Exception {
MockHttpServletRequest request =
MockRequestConstructor.constructMockRequest("GET",
"/test/jaxbasset",
"application/json");
MockHttpServletResponse response = invoke(request);
assertEquals(200, response.getStatus());
compairJsonContent(JSON, response.getContentAsString());
}
public void testGetAtomAsset() throws Exception {
MockHttpServletRequest request =
MockRequestConstructor.constructMockRequest("GET",
"/test/atomasset",
"application/json");
MockHttpServletResponse response = invoke(request);
assertEquals(200, response.getStatus());
compairJsonContent(JSON, response.getContentAsString());
}
}