/**
* 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.cxf.jaxrs.impl;
import java.io.ByteArrayInputStream;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Link;
import javax.ws.rs.core.Link.Builder;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.Response.StatusType;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.Variant;
import javax.ws.rs.core.Variant.VariantListBuilder;
import javax.ws.rs.ext.RuntimeDelegate;
import javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import org.w3c.dom.Document;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.jaxrs.provider.ProviderFactory;
import org.apache.cxf.jaxrs.provider.ServerProviderFactory;
import org.apache.cxf.jaxrs.resources.Book;
import org.apache.cxf.jaxrs.utils.HttpUtils;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.ExchangeImpl;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageImpl;
import org.apache.cxf.staxutils.StaxUtils;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Test;
public class ResponseImplTest extends Assert {
@Test
public void testReadEntityWithNullOutMessage() {
final String str = "ouch";
Response response = Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(str)
.build();
Assert.assertEquals(str, response.readEntity(String.class));
}
@Test
public void testReadBufferedStaxUtils() throws Exception {
ResponseImpl r = new ResponseImpl(200);
Source responseSource = readResponseSource(r);
Document doc = StaxUtils.read(responseSource);
assertEquals("Response", doc.getDocumentElement().getLocalName());
}
@Test
public void testReadBufferedStaxSource() throws Exception {
ResponseImpl r = new ResponseImpl(200);
Source responseSource = readResponseSource(r);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
Transformer transformer = transformerFactory.newTransformer();
DOMResult res = new DOMResult();
transformer.transform(responseSource, res);
Document doc = (Document)res.getNode();
assertEquals("Response", doc.getDocumentElement().getLocalName());
}
private Source readResponseSource(ResponseImpl r) {
String content = "<Response "
+ " xmlns=\"urn:oasis:names:tc:xacml:2.0:context:schema:os\""
+ " xmlns:ns2=\"urn:oasis:names:tc:xacml:2.0:policy:schema:os\">"
+ "<Result><Decision>Permit</Decision><Status><StatusCode"
+ " Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status></Result></Response>";
MultivaluedMap<String, Object> headers = new MetadataMap<String, Object>();
headers.putSingle("Content-Type", "text/xml");
r.addMetadata(headers);
r.setEntity(new ByteArrayInputStream(content.getBytes()), null);
r.setOutMessage(createMessage());
r.bufferEntity();
return r.readEntity(Source.class);
}
private Message createMessage() {
ProviderFactory factory = ServerProviderFactory.getInstance();
Message m = new MessageImpl();
m.put("org.apache.cxf.http.case_insensitive_queries", false);
Exchange e = new ExchangeImpl();
m.setExchange(e);
e.setInMessage(m);
e.setOutMessage(new MessageImpl());
Endpoint endpoint = EasyMock.createMock(Endpoint.class);
endpoint.getEndpointInfo();
EasyMock.expectLastCall().andReturn(null).anyTimes();
endpoint.get(Application.class.getName());
EasyMock.expectLastCall().andReturn(null);
endpoint.size();
EasyMock.expectLastCall().andReturn(0).anyTimes();
endpoint.isEmpty();
EasyMock.expectLastCall().andReturn(true).anyTimes();
endpoint.get(ServerProviderFactory.class.getName());
EasyMock.expectLastCall().andReturn(factory).anyTimes();
EasyMock.replay(endpoint);
e.put(Endpoint.class, endpoint);
return m;
}
@Test
public void testResourceImpl() {
String entity = "bar";
ResponseImpl ri = new ResponseImpl(200, entity);
assertEquals("Wrong status", ri.getStatus(), 200);
assertSame("Wrong entity", entity, ri.getEntity());
MetadataMap<String, Object> meta = new MetadataMap<String, Object>();
ri.addMetadata(meta);
ri.getMetadata();
assertSame("Wrong metadata", meta, ri.getMetadata());
assertSame("Wrong metadata", meta, ri.getHeaders());
}
@Test
public void testGetHeaderStringUsingHeaderDelegate() throws Exception {
StringBean bean = new StringBean("s3");
RuntimeDelegate original = RuntimeDelegate.getInstance();
RuntimeDelegate.setInstance(new StringBeanRuntimeDelegate(original));
try {
Response response = Response.ok().header(bean.get(), bean).build();
String header = response.getHeaderString(bean.get());
assertTrue(header.contains(bean.get()));
} finally {
RuntimeDelegate.setInstance(original);
StringBeanRuntimeDelegate.assertNotStringBeanRuntimeDelegate();
}
}
@Test
public void testHasEntity() {
assertTrue(new ResponseImpl(200, "").hasEntity());
assertFalse(new ResponseImpl(200).hasEntity());
}
@Test
public void testGetEntityUnwrapped() {
final Book book = new Book();
Response r = Response.ok().entity(
new GenericEntity<Book>(book) {
}
).build();
assertSame(book, r.getEntity());
}
@Test
public void testGetEntity() {
final Book book = new Book();
Response r = Response.ok().entity(book).build();
assertSame(book, r.getEntity());
}
@Test(expected = IllegalStateException.class)
public void testGetEntityAfterClose() {
Response response = Response.ok("entity").build();
response.close();
response.getEntity();
}
@Test
public void testStatuInfoForOKStatus() {
StatusType si = new ResponseImpl(200, "").getStatusInfo();
assertNotNull(si);
assertEquals(200, si.getStatusCode());
assertEquals(Status.Family.SUCCESSFUL, si.getFamily());
assertEquals("OK", si.getReasonPhrase());
}
@Test
public void testStatuInfoForClientErrorStatus() {
StatusType si = new ResponseImpl(400, "").getStatusInfo();
assertNotNull(si);
assertEquals(400, si.getStatusCode());
assertEquals(Status.Family.CLIENT_ERROR, si.getFamily());
assertEquals("Bad Request", si.getReasonPhrase());
}
@Test
public void testStatuInfoForClientErrorStatus2() {
StatusType si = new ResponseImpl(499, "").getStatusInfo();
assertNotNull(si);
assertEquals(499, si.getStatusCode());
assertEquals(Status.Family.CLIENT_ERROR, si.getFamily());
assertEquals("", si.getReasonPhrase());
}
@Test(expected = IllegalStateException.class)
public void testHasEntityAfterClose() {
Response r = new ResponseImpl(200, new ByteArrayInputStream("data".getBytes()));
assertTrue(r.hasEntity());
r.close();
r.hasEntity();
}
@Test
public void testBufferEntityNoEntity() {
Response r = new ResponseImpl(200);
assertFalse(r.bufferEntity());
}
@Test
public void testGetHeaderString() {
ResponseImpl ri = new ResponseImpl(200);
MetadataMap<String, Object> meta = new MetadataMap<String, Object>();
ri.addMetadata(meta);
assertNull(ri.getHeaderString("a"));
meta.putSingle("a", "aValue");
assertEquals("aValue", ri.getHeaderString("a"));
meta.add("a", "aValue2");
assertEquals("aValue,aValue2", ri.getHeaderString("a"));
}
@Test
public void testGetHeaderStrings() {
ResponseImpl ri = new ResponseImpl(200);
MetadataMap<String, Object> meta = new MetadataMap<String, Object>();
meta.add("Set-Cookie", NewCookie.valueOf("a=b"));
ri.addMetadata(meta);
MultivaluedMap<String, String> headers = ri.getStringHeaders();
assertEquals(1, headers.size());
assertEquals("a=b;Version=1", headers.getFirst("Set-Cookie"));
}
@Test
public void testGetCookies() {
ResponseImpl ri = new ResponseImpl(200);
MetadataMap<String, Object> meta = new MetadataMap<String, Object>();
meta.add("Set-Cookie", NewCookie.valueOf("a=b"));
meta.add("Set-Cookie", NewCookie.valueOf("c=d"));
ri.addMetadata(meta);
Map<String, NewCookie> cookies = ri.getCookies();
assertEquals(2, cookies.size());
assertEquals("a=b;Version=1", cookies.get("a").toString());
assertEquals("c=d;Version=1", cookies.get("c").toString());
}
@Test
public void testGetContentLength() {
ResponseImpl ri = new ResponseImpl(200);
MetadataMap<String, Object> meta = new MetadataMap<String, Object>();
ri.addMetadata(meta);
assertEquals(-1, ri.getLength());
meta.add("Content-Length", "10");
assertEquals(10, ri.getLength());
}
@Test
public void testGetDate() {
doTestDate(HttpHeaders.DATE);
}
@Test
public void testLastModified() {
doTestDate(HttpHeaders.LAST_MODIFIED);
}
public void doTestDate(String dateHeader) {
boolean date = HttpHeaders.DATE.equals(dateHeader);
ResponseImpl ri = new ResponseImpl(200);
MetadataMap<String, Object> meta = new MetadataMap<String, Object>();
meta.add(dateHeader, "Tue, 21 Oct 2008 17:00:00 GMT");
ri.addMetadata(meta);
assertEquals(HttpUtils.getHttpDate("Tue, 21 Oct 2008 17:00:00 GMT"),
date ? ri.getDate() : ri.getLastModified());
}
@Test
public void testEntityTag() {
ResponseImpl ri = new ResponseImpl(200);
MetadataMap<String, Object> meta = new MetadataMap<String, Object>();
meta.add(HttpHeaders.ETAG, "1234");
ri.addMetadata(meta);
assertEquals("\"1234\"", ri.getEntityTag().toString());
}
@Test
public void testLocation() {
ResponseImpl ri = new ResponseImpl(200);
MetadataMap<String, Object> meta = new MetadataMap<String, Object>();
meta.add(HttpHeaders.LOCATION, "http://localhost:8080");
ri.addMetadata(meta);
assertEquals("http://localhost:8080", ri.getLocation().toString());
}
@Test
public void testGetLanguage() {
ResponseImpl ri = new ResponseImpl(200);
MetadataMap<String, Object> meta = new MetadataMap<String, Object>();
meta.add(HttpHeaders.CONTENT_LANGUAGE, "en-US");
ri.addMetadata(meta);
assertEquals("en_US", ri.getLanguage().toString());
}
@Test
public void testGetMediaType() {
ResponseImpl ri = new ResponseImpl(200);
MetadataMap<String, Object> meta = new MetadataMap<String, Object>();
meta.add(HttpHeaders.CONTENT_TYPE, "text/xml");
ri.addMetadata(meta);
assertEquals("text/xml", ri.getMediaType().toString());
}
@Test
public void testGetNoLinkBuilder() throws Exception {
Response response = Response.ok().build();
Builder builder = response.getLinkBuilder("anyrelation");
assertNull(builder);
}
protected static List<Variant> getVariantList(List<String> encoding,
MediaType... mt) {
return Variant.VariantListBuilder.newInstance()
.mediaTypes(mt)
.languages(new Locale("en", "US"), new Locale("en", "GB"), new Locale("zh", "CN"))
.encodings(encoding.toArray(new String[]{}))
.add()
.build();
}
@Test
public void testGetLinks() {
ResponseImpl ri = new ResponseImpl(200);
MetadataMap<String, Object> meta = new MetadataMap<String, Object>();
ri.addMetadata(meta);
assertFalse(ri.hasLink("next"));
assertNull(ri.getLink("next"));
assertFalse(ri.hasLink("prev"));
assertNull(ri.getLink("prev"));
meta.add(HttpHeaders.LINK, "<http://localhost:8080/next;a=b>;rel=next");
meta.add(HttpHeaders.LINK, "<http://prev>;rel=prev");
assertTrue(ri.hasLink("next"));
Link next = ri.getLink("next");
assertNotNull(next);
assertTrue(ri.hasLink("prev"));
Link prev = ri.getLink("prev");
assertNotNull(prev);
Set<Link> links = ri.getLinks();
assertTrue(links.contains(next));
assertTrue(links.contains(prev));
assertEquals("http://localhost:8080/next;a=b", next.getUri().toString());
assertEquals("next", next.getRel());
assertEquals("http://prev", prev.getUri().toString());
assertEquals("prev", prev.getRel());
}
@Test
public void testGetLinksNoRel() {
ResponseImpl ri = new ResponseImpl(200);
MetadataMap<String, Object> meta = new MetadataMap<String, Object>();
ri.addMetadata(meta);
Set<Link> links = ri.getLinks();
assertTrue(links.isEmpty());
meta.add(HttpHeaders.LINK, "<http://next>");
meta.add(HttpHeaders.LINK, "<http://prev>");
assertFalse(ri.hasLink("next"));
Link next = ri.getLink("next");
assertNull(next);
assertFalse(ri.hasLink("prev"));
Link prev = ri.getLink("prev");
assertNull(prev);
links = ri.getLinks();
assertTrue(links.contains(Link.fromUri("http://next").build()));
assertTrue(links.contains(Link.fromUri("http://prev").build()));
}
public static class StringBean {
private String header;
public StringBean(String header) {
super();
this.header = header;
}
public String get() {
return header;
}
public void set(String h) {
this.header = h;
}
@Override
public String toString() {
return "StringBean. To get a value, use rather #get() method.";
}
}
public static class StringBeanRuntimeDelegate extends RuntimeDelegate {
private RuntimeDelegate original;
public StringBeanRuntimeDelegate(RuntimeDelegate orig) {
super();
this.original = orig;
assertNotStringBeanRuntimeDelegate(orig);
}
@Override
public <T> T createEndpoint(Application arg0, Class<T> arg1)
throws IllegalArgumentException, UnsupportedOperationException {
return original.createEndpoint(arg0, arg1);
}
@SuppressWarnings("unchecked")
@Override
public <T> HeaderDelegate<T> createHeaderDelegate(Class<T> arg0)
throws IllegalArgumentException {
if (arg0 == StringBean.class) {
return (HeaderDelegate<T>) new StringBeanHeaderDelegate();
} else {
return original.createHeaderDelegate(arg0);
}
}
@Override
public ResponseBuilder createResponseBuilder() {
return original.createResponseBuilder();
}
@Override
public UriBuilder createUriBuilder() {
return original.createUriBuilder();
}
@Override
public VariantListBuilder createVariantListBuilder() {
return original.createVariantListBuilder();
}
public RuntimeDelegate getOriginal() {
return original;
}
public static final void assertNotStringBeanRuntimeDelegate() {
RuntimeDelegate delegate = RuntimeDelegate.getInstance();
assertNotStringBeanRuntimeDelegate(delegate);
}
public static final void assertNotStringBeanRuntimeDelegate(RuntimeDelegate delegate) {
if (delegate instanceof StringBeanRuntimeDelegate) {
StringBeanRuntimeDelegate sbrd = (StringBeanRuntimeDelegate) delegate;
if (sbrd.getOriginal() != null) {
RuntimeDelegate.setInstance(sbrd.getOriginal());
throw new RuntimeException(
"RuntimeDelegate.getInstance() is StringBeanRuntimeDelegate");
}
}
}
@Override
public Builder createLinkBuilder() {
return original.createLinkBuilder();
}
}
public static class StringBeanHeaderDelegate implements HeaderDelegate<StringBean> {
@Override
public StringBean fromString(String string) throws IllegalArgumentException {
return new StringBean(string);
}
@Override
public String toString(StringBean bean) throws IllegalArgumentException {
return bean.get();
}
}
}