001package ca.uhn.fhir.rest.api; 002 003/* 004 * #%L 005 * HAPI FHIR - Core Library 006 * %% 007 * Copyright (C) 2014 - 2020 University Health Network 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import java.nio.charset.Charset; 024import java.nio.charset.StandardCharsets; 025import java.util.*; 026 027public class Constants { 028 029 public static final String CT_TEXT_CSV = "text/csv"; 030 public static final String HEADER_REQUEST_ID = "X-Request-ID"; 031 public static final String HEADER_REQUEST_SOURCE = "X-Request-Source"; 032 public static final String CACHE_CONTROL_MAX_RESULTS = "max-results"; 033 public static final String CACHE_CONTROL_NO_CACHE = "no-cache"; 034 public static final String CACHE_CONTROL_NO_STORE = "no-store"; 035 public static final String CHARSET_NAME_UTF8 = "UTF-8"; 036 public static final Charset CHARSET_UTF8; 037 public static final String CHARSET_UTF8_CTSUFFIX = "; charset=" + CHARSET_NAME_UTF8; 038 /** 039 * Contains a standard set of headers which are used by FHIR / HAPI FHIR, and therefore 040 * would make a useful set for CORS AllowedHeader declarations 041 */ 042 public static final Set<String> CORS_ALLOWED_HEADERS; 043 /** 044 * Contains a standard set of HTTP Methods which are used by FHIR / HAPI FHIR, and therefore 045 * would make a useful set for CORS AllowedMethod declarations 046 */ 047 public static final Set<String> CORS_ALLWED_METHODS; 048 public static final String CT_FHIR_JSON = "application/json+fhir"; 049 public static final String CT_RDF_TURTLE = "application/x-turtle"; 050 /** 051 * The FHIR MimeType for JSON encoding in FHIR DSTU3+ 052 */ 053 public static final String CT_FHIR_JSON_NEW = "application/fhir+json"; 054 public static final String CT_FHIR_XML = "application/xml+fhir"; 055 /** 056 * The FHIR MimeType for XML encoding in FHIR DSTU3+ 057 */ 058 public static final String CT_FHIR_XML_NEW = "application/fhir+xml"; 059 public static final String CT_HTML = "text/html"; 060 public static final String CT_HTML_WITH_UTF8 = "text/html" + CHARSET_UTF8_CTSUFFIX; 061 public static final String CT_JSON = "application/json"; 062 public static final String CT_JSON_PATCH = "application/json-patch+json"; 063 public static final String CT_OCTET_STREAM = "application/octet-stream"; 064 public static final String CT_TEXT = "text/plain"; 065 public static final String CT_TEXT_WITH_UTF8 = CT_TEXT + CHARSET_UTF8_CTSUFFIX; 066 public static final String CT_X_FORM_URLENCODED = "application/x-www-form-urlencoded"; 067 public static final String CT_XML = "application/xml"; 068 public static final String CT_XML_PATCH = "application/xml-patch+xml"; 069 public static final String ENCODING_GZIP = "gzip"; 070 public static final String EXTOP_PROCESS_MESSAGE = "$process-message"; //Used in messaging 071 public static final String EXTOP_VALIDATE = "$validate"; 072 public static final String EXTOP_VALIDATE_MODE = "mode"; 073 public static final String EXTOP_VALIDATE_PROFILE = "profile"; 074 public static final String EXTOP_VALIDATE_RESOURCE = "resource"; 075 public static final String FORMAT_HTML = "html"; 076 public static final String FORMAT_JSON = "json"; 077 public static final String FORMAT_XML = "xml"; 078 public static final String FORMAT_TURTLE = "text/turtle"; 079 080 081 /** 082 * "text/html" and "html" 083 */ 084 public static final Set<String> FORMATS_HTML; 085 public static final String FORMATS_HTML_JSON = "html/json"; 086 public static final String FORMATS_HTML_XML = "html/xml"; 087 public static final String HEADER_ACCEPT = "Accept"; 088 public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding"; 089 public static final String HEADER_ACCEPT_VALUE_JSON_NON_LEGACY = CT_FHIR_JSON_NEW + ";q=1.0, " + CT_FHIR_JSON + ";q=0.9"; 090 public static final String HEADER_ACCEPT_VALUE_XML_NON_LEGACY = CT_FHIR_XML_NEW + ";q=1.0, " + CT_FHIR_XML + ";q=0.9"; 091 public static final String HEADER_ACCEPT_VALUE_XML_OR_JSON_LEGACY = CT_FHIR_XML + ";q=1.0, " + CT_FHIR_JSON + ";q=1.0"; 092 public static final String HEADER_ACCEPT_VALUE_XML_OR_JSON_NON_LEGACY = CT_FHIR_XML_NEW + ";q=1.0, " + CT_FHIR_JSON_NEW + ";q=1.0, " + HEADER_ACCEPT_VALUE_XML_OR_JSON_LEGACY.replace("1.0", "0.9"); 093 public static final String HEADER_ALLOW = "Allow"; 094 public static final String HEADER_AUTHORIZATION = "Authorization"; 095 public static final String HEADER_AUTHORIZATION_VALPREFIX_BASIC = "Basic "; 096 public static final String HEADER_AUTHORIZATION_VALPREFIX_BEARER = "Bearer "; 097 public static final String HEADER_CACHE_CONTROL = "Cache-Control"; 098 public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition"; 099 public static final String HEADER_CONTENT_ENCODING = "Content-Encoding"; 100 public static final String HEADER_CONTENT_LOCATION = "Content-Location"; 101 public static final String HEADER_CONTENT_LOCATION_LC = HEADER_CONTENT_LOCATION.toLowerCase(); 102 public static final String HEADER_CONTENT_TYPE = "Content-Type"; 103 public static final String HEADER_CONTENT_TYPE_LC = HEADER_CONTENT_TYPE.toLowerCase(); 104 public static final String HEADER_COOKIE = "Cookie"; 105 public static final String HEADER_CORS_ALLOW_METHODS = "Access-Control-Allow-Methods"; 106 public static final String HEADER_CORS_ALLOW_ORIGIN = "Access-Control-Allow-Origin"; 107 public static final String HEADER_CORS_EXPOSE_HEADERS = "Access-Control-Expose-Headers"; 108 public static final String HEADER_ETAG = "ETag"; 109 public static final String HEADER_ETAG_LC = HEADER_ETAG.toLowerCase(); 110 public static final String HEADER_IF_MATCH = "If-Match"; 111 public static final String HEADER_IF_MATCH_LC = HEADER_IF_MATCH.toLowerCase(); 112 public static final String HEADER_IF_MODIFIED_SINCE = "If-Modified-Since"; 113 public static final String HEADER_IF_MODIFIED_SINCE_LC = HEADER_IF_MODIFIED_SINCE.toLowerCase(); 114 public static final String HEADER_IF_NONE_EXIST = "If-None-Exist"; 115 public static final String HEADER_IF_NONE_EXIST_LC = HEADER_IF_NONE_EXIST.toLowerCase(); 116 public static final String HEADER_IF_NONE_MATCH = "If-None-Match"; 117 public static final String HEADER_IF_NONE_MATCH_LC = HEADER_IF_NONE_MATCH.toLowerCase(); 118 public static final String HEADER_LAST_MODIFIED = "Last-Modified"; 119 public static final String HEADER_LAST_MODIFIED_LOWERCASE = HEADER_LAST_MODIFIED.toLowerCase(); 120 public static final String HEADER_LOCATION = "Location"; 121 public static final String HEADER_LOCATION_LC = HEADER_LOCATION.toLowerCase(); 122 public static final String HEADER_ORIGIN = "Origin"; 123 public static final String HEADER_PREFER = "Prefer"; 124 public static final String HEADER_PREFER_RETURN = "return"; 125 public static final String HEADER_PREFER_RETURN_MINIMAL = "minimal"; 126 public static final String HEADER_PREFER_RETURN_REPRESENTATION = "representation"; 127 public static final String HEADER_PREFER_RETURN_OPERATION_OUTCOME = "OperationOutcome"; 128 public static final String HEADER_SUFFIX_CT_UTF_8 = "; charset=UTF-8"; 129 public static final String HEADERVALUE_CORS_ALLOW_METHODS_ALL = "GET, POST, PUT, DELETE, OPTIONS"; 130 public static final Map<Integer, String> HTTP_STATUS_NAMES; 131 public static final String LINK_FHIR_BASE = "fhir-base"; 132 public static final String LINK_FIRST = "first"; 133 public static final String LINK_LAST = "last"; 134 public static final String LINK_NEXT = "next"; 135 public static final String LINK_PREVIOUS = "previous"; 136 public static final String LINK_SELF = "self"; 137 public static final String OPENSEARCH_NS_OLDER = "http://purl.org/atompub/tombstones/1.0"; 138 public static final String PARAM_ASYNC = "async"; //Used in messaging 139 public static final String PARAM_AT = "_at"; 140 /** 141 * Used in paging links 142 */ 143 public static final String PARAM_BUNDLETYPE = "_bundletype"; 144 public static final String PARAM_FILTER = "_filter"; 145 public static final String PARAM_CONTENT = "_content"; 146 public static final String PARAM_COUNT = "_count"; 147 public static final String PARAM_DELETE = "_delete"; 148 public static final String PARAM_ELEMENTS = "_elements"; 149 public static final String PARAM_ELEMENTS_EXCLUDE_MODIFIER = ":exclude"; 150 public static final String PARAM_FORMAT = "_format"; 151 public static final String PARAM_HAS = "_has"; 152 public static final String PARAM_HISTORY = "_history"; 153 public static final String PARAM_INCLUDE = "_include"; 154 public static final String PARAM_INCLUDE_QUALIFIER_RECURSE = ":recurse"; 155 public static final String PARAM_INCLUDE_RECURSE = "_include" + PARAM_INCLUDE_QUALIFIER_RECURSE; 156 public static final String PARAM_INCLUDE_QUALIFIER_ITERATE = ":iterate"; 157 public static final String PARAM_INCLUDE_ITERATE = "_include" + PARAM_INCLUDE_QUALIFIER_ITERATE; 158 public static final String PARAM_LASTUPDATED = "_lastUpdated"; 159 public static final String PARAM_NARRATIVE = "_narrative"; 160 public static final String PARAM_PAGINGACTION = "_getpages"; 161 public static final String PARAM_PAGINGOFFSET = "_getpagesoffset"; 162 public static final String PARAM_PRETTY = "_pretty"; 163 public static final String PARAM_PRETTY_VALUE_FALSE = "false"; 164 public static final String PARAM_PRETTY_VALUE_TRUE = "true"; 165 public static final String PARAM_PROFILE = "_profile"; 166 public static final String PARAM_QUERY = "_query"; 167 public static final String PARAM_RESPONSE_URL = "response-url"; //Used in messaging 168 public static final String PARAM_REVINCLUDE = "_revinclude"; 169 public static final String PARAM_REVINCLUDE_RECURSE = PARAM_REVINCLUDE + PARAM_INCLUDE_QUALIFIER_RECURSE; 170 public static final String PARAM_REVINCLUDE_ITERATE = PARAM_REVINCLUDE + PARAM_INCLUDE_QUALIFIER_ITERATE; 171 public static final String PARAM_SEARCH = "_search"; 172 public static final String PARAM_SECURITY = "_security"; 173 public static final String PARAM_SINCE = "_since"; 174 public static final String PARAM_SORT = "_sort"; 175 public static final String PARAM_SORT_ASC = "_sort:asc"; 176 public static final String PARAM_SORT_DESC = "_sort:desc"; 177 public static final String PARAM_SOURCE = "_source"; 178 public static final String PARAM_SUMMARY = "_summary"; 179 public static final String PARAM_TAG = "_tag"; 180 public static final String PARAM_TAGS = "_tags"; 181 public static final String PARAM_TEXT = "_text"; 182 public static final String PARAM_VALIDATE = "_validate"; 183 public static final String PARAMQUALIFIER_MISSING = ":missing"; 184 public static final String PARAMQUALIFIER_MISSING_FALSE = "false"; 185 public static final String PARAMQUALIFIER_MISSING_TRUE = "true"; 186 public static final String PARAMQUALIFIER_STRING_CONTAINS = ":contains"; 187 public static final String PARAMQUALIFIER_STRING_EXACT = ":exact"; 188 public static final String PARAMQUALIFIER_TOKEN_TEXT = ":text"; 189 public static final int STATUS_HTTP_200_OK = 200; 190 public static final int STATUS_HTTP_201_CREATED = 201; 191 public static final int STATUS_HTTP_204_NO_CONTENT = 204; 192 public static final int STATUS_HTTP_304_NOT_MODIFIED = 304; 193 public static final int STATUS_HTTP_400_BAD_REQUEST = 400; 194 public static final int STATUS_HTTP_401_CLIENT_UNAUTHORIZED = 401; 195 public static final int STATUS_HTTP_403_FORBIDDEN = 403; 196 197 public static final int STATUS_HTTP_404_NOT_FOUND = 404; 198 public static final int STATUS_HTTP_405_METHOD_NOT_ALLOWED = 405; 199 public static final int STATUS_HTTP_409_CONFLICT = 409; 200 public static final int STATUS_HTTP_410_GONE = 410; 201 public static final int STATUS_HTTP_412_PRECONDITION_FAILED = 412; 202 public static final int STATUS_HTTP_422_UNPROCESSABLE_ENTITY = 422; 203 public static final int STATUS_HTTP_500_INTERNAL_ERROR = 500; 204 public static final int STATUS_HTTP_501_NOT_IMPLEMENTED = 501; 205 public static final String TAG_SUBSETTED_CODE = "SUBSETTED"; 206 public static final String TAG_SUBSETTED_SYSTEM_DSTU3 = "http://hl7.org/fhir/v3/ObservationValue"; 207 public static final String TAG_SUBSETTED_SYSTEM_R4 = "http://terminology.hl7.org/CodeSystem/v3-ObservationValue"; 208 public static final String URL_TOKEN_HISTORY = "_history"; 209 public static final String URL_TOKEN_METADATA = "metadata"; 210 public static final String OO_INFOSTATUS_PROCESSING = "processing"; 211 public static final String PARAM_GRAPHQL_QUERY = "query"; 212 public static final String HEADER_X_CACHE = "X-Cache"; 213 public static final String HEADER_X_SECURITY_CONTEXT = "X-Security-Context"; 214 public static final String POWERED_BY_HEADER = "X-Powered-By"; 215 public static final Charset CHARSET_US_ASCII; 216 public static final String PARAM_PAGEID = "_pageId"; 217 /** 218 * This is provided for testing only! Use with caution as this property may change. 219 */ 220 public static final String TEST_SYSTEM_PROP_VALIDATION_RESOURCE_CACHES_MS = "TEST_SYSTEM_PROP_VALIDATION_RESOURCE_CACHES_MS"; 221 public static final String PARAM_SEARCH_TOTAL_MODE = "_total"; 222 public static final String CAPABILITYSTATEMENT_WEBSOCKET_URL = "http://hl7.org/fhir/StructureDefinition/capabilitystatement-websocket"; 223 public static final String PARAMETER_CASCADE_DELETE = "_cascade"; 224 public static final String HEADER_CASCADE = "X-Cascade"; 225 public static final String CASCADE_DELETE = "delete"; 226 public static final int MAX_RESOURCE_NAME_LENGTH = 100; 227 public static final String CACHE_CONTROL_PRIVATE = "private"; 228 public static final String CT_FHIR_NDJSON = "application/fhir+ndjson"; 229 public static final String CT_APP_NDJSON = "application/ndjson"; 230 public static final String CT_NDJSON = "ndjson"; 231 public static final Set<String> CTS_NDJSON; 232 public static final String HEADER_PREFER_RESPOND_ASYNC = "respond-async"; 233 public static final int STATUS_HTTP_412_PAYLOAD_TOO_LARGE = 413; 234 public static final String OPERATION_NAME_GRAPHQL = "$graphql"; 235 /** 236 * Note that this constant is used in a number of places including DB column lengths! Be careful if you decide to change it. 237 */ 238 public static final int REQUEST_ID_LENGTH = 16; 239 public static final int STATUS_HTTP_202_ACCEPTED = 202; 240 public static final String HEADER_X_PROGRESS = "X-Progress"; 241 public static final String HEADER_RETRY_AFTER = "Retry-After"; 242 /** 243 * Operation name for the $lastn operation 244 */ 245 public static final String OPERATION_LASTN = "$lastn"; 246 /** 247 * <p> 248 * This extension represents the equivalent of the 249 * <code>Resource.meta.source</code> field within R4+ resources, and is for 250 * use in DSTU3 resources. It should contain a value of type <code>uri</code> 251 * and will be located on the Resource.meta 252 * </p> 253 */ 254 public static final String EXT_META_SOURCE = "http://hapifhir.io/fhir/StructureDefinition/resource-meta-source"; 255 public static final String CODESYSTEM_VALIDATE_NOT_NEEDED = UUID.randomUUID().toString(); 256 257 static { 258 CHARSET_UTF8 = StandardCharsets.UTF_8; 259 CHARSET_US_ASCII = StandardCharsets.ISO_8859_1; 260 261 HashSet<String> ctsNdjson = new HashSet<>(); 262 ctsNdjson.add(CT_FHIR_NDJSON); 263 ctsNdjson.add(CT_APP_NDJSON); 264 ctsNdjson.add(CT_NDJSON); 265 CTS_NDJSON = Collections.unmodifiableSet(ctsNdjson); 266 267 HashMap<Integer, String> statusNames = new HashMap<>(); 268 statusNames.put(200, "OK"); 269 statusNames.put(201, "Created"); 270 statusNames.put(202, "Accepted"); 271 statusNames.put(203, "Non-Authoritative Information"); 272 statusNames.put(204, "No Content"); 273 statusNames.put(205, "Reset Content"); 274 statusNames.put(206, "Partial Content"); 275 statusNames.put(207, "Multi-Status"); 276 statusNames.put(208, "Already Reported"); 277 statusNames.put(226, "IM Used"); 278 statusNames.put(300, "Multiple Choices"); 279 statusNames.put(301, "Moved Permanently"); 280 statusNames.put(302, "Found"); 281 statusNames.put(303, "See Other"); 282 statusNames.put(304, "Not Modified"); 283 statusNames.put(305, "Use Proxy"); 284 statusNames.put(307, "Temporary Redirect"); 285 statusNames.put(308, "Permanent Redirect"); 286 statusNames.put(400, "Bad Request"); 287 statusNames.put(401, "Unauthorized"); 288 statusNames.put(402, "Payment Required"); 289 statusNames.put(403, "Forbidden"); 290 statusNames.put(404, "Not Found"); 291 statusNames.put(405, "Method Not Allowed"); 292 statusNames.put(406, "Not Acceptable"); 293 statusNames.put(407, "Proxy Authentication Required"); 294 statusNames.put(408, "Request Timeout"); 295 statusNames.put(409, "Conflict"); 296 statusNames.put(410, "Gone"); 297 statusNames.put(411, "Length Required"); 298 statusNames.put(412, "Precondition Failed"); 299 statusNames.put(413, "Payload Too Large"); 300 statusNames.put(414, "URI Too Long"); 301 statusNames.put(415, "Unsupported Media Type"); 302 statusNames.put(416, "Requested range not satisfiable"); 303 statusNames.put(417, "Expectation Failed"); 304 statusNames.put(418, "I'm a teapot"); 305 statusNames.put(419, "Insufficient Space On Resource"); 306 statusNames.put(420, "Method Failure"); 307 statusNames.put(421, "Destination Locked"); 308 statusNames.put(422, "Unprocessable Entity"); 309 statusNames.put(423, "Locked"); 310 statusNames.put(424, "Failed Dependency"); 311 statusNames.put(426, "Upgrade Required"); 312 statusNames.put(428, "Precondition Required"); 313 statusNames.put(429, "Too Many Requests"); 314 statusNames.put(431, "Request Header Fields Too Large"); 315 statusNames.put(500, "Internal Server Error"); 316 statusNames.put(501, "Not Implemented"); 317 statusNames.put(502, "Bad Gateway"); 318 statusNames.put(503, "Service Unavailable"); 319 statusNames.put(504, "Gateway Timeout"); 320 statusNames.put(505, "HTTP Version not supported"); 321 statusNames.put(506, "Variant Also Negotiates"); 322 statusNames.put(507, "Insufficient Storage"); 323 statusNames.put(508, "Loop Detected"); 324 statusNames.put(509, "Bandwidth Limit Exceeded"); 325 statusNames.put(510, "Not Extended"); 326 statusNames.put(511, "Network Authentication Required"); 327 HTTP_STATUS_NAMES = Collections.unmodifiableMap(statusNames); 328 329 Set<String> formatsHtml = new HashSet<>(); 330 formatsHtml.add(CT_HTML); 331 formatsHtml.add(FORMAT_HTML); 332 FORMATS_HTML = Collections.unmodifiableSet(formatsHtml); 333 334 // ********************************************************* 335 // Update CorsInterceptor's constructor documentation if you change these: 336 // ********************************************************* 337 HashSet<String> corsAllowedHeaders = new HashSet<>(); 338 corsAllowedHeaders.add("Accept"); 339 corsAllowedHeaders.add("Access-Control-Request-Headers"); 340 corsAllowedHeaders.add("Access-Control-Request-Method"); 341 corsAllowedHeaders.add("Cache-Control"); 342 corsAllowedHeaders.add("Content-Type"); 343 corsAllowedHeaders.add("Origin"); 344 corsAllowedHeaders.add("Prefer"); 345 corsAllowedHeaders.add("X-FHIR-Starter"); 346 corsAllowedHeaders.add("X-Requested-With"); 347 CORS_ALLOWED_HEADERS = Collections.unmodifiableSet(corsAllowedHeaders); 348 349 // ********************************************************* 350 // Update CorsInterceptor's constructor documentation if you change these: 351 // ********************************************************* 352 HashSet<String> corsAllowedMethods = new HashSet<>(); 353 corsAllowedMethods.addAll(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH")); 354 CORS_ALLWED_METHODS = Collections.unmodifiableSet(corsAllowedMethods); 355 } 356 357 public static boolean codeSystemNotNeeded(String theCodeSystem) { 358 return Constants.CODESYSTEM_VALIDATE_NOT_NEEDED.equals(theCodeSystem); 359 } 360 361 362 public static String codeSystemWithDefaultDescription(String theSystem) { 363 if (codeSystemNotNeeded(theSystem)) { 364 return "(none)"; 365 } else { 366 return theSystem; 367 } 368 } 369}