package org.jboss.resteasy.specimpl;
import org.jboss.resteasy.core.Headers;
import org.jboss.resteasy.core.ResteasyContext;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.util.HeaderHelper;
import org.jboss.resteasy.util.HttpHeaderNames;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Link;
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.Variant;
import java.lang.annotation.Annotation;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;
public class ResponseBuilderImpl extends Response.ResponseBuilder
{
protected Object entity;
protected Annotation[] entityAnnotations;
protected int status = -1;
protected String reasonPhrase;
protected Headers<Object> metadata = new Headers<Object>();
@Override
public Response build()
{
if (status == -1 && entity == null) status = 204;
else if (status == -1) status = 200;
return new BuiltResponse(status, reasonPhrase, metadata, entity, entityAnnotations);
}
@Override
public Response.ResponseBuilder clone()
{
ResponseBuilderImpl impl = new ResponseBuilderImpl();
impl.metadata.putAll(metadata);
impl.entity = entity;
impl.status = status;
impl.entityAnnotations = entityAnnotations;
return impl;
}
@Override
public Response.ResponseBuilder status(int status, String reasonPhrase)
{
this.status = status;
this.reasonPhrase = reasonPhrase;
return this;
}
@Override
public Response.ResponseBuilder status(int status)
{
return status(status, null);
}
@Override
public Response.ResponseBuilder entity(Object entity)
{
this.entity = entity;
return this;
}
@Override
public Response.ResponseBuilder entity(Object entity, Annotation[] annotations)
{
this.entity = entity;
this.entityAnnotations = annotations;
return this;
}
@Override
public Response.ResponseBuilder type(MediaType type)
{
if (type == null)
{
metadata.remove(HttpHeaderNames.CONTENT_TYPE);
return this;
}
metadata.putSingle(HttpHeaderNames.CONTENT_TYPE, type);
return this;
}
@Override
public Response.ResponseBuilder type(String type)
{
if (type == null)
{
metadata.remove(HttpHeaderNames.CONTENT_TYPE);
return this;
}
metadata.putSingle(HttpHeaderNames.CONTENT_TYPE, type);
return this;
}
@Override
public Response.ResponseBuilder variant(Variant variant)
{
if (variant == null)
{
type((String)null);
language((String)null);
metadata.remove(HttpHeaderNames.CONTENT_ENCODING);
return this;
}
type(variant.getMediaType());
language(variant.getLanguage());
if (variant.getEncoding() != null) metadata.putSingle(HttpHeaderNames.CONTENT_ENCODING, variant.getEncoding());
else metadata.remove(HttpHeaderNames.CONTENT_ENCODING);
return this;
}
@Override
public Response.ResponseBuilder variants(List<Variant> variants)
{
if (variants == null)
{
metadata.remove(HttpHeaderNames.VARY);
return this;
}
String vary = createVaryHeader(variants);
metadata.putSingle(HttpHeaderNames.VARY, vary);
return this;
}
public static String (List<Variant> variants)
{
boolean accept = false;
boolean acceptLanguage = false;
boolean acceptEncoding = false;
for (Variant variant : variants)
{
if (variant.getMediaType() != null) accept = true;
if (variant.getLanguage() != null) acceptLanguage = true;
if (variant.getEncoding() != null) acceptEncoding = true;
}
String vary = null;
if (accept) vary = HttpHeaderNames.ACCEPT;
if (acceptLanguage)
{
if (vary == null) vary = HttpHeaderNames.ACCEPT_LANGUAGE;
else vary += ", " + HttpHeaderNames.ACCEPT_LANGUAGE;
}
if (acceptEncoding)
{
if (vary == null) vary = HttpHeaderNames.ACCEPT_ENCODING;
else vary += ", " + HttpHeaderNames.ACCEPT_ENCODING;
}
return vary;
}
@Override
public Response.ResponseBuilder language(String language)
{
if (language == null)
{
metadata.remove(HttpHeaderNames.CONTENT_LANGUAGE);
return this;
}
metadata.putSingle(HttpHeaderNames.CONTENT_LANGUAGE, language);
return this;
}
@Override
public Response.ResponseBuilder location(URI location)
{
if (location == null)
{
metadata.remove(HttpHeaderNames.LOCATION);
return this;
}
if (!location.isAbsolute() && ResteasyContext.getContextData(HttpRequest.class) != null)
{
String path = location.toString();
if (path.startsWith("/")) path = path.substring(1);
URI baseUri = ResteasyContext.getContextData(HttpRequest.class).getUri().getBaseUri();
location = baseUri.resolve(path);
}
metadata.putSingle(HttpHeaderNames.LOCATION, location);
return this;
}
@Override
public Response.ResponseBuilder contentLocation(URI location)
{
if (location == null)
{
metadata.remove(HttpHeaderNames.CONTENT_LOCATION);
return this;
}
if (!location.isAbsolute() && ResteasyContext.getContextData(HttpRequest.class) != null)
{
String path = location.toString();
if (path.startsWith("/")) path = path.substring(1);
URI baseUri = ResteasyContext.getContextData(HttpRequest.class).getUri().getBaseUri();
location = baseUri.resolve(path);
}
metadata.putSingle(HttpHeaderNames.CONTENT_LOCATION, location);
return this;
}
@Override
public Response.ResponseBuilder tag(EntityTag tag)
{
if (tag == null)
{
metadata.remove(HttpHeaderNames.ETAG);
return this;
}
metadata.putSingle(HttpHeaderNames.ETAG, tag);
return this;
}
@Override
public Response.ResponseBuilder tag(String tag)
{
if (tag == null)
{
metadata.remove(HttpHeaderNames.ETAG);
return this;
}
return tag(new EntityTag(tag));
}
@Override
public Response.ResponseBuilder lastModified(Date lastModified)
{
if (lastModified == null)
{
metadata.remove(HttpHeaderNames.LAST_MODIFIED);
return this;
}
metadata.putSingle(HttpHeaderNames.LAST_MODIFIED, lastModified);
return this;
}
@Override
public Response.ResponseBuilder cacheControl(CacheControl cacheControl)
{
if (cacheControl == null)
{
metadata.remove(HttpHeaderNames.CACHE_CONTROL);
return this;
}
metadata.putSingle(HttpHeaderNames.CACHE_CONTROL, cacheControl);
return this;
}
@Override
public Response.ResponseBuilder (String name, Object value)
{
if (value == null)
{
metadata.remove(name);
return this;
}
metadata.add(name, value);
return this;
}
@Override
public Response.ResponseBuilder cookie(NewCookie... cookies)
{
if (cookies == null)
{
metadata.remove(HttpHeaderNames.SET_COOKIE);
return this;
}
for (NewCookie cookie : cookies)
{
metadata.add(HttpHeaderNames.SET_COOKIE, cookie);
}
return this;
}
public Response.ResponseBuilder language(Locale language)
{
if (language == null)
{
metadata.remove(HttpHeaderNames.CONTENT_LANGUAGE);
return this;
}
metadata.putSingle(HttpHeaderNames.CONTENT_LANGUAGE, language);
return this;
}
public static SimpleDateFormat getDateFormatRFC822()
{
SimpleDateFormat dateFormatRFC822 = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
dateFormatRFC822.setTimeZone(TimeZone.getTimeZone("GMT"));
return dateFormatRFC822;
}
public Response.ResponseBuilder expires(Date expires)
{
if (expires == null)
{
metadata.remove(HttpHeaderNames.EXPIRES);
return this;
}
metadata.putSingle(HttpHeaderNames.EXPIRES, getDateFormatRFC822().format(expires));
return this;
}
public Response.ResponseBuilder allow(String... methods)
{
if (methods == null)
{
return allow((Set<String>)null);
}
HashSet<String> set = new HashSet<String>();
for (String m : methods) set.add(m);
return allow(set);
}
public Response.ResponseBuilder allow(Set<String> methods)
{
HeaderHelper.setAllow(this.metadata, methods);
return this;
}
@Override
public Response.ResponseBuilder encoding(String encoding)
{
if (encoding == null)
{
metadata.remove(HttpHeaders.CONTENT_ENCODING);
return this;
}
metadata.putSingle(HttpHeaders.CONTENT_ENCODING, encoding);
return this;
}
@Override
public Response.ResponseBuilder variants(Variant... variants)
{
return this.variants(Arrays.asList(variants));
}
@Override
public Response.ResponseBuilder links(Link... links)
{
if (links == null)
{
metadata.remove(HttpHeaders.LINK);
return this;
}
for (Link link : links)
{
metadata.add(HttpHeaders.LINK, link);
}
return this;
}
@Override
public Response.ResponseBuilder link(URI uri, String rel)
{
Link link = Link.fromUri(uri).rel(rel).build();
metadata.add(HttpHeaders.LINK, link);
return this;
}
@Override
public Response.ResponseBuilder link(String uri, String rel)
{
Link link = Link.fromUri(uri).rel(rel).build();
metadata.add(HttpHeaders.LINK, link);
return this;
}
@Override
public Response.ResponseBuilder replaceAll(MultivaluedMap<String, Object> headers)
{
metadata.clear();
if (headers == null) return this;
metadata.putAll(headers);
return this;
}
}