001package ca.uhn.fhir.jaxrs.server.util;
002
003import static org.apache.commons.lang3.StringUtils.isNotBlank;
004
005/*
006 * #%L
007 * HAPI FHIR JAX-RS Server
008 * %%
009 * Copyright (C) 2014 - 2019 University Health Network
010 * %%
011 * Licensed under the Apache License, Version 2.0 (the "License");
012 * you may not use this file except in compliance with the License.
013 * You may obtain a copy of the License at
014 * 
015 *      http://www.apache.org/licenses/LICENSE-2.0
016 * 
017 * Unless required by applicable law or agreed to in writing, software
018 * distributed under the License is distributed on an "AS IS" BASIS,
019 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
020 * See the License for the specific language governing permissions and
021 * limitations under the License.
022 * #L%
023 */
024import java.io.*;
025import java.util.List;
026import java.util.Map.Entry;
027
028import javax.ws.rs.core.MediaType;
029import javax.ws.rs.core.Response;
030import javax.ws.rs.core.Response.ResponseBuilder;
031
032import org.apache.commons.lang3.StringUtils;
033import org.hl7.fhir.instance.model.api.IBaseBinary;
034
035import ca.uhn.fhir.context.FhirContext;
036import ca.uhn.fhir.parser.IParser;
037import ca.uhn.fhir.rest.api.*;
038import ca.uhn.fhir.rest.api.server.ParseAction;
039import ca.uhn.fhir.rest.server.RestfulResponse;
040import ca.uhn.fhir.rest.server.RestfulServerUtils;
041
042/**
043 * The JaxRsResponse is a jax-rs specific implementation of the RestfulResponse.
044 * 
045 * @author Peter Van Houte | peter.vanhoute@agfa.com | Agfa Healthcare
046 */
047public class JaxRsResponse extends RestfulResponse<JaxRsRequest> {
048
049        /**
050         * The constructor
051         * 
052         * @param request the JaxRs Request
053         */
054        public JaxRsResponse(JaxRsRequest request) {
055                super(request);
056        }
057
058        /**
059         * The response writer is a simple String Writer. All output is configured
060         * by the server.
061         */
062        @Override
063        public Writer getResponseWriter(int theStatusCode, String theStatusMessage, String theContentType, String theCharset, boolean theRespondGzip)
064                        throws UnsupportedEncodingException, IOException {
065                return new StringWriter();
066        }
067
068        @Override
069        public Response sendWriterResponse(int theStatus, String theContentType, String theCharset, Writer theWriter) {
070                ResponseBuilder builder = buildResponse(theStatus);
071                if (isNotBlank(theContentType)) {
072                        String charContentType = theContentType + "; charset=" + StringUtils.defaultIfBlank(theCharset, Constants.CHARSET_NAME_UTF8);
073                        builder.header(Constants.HEADER_CONTENT_TYPE, charContentType);
074                }
075                builder.entity(theWriter.toString());
076                Response retVal = builder.build();
077                return retVal;
078        }
079
080        @Override
081        public Response sendAttachmentResponse(IBaseBinary bin, int statusCode, String contentType) throws IOException {
082                ResponseBuilder response = buildResponse(statusCode);
083                if (bin.getContent() != null && bin.getContent().length > 0) {
084                        response.header(Constants.HEADER_CONTENT_TYPE, contentType).entity(bin.getContent());
085                }
086                return response.build();
087        }
088
089        @Override
090        public Response returnResponse(ParseAction<?> outcome, int operationStatus, boolean allowPrefer,
091                        MethodOutcome response, String resourceName) throws IOException {
092                StringWriter writer = new StringWriter();
093                if (outcome != null) {
094                        FhirContext fhirContext = getRequestDetails().getServer().getFhirContext();
095                        IParser parser = RestfulServerUtils.getNewParser(fhirContext, fhirContext.getVersion().getVersion(), getRequestDetails());
096                        outcome.execute(parser, writer);
097                }
098                return sendWriterResponse(operationStatus, getParserType(), null, writer);
099        }
100
101        protected String getParserType() {
102                EncodingEnum encodingEnum = RestfulServerUtils.determineResponseEncodingWithDefault(getRequestDetails()).getEncoding();
103                return encodingEnum == EncodingEnum.JSON ? MediaType.APPLICATION_JSON : MediaType.APPLICATION_XML;
104        }
105
106        private ResponseBuilder buildResponse(int statusCode) {
107                ResponseBuilder response = Response.status(statusCode);
108                for (Entry<String, List<String>> header : getHeaders().entrySet()) {
109                        final String key = header.getKey();
110                        for (String value : header.getValue()) {
111                                response.header(key, value);
112                        }
113                }
114                return response;
115        }
116
117}