Package org.apache.cxf.jaxrs.impl

Source Code of org.apache.cxf.jaxrs.impl.ResponseImpl

/**
* 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.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javax.ws.rs.MessageProcessingException;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.GenericType;
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.Response.Status.Family;
import javax.ws.rs.ext.ReaderInterceptor;

import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.jaxrs.provider.ProviderFactory;
import org.apache.cxf.jaxrs.utils.HttpUtils;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.message.Message;

public final class ResponseImpl extends Response {
    private int status;
    private Object entity;
    private Annotation[] entityAnnotations;
    private MultivaluedMap<String, Object> metadata;
   
    private Message responseMessage;
    private boolean entityClosed;   
    private boolean entityBufferred;
   
    ResponseImpl(int s) {
        this.status = s;
    }
   
    ResponseImpl(int s, Object e) {
        this.status = s;
        this.entity = e;
    }
   
    void addMetadata(MultivaluedMap<String, Object> meta) {
        this.metadata = meta;
    }
   
    void setStatus(int s) {
        this.status = s;
    }
   
    void setEntity(Object e, Annotation[] anns) {
        this.entity = e;
        this.entityAnnotations = anns;
    }
   
    Annotation[] getEntityAnnotations() {
        return entityAnnotations;
    }

    //TODO: This method is needed because on the client side the
    // Response processing is done after the chain completes, thus
    // PhaseInterceptorChain.getCurrentMessage() returns null.
    // The refactoring will be required
    public void setMessage(Message message) {
        this.responseMessage = message;
    }
   
    public int getStatus() {
        return status;
    }

    public StatusType getStatusInfo() {
        final Response.Status responseStatus = Response.Status.fromStatusCode(status);
        return new Response.StatusType() {

            public Family getFamily() {
                return responseStatus.getFamily();
            }

            public String getReasonPhrase() {
                return responseStatus.getReasonPhrase();
            }

            public int getStatusCode() {
                return responseStatus.getStatusCode();
            }
           
        };
    }
   
    public Object getEntity() {
        return entity;
    }

    public boolean hasEntity() {
        return getEntity() != null;
    }
   
    public MultivaluedMap<String, Object> getMetadata() {
        return getHeaders();
    }
   
    public MultivaluedMap<String, Object> getHeaders() {
        return metadata;
    }
   
    public MultivaluedMap<String, String> getStringHeaders() {
        MetadataMap<String, String> headers = new MetadataMap<String, String>(metadata.size());
        for (Map.Entry<String, List<Object>> entry : metadata.entrySet()) {
            headers.put(entry.getKey(), toListOfStrings(entry.getValue()));
        }
        return headers;
    }

    // TODO: Make this method private with the upgrade to the latest API snapshot
    public String getHeader(String header) {
        Object value = metadata.getFirst(header);
        return value == null ? null : value.toString();
    }
   
    public String getHeaderString(String header) {
        List<Object> methodValues = metadata.get(header);
        return HttpUtils.getHeaderString(toListOfStrings(methodValues));
    }
   
    // This conversion is needed as some values may not be Strings
    private List<String> toListOfStrings(List<Object> values) {
        if (values == null) {
            return null;
        } else {
            List<String> stringValues = new ArrayList<String>(values.size());
            for (Object value : values) {
                stringValues.add(value.toString());
            }
            return stringValues;
        }
    }
   
    public Set<String> getAllowedMethods() {
        List<Object> methodValues = metadata.get(HttpHeaders.ALLOW);
        if (methodValues == null) {
            return Collections.emptySet();
        } else {
            Set<String> methods = new HashSet<String>();
            for (Object o : methodValues) {
                methods.add(o.toString());
            }
            return methods;
        }
    }

   
   
    public Map<String, NewCookie> getCookies() {
        List<Object> cookieValues = metadata.get(HttpHeaders.SET_COOKIE);
        if (cookieValues == null) {
            return Collections.emptyMap();
        } else {
            Map<String, NewCookie> cookies = new HashMap<String, NewCookie>();
            for (Object o : cookieValues) {
                NewCookie newCookie = NewCookie.valueOf(o.toString());
                cookies.put(newCookie.getName(), newCookie);
            }
            return cookies;
        }
    }

    public Date getDate() {
        return doGetDate(HttpHeaders.DATE);
    }

    private Date doGetDate(String dateHeader) {
        return HttpUtils.getHttpDate(getHeader(dateHeader));
    }
   
    public EntityTag getEntityTag() {
        String header = getHeader(HttpHeaders.ETAG);
        return header == null ? null : EntityTag.valueOf(header);
    }

    public Locale getLanguage() {
        return HttpUtils.getLocale(getHeader(HttpHeaders.CONTENT_LANGUAGE));
    }

    public Date getLastModified() {
        return doGetDate(HttpHeaders.LAST_MODIFIED);
    }

    public int getLength() {
        return HttpUtils.getContentLength(getHeader(HttpHeaders.CONTENT_LENGTH));
    }

    public URI getLocation() {
        String header = getHeader(HttpHeaders.LOCATION);
        return header == null ? null : URI.create(header);
    }

    public MediaType getMediaType() {
        String header = getHeader(HttpHeaders.CONTENT_TYPE);
        return header == null ? null : MediaType.valueOf(header);
    }
   
    public boolean hasLink(String relation) {
        return getLink(relation) != null;
    }
   
    public Link getLink(String relation) {
        Set<Map.Entry<String, Link>> entries = getAllLinks().entrySet();
        for (Map.Entry<String, Link> entry : entries) {
            if (entry.getKey().contains(relation)) {
                return entry.getValue();
            }
        }
        return null;
    }

    public Link.Builder getLinkBuilder(String relation) {
        return Link.fromLink(getLink(relation));
    }

    public Set<Link> getLinks() {
        return new HashSet<Link>(getAllLinks().values());
    }

    private Map<String, Link> getAllLinks() {
        List<Object> linkValues = metadata.get(HttpHeaders.LINK);
        if (linkValues == null) {
            return Collections.emptyMap();
        } else {
            Map<String, Link> links = new HashMap<String, Link>();
            for (Object o : linkValues) {
                Link link = Link.valueOf(o.toString());
                links.put(link.getRel(), link);
            }
            return links;
        }
    }
   
    public <T> T readEntity(Class<T> cls) throws MessageProcessingException, IllegalStateException {
        return readEntity(cls, new Annotation[]{});
    }

    public <T> T readEntity(GenericType<T> genType) throws MessageProcessingException, IllegalStateException {
        return readEntity(genType, new Annotation[]{});
    }

    public <T> T readEntity(Class<T> cls, Annotation[] anns) throws MessageProcessingException,
        IllegalStateException {
       
        return doReadEntity(cls, cls, anns);
    }

    @SuppressWarnings("unchecked")
    public <T> T readEntity(GenericType<T> genType, Annotation[] anns) throws MessageProcessingException,
        IllegalStateException {
        return doReadEntity((Class<T>)genType.getRawType(),
                            genType.getType(), anns);
    }
   
    public <T> T doReadEntity(Class<T> cls, Type t, Annotation[] anns) throws MessageProcessingException,
        IllegalStateException {
       
        checkEntityIsClosed();
       
        if (!hasEntity()) {
            return null;
        }
       
        if (cls.isAssignableFrom(entity.getClass())) {
            T response = cls.cast(entity);
            closeIfNotBufferred(cls);
            return response;
        }
       
        if (responseMessage != null && entity instanceof InputStream) {
            MediaType mediaType = getMediaType();
            if (mediaType == null) {
                mediaType = MediaType.WILDCARD_TYPE;
            }
           
            List<ReaderInterceptor> readers = ProviderFactory.getInstance(responseMessage)
                .createMessageBodyReaderInterceptor(cls, t, anns, mediaType,
                                                    responseMessage.getExchange().getOutMessage());
            if (readers != null) {
                try {
                    responseMessage.put(Message.PROTOCOL_HEADERS, this.getMetadata());
                    return cls.cast(JAXRSUtils.readFromMessageBodyReader(readers, cls, t,
                                                                anns,
                                                                InputStream.class.cast(entity),
                                                                mediaType,
                                                                responseMessage));
                } catch (Exception ex) {
                    throw new MessageProcessingException(ex);
                } finally {
                    closeIfNotBufferred(cls);
                }
            }
        }
       
        throw new MessageProcessingException("No Message Body reader is available");
    }
   
    private void closeIfNotBufferred(Class<?> responseCls) {
        if (!entityBufferred && !InputStream.class.isAssignableFrom(responseCls)) {
            close();
        }
    }
   
    public boolean bufferEntity() throws MessageProcessingException {
        if (entityClosed) {
            throw new IllegalStateException();
        }
        if (!entityBufferred && entity instanceof InputStream) {
            try {
                InputStream oldEntity = (InputStream)entity;
                entity = IOUtils.loadIntoBAIS(oldEntity);
                entityBufferred = true;
            } catch (IOException ex) {
                throw new MessageProcessingException(ex);
            }
        }
        return entityBufferred;
    }

    public void close() throws MessageProcessingException {
        if (!entityClosed) {
            if (entity instanceof InputStream) {
                try {
                    ((InputStream)entity).close();
                    entity = null;
                } catch (IOException ex) {
                    throw new MessageProcessingException(ex);
                }
            }
            entityClosed = true;
           
        }
       
    }
   
    private void checkEntityIsClosed() {
        if (entityClosed) {
            throw new IllegalStateException("Entity is not available");
        }
    }
}
TOP

Related Classes of org.apache.cxf.jaxrs.impl.ResponseImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.