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