001package ca.uhn.fhir.rest.method; 002 003import java.io.IOException; 004import java.io.InputStream; 005import java.io.Reader; 006import java.io.UnsupportedEncodingException; 007 008/* 009 * #%L 010 * HAPI FHIR - Core Library 011 * %% 012 * Copyright (C) 2014 - 2016 University Health Network 013 * %% 014 * Licensed under the Apache License, Version 2.0 (the "License"); 015 * you may not use this file except in compliance with the License. 016 * You may obtain a copy of the License at 017 * 018 * http://www.apache.org/licenses/LICENSE-2.0 019 * 020 * Unless required by applicable law or agreed to in writing, software 021 * distributed under the License is distributed on an "AS IS" BASIS, 022 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 023 * See the License for the specific language governing permissions and 024 * limitations under the License. 025 * #L% 026 */ 027 028import java.util.ArrayList; 029import java.util.Collections; 030import java.util.HashMap; 031import java.util.List; 032import java.util.Map; 033 034import org.hl7.fhir.instance.model.api.IIdType; 035 036import ca.uhn.fhir.rest.api.RequestTypeEnum; 037import ca.uhn.fhir.rest.api.RestOperationTypeEnum; 038import ca.uhn.fhir.rest.server.IRestfulResponse; 039import ca.uhn.fhir.rest.server.IRestfulServerDefaults; 040 041public abstract class RequestDetails { 042 043 private byte[] myRequestContents; 044 private String myCompartmentName; 045 private String myCompleteUrl; 046 private String myFhirServerBase; 047 private IIdType myId; 048 private String myOperation; 049 private Map<String, String[]> myParameters; 050 private String myRequestPath; 051 private RequestTypeEnum myRequestType; 052 private String myResourceName; 053 private boolean myRespondGzip; 054 private RestOperationTypeEnum myRestOperationType; 055 private String mySecondaryOperation; 056 private Map<String, List<String>> myUnqualifiedToQualifiedNames; 057 private IRestfulResponse myResponse; 058 059 public String getCompartmentName() { 060 return myCompartmentName; 061 } 062 063 public String getCompleteUrl() { 064 return myCompleteUrl; 065 } 066 067 /** 068 * The fhir server base url, independant of the query being executed 069 * 070 * @return the fhir server base url 071 */ 072 public String getFhirServerBase() { 073 return myFhirServerBase; 074 } 075 076 public IIdType getId() { 077 return myId; 078 } 079 080 public String getOperation() { 081 return myOperation; 082 } 083 084 public Map<String, String[]> getParameters() { 085 return myParameters; 086 } 087 088 /** 089 * The part of the request URL that comes after the server base. 090 * <p> 091 * Will not contain a leading '/' 092 * </p> 093 */ 094 public String getRequestPath() { 095 return myRequestPath; 096 } 097 098 public RequestTypeEnum getRequestType() { 099 return myRequestType; 100 } 101 102 public String getResourceName() { 103 return myResourceName; 104 } 105 106 public RestOperationTypeEnum getRestOperationType() { 107 return myRestOperationType; 108 } 109 110 public String getSecondaryOperation() { 111 return mySecondaryOperation; 112 } 113 114 public abstract IRestfulServerDefaults getServer(); 115 116 public Map<String, List<String>> getUnqualifiedToQualifiedNames() { 117 return myUnqualifiedToQualifiedNames; 118 } 119 120 public boolean isRespondGzip() { 121 return myRespondGzip; 122 } 123 124 public void setCompartmentName(String theCompartmentName) { 125 myCompartmentName = theCompartmentName; 126 } 127 128 public void setCompleteUrl(String theCompleteUrl) { 129 myCompleteUrl = theCompleteUrl; 130 } 131 132 public void setFhirServerBase(String theFhirServerBase) { 133 myFhirServerBase = theFhirServerBase; 134 } 135 136 public void setId(IIdType theId) { 137 myId = theId; 138 } 139 140 public void setOperation(String theOperation) { 141 myOperation = theOperation; 142 } 143 144 public void setParameters(Map<String, String[]> theParams) { 145 myParameters = theParams; 146 147 for (String next : theParams.keySet()) { 148 for (int i = 0; i < next.length(); i++) { 149 char nextChar = next.charAt(i); 150 if (nextChar == ':' || nextChar == '.') { 151 if (myUnqualifiedToQualifiedNames == null) { 152 myUnqualifiedToQualifiedNames = new HashMap<String, List<String>>(); 153 } 154 String unqualified = next.substring(0, i); 155 List<String> list = myUnqualifiedToQualifiedNames.get(unqualified); 156 if (list == null) { 157 list = new ArrayList<String>(4); 158 myUnqualifiedToQualifiedNames.put(unqualified, list); 159 } 160 list.add(next); 161 break; 162 } 163 } 164 } 165 166 if (myUnqualifiedToQualifiedNames == null) { 167 myUnqualifiedToQualifiedNames = Collections.emptyMap(); 168 } 169 170 } 171 172 public void setRequestPath(String theRequestPath) { 173 assert theRequestPath.length() == 0 || theRequestPath.charAt(0) != '/'; 174 myRequestPath = theRequestPath; 175 } 176 177 public void setRequestType(RequestTypeEnum theRequestType) { 178 myRequestType = theRequestType; 179 } 180 181 public void setResourceName(String theResourceName) { 182 myResourceName = theResourceName; 183 } 184 185 public void setRespondGzip(boolean theRespondGzip) { 186 myRespondGzip = theRespondGzip; 187 } 188 189 public void setRestOperationType(RestOperationTypeEnum theRestOperationType) { 190 myRestOperationType = theRestOperationType; 191 } 192 193 public void setSecondaryOperation(String theSecondaryOperation) { 194 mySecondaryOperation = theSecondaryOperation; 195 } 196 197 public IRestfulResponse getResponse() { 198 return myResponse; 199 } 200 201 public void setResponse(IRestfulResponse theResponse) { 202 this.myResponse = theResponse; 203 } 204 205 public abstract String getHeader(String name); 206 207 public final byte[] loadRequestContents() { 208 if (myRequestContents == null) { 209 myRequestContents = getByteStreamRequestContents(); 210 } 211 return myRequestContents; 212 } 213 214 protected abstract byte[] getByteStreamRequestContents(); 215 216 public abstract List<String> getHeaders(String name); 217 218 /** 219 * Retrieves the body of the request as character data using a <code>BufferedReader</code>. The reader translates the 220 * character data according to the character encoding used on the body. Either this method or {@link #getInputStream} 221 * may be called to read the body, not both. 222 * 223 * @return a <code>Reader</code> containing the body of the request 224 * 225 * @exception UnsupportedEncodingException 226 * if the character set encoding used is not supported and the text cannot be decoded 227 * 228 * @exception IllegalStateException 229 * if {@link #getInputStream} method has been called on this request 230 * 231 * @exception IOException 232 * if an input or output exception occurred 233 * 234 * @see javax.servlet.http.HttpServletRequest#getInputStream 235 */ 236 public abstract Reader getReader() throws IOException; 237 238 /** 239 * Retrieves the body of the request as binary data. Either this method or {@link #getReader} may be called to read 240 * the body, not both. 241 * 242 * @return a {@link InputStream} object containing the body of the request 243 * 244 * @exception IllegalStateException 245 * if the {@link #getReader} method has already been called for this request 246 * 247 * @exception IOException 248 * if an input or output exception occurred 249 */ 250 public abstract InputStream getInputStream() throws IOException; 251 252 /** 253 * Returns the server base URL (with no trailing '/') for a given request 254 */ 255 public abstract String getServerBaseForRequest(); 256 257}