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 - 2016 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 */ 024 025import java.io.IOException; 026import java.io.StringWriter; 027import java.io.UnsupportedEncodingException; 028import java.io.Writer; 029import java.util.Map.Entry; 030 031import javax.ws.rs.core.MediaType; 032import javax.ws.rs.core.Response; 033import javax.ws.rs.core.Response.ResponseBuilder; 034 035import org.apache.commons.lang3.StringUtils; 036import org.hl7.fhir.instance.model.api.IBaseBinary; 037 038import ca.uhn.fhir.context.FhirContext; 039import ca.uhn.fhir.parser.IParser; 040import ca.uhn.fhir.rest.api.MethodOutcome; 041import ca.uhn.fhir.rest.method.ParseAction; 042import ca.uhn.fhir.rest.server.Constants; 043import ca.uhn.fhir.rest.server.EncodingEnum; 044import ca.uhn.fhir.rest.server.RestfulResponse; 045import ca.uhn.fhir.rest.server.RestfulServerUtils; 046 047/** 048 * The JaxRsResponse is a jax-rs specific implementation of the RestfulResponse. 049 * 050 * @author Peter Van Houte | peter.vanhoute@agfa.com | Agfa Healthcare 051 */ 052public class JaxRsResponse extends RestfulResponse<JaxRsRequest> { 053 054 /** 055 * The constructor 056 * 057 * @param request the JaxRs Request 058 */ 059 public JaxRsResponse(JaxRsRequest request) { 060 super(request); 061 } 062 063 /** 064 * The response writer is a simple String Writer. All output is configured 065 * by the server. 066 */ 067 @Override 068 public Writer getResponseWriter(int theStatusCode, String theStatusMessage, String theContentType, String theCharset, boolean theRespondGzip) 069 throws UnsupportedEncodingException, IOException { 070 return new StringWriter(); 071 } 072 073 @Override 074 public Response sendWriterResponse(int theStatus, String theContentType, String theCharset, Writer theWriter) { 075 ResponseBuilder builder = buildResponse(theStatus); 076 if (isNotBlank(theContentType)) { 077 String charContentType = theContentType + "; charset=" + StringUtils.defaultIfBlank(theCharset, Constants.CHARSET_NAME_UTF8); 078 builder.header(Constants.HEADER_CONTENT_TYPE, charContentType); 079 } 080 builder.entity(theWriter.toString()); 081 Response retVal = builder.build(); 082 return retVal; 083 } 084 085 @Override 086 public Response sendAttachmentResponse(IBaseBinary bin, int statusCode, String contentType) throws IOException { 087 ResponseBuilder response = buildResponse(statusCode); 088 if (bin.getContent() != null && bin.getContent().length > 0) { 089 response.header(Constants.HEADER_CONTENT_TYPE, contentType).entity(bin.getContent()); 090 } 091 return response.build(); 092 } 093 094 @Override 095 public Response returnResponse(ParseAction<?> outcome, int operationStatus, boolean allowPrefer, 096 MethodOutcome response, String resourceName) throws IOException { 097 StringWriter writer = new StringWriter(); 098 if (outcome != null) { 099 FhirContext fhirContext = getRequestDetails().getServer().getFhirContext(); 100 IParser parser = RestfulServerUtils.getNewParser(fhirContext, getRequestDetails()); 101 outcome.execute(parser, writer); 102 } 103 return sendWriterResponse(operationStatus, getParserType(), null, writer); 104 } 105 106 protected String getParserType() { 107 EncodingEnum encodingEnum = RestfulServerUtils.determineResponseEncodingWithDefault(getRequestDetails()).getEncoding(); 108 return encodingEnum == EncodingEnum.JSON ? MediaType.APPLICATION_JSON : MediaType.APPLICATION_XML; 109 } 110 111 private ResponseBuilder buildResponse(int statusCode) { 112 ResponseBuilder response = Response.status(statusCode); 113 for (Entry<String, String> header : getHeaders().entrySet()) { 114 response.header(header.getKey(), header.getValue()); 115 } 116 return response; 117 } 118 119}