001/*
002 * #%L
003 * HAPI FHIR - Core Library
004 * %%
005 * Copyright (C) 2014 - 2025 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.rest.api;
021
022import java.nio.charset.Charset;
023import java.nio.charset.StandardCharsets;
024import java.util.Arrays;
025import java.util.Collections;
026import java.util.HashMap;
027import java.util.HashSet;
028import java.util.List;
029import java.util.Map;
030import java.util.Set;
031
032import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
033
034public class Constants {
035
036        // ==============================================================
037        // Standard HTTP headers
038        // ==============================================================
039
040        public static final String HEADER_ACCEPT = "Accept";
041        public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
042        public static final String HEADER_ALLOW = "Allow";
043        public static final String HEADER_AUTHORIZATION = "Authorization";
044        public static final String HEADER_CACHE_CONTROL = "Cache-Control";
045        public static final String HEADER_CONTENT_ENCODING = "Content-Encoding";
046        public static final String HEADER_CONTENT_LOCATION = "Content-Location";
047        public static final String HEADER_CONTENT_LOCATION_LC = HEADER_CONTENT_LOCATION.toLowerCase();
048        public static final String HEADER_CONTENT_TYPE = "Content-Type";
049        public static final String HEADER_CONTENT_TYPE_LC = HEADER_CONTENT_TYPE.toLowerCase();
050        public static final String HEADER_ETAG = "ETag";
051        public static final String HEADER_ETAG_LC = HEADER_ETAG.toLowerCase();
052        public static final String HEADER_IF_MATCH = "If-Match";
053        public static final String HEADER_IF_MATCH_LC = HEADER_IF_MATCH.toLowerCase();
054        public static final String HEADER_IF_MODIFIED_SINCE = "If-Modified-Since";
055        public static final String HEADER_IF_MODIFIED_SINCE_LC = HEADER_IF_MODIFIED_SINCE.toLowerCase();
056        public static final String HEADER_IF_NONE_MATCH = "If-None-Match";
057        public static final String HEADER_IF_NONE_MATCH_LC = HEADER_IF_NONE_MATCH.toLowerCase();
058        public static final String HEADER_LAST_MODIFIED = "Last-Modified";
059        public static final String HEADER_LAST_MODIFIED_LOWERCASE = HEADER_LAST_MODIFIED.toLowerCase();
060        public static final String HEADER_LOCATION = "Location";
061        public static final String HEADER_LOCATION_LC = HEADER_LOCATION.toLowerCase();
062        public static final String HEADER_RETRY_AFTER = "Retry-After";
063        public static final String HEADER_DATE = "Date";
064
065        // ==============================================================
066        // Standard FHIR headers
067        // ==============================================================
068
069        public static final String HEADER_IF_NONE_EXIST = "If-None-Exist";
070
071        // ==============================================================
072        // Standard CORS headers
073        // ==============================================================
074
075        public static final String HEADER_CORS_ORIGIN = "Origin";
076        public static final String HEADER_CORS_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
077        public static final String HEADER_CORS_ALLOW_HEADERS = "Access-Control-Allow-Headers";
078        public static final String HEADER_CORS_ALLOW_METHODS = "Access-Control-Allow-Methods";
079        public static final String HEADER_CORS_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
080        public static final String HEADER_CORS_EXPOSE_HEADERS = "Access-Control-Expose-Headers";
081        public static final String HEADER_CORS_REQUEST_HEADERS = "Access-Control-Request-Headers";
082        public static final String HEADER_CORS_REQUEST_METHOD = "Access-Control-Request-Method";
083        public static final String HEADER_CORS_MAX_AGE = "Access-Control-Max-Age";
084
085        // ==============================================================
086        // Common non-standard HTTP headers
087        // ==============================================================
088
089        public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
090        public static final String HEADER_COOKIE = "Cookie";
091        public static final String HEADER_PREFER = "Prefer";
092        public static final String HEADER_POWERED_BY = "X-Powered-By";
093        public static final String HEADER_REQUEST_ID = "X-Request-ID";
094        public static final String HEADER_X_CACHE = "X-Cache";
095        public static final String HEADER_X_REQUESTED_WITH = "X-Requested-With";
096        public static final String HEADER_X_CORRELATION_ID = "X-Correlation-ID";
097        public static final String HEADER_X_FORWARDED_HOST = "X-Forwarded-Host";
098        public static final String HEADER_X_FORWARDED_PROTO = "X-Forwarded-Proto";
099        public static final String HEADER_X_FORWARDED_PREFIX = "X-Forwarded-Prefix";
100        public static final String HEADER_X_FORWARDED_FOR = "X-Forwarded-For";
101        // This is used by clinical-reasoning to pass the timezone of the client
102        public static final String HEADER_CLIENT_TIMEZONE = "Timezone";
103
104        // ==============================================================
105        // Proprietary HAPI HTTP headers
106        // ==============================================================
107
108        public static final String HEADER_REQUEST_SOURCE = "X-Request-Source";
109        public static final String HEADER_REWRITE_HISTORY = "X-Rewrite-History";
110        public static final String HEADER_RETRY_ON_VERSION_CONFLICT = "X-Retry-On-Version-Conflict";
111        public static final String HEADER_X_SECURITY_CONTEXT = "X-Security-Context";
112        public static final String HEADER_CASCADE = "X-Cascade";
113        public static final String HEADER_X_PROGRESS = "X-Progress";
114        public static final String HEADER_X_PROGRESS_LC = HEADER_X_PROGRESS.toLowerCase();
115        public static final String HEADER_X_FHIR_STARTER = "X-FHIR-Starter";
116        public static final String HEADER_X_REQUEST_PARTITION_IDS = "X-Request-Partition-IDs";
117
118        // ==============================================================
119        // Other Constants
120        // ==============================================================
121
122        public static final String CT_TEXT_CSV = "text/csv";
123        public static final String CACHE_CONTROL_MAX_RESULTS = "max-results";
124        public static final String CACHE_CONTROL_NO_CACHE = "no-cache";
125        public static final String CACHE_CONTROL_NO_STORE = "no-store";
126        public static final String CHARSET_NAME_UTF8 = "UTF-8";
127        public static final Charset CHARSET_UTF8;
128        public static final String CHARSET_UTF8_CTSUFFIX = "; charset=" + CHARSET_NAME_UTF8;
129
130        public static final String CT_FHIR_JSON = "application/json+fhir";
131        public static final String CT_RDF_TURTLE = "application/x-turtle";
132        /**
133         * The FHIR MimeType for JSON encoding in FHIR DSTU3+
134         */
135        public static final String CT_FHIR_JSON_NEW = "application/fhir+json";
136
137        public static final String CT_FHIR_XML = "application/xml+fhir";
138
139        /**
140         * The FHIR MimeType for XML encoding in FHIR DSTU3+
141         */
142        public static final String CT_FHIR_XML_NEW = "application/fhir+xml";
143
144        public static final String CT_HTML = "text/html";
145        public static final String CT_HTML_WITH_UTF8 = "text/html" + CHARSET_UTF8_CTSUFFIX;
146        public static final String CT_JSON = "application/json";
147        public static final String CT_GRAPHQL = "application/graphql";
148        public static final String CT_JSON_PATCH = "application/json-patch+json";
149        public static final String CT_OCTET_STREAM = "application/octet-stream";
150        public static final String CT_TEXT = "text/plain";
151        public static final String CT_TEXT_WITH_UTF8 = CT_TEXT + CHARSET_UTF8_CTSUFFIX;
152        public static final String CT_TEXT_CDA = "text/xml+cda";
153        public static final String CT_X_FORM_URLENCODED = "application/x-www-form-urlencoded";
154        public static final String CT_XML = "application/xml";
155        public static final String CT_XML_PATCH = "application/xml-patch+xml";
156        public static final String ENCODING_GZIP = "gzip";
157        public static final String EXTOP_PROCESS_MESSAGE = "$process-message"; // Used in messaging
158        public static final String EXTOP_VALIDATE = "$validate";
159        public static final String EXTOP_VALIDATE_MODE = "mode";
160        public static final String EXTOP_VALIDATE_PROFILE = "profile";
161        public static final String EXTOP_VALIDATE_RESOURCE = "resource";
162        public static final String FORMAT_HTML = "html";
163        public static final String FORMAT_JSON = "json";
164        public static final String FORMAT_NDJSON = "ndjson";
165        public static final String FORMAT_XML = "xml";
166        public static final String CT_RDF_TURTLE_LEGACY = "text/turtle";
167        public static final String FORMAT_TURTLE = "ttl";
168
169        /**
170         * "text/html" and "html"
171         */
172        public static final Set<String> FORMATS_HTML;
173
174        public static final String FORMATS_HTML_JSON = "html/json";
175        public static final String FORMATS_HTML_XML = "html/xml";
176        public static final String FORMATS_HTML_TTL = "html/turtle";
177        public static final String HEADER_ACCEPT_VALUE_JSON_NON_LEGACY =
178                        CT_FHIR_JSON_NEW + ";q=1.0, " + CT_FHIR_JSON + ";q=0.9";
179        public static final String HEADER_ACCEPT_VALUE_XML_NON_LEGACY =
180                        CT_FHIR_XML_NEW + ";q=1.0, " + CT_FHIR_XML + ";q=0.9";
181        public static final String HEADER_ACCEPT_VALUE_XML_OR_JSON_LEGACY =
182                        CT_FHIR_XML + ";q=1.0, " + CT_FHIR_JSON + ";q=1.0";
183        public static final String HEADER_ACCEPT_VALUE_XML_OR_JSON_NON_LEGACY = CT_FHIR_XML_NEW + ";q=1.0, "
184                        + CT_FHIR_JSON_NEW + ";q=1.0, " + HEADER_ACCEPT_VALUE_XML_OR_JSON_LEGACY.replace("1.0", "0.9");
185        public static final String HEADER_AUTHORIZATION_VALPREFIX_BASIC = "Basic ";
186        public static final String HEADER_AUTHORIZATION_VALPREFIX_BEARER = "Bearer ";
187        public static final String HEADER_PREFER_HANDLING = "handling";
188        public static final String HEADER_PREFER_HANDLING_STRICT = "strict";
189        public static final String HEADER_PREFER_HANDLING_LENIENT = "lenient";
190        public static final String HEADER_PREFER_RETURN = "return";
191        public static final String HEADER_PREFER_RETURN_MINIMAL = "minimal";
192        public static final String HEADER_PREFER_RETURN_REPRESENTATION = "representation";
193        public static final String HEADER_PREFER_RETURN_OPERATION_OUTCOME = "OperationOutcome";
194        public static final String HEADER_SUFFIX_CT_UTF_8 = "; charset=UTF-8";
195        public static final String HEADERVALUE_CORS_ALLOW_METHODS_ALL = "GET, POST, PUT, DELETE, OPTIONS";
196        public static final String HEADER_MAX_RETRIES = "max-retries";
197        public static final String HEADER_RETRY = "retry";
198        public static final Map<Integer, String> HTTP_STATUS_NAMES;
199        public static final String LINK_FHIR_BASE = "fhir-base";
200        public static final String LINK_FIRST = "first";
201        public static final String LINK_LAST = "last";
202        public static final String LINK_NEXT = "next";
203        public static final String LINK_PREVIOUS = "previous";
204        public static final String LINK_SELF = "self";
205        public static final String OPENSEARCH_NS_OLDER = "http://purl.org/atompub/tombstones/1.0";
206        public static final String PARAM_ASYNC = "async"; // Used in messaging
207        public static final String PARAM_AT = "_at";
208        public static final String PARAM_ID = "_id";
209        public static final String PARAM_IN = "_in";
210        public static final String PARAM_ID_URL = "http://hl7.org/fhir/SearchParameter/Resource-id";
211        /**
212         * Used in paging links
213         */
214        public static final String PARAM_BUNDLETYPE = "_bundletype";
215
216        public static final String PARAM_FILTER = "_filter";
217        public static final String PARAM_CONTAINED = "_contained";
218        public static final String PARAM_CONTAINED_TYPE = "_containedType";
219        public static final String PARAM_CONTENT = "_content";
220        public static final String PARAM_CONTENT_URL = "http://hl7.org/fhir/SearchParameter/Resource-content";
221        public static final String PARAM_COUNT = "_count";
222        public static final String PARAM_OFFSET = "_offset";
223        public static final String PARAM_DELETE = "_delete";
224        public static final String PARAM_ELEMENTS = "_elements";
225        public static final String PARAM_ELEMENTS_EXCLUDE_MODIFIER = ":exclude";
226        public static final String PARAM_FORMAT = "_format";
227        public static final String PARAM_HAS = "_has";
228        public static final String PARAM_HISTORY = "_history";
229        public static final String PARAM_INCLUDE = "_include";
230        /**
231         * @since 7.0.0
232         */
233        public static final String PARAM_LANGUAGE = "_language";
234
235        public static final String PARAM_LANGUAGE_URL = "http://hl7.org/fhir/SearchParameter/Resource-language";
236
237        public static final String PARAM_INCLUDE_QUALIFIER_RECURSE = ":recurse";
238        public static final String PARAM_INCLUDE_RECURSE = "_include" + PARAM_INCLUDE_QUALIFIER_RECURSE;
239        public static final String PARAM_INCLUDE_QUALIFIER_ITERATE = ":iterate";
240        public static final String PARAM_INCLUDE_ITERATE = "_include" + PARAM_INCLUDE_QUALIFIER_ITERATE;
241        public static final String PARAM_LASTUPDATED = "_lastUpdated";
242        public static final String PARAM_NARRATIVE = "_narrative";
243        public static final String PARAM_PAGINGACTION = "_getpages";
244        public static final String PARAM_PAGINGOFFSET = "_getpagesoffset";
245        public static final String PARAM_PRETTY = "_pretty";
246        public static final String PARAM_PRETTY_VALUE_FALSE = "false";
247        public static final String PARAM_PRETTY_VALUE_TRUE = "true";
248        public static final String PARAM_PROFILE = "_profile";
249        public static final String PARAM_PID = "_pid";
250
251        public static final String PARAM_QUERY = "_query";
252        public static final String PARAM_RESPONSE_URL = "response-url"; // Used in messaging
253        public static final String PARAM_REVINCLUDE = "_revinclude";
254        public static final String PARAM_REVINCLUDE_RECURSE = PARAM_REVINCLUDE + PARAM_INCLUDE_QUALIFIER_RECURSE;
255        public static final String PARAM_REVINCLUDE_ITERATE = PARAM_REVINCLUDE + PARAM_INCLUDE_QUALIFIER_ITERATE;
256        public static final String PARAM_SEARCH = "_search";
257        public static final String PARAM_SECURITY = "_security";
258        public static final String PARAM_SINCE = "_since";
259        public static final String PARAM_SORT = "_sort";
260        public static final String PARAM_SORT_ASC = "_sort:asc";
261        public static final String PARAM_SORT_DESC = "_sort:desc";
262        public static final String PARAM_SOURCE = "_source";
263        public static final String PARAM_SUMMARY = "_summary";
264        public static final String PARAM_TAG = "_tag";
265        public static final String PARAM_LIST = "_list";
266        public static final String PARAM_TAGS = "_tags";
267        public static final String PARAM_TEXT = "_text";
268        public static final String PARAM_TEXT_URL = "http://hl7.org/fhir/SearchParameter/DomainResource-text";
269        public static final String PARAM_VALIDATE = "_validate";
270        public static final String PARAM_MDM = "_mdm";
271
272        public static final String PARAMQUALIFIER_MISSING = ":missing";
273        public static final String PARAMQUALIFIER_MISSING_FALSE = "false";
274        public static final String PARAMQUALIFIER_MISSING_TRUE = "true";
275        public static final String PARAMQUALIFIER_STRING_TEXT = ":text";
276        public static final String PARAMQUALIFIER_STRING_CONTAINS = ":contains";
277        public static final String PARAMQUALIFIER_STRING_EXACT = ":exact";
278        public static final String PARAMQUALIFIER_TOKEN_TEXT = ":text";
279        public static final String PARAMQUALIFIER_MDM = ":mdm";
280        public static final String PARAMQUALIFIER_NICKNAME = ":nickname";
281        public static final String PARAMQUALIFIER_TOKEN_OF_TYPE = ":of-type";
282        public static final String PARAMQUALIFIER_TOKEN_NOT = ":not";
283        public static final String PARAMQUALIFIER_TOKEN_IDENTIFIER = ":identifier";
284
285        public static final int STATUS_HTTP_200_OK = 200;
286        public static final int STATUS_HTTP_201_CREATED = 201;
287        public static final int STATUS_HTTP_204_NO_CONTENT = 204;
288        public static final int STATUS_HTTP_304_NOT_MODIFIED = 304;
289        public static final int STATUS_HTTP_400_BAD_REQUEST = 400;
290        public static final int STATUS_HTTP_401_CLIENT_UNAUTHORIZED = 401;
291        public static final int STATUS_HTTP_403_FORBIDDEN = 403;
292
293        public static final int STATUS_HTTP_404_NOT_FOUND = 404;
294        public static final int STATUS_HTTP_405_METHOD_NOT_ALLOWED = 405;
295        public static final int STATUS_HTTP_409_CONFLICT = 409;
296        public static final int STATUS_HTTP_410_GONE = 410;
297        public static final int STATUS_HTTP_412_PRECONDITION_FAILED = 412;
298        public static final int STATUS_HTTP_422_UNPROCESSABLE_ENTITY = 422;
299        public static final int STATUS_HTTP_500_INTERNAL_ERROR = 500;
300        public static final int STATUS_HTTP_501_NOT_IMPLEMENTED = 501;
301        public static final String TAG_SUBSETTED_CODE = "SUBSETTED";
302        public static final String TAG_SUBSETTED_SYSTEM_DSTU3 = "http://hl7.org/fhir/v3/ObservationValue";
303        public static final String TAG_SUBSETTED_SYSTEM_R4 = "http://terminology.hl7.org/CodeSystem/v3-ObservationValue";
304        public static final String URL_TOKEN_HISTORY = "_history";
305        public static final String URL_TOKEN_METADATA = "metadata";
306        public static final String OO_INFOSTATUS_PROCESSING = "processing";
307        public static final String PARAM_GRAPHQL_QUERY = "query";
308        public static final Charset CHARSET_US_ASCII;
309        public static final String PARAM_PAGEID = "_pageId";
310        public static final String JAVA_VALIDATOR_DETAILS_SYSTEM = "http://hl7.org/fhir/java-core-messageId";
311        public static final String PARAM_SEARCH_TOTAL_MODE = "_total";
312        public static final String CAPABILITYSTATEMENT_WEBSOCKET_URL =
313                        "http://hl7.org/fhir/StructureDefinition/capabilitystatement-websocket";
314        public static final String PARAMETER_CASCADE_DELETE = "_cascade";
315        public static final String PARAMETER_CASCADE_DELETE_MAX_ROUNDS = "_maxRounds";
316        public static final String HEADER_CASCADE_MAX_ROUNDS = "max-rounds";
317        public static final String CASCADE_DELETE = "delete";
318        public static final int MAX_RESOURCE_NAME_LENGTH = 100;
319        public static final String CACHE_CONTROL_PRIVATE = "private";
320        public static final String CT_FHIR_NDJSON = "application/fhir+ndjson";
321        public static final String CT_APP_NDJSON = "application/ndjson";
322        public static final String CT_APP_X_NDJSON = "application/x-ndjson";
323        public static final String CT_NDJSON = "ndjson";
324        public static final Set<String> CTS_NDJSON;
325        public static final Set<String> CTS_JSON =
326                        Set.of(CT_FHIR_JSON, CT_FHIR_JSON_NEW, CT_JSON, FORMAT_JSON, FORMATS_HTML_JSON);
327        public static final String HEADER_PREFER_RESPOND_ASYNC = "respond-async";
328        public static final int STATUS_HTTP_412_PAYLOAD_TOO_LARGE = 413;
329        public static final String OPERATION_NAME_GRAPHQL = "$graphql";
330        /**
331         * Note that this constant is used in a number of places including DB column lengths! Be careful if you decide to change it.
332         */
333        public static final int REQUEST_ID_LENGTH = 16;
334
335        public static final int STATUS_HTTP_202_ACCEPTED = 202;
336        /**
337         * Operation name for the $lastn operation
338         */
339        public static final String OPERATION_LASTN = "$lastn";
340
341        public static final String PARAM_FHIRPATH = "_fhirpath";
342        public static final String PARAM_TYPE = "_type";
343
344        /**
345         * {@link org.hl7.fhir.instance.model.api.IBaseResource#getUserData(String) User metadata key} used
346         * to store the partition ID (if any) associated with the given resource. Value for this
347         * key will be of type {@link ca.uhn.fhir.interceptor.model.RequestPartitionId}.
348         */
349        public static final String RESOURCE_PARTITION_ID = Constants.class.getName() + "_RESOURCE_PARTITION_ID";
350
351        public static final String PARTITION_IDS = "partitionIds";
352        public static final String CT_APPLICATION_GZIP = "application/gzip";
353        public static final String[] EMPTY_STRING_ARRAY = new String[0];
354        public static final String SUBSCRIPTION_MULTITYPE_PREFIX = "[";
355        public static final String SUBSCRIPTION_MULTITYPE_SUFFIX = "]";
356        public static final String SUBSCRIPTION_MULTITYPE_STAR = "*";
357        public static final String SUBSCRIPTION_STAR_CRITERIA =
358                        SUBSCRIPTION_MULTITYPE_PREFIX + SUBSCRIPTION_MULTITYPE_STAR + SUBSCRIPTION_MULTITYPE_SUFFIX;
359        public static final String INCLUDE_STAR = "*";
360        public static final String PARAMQUALIFIER_TOKEN_IN = ":in";
361        public static final String PARAMQUALIFIER_TOKEN_NOT_IN = ":not-in";
362        public static final String PARAMQUALIFIER_TOKEN_ABOVE = ":above";
363        public static final String PARAMQUALIFIER_TOKEN_BELOW = ":below";
364
365        public static final List<String> VALID_MODIFIERS = Collections.unmodifiableList(Arrays.asList(
366                        PARAMQUALIFIER_STRING_CONTAINS,
367                        PARAMQUALIFIER_STRING_EXACT,
368                        PARAMQUALIFIER_TOKEN_IN,
369                        PARAM_INCLUDE_QUALIFIER_ITERATE,
370                        PARAMQUALIFIER_MISSING,
371                        PARAMQUALIFIER_TOKEN_NOT_IN,
372                        PARAMQUALIFIER_TOKEN_OF_TYPE,
373                        PARAM_INCLUDE_QUALIFIER_RECURSE,
374                        PARAMQUALIFIER_TOKEN_TEXT));
375        /**
376         * The number of characters in a UUID (36)
377         */
378        public static final int UUID_LENGTH = 36;
379
380        public static final String BULK_DATA_ACCESS_IG_URL =
381                        "http://hl7.org/fhir/uv/bulkdata/CapabilityStatement/bulk-data";
382
383        /**
384         * Application configuration key used to enable or disable Hibernate Envers.
385         */
386        public static final String HIBERNATE_INTEGRATION_ENVERS_ENABLED = "hibernate.integration.envers.enabled";
387
388        public static final String OPENTELEMETRY_BASE_NAME = "io.hapifhir";
389
390        /**
391         * Contains a standard set of headers which are used by FHIR / HAPI FHIR, and therefore
392         * would make a useful set for CORS AllowedHeader declarations
393         */
394        public static final Set<String> CORS_ALLOWED_HEADERS;
395        /**
396         * Contains a standard set of HTTP Methods which are used by FHIR / HAPI FHIR, and therefore
397         * would make a useful set for CORS AllowedMethod declarations
398         */
399        public static final Set<String> CORS_ALLOWED_METHODS;
400
401        static {
402                CHARSET_UTF8 = StandardCharsets.UTF_8;
403                CHARSET_US_ASCII = StandardCharsets.ISO_8859_1;
404
405                HashSet<String> ctsNdjson = new HashSet<>();
406                ctsNdjson.add(CT_FHIR_NDJSON);
407                ctsNdjson.add(CT_APP_NDJSON);
408                ctsNdjson.add(CT_NDJSON);
409                ctsNdjson.add(CT_APP_X_NDJSON);
410                CTS_NDJSON = Collections.unmodifiableSet(ctsNdjson);
411
412                HashMap<Integer, String> statusNames = new HashMap<>();
413                statusNames.put(200, "OK");
414                statusNames.put(201, "Created");
415                statusNames.put(202, "Accepted");
416                statusNames.put(203, "Non-Authoritative Information");
417                statusNames.put(204, "No Content");
418                statusNames.put(205, "Reset Content");
419                statusNames.put(206, "Partial Content");
420                statusNames.put(207, "Multi-Status");
421                statusNames.put(208, "Already Reported");
422                statusNames.put(226, "IM Used");
423                statusNames.put(300, "Multiple Choices");
424                statusNames.put(301, "Moved Permanently");
425                statusNames.put(302, "Found");
426                statusNames.put(303, "See Other");
427                statusNames.put(304, "Not Modified");
428                statusNames.put(305, "Use Proxy");
429                statusNames.put(307, "Temporary Redirect");
430                statusNames.put(308, "Permanent Redirect");
431                statusNames.put(400, "Bad Request");
432                statusNames.put(401, "Unauthorized");
433                statusNames.put(402, "Payment Required");
434                statusNames.put(403, "Forbidden");
435                statusNames.put(404, "Not Found");
436                statusNames.put(405, "Method Not Allowed");
437                statusNames.put(406, "Not Acceptable");
438                statusNames.put(407, "Proxy Authentication Required");
439                statusNames.put(408, "Request Timeout");
440                statusNames.put(409, "Conflict");
441                statusNames.put(410, "Gone");
442                statusNames.put(411, "Length Required");
443                statusNames.put(412, "Precondition Failed");
444                statusNames.put(413, "Payload Too Large");
445                statusNames.put(414, "URI Too Long");
446                statusNames.put(415, "Unsupported Media Type");
447                statusNames.put(416, "Requested range not satisfiable");
448                statusNames.put(417, "Expectation Failed");
449                statusNames.put(418, "I'm a teapot");
450                statusNames.put(419, "Insufficient Space On Resource");
451                statusNames.put(420, "Method Failure");
452                statusNames.put(421, "Destination Locked");
453                statusNames.put(422, "Unprocessable Entity");
454                statusNames.put(423, "Locked");
455                statusNames.put(424, "Failed Dependency");
456                statusNames.put(426, "Upgrade Required");
457                statusNames.put(428, "Precondition Required");
458                statusNames.put(429, "Too Many Requests");
459                statusNames.put(431, "Request Header Fields Too Large");
460                statusNames.put(500, "Internal Server Error");
461                statusNames.put(501, "Not Implemented");
462                statusNames.put(502, "Bad Gateway");
463                statusNames.put(503, "Service Unavailable");
464                statusNames.put(504, "Gateway Timeout");
465                statusNames.put(505, "HTTP Version not supported");
466                statusNames.put(506, "Variant Also Negotiates");
467                statusNames.put(507, "Insufficient Storage");
468                statusNames.put(508, "Loop Detected");
469                statusNames.put(509, "Bandwidth Limit Exceeded");
470                statusNames.put(510, "Not Extended");
471                statusNames.put(511, "Network Authentication Required");
472                HTTP_STATUS_NAMES = Collections.unmodifiableMap(statusNames);
473
474                Set<String> formatsHtml = new HashSet<>();
475                formatsHtml.add(CT_HTML);
476                formatsHtml.add(FORMAT_HTML);
477                FORMATS_HTML = Collections.unmodifiableSet(formatsHtml);
478
479                // *********************************************************
480                // Update CorsInterceptor's constructor documentation if you change these:
481                // *********************************************************
482                HashSet<String> corsAllowedHeaders = new HashSet<>();
483                corsAllowedHeaders.add(HEADER_ACCEPT);
484                corsAllowedHeaders.add(Constants.HEADER_CORS_REQUEST_HEADERS);
485                corsAllowedHeaders.add(Constants.HEADER_CORS_REQUEST_METHOD);
486                corsAllowedHeaders.add(HEADER_CACHE_CONTROL);
487                corsAllowedHeaders.add(HEADER_CONTENT_TYPE);
488                corsAllowedHeaders.add(Constants.HEADER_CORS_ORIGIN);
489                corsAllowedHeaders.add(HEADER_PREFER);
490                corsAllowedHeaders.add(Constants.HEADER_X_FHIR_STARTER);
491                corsAllowedHeaders.add(HEADER_X_REQUESTED_WITH);
492                CORS_ALLOWED_HEADERS = Collections.unmodifiableSet(corsAllowedHeaders);
493
494                // *********************************************************
495                // Update CorsInterceptor's constructor documentation if you change these:
496                // *********************************************************
497                HashSet<String> corsAllowedMethods = new HashSet<>();
498                corsAllowedMethods.addAll(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"));
499                CORS_ALLOWED_METHODS = Collections.unmodifiableSet(corsAllowedMethods);
500        }
501
502        public static String codeSystemWithDefaultDescription(String theSystem) {
503                return defaultIfBlank(theSystem, "(none)");
504        }
505}