All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.wink.common.internal.ResponseImpl Maven / Gradle / Ivy

There is a newer version: 1.4
Show newest version
/*******************************************************************************
 * 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 metadata;

    private ResponseImpl(int status, Object entity, MultivaluedMap metadata) {
        this.status = status;
        this.entity = entity;
        this.metadata = metadata;
    }

    @Override
    public Object getEntity() {
        return entity;
    }

    @Override
    public MultivaluedMap getMetadata() {
        return metadata;
    }

    @Override
    public int getStatus() {
        return status;
    }

    public static class ResponseBuilderImpl extends ResponseBuilder {

        private Object                               entity;
        private int                                  status;
        private final MultivaluedMap metadata;

        public ResponseBuilderImpl() {
            super();
            metadata = new CaseInsensitiveMultivaluedMap();
            status = DEFAULT_STATUS;

        }

        private ResponseBuilderImpl(int status,
                                    Object entity,
                                    MultivaluedMap 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 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);
            }
        }

    }

}