/******************************************************************************* * 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.common.internal; import java.net.URI; import java.util.Date; import java.util.List; import java.util.Locale; import javax.ws.rs.core.CacheControl; import javax.ws.rs.core.EntityTag; import javax.ws.rs.core.HttpHeaders; 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.UriBuilder; import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.Variant; import org.apache.wink.common.RuntimeContext; import org.apache.wink.common.internal.runtime.RuntimeContextTLS; public class ResponseImpl extends Response { private static final int DEFAULT_STATUS = -1; private Object entity; private int status = DEFAULT_STATUS; private MultivaluedMap<String, Object> metadata; private ResponseImpl(int status, Object entity, MultivaluedMap<String, Object> metadata) { this.status = status; this.entity = entity; this.metadata = metadata; } @Override public Object getEntity() { return entity; } @Override public MultivaluedMap<String, Object> getMetadata() { return metadata; } @Override public int getStatus() { return status; } public static class ResponseBuilderImpl extends ResponseBuilder { private Object entity; private int status; private final MultivaluedMap<String, Object> metadata; public ResponseBuilderImpl() { super(); metadata = new CaseInsensitiveMultivaluedMap<Object>(); status = DEFAULT_STATUS; } private ResponseBuilderImpl(int status, Object entity, MultivaluedMap<String, Object> metadata) { super(); this.status = status; this.entity = entity; this.metadata = metadata; } @Override public Response build() { return new ResponseImpl(status, entity, metadata); } @Override public ResponseBuilder cacheControl(CacheControl cacheControl) { return singleHeader(HttpHeaders.CACHE_CONTROL, cacheControl); } @Override public ResponseBuilder clone() { return new ResponseBuilderImpl(status, entity, metadata); } @Override public ResponseBuilder contentLocation(URI location) { return singleHeader(HttpHeaders.CONTENT_LOCATION, location); } @Override public ResponseBuilder cookie(NewCookie... cookies) { if (cookies == null) { metadata.remove(HttpHeaders.SET_COOKIE); } else { for (NewCookie cookie : cookies) { header(HttpHeaders.SET_COOKIE, cookie); } } return this; } @Override public ResponseBuilder entity(Object entity) { this.entity = entity; return this; } @Override public ResponseBuilder expires(Date expires) { return singleHeader(HttpHeaders.EXPIRES, expires); } @Override public ResponseBuilder header(String name, Object value) { if (value == null) { metadata.remove(name); } else { metadata.add(name, value); } return this; } @Override public ResponseBuilder language(String language) { return singleHeader(HttpHeaders.CONTENT_LANGUAGE, language); } @Override public ResponseBuilder language(Locale language) { return singleHeader(HttpHeaders.CONTENT_LANGUAGE, language); } @Override public ResponseBuilder lastModified(Date lastModified) { return singleHeader(HttpHeaders.LAST_MODIFIED, lastModified); } @Override public ResponseBuilder location(URI location) { if (location != null && !location.isAbsolute()) { RuntimeContext rtContext = RuntimeContextTLS.getRuntimeContext(); if (rtContext != null) { UriInfo info = RuntimeContextTLS.getRuntimeContext().getAttribute(UriInfo.class); if (info != null) { location = UriBuilder.fromUri(info.getBaseUri()).path(location.getPath()) .fragment(location.getFragment()).build(); } } } return singleHeader(HttpHeaders.LOCATION, location); } @Override public ResponseBuilder status(int status) { this.status = status; return this; } @Override public ResponseBuilder tag(EntityTag tag) { return singleHeader(HttpHeaders.ETAG, tag); } @Override public ResponseBuilder tag(String tag) { return singleHeader(HttpHeaders.ETAG, tag); } @Override public ResponseBuilder type(MediaType type) { return singleHeader(HttpHeaders.CONTENT_TYPE, type); } @Override public ResponseBuilder type(String type) { return singleHeader(HttpHeaders.CONTENT_TYPE, type); } public ResponseBuilder encoding(String encoding) { return singleHeader(HttpHeaders.CONTENT_ENCODING, encoding); } @Override public ResponseBuilder variant(Variant variant) { if (variant != null) { language(variant.getLanguage()); encoding(variant.getEncoding()); type(variant.getMediaType()); } else { language((String)null); encoding(null); type((String)null); } return this; } @Override public ResponseBuilder variants(List<Variant> variants) { if (variants == null) { header(HttpHeaders.VARY, null); return this; } if (variants.isEmpty()) { return this; } boolean encoding = false; boolean lang = false; boolean mediatype = false; for (Variant v : variants) { encoding = encoding || (v.getEncoding() != null); lang = lang || (v.getLanguage() != null); mediatype = mediatype || (v.getMediaType() != null); } StringBuilder sb = new StringBuilder(); conditionalAppend(sb, mediatype, HttpHeaders.ACCEPT); conditionalAppend(sb, lang, HttpHeaders.ACCEPT_LANGUAGE); conditionalAppend(sb, encoding, HttpHeaders.ACCEPT_ENCODING); if (sb.length() > 0) { header(HttpHeaders.VARY, sb.toString()); } return this; } // /////////////////// helper methods //////////////////////// private ResponseBuilder singleHeader(String key, Object value) { if (value == null) { metadata.remove(key); } else { metadata.putSingle(key, value); } return this; } private void conditionalAppend(StringBuilder sb, boolean b, String s) { if (b) { if (sb.length() > 0) sb.append(","); //$NON-NLS-1$ sb.append(s); } } } }