001/*
002 * #%L
003 * HAPI FHIR Storage api
004 * %%
005 * Copyright (C) 2014 - 2023 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.jpa.api.config;
021
022import ca.uhn.fhir.context.support.IValidationSupport;
023import ca.uhn.fhir.jpa.api.model.HistoryCountModeEnum;
024import ca.uhn.fhir.jpa.api.model.WarmCacheEntry;
025import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
026import ca.uhn.fhir.jpa.model.entity.StorageSettings;
027import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
028import ca.uhn.fhir.system.HapiSystemProperties;
029import ca.uhn.fhir.util.HapiExtensions;
030import ca.uhn.fhir.validation.FhirValidator;
031import com.google.common.collect.Sets;
032import org.apache.commons.io.FileUtils;
033import org.apache.commons.lang3.StringUtils;
034import org.apache.commons.lang3.Validate;
035import org.apache.commons.lang3.time.DateUtils;
036import org.hl7.fhir.r4.model.Bundle;
037import org.slf4j.Logger;
038import org.slf4j.LoggerFactory;
039
040import java.util.ArrayList;
041import java.util.Arrays;
042import java.util.Collections;
043import java.util.List;
044import java.util.Set;
045import java.util.TreeSet;
046import javax.annotation.Nonnull;
047import javax.annotation.Nullable;
048
049@SuppressWarnings("JavadocLinkAsPlainText")
050public class JpaStorageSettings extends StorageSettings {
051
052        /**
053         * Default value for {@link #setReuseCachedSearchResultsForMillis(Long)}: 60000ms (one minute)
054         */
055        public static final Long DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS = DateUtils.MILLIS_PER_MINUTE;
056        /**
057         * Default value for {@link #myTranslationCachesExpireAfterWriteInMinutes}: 60 minutes
058         *
059         * @see #myTranslationCachesExpireAfterWriteInMinutes
060         */
061        public static final Long DEFAULT_TRANSLATION_CACHES_EXPIRE_AFTER_WRITE_IN_MINUTES = 60L;
062        /**
063         * Default {@link #setBundleTypesAllowedForStorage(Set)} value:
064         * <ul>
065         * <li>collection</li>
066         * <li>document</li>
067         * <li>message</li>
068         * </ul>
069         */
070        @SuppressWarnings("WeakerAccess")
071        public static final Set<String> DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE =
072                        Collections.unmodifiableSet(new TreeSet<>(Sets.newHashSet(
073                                        Bundle.BundleType.COLLECTION.toCode(),
074                                        Bundle.BundleType.DOCUMENT.toCode(),
075                                        Bundle.BundleType.MESSAGE.toCode())));
076        // update setter javadoc if default changes
077        public static final int DEFAULT_MAX_EXPANSION_SIZE = 1000;
078        public static final HistoryCountModeEnum DEFAULT_HISTORY_COUNT_MODE =
079                        HistoryCountModeEnum.CACHED_ONLY_WITHOUT_OFFSET;
080        /**
081         * This constant applies to task enablement, e.g. {@link #setEnableTaskStaleSearchCleanup(boolean)}.
082         * <p>
083         * By default, all are enabled.
084         */
085        public static final boolean DEFAULT_ENABLE_TASKS = true;
086
087        public static final int DEFAULT_MAXIMUM_INCLUDES_TO_LOAD_PER_PAGE = 1000;
088        /**
089         * @since 5.5.0
090         */
091        public static final TagStorageModeEnum DEFAULT_TAG_STORAGE_MODE = TagStorageModeEnum.VERSIONED;
092
093        public static final int DEFAULT_EXPUNGE_BATCH_SIZE = 800;
094        public static final int DEFAULT_BUNDLE_BATCH_QUEUE_CAPACITY = 200;
095
096        public static final int DEFAULT_BULK_EXPORT_FILE_MAXIMUM_CAPACITY = 1_000;
097        /**
098         * Default value for {@link #setMaximumSearchResultCountInTransaction(Integer)}
099         *
100         * @see #setMaximumSearchResultCountInTransaction(Integer)
101         */
102        private static final Integer DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT_IN_TRANSACTION = null;
103
104        private static final Logger ourLog = LoggerFactory.getLogger(JpaStorageSettings.class);
105        private static final int DEFAULT_REINDEX_BATCH_SIZE = 800;
106        private static final int DEFAULT_MAXIMUM_DELETE_CONFLICT_COUNT = 60;
107        /**
108         * Child Configurations
109         */
110        private static final Integer DEFAULT_INTERNAL_SYNCHRONOUS_SEARCH_SIZE = 10000;
111
112        private static final boolean DEFAULT_PREVENT_INVALIDATING_CONDITIONAL_MATCH_CRITERIA = false;
113
114        /**
115         * Do not change default of {@code 0}!
116         *
117         * @since 4.1.0
118         */
119        private final int myPreExpandValueSetsDefaultOffset = 0;
120        /**
121         * update setter javadoc if default changes
122         */
123        @Nonnull
124        private final Long myTranslationCachesExpireAfterWriteInMinutes =
125                        DEFAULT_TRANSLATION_CACHES_EXPIRE_AFTER_WRITE_IN_MINUTES;
126        /**
127         * @since 5.5.0
128         */
129        @Nullable
130        private Integer myMaximumIncludesToLoadPerPage = DEFAULT_MAXIMUM_INCLUDES_TO_LOAD_PER_PAGE;
131        /**
132         * update setter javadoc if default changes
133         */
134        private boolean myAllowInlineMatchUrlReferences = true;
135
136        private boolean myAllowMultipleDelete;
137        /**
138         * update setter javadoc if default changes
139         */
140        private int myDeferIndexingForCodesystemsOfSize = 100;
141
142        private boolean myDeleteStaleSearches = true;
143        private boolean myEnforceReferentialIntegrityOnDelete = true;
144        private boolean myUniqueIndexesEnabled = true;
145        private boolean myUniqueIndexesCheckedBeforeSave = true;
146        private boolean myEnforceReferentialIntegrityOnWrite = true;
147        private SearchTotalModeEnum myDefaultTotalMode = null;
148        private int myEverythingIncludesFetchPageSize = 50;
149        private TagStorageModeEnum myTagStorageMode = DEFAULT_TAG_STORAGE_MODE;
150        /**
151         * update setter javadoc if default changes
152         */
153        private long myExpireSearchResultsAfterMillis = DateUtils.MILLIS_PER_HOUR;
154        /**
155         * update setter javadoc if default changes
156         */
157        private Integer myFetchSizeDefaultMaximum = null;
158
159        private int myMaximumExpansionSize = DEFAULT_MAX_EXPANSION_SIZE;
160        private Integer myMaximumSearchResultCountInTransaction = DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT_IN_TRANSACTION;
161        private ResourceEncodingEnum myResourceEncoding = ResourceEncodingEnum.JSONC;
162        /**
163         * update setter javadoc if default changes
164         */
165        private Integer myResourceMetaCountHardLimit = 1000;
166
167        private Long myReuseCachedSearchResultsForMillis = DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS;
168        private boolean mySchedulingDisabled;
169        private boolean mySuppressUpdatesWithNoChange = true;
170        private Integer myCacheControlNoStoreMaxResultsUpperLimit = 1000;
171        private Integer myCountSearchResultsUpTo = null;
172        private boolean myStatusBasedReindexingDisabled;
173        private IdStrategyEnum myResourceServerIdStrategy = IdStrategyEnum.SEQUENTIAL_NUMERIC;
174        private boolean myMarkResourcesForReindexingUponSearchParameterChange;
175        private boolean myExpungeEnabled;
176        private boolean myDeleteExpungeEnabled;
177        private int myExpungeBatchSize = DEFAULT_EXPUNGE_BATCH_SIZE;
178        private int myReindexThreadCount;
179        private int myExpungeThreadCount;
180        private Set<String> myBundleTypesAllowedForStorage;
181        private boolean myValidateSearchParameterExpressionsOnSave = true;
182
183        // start with a tiny number so our first page always loads quickly.
184        // If they fetch the second page, fetch more.
185        // Use prime sizes to avoid empty next links.
186        private List<Integer> mySearchPreFetchThresholds = Arrays.asList(13, 503, 2003, -1);
187        private List<WarmCacheEntry> myWarmCacheEntries = new ArrayList<>();
188        private boolean myEnforceReferenceTargetTypes = true;
189        private ClientIdStrategyEnum myResourceClientIdStrategy = ClientIdStrategyEnum.ALPHANUMERIC;
190        private boolean myFilterParameterEnabled = false;
191        private StoreMetaSourceInformationEnum myStoreMetaSourceInformation =
192                        StoreMetaSourceInformationEnum.SOURCE_URI_AND_REQUEST_ID;
193        private HistoryCountModeEnum myHistoryCountMode = DEFAULT_HISTORY_COUNT_MODE;
194        private int myInternalSynchronousSearchSize = DEFAULT_INTERNAL_SYNCHRONOUS_SEARCH_SIZE;
195        /**
196         * update setter javadoc if default changes
197         */
198        private Integer myMaximumDeleteConflictQueryCount = DEFAULT_MAXIMUM_DELETE_CONFLICT_COUNT;
199        /**
200         * Do not change default of {@code true}!
201         *
202         * @since 4.1.0
203         */
204        private boolean myPreExpandValueSets = true;
205        /**
206         * Do not change default of {@code 1000}!
207         *
208         * @since 4.1.0
209         */
210        private int myPreExpandValueSetsDefaultCount = 1000;
211        /**
212         * Do not change default of {@code 1000}!
213         *
214         * @since 4.1.0
215         */
216        private int myPreExpandValueSetsMaxCount = 1000;
217        /**
218         * Do not change default of {@code true}!
219         *
220         * @since 4.2.0
221         */
222        private boolean myPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets = true;
223        /**
224         * @since 5.0.0
225         */
226        private boolean myDeleteEnabled = true;
227        /**
228         * @since 5.1.0
229         */
230        private boolean myLastNEnabled = false;
231        /**
232         * @since 5.4.0
233         */
234        private boolean myMatchUrlCacheEnabled;
235        /**
236         * @since 5.5.0
237         */
238        private boolean myEnableTaskBulkImportJobExecution;
239        /**
240         * @since 5.5.0
241         */
242        private boolean myEnableTaskStaleSearchCleanup;
243        /**
244         * @since 5.5.0
245         */
246        private boolean myEnableTaskPreExpandValueSets;
247        /**
248         * @since 5.5.0
249         */
250        private boolean myEnableTaskResourceReindexing;
251        /**
252         * @since 5.5.0
253         */
254        private boolean myEnableTaskBulkExportJobExecution;
255
256        private boolean myAccountForDateIndexNulls;
257        /**
258         * @since 5.6.0
259         */
260        private String myHSearchIndexPrefix;
261
262        /**
263         * Activates the new HSearch indexing of search parameters.
264         * When active, string, token, and reference parameters will be indexed and
265         * queried within Hibernate Search.
266         *
267         * @since 5.6.0
268         */
269        private boolean myAdvancedHSearchIndexing = false;
270        /**
271         * If set to a positive number, any resources with a character length at or below the given number
272         * of characters will be stored inline in the <code>HFJ_RES_VER</code> table instead of using a
273         * separate LOB column.
274         *
275         * @since 5.7.0
276         */
277        private int myInlineResourceTextBelowSize = 0;
278
279        /**
280         * @since 5.7.0
281         */
282        private boolean myStoreResourceInHSearchIndex;
283
284        /**
285         * @see FhirValidator#isConcurrentBundleValidation()
286         * @since 5.7.0
287         */
288        private boolean myConcurrentBundleValidation;
289
290        /**
291         * Since 6.0.0
292         */
293        private boolean myAllowAutoInflateBinaries = true;
294        /**
295         * Since 6.0.0
296         */
297        private long myAutoInflateBinariesMaximumBytes = 10 * FileUtils.ONE_MB;
298
299        /**
300         * Since 6.0.0
301         */
302        private int myBulkExportFileRetentionPeriodHours = 2;
303
304        /**
305         * Since 6.2.0
306         */
307        private boolean myEnableBulkExportJobReuse = true;
308
309        /**
310         * Since 6.1.0
311         */
312        private boolean myUpdateWithHistoryRewriteEnabled = false;
313
314        /**
315         * Since 6.2.0
316         */
317        private boolean myPreserveRequestIdInResourceBody = false;
318
319        /**
320         * Since 6.2.0
321         */
322        private int myBulkExportFileMaximumCapacity = DEFAULT_BULK_EXPORT_FILE_MAXIMUM_CAPACITY;
323        /**
324         * Since 6.4.0
325         */
326        private boolean myJobFastTrackingEnabled = false;
327
328        /**
329         * Since 6.6.0
330         * Applies to MDM links.
331         */
332        private boolean myNonResourceDbHistoryEnabled = true;
333        /**
334         * Since 7.0.0
335         */
336        private boolean myResourceHistoryDbEnabled = true;
337
338        /**
339         * @since 7.0.0
340         */
341        @Nonnull
342        private IValidationSupport.IssueSeverity myIssueSeverityForCodeDisplayMismatch =
343                        IValidationSupport.IssueSeverity.WARNING;
344
345        /**
346         * This setting allows preventing a conditional update to invalidate the match criteria.
347         * <p/>
348         * By default, this is disabled unless explicitly enabled.
349         *
350         * @since 6.8.2
351         */
352        private boolean myPreventInvalidatingConditionalMatchCriteria =
353                        DEFAULT_PREVENT_INVALIDATING_CONDITIONAL_MATCH_CRITERIA;
354
355        /**
356         * Constructor
357         */
358        public JpaStorageSettings() {
359                setMarkResourcesForReindexingUponSearchParameterChange(true);
360                setReindexThreadCount(Runtime.getRuntime().availableProcessors());
361                setExpungeThreadCount(Runtime.getRuntime().availableProcessors());
362                setBundleTypesAllowedForStorage(DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE);
363
364                // Scheduled tasks are all enabled by default
365                setEnableTaskBulkImportJobExecution(DEFAULT_ENABLE_TASKS);
366                setEnableTaskBulkExportJobExecution(DEFAULT_ENABLE_TASKS);
367                setEnableTaskStaleSearchCleanup(DEFAULT_ENABLE_TASKS);
368                setEnableTaskPreExpandValueSets(DEFAULT_ENABLE_TASKS);
369                setEnableTaskResourceReindexing(DEFAULT_ENABLE_TASKS);
370
371                if (HapiSystemProperties.isDisableStatusBasedReindex()) {
372                        ourLog.info("Status based reindexing is DISABLED");
373                        setStatusBasedReindexingDisabled(true);
374                }
375                if (HapiSystemProperties.isUnitTestModeEnabled()) {
376                        setJobFastTrackingEnabled(true);
377                }
378                if (HapiSystemProperties.isPreventInvalidatingConditionalMatchCriteria()) {
379                        setPreventInvalidatingConditionalMatchCriteria(true);
380                }
381        }
382
383        /**
384         * If set to a positive number, any resources with a character length at or below the given number
385         * of characters will be stored inline in the <code>HFJ_RES_VER</code> table instead of using a
386         * separate LOB column.
387         *
388         * @since 5.7.0
389         */
390        public int getInlineResourceTextBelowSize() {
391                return myInlineResourceTextBelowSize;
392        }
393
394        /**
395         * If set to a positive number, any resources with a character length at or below the given number
396         * of characters will be stored inline in the <code>HFJ_RES_VER</code> table instead of using a
397         * separate LOB column.
398         *
399         * @since 5.7.0
400         */
401        public void setInlineResourceTextBelowSize(int theInlineResourceTextBelowSize) {
402                myInlineResourceTextBelowSize = theInlineResourceTextBelowSize;
403        }
404
405        /**
406         * Sets the tag storage mode for the server. Default is {@link TagStorageModeEnum#VERSIONED}.
407         *
408         * @since 5.5.0
409         */
410        @Nonnull
411        public TagStorageModeEnum getTagStorageMode() {
412                return myTagStorageMode;
413        }
414
415        /**
416         * Sets the tag storage mode for the server. Default is {@link TagStorageModeEnum#VERSIONED}.
417         *
418         * @since 5.5.0
419         */
420        public void setTagStorageMode(@Nonnull TagStorageModeEnum theTagStorageMode) {
421                Validate.notNull(theTagStorageMode, "theTagStorageMode must not be null");
422                myTagStorageMode = theTagStorageMode;
423        }
424
425        /**
426         * Specifies the maximum number of <code>_include</code> and <code>_revinclude</code> results to return in a
427         * single page of results. The default is <code>1000</code>, and <code>null</code> may be used
428         * to indicate that there is no limit.
429         *
430         * @since 5.5.0
431         */
432        @Nullable
433        public Integer getMaximumIncludesToLoadPerPage() {
434                return myMaximumIncludesToLoadPerPage;
435        }
436
437        /**
438         * Specifies the maximum number of <code>_include</code> and <code>_revinclude</code> results to return in a
439         * single page of results. The default is <code>1000</code>, and <code>null</code> may be used
440         * to indicate that there is no limit.
441         *
442         * @since 5.5.0
443         */
444        public void setMaximumIncludesToLoadPerPage(@Nullable Integer theMaximumIncludesToLoadPerPage) {
445                myMaximumIncludesToLoadPerPage = theMaximumIncludesToLoadPerPage;
446        }
447
448        /**
449         * When performing a FHIR history operation, a <code>Bundle.total</code> value is included in the
450         * response, indicating the total number of history entries. This response is calculated using a
451         * SQL COUNT query statement which can be expensive. This setting allows the results of the count
452         * query to be cached, resulting in a much lighter load on the server, at the expense of
453         * returning total values that may be slightly out of date. Total counts can also be disabled,
454         * or forced to always be accurate.
455         * <p>
456         * In {@link HistoryCountModeEnum#CACHED_ONLY_WITHOUT_OFFSET} mode, a loading cache is used to fetch the value,
457         * meaning that only one thread per JVM will fetch the count, and others will block while waiting
458         * for the cache to load, avoiding excessive load on the database.
459         * </p>
460         * <p>
461         * Default is {@link HistoryCountModeEnum#CACHED_ONLY_WITHOUT_OFFSET}
462         * </p>
463         *
464         * @since 5.4.0
465         */
466        public HistoryCountModeEnum getHistoryCountMode() {
467                return myHistoryCountMode;
468        }
469
470        /**
471         * When performing a FHIR history operation, a <code>Bundle.total</code> value is included in the
472         * response, indicating the total number of history entries. This response is calculated using a
473         * SQL COUNT query statement which can be expensive. This setting allows the results of the count
474         * query to be cached, resulting in a much lighter load on the server, at the expense of
475         * returning total values that may be slightly out of date. Total counts can also be disabled,
476         * or forced to always be accurate.
477         * <p>
478         * In {@link HistoryCountModeEnum#CACHED_ONLY_WITHOUT_OFFSET} mode, a loading cache is used to fetch the value,
479         * meaning that only one thread per JVM will fetch the count, and others will block while waiting
480         * for the cache to load, avoiding excessive load on the database.
481         * </p>
482         * <p>
483         * Default is {@link HistoryCountModeEnum#CACHED_ONLY_WITHOUT_OFFSET}
484         * </p>
485         *
486         * @since 5.4.0
487         */
488        public void setHistoryCountMode(@Nonnull HistoryCountModeEnum theHistoryCountMode) {
489
490                Validate.notNull(theHistoryCountMode, "theHistoryCountMode must not be null");
491                myHistoryCountMode = theHistoryCountMode;
492        }
493
494        /**
495         * If set to <code>true</code> (default is <code>false</code>) the <code>$lastn</code> operation will be enabled for
496         * indexing Observation resources. This operation involves creating a special set of tables in hsearch for
497         * discovering Observation resources. Enabling this setting increases the amount of storage space required, and can
498         * slow write operations, but can be very useful for searching for collections of Observations for some applications.
499         *
500         * @since 5.1.0
501         */
502        public boolean isLastNEnabled() {
503                return myLastNEnabled;
504        }
505
506        /**
507         * If set to <code>true</code> (default is <code>false</code>) the <code>$lastn</code> operation will be enabled for
508         * indexing Observation resources. This operation involves creating a special set of tables in hsearch for
509         * discovering Observation resources. Enabling this setting increases the amount of storage space required, and can
510         * slow write operations, but can be very useful for searching for collections of Observations for some applications.
511         *
512         * @since 5.1.0
513         */
514        public void setLastNEnabled(boolean theLastNEnabled) {
515                myLastNEnabled = theLastNEnabled;
516        }
517
518        /**
519         * Specifies the duration in minutes for which values will be retained after being
520         * written to the terminology translation cache. Defaults to 60.
521         */
522        @Nonnull
523        public Long getTranslationCachesExpireAfterWriteInMinutes() {
524                return myTranslationCachesExpireAfterWriteInMinutes;
525        }
526
527        /**
528         * If enabled, resolutions for match URLs (e.g. conditional create URLs, conditional update URLs, etc) will be
529         * cached in an in-memory cache. This cache can have a noticeable improvement on write performance on servers
530         * where conditional operations are frequently performed, but note that this cache will not be
531         * invalidated based on updates to resources so this may have detrimental effects.
532         * <p>
533         * Default is <code>false</code>
534         *
535         * @since 5.4.0
536         * @deprecated Deprecated in 5.5.0. Use {@link #isMatchUrlCacheEnabled()} instead (the name of this method is misleading)
537         */
538        @Deprecated
539        public boolean getMatchUrlCache() {
540                return myMatchUrlCacheEnabled;
541        }
542
543        /**
544         * If enabled, resolutions for match URLs (e.g. conditional create URLs, conditional update URLs, etc) will be
545         * cached in an in-memory cache. This cache can have a noticeable improvement on write performance on servers
546         * where conditional operations are frequently performed, but note that this cache will not be
547         * invalidated based on updates to resources so this may have detrimental effects.
548         * <p>
549         * Default is <code>false</code>
550         *
551         * @since 5.4.0
552         * @deprecated Deprecated in 5.5.0. Use {@link #setMatchUrlCacheEnabled(boolean)} instead (the name of this method is misleading)
553         */
554        @Deprecated
555        public void setMatchUrlCache(boolean theMatchUrlCache) {
556                myMatchUrlCacheEnabled = theMatchUrlCache;
557        }
558
559        /**
560         * If enabled, resolutions for match URLs (e.g. conditional create URLs, conditional update URLs, etc) will be
561         * cached in an in-memory cache. This cache can have a noticeable improvement on write performance on servers
562         * where conditional operations are frequently performed, but note that this cache will not be
563         * invalidated based on updates to resources so this may have detrimental effects.
564         * <p>
565         * Default is <code>false</code>
566         *
567         * @since 5.5.0
568         */
569        public boolean isMatchUrlCacheEnabled() {
570                return getMatchUrlCache();
571        }
572
573        /**
574         * If enabled, resolutions for match URLs (e.g. conditional create URLs, conditional update URLs, etc) will be
575         * cached in an in-memory cache. This cache can have a noticeable improvement on write performance on servers
576         * where conditional operations are frequently performed, but note that this cache will not be
577         * invalidated based on updates to resources so this may have detrimental effects.
578         * <p>
579         * Default is <code>false</code>
580         *
581         * @since 5.5.0
582         */
583        public void setMatchUrlCacheEnabled(boolean theMatchUrlCache) {
584                setMatchUrlCache(theMatchUrlCache);
585        }
586
587        /**
588         * If set to <code>true</code> (default is true) when a resource is being persisted,
589         * the target resource types of references will be validated to ensure that they
590         * are appropriate for the field containing the reference. This is generally a good idea
591         * because invalid reference target types may not be searchable.
592         */
593        public boolean isEnforceReferenceTargetTypes() {
594                return myEnforceReferenceTargetTypes;
595        }
596
597        /**
598         * If set to <code>true</code> (default is true) when a resource is being persisted,
599         * the target resource types of references will be validated to ensure that they
600         * are appropriate for the field containing the reference. This is generally a good idea
601         * because invalid reference target types may not be searchable.
602         */
603        public void setEnforceReferenceTargetTypes(boolean theEnforceReferenceTargetTypes) {
604                myEnforceReferenceTargetTypes = theEnforceReferenceTargetTypes;
605        }
606
607        /**
608         * If a non-null value is supplied (default is <code>null</code>), a default
609         * for the <code>_total</code> parameter may be specified here. For example,
610         * setting this value to {@link SearchTotalModeEnum#ACCURATE} will force a
611         * count to always be calculated for all searches. This can have a performance impact
612         * since it means that a count query will always be performed, but this is desirable
613         * for some solutions.
614         */
615        public SearchTotalModeEnum getDefaultTotalMode() {
616                return myDefaultTotalMode;
617        }
618
619        /**
620         * If a non-null value is supplied (default is <code>null</code>), a default
621         * for the <code>_total</code> parameter may be specified here. For example,
622         * setting this value to {@link SearchTotalModeEnum#ACCURATE} will force a
623         * count to always be calculated for all searches. This can have a performance impact
624         * since it means that a count query will always be performed, but this is desirable
625         * for some solutions.
626         */
627        public void setDefaultTotalMode(SearchTotalModeEnum theDefaultTotalMode) {
628                myDefaultTotalMode = theDefaultTotalMode;
629        }
630
631        /**
632         * Returns a set of searches that should be kept "warm", meaning that
633         * searches will periodically be performed in the background to
634         * keep results ready for this search
635         */
636        public List<WarmCacheEntry> getWarmCacheEntries() {
637                if (myWarmCacheEntries == null) {
638                        myWarmCacheEntries = new ArrayList<>();
639                }
640                return myWarmCacheEntries;
641        }
642
643        public void setWarmCacheEntries(List<WarmCacheEntry> theWarmCacheEntries) {
644                myWarmCacheEntries = theWarmCacheEntries;
645        }
646
647        /**
648         * If set to <code>true</code> (default is false), the reindexing of search parameters
649         * using a query on the HFJ_RESOURCE.SP_INDEX_STATUS column will be disabled completely.
650         * This query is just not efficient on Oracle and bogs the system down when there are
651         * a lot of resources. A more efficient way of doing this will be introduced
652         * in the next release of HAPI FHIR.
653         *
654         * @since 3.5.0
655         */
656        public boolean isStatusBasedReindexingDisabled() {
657                return myStatusBasedReindexingDisabled;
658        }
659
660        /**
661         * If set to <code>true</code> (default is false), the reindexing of search parameters
662         * using a query on the HFJ_RESOURCE.SP_INDEX_STATUS column will be disabled completely.
663         * This query is just not efficient on Oracle and bogs the system down when there are
664         * a lot of resources. A more efficient way of doing this will be introduced
665         * in the next release of HAPI FHIR.
666         *
667         * @since 3.5.0
668         */
669        public void setStatusBasedReindexingDisabled(boolean theStatusBasedReindexingDisabled) {
670                myStatusBasedReindexingDisabled = theStatusBasedReindexingDisabled;
671        }
672
673        /**
674         * This setting specifies the bundle types (<code>Bundle.type</code>) that
675         * are allowed to be stored as-is on the /Bundle endpoint.
676         *
677         * @see #DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE
678         */
679        public Set<String> getBundleTypesAllowedForStorage() {
680                return myBundleTypesAllowedForStorage;
681        }
682
683        /**
684         * This setting specifies the bundle types (<code>Bundle.type</code>) that
685         * are allowed to be stored as-is on the /Bundle endpoint.
686         *
687         * @see #DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE
688         */
689        public void setBundleTypesAllowedForStorage(Set<String> theBundleTypesAllowedForStorage) {
690                Validate.notNull(theBundleTypesAllowedForStorage, "theBundleTypesAllowedForStorage must not be null");
691                myBundleTypesAllowedForStorage = theBundleTypesAllowedForStorage;
692        }
693
694        /**
695         * Specifies the highest number that a client is permitted to use in a
696         * <code>Cache-Control: nostore, max-results=NNN</code>
697         * directive. If the client tries to exceed this limit, the
698         * request will be denied. Defaults to 1000.
699         */
700        public Integer getCacheControlNoStoreMaxResultsUpperLimit() {
701                return myCacheControlNoStoreMaxResultsUpperLimit;
702        }
703
704        /**
705         * Specifies the highest number that a client is permitted to use in a
706         * <code>Cache-Control: nostore, max-results=NNN</code>
707         * directive. If the client tries to exceed this limit, the
708         * request will be denied. Defaults to 1000.
709         */
710        public void setCacheControlNoStoreMaxResultsUpperLimit(Integer theCacheControlNoStoreMaxResults) {
711                myCacheControlNoStoreMaxResultsUpperLimit = theCacheControlNoStoreMaxResults;
712        }
713
714        /**
715         * When searching, if set to a non-null value (default is <code>null</code>) the
716         * search coordinator will attempt to find at least this many results
717         * before returning a response to the client. This parameter mainly affects
718         * whether a "total count" is included in the response bundle for searches that
719         * return large amounts of data.
720         * <p>
721         * For a search that returns 10000 results, if this value is set to
722         * 10000 the search coordinator will find all 10000 results
723         * prior to returning, so the initial response bundle will have the
724         * total set to 10000. If this value is null (or less than 10000)
725         * the response bundle will likely return slightly faster, but will
726         * not include the total. Subsequent page requests will likely
727         * include the total however, if they are performed after the
728         * search coordinator has found all results.
729         * </p>
730         * <p>
731         * Set this value to <code>0</code> to always load all
732         * results before returning.
733         * </p>
734         */
735        public Integer getCountSearchResultsUpTo() {
736                return myCountSearchResultsUpTo;
737        }
738
739        /**
740         * When searching, if set to a non-null value (default is <code>null</code>) the
741         * search coordinator will attempt to find at least this many results
742         * before returning a response to the client. This parameter mainly affects
743         * whether a "total count" is included in the response bundle for searches that
744         * return large amounts of data.
745         * <p>
746         * For a search that returns 10000 results, if this value is set to
747         * 10000 the search coordinator will find all 10000 results
748         * prior to returning, so the initial response bundle will have the
749         * total set to 10000. If this value is null (or less than 10000)
750         * the response bundle will likely return slightly faster, but will
751         * not include the total. Subsequent page requests will likely
752         * include the total however, if they are performed after the
753         * search coordinator has found all results.
754         * </p>
755         * <p>
756         * Set this value to <code>0</code> to always load all
757         * results before returning.
758         * </p>
759         */
760        public void setCountSearchResultsUpTo(Integer theCountSearchResultsUpTo) {
761                myCountSearchResultsUpTo = theCountSearchResultsUpTo;
762        }
763
764        /**
765         * When a code system is added that contains more than this number of codes,
766         * the code system will be indexed later in an incremental process in order to
767         * avoid overwhelming Lucene with a huge number of codes in a single operation.
768         * <p>
769         * Defaults to 100
770         * </p>
771         */
772        public int getDeferIndexingForCodesystemsOfSize() {
773                return myDeferIndexingForCodesystemsOfSize;
774        }
775
776        /**
777         * When a code system is added that contains more than this number of codes,
778         * the code system will be indexed later in an incremental process in order to
779         * avoid overwhelming Lucene with a huge number of codes in a single operation.
780         * <p>
781         * Defaults to 100
782         * </p>
783         */
784        public void setDeferIndexingForCodesystemsOfSize(int theDeferIndexingForCodesystemsOfSize) {
785                myDeferIndexingForCodesystemsOfSize = theDeferIndexingForCodesystemsOfSize;
786        }
787
788        /**
789         * Unlike with normal search queries, $everything queries have their _includes loaded by the main search thread and these included results
790         * are added to the normal search results instead of being added on as extras in a page. This means that they will not appear multiple times
791         * as the search results are paged over.
792         * <p>
793         * In order to recursively load _includes, we process the original results in batches of this size. Adjust with caution, increasing this
794         * value may improve performance but may also cause memory issues.
795         * </p>
796         * <p>
797         * The default value is 50
798         * </p>
799         */
800        public int getEverythingIncludesFetchPageSize() {
801                return myEverythingIncludesFetchPageSize;
802        }
803
804        /**
805         * Unlike with normal search queries, $everything queries have their _includes loaded by the main search thread and these included results
806         * are added to the normal search results instead of being added on as extras in a page. This means that they will not appear multiple times
807         * as the search results are paged over.
808         * <p>
809         * In order to recursively load _includes, we process the original results in batches of this size. Adjust with caution, increasing this
810         * value may improve performance but may also cause memory issues.
811         * </p>
812         * <p>
813         * The default value is 50
814         * </p>
815         */
816        public void setEverythingIncludesFetchPageSize(int theEverythingIncludesFetchPageSize) {
817                Validate.inclusiveBetween(1, Integer.MAX_VALUE, theEverythingIncludesFetchPageSize);
818                myEverythingIncludesFetchPageSize = theEverythingIncludesFetchPageSize;
819        }
820
821        /**
822         * Sets the number of milliseconds that search results for a given client search
823         * should be preserved before being purged from the database.
824         * <p>
825         * Search results are stored in the database so that they can be paged over multiple
826         * requests. After this
827         * number of milliseconds, they will be deleted from the database, and any paging links
828         * (next/prev links in search response bundles) will become invalid. Defaults to 1 hour.
829         * </p>
830         * <p>
831         * To disable this feature entirely, see {@link #setExpireSearchResults(boolean)}
832         * </p>
833         *
834         * @since 1.5
835         */
836        public long getExpireSearchResultsAfterMillis() {
837                return myExpireSearchResultsAfterMillis;
838        }
839
840        /**
841         * Sets the number of milliseconds that search results for a given client search
842         * should be preserved before being purged from the database.
843         * <p>
844         * Search results are stored in the database so that they can be paged over multiple
845         * requests. After this
846         * number of milliseconds, they will be deleted from the database, and any paging links
847         * (next/prev links in search response bundles) will become invalid. Defaults to 1 hour.
848         * </p>
849         * <p>
850         * To disable this feature entirely, see {@link #setExpireSearchResults(boolean)}
851         * </p>
852         *
853         * @since 1.5
854         */
855        public void setExpireSearchResultsAfterMillis(long theExpireSearchResultsAfterMillis) {
856                myExpireSearchResultsAfterMillis = theExpireSearchResultsAfterMillis;
857        }
858
859        /**
860         * Gets the default maximum number of results to load in a query.
861         * <p>
862         * For example, if the database has a million Patient resources in it, and
863         * the client requests <code>GET /Patient</code>, if this value is set
864         * to a non-null value (default is <code>null</code>) only this number
865         * of results will be fetched. Setting this value appropriately
866         * can be useful to improve performance in some situations.
867         * </p>
868         */
869        public Integer getFetchSizeDefaultMaximum() {
870                return myFetchSizeDefaultMaximum;
871        }
872
873        /**
874         * Gets the default maximum number of results to load in a query.
875         * <p>
876         * For example, if the database has a million Patient resources in it, and
877         * the client requests <code>GET /Patient</code>, if this value is set
878         * to a non-null value (default is <code>null</code>) only this number
879         * of results will be fetched. Setting this value appropriately
880         * can be useful to improve performance in some situations.
881         * </p>
882         */
883        public void setFetchSizeDefaultMaximum(Integer theFetchSizeDefaultMaximum) {
884                myFetchSizeDefaultMaximum = theFetchSizeDefaultMaximum;
885        }
886
887        /**
888         * See {@link #setMaximumExpansionSize(int)}
889         */
890        public int getMaximumExpansionSize() {
891                return myMaximumExpansionSize;
892        }
893
894        /**
895         * Sets the maximum number of codes that will be added to an in-memory valueset expansion before
896         * the operation will be failed as too costly. Note that this setting applies only to
897         * in-memory expansions and does not apply to expansions that are being pre-calculated.
898         * <p>
899         * The default value for this setting is 1000.
900         * </p>
901         */
902        public void setMaximumExpansionSize(int theMaximumExpansionSize) {
903                Validate.isTrue(theMaximumExpansionSize > 0, "theMaximumExpansionSize must be > 0");
904                myMaximumExpansionSize = theMaximumExpansionSize;
905        }
906
907        /**
908         * Provides the maximum number of results which may be returned by a search (HTTP GET) which
909         * is executed as a sub-operation within within a FHIR <code>transaction</code> or
910         * <code>batch</code> operation. For example, if this value is set to <code>100</code> and
911         * a FHIR transaction is processed with a sub-request for <code>Patient?gender=male</code>,
912         * the server will throw an error (and the transaction will fail) if there are more than
913         * 100 resources on the server which match this query.
914         * <p>
915         * The default value is <code>null</code>, which means that there is no limit.
916         * </p>
917         */
918        public Integer getMaximumSearchResultCountInTransaction() {
919                return myMaximumSearchResultCountInTransaction;
920        }
921
922        /**
923         * Provides the maximum number of results which may be returned by a search (HTTP GET) which
924         * is executed as a sub-operation within within a FHIR <code>transaction</code> or
925         * <code>batch</code> operation. For example, if this value is set to <code>100</code> and
926         * a FHIR transaction is processed with a sub-request for <code>Patient?gender=male</code>,
927         * the server will throw an error (and the transaction will fail) if there are more than
928         * 100 resources on the server which match this query.
929         * <p>
930         * The default value is <code>null</code>, which means that there is no limit.
931         * </p>
932         */
933        public void setMaximumSearchResultCountInTransaction(Integer theMaximumSearchResultCountInTransaction) {
934                myMaximumSearchResultCountInTransaction = theMaximumSearchResultCountInTransaction;
935        }
936
937        /**
938         * This setting controls the number of threads allocated to resource reindexing
939         * (which is only ever used if SearchParameters change, or a manual reindex is
940         * triggered due to a HAPI FHIR upgrade or some other reason).
941         * <p>
942         * The default value is set to the number of available processors
943         * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value
944         * for this setting must be a positive integer.
945         * </p>
946         */
947        public int getReindexThreadCount() {
948                return myReindexThreadCount;
949        }
950
951        /**
952         * This setting controls the number of threads allocated to resource reindexing
953         * (which is only ever used if SearchParameters change, or a manual reindex is
954         * triggered due to a HAPI FHIR upgrade or some other reason).
955         * <p>
956         * The default value is set to the number of available processors
957         * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value
958         * for this setting must be a positive integer.
959         * </p>
960         */
961        public void setReindexThreadCount(int theReindexThreadCount) {
962                myReindexThreadCount = theReindexThreadCount;
963                myReindexThreadCount = Math.max(myReindexThreadCount, 1); // Minimum of 1
964        }
965
966        /**
967         * This setting controls the number of threads allocated to the expunge operation
968         * <p>
969         * The default value is set to the number of available processors
970         * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value
971         * for this setting must be a positive integer.
972         * </p>
973         */
974        public int getExpungeThreadCount() {
975                return myExpungeThreadCount;
976        }
977
978        /**
979         * This setting controls the number of threads allocated to the expunge operation
980         * <p>
981         * The default value is set to the number of available processors
982         * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value
983         * for this setting must be a positive integer.
984         * </p>
985         */
986        public void setExpungeThreadCount(int theExpungeThreadCount) {
987                myExpungeThreadCount = theExpungeThreadCount;
988                myExpungeThreadCount = Math.max(myExpungeThreadCount, 1); // Minimum of 1
989        }
990
991        public ResourceEncodingEnum getResourceEncoding() {
992                return myResourceEncoding;
993        }
994
995        public void setResourceEncoding(ResourceEncodingEnum theResourceEncoding) {
996                myResourceEncoding = theResourceEncoding;
997        }
998
999        /**
1000         * If set, an individual resource will not be allowed to have more than the
1001         * given number of tags, profiles, and security labels (the limit is for the combined
1002         * total for all of these things on an individual resource).
1003         * <p>
1004         * If set to <code>null</code>, no limit will be applied.
1005         * </p>
1006         * <p>
1007         * The default value for this setting is 1000.
1008         * </p>
1009         */
1010        public Integer getResourceMetaCountHardLimit() {
1011                return myResourceMetaCountHardLimit;
1012        }
1013
1014        /**
1015         * If set, an individual resource will not be allowed to have more than the
1016         * given number of tags, profiles, and security labels (the limit is for the combined
1017         * total for all of these things on an individual resource).
1018         * <p>
1019         * If set to <code>null</code>, no limit will be applied.
1020         * </p>
1021         * <p>
1022         * The default value for this setting is 1000.
1023         * </p>
1024         */
1025        public void setResourceMetaCountHardLimit(Integer theResourceMetaCountHardLimit) {
1026                myResourceMetaCountHardLimit = theResourceMetaCountHardLimit;
1027        }
1028
1029        /**
1030         * Controls the behaviour when a client-assigned ID is encountered, i.e. an HTTP PUT
1031         * on a resource ID that does not already exist in the database.
1032         * <p>
1033         * Default is {@link ClientIdStrategyEnum#ALPHANUMERIC}
1034         * </p>
1035         */
1036        public ClientIdStrategyEnum getResourceClientIdStrategy() {
1037                return myResourceClientIdStrategy;
1038        }
1039
1040        /**
1041         * Controls the behaviour when a client-assigned ID is encountered, i.e. an HTTP PUT
1042         * on a resource ID that does not already exist in the database.
1043         * <p>
1044         * Default is {@link ClientIdStrategyEnum#ALPHANUMERIC}
1045         * </p>
1046         *
1047         * @param theResourceClientIdStrategy Must not be <code>null</code>
1048         */
1049        public void setResourceClientIdStrategy(ClientIdStrategyEnum theResourceClientIdStrategy) {
1050                Validate.notNull(theResourceClientIdStrategy, "theClientIdStrategy must not be null");
1051                myResourceClientIdStrategy = theResourceClientIdStrategy;
1052        }
1053
1054        /**
1055         * This setting configures the strategy to use in generating IDs for newly
1056         * created resources on the server. The default is {@link IdStrategyEnum#SEQUENTIAL_NUMERIC}.
1057         * <p>
1058         * This strategy is only used for server-assigned IDs, i.e. for HTTP POST
1059         * where the client is requesing that the server store a new resource and give
1060         * it an ID.
1061         * </p>
1062         */
1063        public IdStrategyEnum getResourceServerIdStrategy() {
1064                return myResourceServerIdStrategy;
1065        }
1066
1067        /**
1068         * This setting configures the strategy to use in generating IDs for newly
1069         * created resources on the server. The default is {@link IdStrategyEnum#SEQUENTIAL_NUMERIC}.
1070         * <p>
1071         * This strategy is only used for server-assigned IDs, i.e. for HTTP POST
1072         * where the client is requesing that the server store a new resource and give
1073         * it an ID.
1074         * </p>
1075         *
1076         * @param theResourceIdStrategy The strategy. Must not be <code>null</code>.
1077         */
1078        public void setResourceServerIdStrategy(IdStrategyEnum theResourceIdStrategy) {
1079                Validate.notNull(theResourceIdStrategy, "theResourceIdStrategy must not be null");
1080                myResourceServerIdStrategy = theResourceIdStrategy;
1081        }
1082
1083        /**
1084         * If set to a non {@literal null} value (default is {@link #DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS non null})
1085         * if an identical search is requested multiple times within this window, the same results will be returned
1086         * to multiple queries. For example, if this value is set to 1 minute and a client searches for all
1087         * patients named "smith", and then a second client also performs the same search within 1 minute,
1088         * the same cached results will be returned.
1089         * <p>
1090         * This approach can improve performance, especially under heavy load, but can also mean that
1091         * searches may potentially return slightly out-of-date results.
1092         * </p>
1093         * <p>
1094         * Note that if this is set to a non-null value, clients may override this setting by using
1095         * the <code>Cache-Control</code> header. If this is set to <code>null</code>, the Cache-Control
1096         * header will be ignored.
1097         * </p>
1098         */
1099        public Long getReuseCachedSearchResultsForMillis() {
1100                return myReuseCachedSearchResultsForMillis;
1101        }
1102
1103        /**
1104         * If set to a non {@literal null} value (default is {@link #DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS non null})
1105         * if an identical search is requested multiple times within this window, the same results will be returned
1106         * to multiple queries. For example, if this value is set to 1 minute and a client searches for all
1107         * patients named "smith", and then a second client also performs the same search within 1 minute,
1108         * the same cached results will be returned.
1109         * <p>
1110         * This approach can improve performance, especially under heavy load, but can also mean that
1111         * searches may potentially return slightly out-of-date results.
1112         * </p>
1113         * <p>
1114         * Note that if this is set to a non-null value, clients may override this setting by using
1115         * the <code>Cache-Control</code> header. If this is set to <code>null</code>, the Cache-Control
1116         * header will be ignored.
1117         * </p>
1118         */
1119        public void setReuseCachedSearchResultsForMillis(Long theReuseCachedSearchResultsForMillis) {
1120                myReuseCachedSearchResultsForMillis = theReuseCachedSearchResultsForMillis;
1121        }
1122
1123        /**
1124         * @see #setAllowInlineMatchUrlReferences(boolean)
1125         */
1126        public boolean isAllowInlineMatchUrlReferences() {
1127                return myAllowInlineMatchUrlReferences;
1128        }
1129
1130        /**
1131         * Should references containing match URLs be resolved and replaced in create and update operations. For
1132         * example, if this property is set to true and a resource is created containing a reference
1133         * to "Patient?identifier=12345", this is reference match URL will be resolved and replaced according
1134         * to the usual match URL rules.
1135         * <p>
1136         * Default is {@literal true} beginning in HAPI FHIR 2.4, since this
1137         * feature is now specified in the FHIR specification. (Previously it
1138         * was an experimental/proposed feature)
1139         * </p>
1140         *
1141         * @since 1.5
1142         */
1143        public void setAllowInlineMatchUrlReferences(boolean theAllowInlineMatchUrlReferences) {
1144                myAllowInlineMatchUrlReferences = theAllowInlineMatchUrlReferences;
1145        }
1146
1147        public boolean isAllowMultipleDelete() {
1148                return myAllowMultipleDelete;
1149        }
1150
1151        public void setAllowMultipleDelete(boolean theAllowMultipleDelete) {
1152                myAllowMultipleDelete = theAllowMultipleDelete;
1153        }
1154
1155        /**
1156         * When {@link #setAutoCreatePlaceholderReferenceTargets(boolean)} is enabled, if this
1157         * setting is set to <code>true</code> (default is <code>true</code>) and the source
1158         * reference has an identifier populated, the identifier will be copied to the target
1159         * resource.
1160         * <p>
1161         * When enabled, if an Observation contains a reference like the one below,
1162         * and no existing resource was found that matches the given ID, a new
1163         * one will be created and its <code>Patient.identifier</code> value will be
1164         * populated using the value from <code>Observation.subject.identifier</code>.
1165         * </p>
1166         * <pre>
1167         * {
1168         *   "resourceType": "Observation",
1169         *   "subject": {
1170         *     "reference": "Patient/ABC",
1171         *     "identifier": {
1172         *       "system": "http://foo",
1173         *       "value": "123"
1174         *     }
1175         *   }
1176         * }
1177         * </pre>
1178         * <p>
1179         * This method is often combined with {@link #setAllowInlineMatchUrlReferences(boolean)}.
1180         * </p>
1181         * <p>
1182         * In other words if an Observation contains a reference like the one below,
1183         * and no existing resource was found that matches the given match URL, a new
1184         * one will be created and its <code>Patient.identifier</code> value will be
1185         * populated using the value from <code>Observation.subject.identifier</code>.
1186         * </p>
1187         * <pre>
1188         * {
1189         *   "resourceType": "Observation",
1190         *   "subject": {
1191         *     "reference": "Patient?identifier=http://foo|123",
1192         *     "identifier": {
1193         *       "system": "http://foo",
1194         *       "value": "123"
1195         *     }
1196         *   }
1197         * }
1198         * </pre>
1199         * <p>
1200         * Note that the default for this setting was previously <code>false</code>, and was changed to <code>true</code>
1201         * in 5.4.0 with consideration to the following:
1202         * </p>
1203         * <pre>
1204         * CP = Auto-Create Placeholder Reference Targets
1205         * PI = Populate Identifier in Auto-Created Placeholder Reference Targets
1206         *
1207         * CP | PI
1208         * -------
1209         *  F | F  <- PI=F is ignored
1210         *  F | T  <- PI=T is ignored
1211         *  T | F  <- resources may reference placeholder reference targets that are never updated : (
1212         *  T | T  <- placeholder reference targets can be updated : )
1213         * </pre>
1214         * <p>
1215         * Where CP=T and PI=F, the following could happen:
1216         * </p>
1217         * <ol>
1218         *    <li>
1219         *       Resource instance A is created with a reference to resource instance B. B is a placeholder reference target
1220         *       without an identifier.
1221         *    </li>
1222         *    <li>
1223         *         Resource instance C is conditionally created using a match URL. It is not matched to B although these
1224         *         resources represent the same entity.
1225         *    </li>
1226         *    <li>
1227         *       A continues to reference placeholder B, and does not reference populated C.
1228         *    </li>
1229         * </ol>
1230         * <p>
1231         * There may be cases where configuring this setting to <code>false</code> would be appropriate; however, these are
1232         * exceptional cases that should be opt-in.
1233         * </p>
1234         *
1235         * @since 4.2.0
1236         */
1237        public boolean isPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets() {
1238                return myPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets;
1239        }
1240
1241        /**
1242         * When {@link #setAutoCreatePlaceholderReferenceTargets(boolean)} is enabled, if this
1243         * setting is set to <code>true</code> (default is <code>true</code>) and the source
1244         * reference has an identifier populated, the identifier will be copied to the target
1245         * resource.
1246         * <p>
1247         * When enabled, if an Observation contains a reference like the one below,
1248         * and no existing resource was found that matches the given ID, a new
1249         * one will be created and its <code>Patient.identifier</code> value will be
1250         * populated using the value from <code>Observation.subject.identifier</code>.
1251         * </p>
1252         * <pre>
1253         * {
1254         *   "resourceType": "Observation",
1255         *   "subject": {
1256         *     "reference": "Patient/ABC",
1257         *     "identifier": {
1258         *       "system": "http://foo",
1259         *       "value": "123"
1260         *     }
1261         *   }
1262         * }
1263         * </pre>
1264         * <p>
1265         * This method is often combined with {@link #setAllowInlineMatchUrlReferences(boolean)}.
1266         * </p>
1267         * <p>
1268         * In other words if an Observation contains a reference like the one below,
1269         * and no existing resource was found that matches the given match URL, a new
1270         * one will be created and its <code>Patient.identifier</code> value will be
1271         * populated using the value from <code>Observation.subject.identifier</code>.
1272         * </p>
1273         * <pre>
1274         * {
1275         *   "resourceType": "Observation",
1276         *   "subject": {
1277         *     "reference": "Patient?identifier=http://foo|123",
1278         *     "identifier": {
1279         *       "system": "http://foo",
1280         *       "value": "123"
1281         *     }
1282         *   }
1283         * }
1284         * </pre>
1285         * <p>
1286         * Note that the default for this setting was previously <code>false</code>, and was changed to <code>true</code>
1287         * in 5.4.0 with consideration to the following:
1288         * </p>
1289         * <pre>
1290         * CP = Auto-Create Placeholder Reference Targets
1291         * PI = Populate Identifier in Auto-Created Placeholder Reference Targets
1292         *
1293         * CP | PI
1294         * -------
1295         *  F | F  <- PI=F is ignored
1296         *  F | T  <- PI=T is ignored
1297         *  T | F  <- resources may reference placeholder reference targets that are never updated : (
1298         *  T | T  <- placeholder reference targets can be updated : )
1299         * </pre>
1300         * <p>
1301         * Where CP=T and PI=F, the following could happen:
1302         * </p>
1303         * <ol>
1304         *    <li>
1305         *       Resource instance A is created with a reference to resource instance B. B is a placeholder reference target
1306         *       without an identifier.
1307         *    </li>
1308         *    <li>
1309         *         Resource instance C is conditionally created using a match URL. It is not matched to B although these
1310         *         resources represent the same entity.
1311         *    </li>
1312         *    <li>
1313         *       A continues to reference placeholder B, and does not reference populated C.
1314         *    </li>
1315         * </ol>
1316         * <p>
1317         * There may be cases where configuring this setting to <code>false</code> would be appropriate; however, these are
1318         * exceptional cases that should be opt-in.
1319         * </p>
1320         *
1321         * @since 4.2.0
1322         */
1323        public void setPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets(
1324                        boolean thePopulateIdentifierInAutoCreatedPlaceholderReferenceTargets) {
1325                myPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets =
1326                                thePopulateIdentifierInAutoCreatedPlaceholderReferenceTargets;
1327        }
1328
1329        /**
1330         * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be
1331         * deleted even if other resources currently contain references to them.
1332         * <p>
1333         * This property can cause confusing results for clients of the server since searches, includes,
1334         * and other FHIR features may not behave as expected when referential integrity is not
1335         * preserved. Use this feature with caution.
1336         * </p>
1337         */
1338        public boolean isEnforceReferentialIntegrityOnDelete() {
1339                return myEnforceReferentialIntegrityOnDelete;
1340        }
1341
1342        /**
1343         * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be
1344         * deleted even if other resources currently contain references to them.
1345         * <p>
1346         * This property can cause confusing results for clients of the server since searches, includes,
1347         * and other FHIR features may not behave as expected when referential integrity is not
1348         * preserved. Use this feature with caution.
1349         * </p>
1350         */
1351        public void setEnforceReferentialIntegrityOnDelete(boolean theEnforceReferentialIntegrityOnDelete) {
1352                myEnforceReferentialIntegrityOnDelete = theEnforceReferentialIntegrityOnDelete;
1353        }
1354
1355        /**
1356         * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be
1357         * created or updated even if they contain references to local resources that do not exist.
1358         * <p>
1359         * For example, if a patient contains a reference to managing organization <code>Organization/FOO</code>
1360         * but FOO is not a valid ID for an organization on the server, the operation will be blocked unless
1361         * this property has been set to <code>false</code>
1362         * </p>
1363         * <p>
1364         * This property can cause confusing results for clients of the server since searches, includes,
1365         * and other FHIR features may not behave as expected when referential integrity is not
1366         * preserved. Use this feature with caution.
1367         * </p>
1368         */
1369        public boolean isEnforceReferentialIntegrityOnWrite() {
1370                return myEnforceReferentialIntegrityOnWrite;
1371        }
1372
1373        /**
1374         * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be
1375         * created or updated even if they contain references to local resources that do not exist.
1376         * <p>
1377         * For example, if a patient contains a reference to managing organization <code>Organization/FOO</code>
1378         * but FOO is not a valid ID for an organization on the server, the operation will be blocked unless
1379         * this property has been set to <code>false</code>
1380         * </p>
1381         * <p>
1382         * This property can cause confusing results for clients of the server since searches, includes,
1383         * and other FHIR features may not behave as expected when referential integrity is not
1384         * preserved. Use this feature with caution.
1385         * </p>
1386         */
1387        public void setEnforceReferentialIntegrityOnWrite(boolean theEnforceReferentialIntegrityOnWrite) {
1388                myEnforceReferentialIntegrityOnWrite = theEnforceReferentialIntegrityOnWrite;
1389        }
1390
1391        /**
1392         * If this is set to <code>false</code> (default is <code>true</code>) the stale search deletion
1393         * task will be disabled (meaning that search results will be retained in the database indefinitely). USE WITH CAUTION.
1394         * <p>
1395         * This feature is useful if you want to define your own process for deleting these (e.g. because
1396         * you are running in a cluster)
1397         * </p>
1398         */
1399        public boolean isExpireSearchResults() {
1400                return myDeleteStaleSearches;
1401        }
1402
1403        /**
1404         * If this is set to <code>false</code> (default is <code>true</code>) the stale search deletion
1405         * task will be disabled (meaning that search results will be retained in the database indefinitely). USE WITH CAUTION.
1406         * <p>
1407         * This feature is useful if you want to define your own process for deleting these (e.g. because
1408         * you are running in a cluster)
1409         * </p>
1410         */
1411        public void setExpireSearchResults(boolean theDeleteStaleSearches) {
1412                myDeleteStaleSearches = theDeleteStaleSearches;
1413        }
1414
1415        /**
1416         * If set to <code>true</code> (default is <code>false</code>), the $expunge operation
1417         * will be enabled on this server. This operation is potentially dangerous since it allows
1418         * a client to physically delete data in a way that can not be recovered (without resorting
1419         * to backups).
1420         * <p>
1421         * It is recommended to not enable this setting without appropriate security
1422         * in place on your server to prevent non-administrators from using this
1423         * operation.
1424         * </p>
1425         */
1426        public boolean isExpungeEnabled() {
1427                return myExpungeEnabled;
1428        }
1429
1430        /**
1431         * If set to <code>true</code> (default is <code>false</code>), the $expunge operation
1432         * will be enabled on this server. This operation is potentially dangerous since it allows
1433         * a client to physically delete data in a way that can not be recovered (without resorting
1434         * to backups).
1435         * <p>
1436         * It is recommended to not enable this setting without appropriate security
1437         * in place on your server to prevent non-administrators from using this
1438         * operation.
1439         * </p>
1440         */
1441        public void setExpungeEnabled(boolean theExpungeEnabled) {
1442                myExpungeEnabled = theExpungeEnabled;
1443        }
1444
1445        /**
1446         * If set to <code>true</code> (default is <code>false</code>), the _expunge parameter on the DELETE
1447         * operation will be enabled on this server. DELETE _expunge removes all data associated with a resource in a highly performant
1448         * way, skipping most of the the checks that are enforced with usual DELETE operations.  The only check
1449         * that is performed before deleting the data is that no other resources reference the resources about to
1450         * be deleted.  This operation is potentially dangerous since it allows
1451         * a client to physically delete data in a way that can not be recovered (without resorting
1452         * to backups).
1453         * <p>
1454         * It is recommended to not enable this setting without appropriate security
1455         * in place on your server to prevent non-administrators from using this
1456         * operation.
1457         * </p>
1458         */
1459        public boolean isDeleteExpungeEnabled() {
1460                return myDeleteExpungeEnabled;
1461        }
1462
1463        /**
1464         * If set to <code>true</code> (default is <code>false</code>), the _expunge parameter on the DELETE
1465         * operation will be enabled on this server. DELETE _expunge removes all data associated with a resource in a highly performant
1466         * way, skipping most of the the checks that are enforced with usual DELETE operations.  The only check
1467         * that is performed before deleting the resources and their indexes is that no other resources reference the resources about to
1468         * be deleted.  This operation is potentially dangerous since it allows
1469         * a client to physically delete data in a way that can not be recovered (without resorting
1470         * to backups).
1471         * <p>
1472         * It is recommended to not enable this setting without appropriate security
1473         * in place on your server to prevent non-administrators from using this
1474         * operation.
1475         * </p>
1476         */
1477        public void setDeleteExpungeEnabled(boolean theDeleteExpungeEnabled) {
1478                myDeleteExpungeEnabled = theDeleteExpungeEnabled;
1479        }
1480
1481        /**
1482         * The expunge batch size (default 800) determines the number of records deleted within a single transaction by the
1483         * expunge operation.  When expunging via DELETE ?_expunge=true, then this value determines the batch size for
1484         * the number of resources deleted and expunged at a time.
1485         */
1486        public int getExpungeBatchSize() {
1487                return myExpungeBatchSize;
1488        }
1489
1490        /**
1491         * The expunge batch size (default 800) determines the number of records deleted within a single transaction by the
1492         * expunge operation.  When expunging via DELETE ?_expunge=true, then this value determines the batch size for
1493         * the number of resources deleted and expunged at a time.
1494         */
1495        public void setExpungeBatchSize(int theExpungeBatchSize) {
1496                myExpungeBatchSize = theExpungeBatchSize;
1497        }
1498
1499        /**
1500         * Should resources be marked as needing reindexing when a
1501         * SearchParameter resource is added or changed. This should generally
1502         * be true (which is the default)
1503         */
1504        public boolean isMarkResourcesForReindexingUponSearchParameterChange() {
1505                return myMarkResourcesForReindexingUponSearchParameterChange;
1506        }
1507
1508        /**
1509         * Should resources be marked as needing reindexing when a
1510         * SearchParameter resource is added or changed. This should generally
1511         * be true (which is the default)
1512         */
1513        public void setMarkResourcesForReindexingUponSearchParameterChange(
1514                        boolean theMarkResourcesForReindexingUponSearchParameterChange) {
1515                myMarkResourcesForReindexingUponSearchParameterChange = theMarkResourcesForReindexingUponSearchParameterChange;
1516        }
1517
1518        public boolean isSchedulingDisabled() {
1519                return mySchedulingDisabled;
1520        }
1521
1522        public void setSchedulingDisabled(boolean theSchedulingDisabled) {
1523                mySchedulingDisabled = theSchedulingDisabled;
1524        }
1525
1526        /**
1527         * If set to {@literal true} (default is true), if a client performs an update which does not actually
1528         * result in any chance to a given resource (e.g. an update where the resource body matches the
1529         * existing resource body in the database) the operation will succeed but a new version (and corresponding history
1530         * entry) will not actually be created. The existing resource version will be returned to the client.
1531         * <p>
1532         * If set to {@literal false}, all updates will result in the creation of a new version
1533         * </p>
1534         */
1535        public boolean isSuppressUpdatesWithNoChange() {
1536                return mySuppressUpdatesWithNoChange;
1537        }
1538
1539        /**
1540         * If set to {@literal true} (default is true), if a client performs an update which does not actually
1541         * result in any chance to a given resource (e.g. an update where the resource body matches the
1542         * existing resource body in the database) the operation will succeed but a new version (and corresponding history
1543         * entry) will not actually be created. The existing resource version will be returned to the client.
1544         * <p>
1545         * If set to {@literal false}, all updates will result in the creation of a new version
1546         * </p>
1547         */
1548        public void setSuppressUpdatesWithNoChange(boolean theSuppressUpdatesWithNoChange) {
1549                mySuppressUpdatesWithNoChange = theSuppressUpdatesWithNoChange;
1550        }
1551
1552        /**
1553         * When using {@link #setUniqueIndexesEnabled(boolean) unique indexes}, if this
1554         * setting is set to <code>true</code> (default is <code>true</code>) the system
1555         * will test for the existence of a particular unique index value prior to saving
1556         * a new one.
1557         * <p>
1558         * This causes friendlier error messages to be generated, but adds an
1559         * extra round-trip to the database for eavh save so it can cause
1560         * a small performance hit.
1561         * </p>
1562         */
1563        public boolean isUniqueIndexesCheckedBeforeSave() {
1564                return myUniqueIndexesCheckedBeforeSave;
1565        }
1566
1567        /**
1568         * When using {@link #setUniqueIndexesEnabled(boolean) unique indexes}, if this
1569         * setting is set to <code>true</code> (default is <code>true</code>) the system
1570         * will test for the existence of a particular unique index value prior to saving
1571         * a new one.
1572         * <p>
1573         * This causes friendlier error messages to be generated, but adds an
1574         * extra round-trip to the database for each save so it can cause
1575         * a small performance hit.
1576         * </p>
1577         */
1578        public void setUniqueIndexesCheckedBeforeSave(boolean theUniqueIndexesCheckedBeforeSave) {
1579                myUniqueIndexesCheckedBeforeSave = theUniqueIndexesCheckedBeforeSave;
1580        }
1581
1582        /**
1583         * If set to <code>true</code> (default is <code>true</code>), indexes will be
1584         * created for search parameters marked as {@link HapiExtensions#EXT_SP_UNIQUE}.
1585         * This is a HAPI FHIR specific extension which can be used to specify that no more than one
1586         * resource can exist which matches a given criteria, using a database constraint to
1587         * enforce this.
1588         */
1589        public boolean isUniqueIndexesEnabled() {
1590                return myUniqueIndexesEnabled;
1591        }
1592
1593        /**
1594         * If set to <code>true</code> (default is <code>true</code>), indexes will be
1595         * created for search parameters marked as {@link HapiExtensions#EXT_SP_UNIQUE}.
1596         * This is a HAPI FHIR specific extension which can be used to specify that no more than one
1597         * resource can exist which matches a given criteria, using a database constraint to
1598         * enforce this.
1599         */
1600        public void setUniqueIndexesEnabled(boolean theUniqueIndexesEnabled) {
1601                myUniqueIndexesEnabled = theUniqueIndexesEnabled;
1602        }
1603
1604        /**
1605         * If <code>true</code> (default is <code>true</code>), before allowing a
1606         * SearchParameter resource to be stored (create, update, etc.) the
1607         * expression will be performed against an empty resource to ensure that
1608         * the FHIRPath executor is able to process it.
1609         * <p>
1610         * This should proabably always be set to true, but is configurable
1611         * in order to support some unit tests.
1612         * </p>
1613         */
1614        public boolean isValidateSearchParameterExpressionsOnSave() {
1615                return myValidateSearchParameterExpressionsOnSave;
1616        }
1617
1618        /**
1619         * If <code>true</code> (default is <code>true</code>), before allowing a
1620         * SearchParameter resource to be stored (create, update, etc.) the
1621         * expression will be performed against an empty resource to ensure that
1622         * the FHIRPath executor is able to process it.
1623         * <p>
1624         * This should proabably always be set to true, but is configurable
1625         * in order to support some unit tests.
1626         * </p>
1627         */
1628        public void setValidateSearchParameterExpressionsOnSave(boolean theValidateSearchParameterExpressionsOnSave) {
1629                myValidateSearchParameterExpressionsOnSave = theValidateSearchParameterExpressionsOnSave;
1630        }
1631
1632        /**
1633         * This setting sets the number of search results to prefetch. For example, if this list
1634         * is set to [100, 1000, -1] then the server will initially load 100 results and not
1635         * attempt to load more. If the user requests subsequent page(s) of results and goes
1636         * past 100 results, the system will load the next 900 (up to the following threshold of 1000).
1637         * The system will progressively work through these thresholds.
1638         *
1639         * <p>
1640         * A threshold of -1 means to load all results. Note that if the final threshold is a
1641         * number other than <code>-1</code>, the system will never prefetch more than the
1642         * given number.
1643         * </p>
1644         */
1645        public List<Integer> getSearchPreFetchThresholds() {
1646                return mySearchPreFetchThresholds;
1647        }
1648
1649        /**
1650         * This setting sets the number of search results to prefetch. For example, if this list
1651         * is set to [100, 1000, -1] then the server will initially load 100 results and not
1652         * attempt to load more. If the user requests subsequent page(s) of results and goes
1653         * past 100 results, the system will load the next 900 (up to the following threshold of 1000).
1654         * The system will progressively work through these thresholds.
1655         *
1656         * <p>
1657         * A threshold of -1 means to load all results. Note that if the final threshold is a
1658         * number other than <code>-1</code>, the system will never prefetch more than the
1659         * given number.
1660         * </p>
1661         */
1662        public void setSearchPreFetchThresholds(List<Integer> thePreFetchThresholds) {
1663                Validate.isTrue(thePreFetchThresholds.size() > 0, "thePreFetchThresholds must not be empty");
1664                int last = 0;
1665                for (Integer nextInt : thePreFetchThresholds) {
1666                        Validate.isTrue(nextInt > 0 || nextInt == -1, nextInt + " is not a valid prefetch threshold");
1667                        Validate.isTrue(nextInt != last, "Prefetch thresholds must be sequential");
1668                        Validate.isTrue(nextInt > last || nextInt == -1, "Prefetch thresholds must be sequential");
1669                        Validate.isTrue(last != -1, "Prefetch thresholds must be sequential");
1670                        last = nextInt;
1671                }
1672                mySearchPreFetchThresholds = thePreFetchThresholds;
1673        }
1674
1675        /**
1676         * If set to <code>true</code> the _filter search parameter will be enabled on this server. Note that _filter
1677         * is very powerful, but also potentially dangerous as it can allow a user to create a query for which there
1678         * are no indexes or efficient query plans for the database to leverage while performing the query.
1679         * As a result, this feature is recommended only for servers where the querying applications are known in advance
1680         * and a database administrator can properly tune the database for the resulting queries.
1681         */
1682        public boolean isFilterParameterEnabled() {
1683                return myFilterParameterEnabled;
1684        }
1685
1686        /**
1687         * If set to <code>true</code> the _filter search parameter will be enabled on this server. Note that _filter
1688         * is very powerful, but also potentially dangerous as it can allow a user to create a query for which there
1689         * are no indexes or efficient query plans for the database to leverage while performing the query.
1690         * As a result, this feature is recommended only for servers where the querying applications are known in advance
1691         * and a database administrator can properly tune the database for the resulting queries.
1692         */
1693        public void setFilterParameterEnabled(boolean theFilterParameterEnabled) {
1694                myFilterParameterEnabled = theFilterParameterEnabled;
1695        }
1696
1697        /**
1698         * If enabled, resource source information (<code>Resource.meta.source</code>) will be persisted along with
1699         * each resource. This adds extra table and index space so it should be disabled if it is not being
1700         * used.
1701         * <p>
1702         * Default is {@link StoreMetaSourceInformationEnum#SOURCE_URI_AND_REQUEST_ID}
1703         * </p>
1704         */
1705        public StoreMetaSourceInformationEnum getStoreMetaSourceInformation() {
1706                return myStoreMetaSourceInformation;
1707        }
1708
1709        /**
1710         * If enabled, resource source information (<code>Resource.meta.source</code>) will be persisted along with
1711         * each resource. This adds extra table and index space so it should be disabled if it is not being
1712         * used.
1713         * <p>
1714         * Default is {@link StoreMetaSourceInformationEnum#SOURCE_URI_AND_REQUEST_ID}
1715         * </p>
1716         */
1717        public void setStoreMetaSourceInformation(StoreMetaSourceInformationEnum theStoreMetaSourceInformation) {
1718                Validate.notNull(theStoreMetaSourceInformation, "theStoreMetaSourceInformation must not be null");
1719                myStoreMetaSourceInformation = theStoreMetaSourceInformation;
1720        }
1721
1722        /**
1723         * <p>
1724         * If set to {@code true}, ValueSets and expansions are stored in terminology tables. This is to facilitate
1725         * optimization of the $expand operation on large ValueSets.
1726         * </p>
1727         * <p>
1728         * The default value for this setting is {@code true}.
1729         * </p>
1730         *
1731         * @since 4.1.0
1732         */
1733        public boolean isPreExpandValueSets() {
1734                return myPreExpandValueSets;
1735        }
1736
1737        /**
1738         * <p>
1739         * If set to {@code true}, ValueSets and expansions are stored in terminology tables. This is to facilitate
1740         * optimization of the $expand operation on large ValueSets.
1741         * </p>
1742         * <p>
1743         * The default value for this setting is {@code true}.
1744         * </p>
1745         *
1746         * @since 4.1.0
1747         */
1748        public void setPreExpandValueSets(boolean thePreExpandValueSets) {
1749                myPreExpandValueSets = thePreExpandValueSets;
1750        }
1751
1752        /**
1753         * <p>
1754         * This is the default value of {@code offset} parameter for the ValueSet {@code $expand} operation when
1755         * {@link JpaStorageSettings#isPreExpandValueSets()} returns {@code true}.
1756         * </p>
1757         * <p>
1758         * The default value for this setting is {@code 0}.
1759         * </p>
1760         *
1761         * @since 4.1.0
1762         */
1763        public int getPreExpandValueSetsDefaultOffset() {
1764                return myPreExpandValueSetsDefaultOffset;
1765        }
1766
1767        /**
1768         * <p>
1769         * This is the default value of {@code count} parameter for the ValueSet {@code $expand} operation when
1770         * {@link JpaStorageSettings#isPreExpandValueSets()} returns {@code true}.
1771         * </p>
1772         * <p>
1773         * The default value for this setting is {@code 1000}.
1774         * </p>
1775         *
1776         * @since 4.1.0
1777         */
1778        public int getPreExpandValueSetsDefaultCount() {
1779                return myPreExpandValueSetsDefaultCount;
1780        }
1781
1782        /**
1783         * <p>
1784         * This is the default value of {@code count} parameter for the ValueSet {@code $expand} operation when
1785         * {@link JpaStorageSettings#isPreExpandValueSets()} returns {@code true}.
1786         * </p>
1787         * <p>
1788         * If {@code thePreExpandValueSetsDefaultCount} is greater than
1789         * {@link JpaStorageSettings#getPreExpandValueSetsMaxCount()}, the lesser value is used.
1790         * </p>
1791         * <p>
1792         * The default value for this setting is {@code 1000}.
1793         * </p>
1794         *
1795         * @since 4.1.0
1796         */
1797        public void setPreExpandValueSetsDefaultCount(int thePreExpandValueSetsDefaultCount) {
1798                myPreExpandValueSetsDefaultCount = Math.min(thePreExpandValueSetsDefaultCount, getPreExpandValueSetsMaxCount());
1799        }
1800
1801        /**
1802         * <p>
1803         * This is the max value of {@code count} parameter for the ValueSet {@code $expand} operation when
1804         * {@link JpaStorageSettings#isPreExpandValueSets()} returns {@code true}.
1805         * </p>
1806         * <p>
1807         * The default value for this setting is {@code 1000}.
1808         * </p>
1809         *
1810         * @since 4.1.0
1811         */
1812        public int getPreExpandValueSetsMaxCount() {
1813                return myPreExpandValueSetsMaxCount;
1814        }
1815
1816        /**
1817         * <p>
1818         * This is the max value of {@code count} parameter for the ValueSet {@code $expand} operation when
1819         * {@link JpaStorageSettings#isPreExpandValueSets()} returns {@code true}.
1820         * </p>
1821         * <p>
1822         * If {@code thePreExpandValueSetsMaxCount} is lesser than
1823         * {@link JpaStorageSettings#getPreExpandValueSetsDefaultCount()}, the default {@code count} is lowered to the
1824         * new max {@code count}.
1825         * </p>
1826         * <p>
1827         * The default value for this setting is {@code 1000}.
1828         * </p>
1829         *
1830         * @since 4.1.0
1831         */
1832        public void setPreExpandValueSetsMaxCount(int thePreExpandValueSetsMaxCount) {
1833                myPreExpandValueSetsMaxCount = thePreExpandValueSetsMaxCount;
1834                setPreExpandValueSetsDefaultCount(
1835                                Math.min(getPreExpandValueSetsDefaultCount(), getPreExpandValueSetsMaxCount()));
1836        }
1837
1838        /**
1839         * This setting should be disabled (set to <code>false</code>) on servers that are not allowing
1840         * deletes. Default is <code>true</code>. If deletes are disabled, some checks for resource
1841         * deletion can be skipped, which improves performance. This is particularly helpful when large
1842         * amounts of data containing client-assigned IDs are being loaded, but it can also improve
1843         * search performance.
1844         *
1845         * @since 5.0.0
1846         */
1847        public boolean isDeleteEnabled() {
1848                return myDeleteEnabled;
1849        }
1850
1851        /**
1852         * This setting should be disabled (set to <code>false</code>) on servers that are not allowing
1853         * deletes. Default is <code>true</code>. If deletes are disabled, some checks for resource
1854         * deletion can be skipped, which improves performance. This is particularly helpful when large
1855         * amounts of data containing client-assigned IDs are being loaded, but it can also improve
1856         * search performance.
1857         *
1858         * @since 5.0.0
1859         */
1860        public void setDeleteEnabled(boolean theDeleteEnabled) {
1861                myDeleteEnabled = theDeleteEnabled;
1862        }
1863
1864        /**
1865         * <p>
1866         * This determines the maximum number of conflicts that should be fetched and handled while retrying a delete of a resource.
1867         * This can also be thought of as the maximum number of rounds of cascading deletion.
1868         * </p>
1869         * <p>
1870         * The default value for this setting is {@code 60}.
1871         * </p>
1872         *
1873         * @since 5.1.0
1874         */
1875        public Integer getMaximumDeleteConflictQueryCount() {
1876                return myMaximumDeleteConflictQueryCount;
1877        }
1878
1879        /**
1880         * <p>
1881         * This determines the maximum number of conflicts that should be fetched and handled while retrying a delete of a resource.
1882         * This can also be thought of as the maximum number of rounds of cascading deletion.
1883         * </p>
1884         * <p>
1885         * The default value for this setting is {@code 60}.
1886         * </p>
1887         *
1888         * @since 5.1.0
1889         */
1890        public void setMaximumDeleteConflictQueryCount(Integer theMaximumDeleteConflictQueryCount) {
1891                myMaximumDeleteConflictQueryCount = theMaximumDeleteConflictQueryCount;
1892        }
1893
1894        /**
1895         * <p>
1896         * This determines whether $binary-access-write operations should first load the InputStream into memory before persisting the
1897         * contents to the database. This needs to be enabled for MS SQL Server as this DB requires that the blob size be known
1898         * in advance.
1899         * </p>
1900         * <p>
1901         * Note that this setting should be enabled with caution as it can lead to significant demands on memory.
1902         * </p>
1903         * <p>
1904         * The default value for this setting is {@code false}.
1905         * </p>
1906         *
1907         * @since 5.1.0
1908         * @deprecated In 5.2.0 this setting no longer does anything
1909         */
1910        @Deprecated
1911        public void setPreloadBlobFromInputStream(Boolean thePreloadBlobFromInputStream) {
1912                // ignore
1913        }
1914
1915        /**
1916         * <p>
1917         * This determines the internal search size that is run synchronously during operations such as searching for
1918         * Code System IDs by System and Code
1919         * </p>
1920         *
1921         * @since 5.4.0
1922         */
1923        public Integer getInternalSynchronousSearchSize() {
1924                return myInternalSynchronousSearchSize;
1925        }
1926
1927        /**
1928         * <p>
1929         * This determines the internal search size that is run synchronously during operations such as searching for
1930         * Code System IDs by System and Code
1931         * </p>
1932         *
1933         * @since 5.4.0
1934         */
1935        public void setInternalSynchronousSearchSize(Integer theInternalSynchronousSearchSize) {
1936                myInternalSynchronousSearchSize = theInternalSynchronousSearchSize;
1937        }
1938
1939        /**
1940         * If this is enabled (this is the default), this server will attempt to activate and run <b>Bulk Import</b>
1941         * batch jobs. Otherwise, this server will not.
1942         *
1943         * @since 5.5.0
1944         */
1945        public boolean isEnableTaskBulkImportJobExecution() {
1946                return myEnableTaskBulkImportJobExecution;
1947        }
1948
1949        /**
1950         * If this is enabled (this is the default), this server will attempt to activate and run <b>Bulk Import</b>
1951         * batch jobs. Otherwise, this server will not.
1952         *
1953         * @since 5.5.0
1954         */
1955        public void setEnableTaskBulkImportJobExecution(boolean theEnableTaskBulkImportJobExecution) {
1956                myEnableTaskBulkImportJobExecution = theEnableTaskBulkImportJobExecution;
1957        }
1958
1959        /**
1960         * If this is enabled (this is the default), this server will attempt to activate and run <b>Bulk Export</b>
1961         * batch jobs. Otherwise, this server will not.
1962         *
1963         * @since 5.5.0
1964         */
1965        public boolean isEnableTaskBulkExportJobExecution() {
1966                return myEnableTaskBulkExportJobExecution;
1967        }
1968
1969        /**
1970         * If this is enabled (this is the default), this server will attempt to activate and run <b>Bulk Export</b>
1971         * batch jobs. Otherwise, this server will not.
1972         *
1973         * @since 5.5.0
1974         */
1975        public void setEnableTaskBulkExportJobExecution(boolean theEnableTaskBulkExportJobExecution) {
1976                myEnableTaskBulkExportJobExecution = theEnableTaskBulkExportJobExecution;
1977        }
1978
1979        /**
1980         * If this is enabled (this is the default), this server will attempt to pre-expand any ValueSets that
1981         * have been uploaded and are not yet pre-expanded. Otherwise, this server will not.
1982         *
1983         * @since 5.5.0
1984         */
1985        public boolean isEnableTaskPreExpandValueSets() {
1986                return myEnableTaskPreExpandValueSets;
1987        }
1988
1989        /**
1990         * If this is enabled (this is the default), this server will attempt to pre-expand any ValueSets that
1991         * have been uploaded and are not yet pre-expanded. Otherwise, this server will not.
1992         *
1993         * @since 5.5.0
1994         */
1995        public void setEnableTaskPreExpandValueSets(boolean theEnableTaskPreExpandValueSets) {
1996                myEnableTaskPreExpandValueSets = theEnableTaskPreExpandValueSets;
1997        }
1998
1999        /**
2000         * If this is enabled (this is the default), this server will periodically scan for and try to delete
2001         * stale searches in the database. Otherwise, this server will not.
2002         *
2003         * @since 5.5.0
2004         */
2005        public boolean isEnableTaskStaleSearchCleanup() {
2006                return myEnableTaskStaleSearchCleanup;
2007        }
2008
2009        /**
2010         * If this is enabled (this is the default), this server will periodically scan for and try to delete
2011         * stale searches in the database. Otherwise, this server will not.
2012         *
2013         * @since 5.5.0
2014         */
2015        public void setEnableTaskStaleSearchCleanup(boolean theEnableTaskStaleSearchCleanup) {
2016                myEnableTaskStaleSearchCleanup = theEnableTaskStaleSearchCleanup;
2017        }
2018
2019        /**
2020         * If this is enabled (this is the default), this server will attempt to run resource reindexing jobs.
2021         * Otherwise, this server will not.
2022         *
2023         * @since 5.5.0
2024         */
2025        public boolean isEnableTaskResourceReindexing() {
2026                return myEnableTaskResourceReindexing;
2027        }
2028
2029        /**
2030         * If this is enabled (this is the default), this server will attempt to run resource reindexing jobs.
2031         * Otherwise, this server will not.
2032         *
2033         * @since 5.5.0
2034         */
2035        public void setEnableTaskResourceReindexing(boolean theEnableTaskResourceReindexing) {
2036                myEnableTaskResourceReindexing = theEnableTaskResourceReindexing;
2037        }
2038
2039        /**
2040         * If set to true (default is false), date indexes will account for null values in the range columns. As of 5.3.0
2041         * we no longer place null values in these columns, but legacy data may exist that still has these values. Note that
2042         * enabling this results in more complexity in the search SQL.
2043         *
2044         * @since 5.5.0
2045         */
2046        public boolean isAccountForDateIndexNulls() {
2047                return myAccountForDateIndexNulls;
2048        }
2049
2050        /**
2051         * If set to true (default is false), date indexes will account for null values in the range columns. As of 5.3.0
2052         * we no longer place null values in these columns, but legacy data may exist that still has these values. Note that
2053         * enabling this results in more complexity in the search SQL.
2054         *
2055         * @since 5.5.0
2056         */
2057        public void setAccountForDateIndexNulls(boolean theAccountForDateIndexNulls) {
2058                myAccountForDateIndexNulls = theAccountForDateIndexNulls;
2059        }
2060
2061        public boolean canDeleteExpunge() {
2062                return isAllowMultipleDelete() && isExpungeEnabled() && isDeleteExpungeEnabled();
2063        }
2064
2065        public String cannotDeleteExpungeReason() {
2066                List<String> reasons = new ArrayList<>();
2067                if (!isAllowMultipleDelete()) {
2068                        reasons.add("Multiple Delete");
2069                }
2070                if (!isExpungeEnabled()) {
2071                        reasons.add("Expunge");
2072                }
2073                if (!isDeleteExpungeEnabled()) {
2074                        reasons.add("Delete Expunge");
2075                }
2076                String retval = "Delete Expunge is not supported on this server.  ";
2077                if (reasons.size() == 1) {
2078                        retval += reasons.get(0) + " is disabled.";
2079                } else {
2080                        retval += "The following configurations are disabled: " + StringUtils.join(reasons, ", ");
2081                }
2082                return retval;
2083        }
2084
2085        /**
2086         * Sets a prefix for any indexes created when interacting with hsearch. This will apply to fulltext search indexes
2087         * and terminology expansion indexes.
2088         *
2089         * @since 5.6.0
2090         */
2091        public String getHSearchIndexPrefix() {
2092                return myHSearchIndexPrefix;
2093        }
2094
2095        /**
2096         * Sets a prefix for any indexes created when interacting with hsearch. This will apply to fulltext search indexes
2097         * and terminology expansion indexes.
2098         *
2099         * @since 5.6.0
2100         */
2101        public void setHSearchIndexPrefix(String thePrefix) {
2102                myHSearchIndexPrefix = thePrefix;
2103        }
2104
2105        /**
2106         * Is HSearch indexing enabled beyond _contains or _text?
2107         *
2108         * @since 5.6.0
2109         */
2110        public boolean isAdvancedHSearchIndexing() {
2111                return myAdvancedHSearchIndexing;
2112        }
2113
2114        /**
2115         * Enable/disable HSearch indexing enabled beyond _contains or _text.
2116         * <p>
2117         * String, token, and reference parameters can be indexed in HSearch.
2118         * This extends token search to support :text searches, as well as supporting
2119         * :contains and :text on string parameters.
2120         *
2121         * @since 5.6.0
2122         */
2123        public void setAdvancedHSearchIndexing(boolean theAdvancedHSearchIndexing) {
2124                this.myAdvancedHSearchIndexing = theAdvancedHSearchIndexing;
2125        }
2126
2127        /**
2128         * Is storing of Resource in HSearch index enabled?
2129         *
2130         * @since 5.7.0
2131         */
2132        public boolean isStoreResourceInHSearchIndex() {
2133                return myStoreResourceInHSearchIndex;
2134        }
2135
2136        /**
2137         * <p>
2138         * Enable Resource to be stored inline with HSearch index mappings.
2139         * This is useful in cases where after performing a search operation the resulting resource identifiers don't have to be
2140         * looked up in the persistent storage, but rather the inline stored resource can be used instead.
2141         * </p>
2142         * <p>
2143         * For e.g - Storing Observation resource in HSearch index would be useful when performing
2144         * <a href="https://www.hl7.org/fhir/observation-operation-lastn.html">$lastn</a> operation.
2145         * </p>
2146         *
2147         * @since 5.7.0
2148         */
2149        public void setStoreResourceInHSearchIndex(boolean theStoreResourceInHSearchIndex) {
2150                myStoreResourceInHSearchIndex = theStoreResourceInHSearchIndex;
2151        }
2152
2153        /**
2154         * @see FhirValidator#isConcurrentBundleValidation()
2155         * @since 5.7.0
2156         */
2157        public boolean isConcurrentBundleValidation() {
2158                return myConcurrentBundleValidation;
2159        }
2160
2161        /**
2162         * @see FhirValidator#isConcurrentBundleValidation()
2163         * @since 5.7.0
2164         */
2165        public JpaStorageSettings setConcurrentBundleValidation(boolean theConcurrentBundleValidation) {
2166                myConcurrentBundleValidation = theConcurrentBundleValidation;
2167                return this;
2168        }
2169
2170        /**
2171         * This setting indicates whether binaries are allowed to be automatically inflated from external storage during requests.
2172         * Default is true.
2173         *
2174         * @return whether binaries are allowed to be automatically inflated from external storage during requests.
2175         * @since 6.0.0
2176         */
2177        public boolean isAllowAutoInflateBinaries() {
2178                return myAllowAutoInflateBinaries;
2179        }
2180
2181        /**
2182         * This setting indicates whether binaries are allowed to be automatically inflated from external storage during requests.
2183         * Default is true.
2184         *
2185         * @param theAllowAutoDeExternalizingBinaries the value to set.
2186         * @since 6.0.0
2187         */
2188        public void setAllowAutoInflateBinaries(boolean theAllowAutoDeExternalizingBinaries) {
2189                myAllowAutoInflateBinaries = theAllowAutoDeExternalizingBinaries;
2190        }
2191
2192        /**
2193         * This setting controls how many bytes of binaries will be automatically inflated from external storage during requests.
2194         * which contain binary data.
2195         * Default is 10MB
2196         *
2197         * @return the number of bytes to de-externalize during requests.
2198         * @since 6.0.0
2199         */
2200        public long getAutoInflateBinariesMaximumBytes() {
2201                return myAutoInflateBinariesMaximumBytes;
2202        }
2203
2204        /**
2205         * This setting controls how many bytes of binaries will be automatically inflated from external storage during requests.
2206         * which contain binary data.
2207         * Default is 10MB
2208         *
2209         * @param theAutoInflateBinariesMaximumBytes the maximum number of bytes to de-externalize.
2210         * @since 6.0.0
2211         */
2212        public void setAutoInflateBinariesMaximumBytes(long theAutoInflateBinariesMaximumBytes) {
2213                myAutoInflateBinariesMaximumBytes = theAutoInflateBinariesMaximumBytes;
2214        }
2215
2216        /**
2217         * This setting controls how long Bulk Export collection entities will be retained after job start.
2218         * Default is 2 hours. Setting this value to 0 or less will cause Bulk Export collection entities to never be expired.
2219         *
2220         * @since 6.0.0
2221         */
2222        public int getBulkExportFileRetentionPeriodHours() {
2223                return myBulkExportFileRetentionPeriodHours;
2224        }
2225
2226        /**
2227         * This setting controls how long Bulk Export collection entities will be retained after job start.
2228         * Default is 2 hours. Setting this value to 0 or less will cause Bulk Export collection entities to never be expired.
2229         *
2230         * @since 6.0.0
2231         */
2232        public void setBulkExportFileRetentionPeriodHours(int theBulkExportFileRetentionPeriodHours) {
2233                myBulkExportFileRetentionPeriodHours = theBulkExportFileRetentionPeriodHours;
2234        }
2235
2236        /**
2237         * This setting controls whether, upon receiving a request for an $export operation, if a batch job already exists
2238         * that exactly matches the new request, the system should attempt to reuse the batch job. Default is true.
2239         */
2240        public boolean getEnableBulkExportJobReuse() {
2241                return myEnableBulkExportJobReuse;
2242        }
2243
2244        /**
2245         * This setting controls whether, upon receiving a request for an $export operation, if a batch job already exists
2246         * that exactly matches the new request, the system should attempt to reuse the batch job. Default is true.
2247         */
2248        public void setEnableBulkExportJobReuse(boolean theEnableBulkExportJobReuse) {
2249                myEnableBulkExportJobReuse = theEnableBulkExportJobReuse;
2250        }
2251
2252        /**
2253         * This setting indicates whether updating the history of a resource is allowed.
2254         * Default is false.
2255         *
2256         * @since 6.1.0
2257         */
2258        public boolean isUpdateWithHistoryRewriteEnabled() {
2259                return myUpdateWithHistoryRewriteEnabled;
2260        }
2261
2262        /**
2263         * This setting indicates whether updating the history of a resource is allowed.
2264         * Default is false.
2265         *
2266         * @since 6.1.0
2267         */
2268        public void setUpdateWithHistoryRewriteEnabled(boolean theUpdateWithHistoryRewriteEnabled) {
2269                myUpdateWithHistoryRewriteEnabled = theUpdateWithHistoryRewriteEnabled;
2270        }
2271
2272        /**
2273         * This setting indicate whether a providedResource.meta.source requestID (source#requestID)
2274         * should be preserved or overwritten.
2275         *
2276         * @since 6.2.0
2277         */
2278        public boolean isPreserveRequestIdInResourceBody() {
2279                return myPreserveRequestIdInResourceBody;
2280        }
2281
2282        /**
2283         * This setting indicate whether a providedResource.meta.source requestID (source#requestID)
2284         * should be preserved or overwritten.
2285         * Default is false. This means that a client provided requestId will be overwritten.
2286         *
2287         * @since 6.2.0
2288         */
2289        public void setPreserveRequestIdInResourceBody(boolean thePreserveRequestIdInResourceBody) {
2290                myPreserveRequestIdInResourceBody = thePreserveRequestIdInResourceBody;
2291        }
2292
2293        /**
2294         * This setting controls how many resources will be stored in each binary file created by a bulk export.
2295         * Default is 1000 resources per file.
2296         *
2297         * @since 6.2.0
2298         */
2299        public int getBulkExportFileMaximumCapacity() {
2300                return myBulkExportFileMaximumCapacity;
2301        }
2302
2303        /**
2304         * This setting controls how many resources will be stored in each binary file created by a bulk export.
2305         * Default is 1000 resources per file.
2306         *
2307         * @since 6.2.0
2308         */
2309        public void setBulkExportFileMaximumCapacity(int theBulkExportFileMaximumCapacity) {
2310                myBulkExportFileMaximumCapacity = theBulkExportFileMaximumCapacity;
2311        }
2312
2313        /**
2314         * If this setting is enabled, then gated batch jobs that produce only one chunk will immediately trigger a batch
2315         * maintenance job.  This may be useful for testing, but is not recommended for production use.
2316         *
2317         * @since 6.4.0
2318         */
2319        public boolean isJobFastTrackingEnabled() {
2320                return myJobFastTrackingEnabled;
2321        }
2322
2323        /**
2324         * If this setting is enabled, then gated batch jobs that produce only one chunk will immediately trigger a batch
2325         * maintenance job.  This may be useful for testing, but is not recommended for production use.
2326         *
2327         * @since 6.4.0
2328         */
2329        public void setJobFastTrackingEnabled(boolean theJobFastTrackingEnabled) {
2330                myJobFastTrackingEnabled = theJobFastTrackingEnabled;
2331        }
2332
2333        /**
2334         * If set to {@literal false} (default is {@literal true}), the server will not
2335         * preserve resource history and will delete previous versions of resources when
2336         * a resource is updated.
2337         * <p>
2338         * Note that this does not make the server completely version-less. Resources will
2339         * still have a version number which increases every time a resource is modified,
2340         * operations such as vread and history will still be supported, and features
2341         * such as ETags and ETag-aware updates will still work. Disabling this setting
2342         * simply means that when a resource is updated, the previous version of the
2343         * resource will be expunged. This could be done in order to conserve space, or
2344         * in cases where there is no business value to storing previous versions of
2345         * resources.
2346         * </p>
2347         *
2348         * @since 7.0.0
2349         */
2350        public boolean isResourceDbHistoryEnabled() {
2351                return myResourceHistoryDbEnabled;
2352        }
2353
2354        /**
2355         * If set to {@literal false} (default is {@literal true}), the server will not
2356         * preserve resource history and will delete previous versions of resources when
2357         * a resource is updated.
2358         * <p>
2359         * Note that this does not make the server completely version-less. Resources will
2360         * still have a version number which increases every time a resource is modified,
2361         * operations such as vread and history will still be supported, and features
2362         * such as ETags and ETag-aware updates will still work. Disabling this setting
2363         * simply means that when a resource is updated, the previous version of the
2364         * resource will be expunged. This could be done in order to conserve space, or
2365         * in cases where there is no business value to storing previous versions of
2366         * resources.
2367         * </p>
2368         *
2369         * @since 7.0.0
2370         */
2371        public void setResourceDbHistoryEnabled(boolean theResourceHistoryEnabled) {
2372                myResourceHistoryDbEnabled = theResourceHistoryEnabled;
2373        }
2374
2375        /**
2376         * This setting controls whether MdmLink and other non-resource DB history is enabled.
2377         * <p/>
2378         * By default, this is enabled unless explicitly disabled.
2379         *
2380         * @return Whether non-resource DB history is enabled (default is true);
2381         * @since 6.6.0
2382         */
2383        public boolean isNonResourceDbHistoryEnabled() {
2384                return myNonResourceDbHistoryEnabled;
2385        }
2386
2387        /**
2388         * This setting controls the validation issue severity to report when a code validation
2389         * finds that the code is present in the given CodeSystem, but the display name being
2390         * validated doesn't match the expected value(s). Defaults to
2391         * {@link ca.uhn.fhir.context.support.IValidationSupport.IssueSeverity#WARNING}. Set this
2392         * value to {@link ca.uhn.fhir.context.support.IValidationSupport.IssueSeverity#INFORMATION}
2393         * if you don't want to see display name validation issues at all in resource validation
2394         * outcomes.
2395         *
2396         * @since 7.0.0
2397         */
2398        @Nonnull
2399        public IValidationSupport.IssueSeverity getIssueSeverityForCodeDisplayMismatch() {
2400                return myIssueSeverityForCodeDisplayMismatch;
2401        }
2402
2403        /**
2404         * This setting controls the validation issue severity to report when a code validation
2405         * finds that the code is present in the given CodeSystem, but the display name being
2406         * validated doesn't match the expected value(s). Defaults to
2407         * {@link ca.uhn.fhir.context.support.IValidationSupport.IssueSeverity#WARNING}. Set this
2408         * value to {@link ca.uhn.fhir.context.support.IValidationSupport.IssueSeverity#INFORMATION}
2409         * if you don't want to see display name validation issues at all in resource validation
2410         * outcomes.
2411         *
2412         * @param theIssueSeverityForCodeDisplayMismatch The severity. Must not be {@literal null}.
2413         * @since 7.0.0
2414         */
2415        public void setIssueSeverityForCodeDisplayMismatch(
2416                        @Nonnull IValidationSupport.IssueSeverity theIssueSeverityForCodeDisplayMismatch) {
2417                Validate.notNull(
2418                                theIssueSeverityForCodeDisplayMismatch, "theIssueSeverityForCodeDisplayMismatch must not be null");
2419                myIssueSeverityForCodeDisplayMismatch = theIssueSeverityForCodeDisplayMismatch;
2420        }
2421
2422        /**
2423         * This setting controls whether MdmLink and other non-resource DB history is enabled.
2424         * <p/>
2425         * By default, this is enabled unless explicitly disabled.
2426         *
2427         * @param theNonResourceDbHistoryEnabled Whether non-resource DB history is enabled (default is true);
2428         * @since 6.6.0
2429         */
2430        public void setNonResourceDbHistoryEnabled(boolean theNonResourceDbHistoryEnabled) {
2431                myNonResourceDbHistoryEnabled = theNonResourceDbHistoryEnabled;
2432        }
2433
2434        public void setPreventInvalidatingConditionalMatchCriteria(boolean theCriteria) {
2435                myPreventInvalidatingConditionalMatchCriteria = theCriteria;
2436        }
2437
2438        public boolean isPreventInvalidatingConditionalMatchCriteria() {
2439                return myPreventInvalidatingConditionalMatchCriteria;
2440        }
2441
2442        public enum StoreMetaSourceInformationEnum {
2443                NONE(false, false),
2444                SOURCE_URI(true, false),
2445                REQUEST_ID(false, true),
2446                SOURCE_URI_AND_REQUEST_ID(true, true);
2447
2448                private final boolean myStoreSourceUri;
2449                private final boolean myStoreRequestId;
2450
2451                StoreMetaSourceInformationEnum(boolean theStoreSourceUri, boolean theStoreRequestId) {
2452                        myStoreSourceUri = theStoreSourceUri;
2453                        myStoreRequestId = theStoreRequestId;
2454                }
2455
2456                public boolean isStoreSourceUri() {
2457                        return myStoreSourceUri;
2458                }
2459
2460                public boolean isStoreRequestId() {
2461                        return myStoreRequestId;
2462                }
2463        }
2464
2465        /**
2466         * This enum provides allowable options for {@link #setResourceServerIdStrategy(IdStrategyEnum)}
2467         */
2468        public enum IdStrategyEnum {
2469                /**
2470                 * This strategy is the default strategy, and it simply uses a sequential
2471                 * numeric ID for each newly created resource.
2472                 */
2473                SEQUENTIAL_NUMERIC,
2474                /**
2475                 * Each resource will receive a randomly generated UUID
2476                 */
2477                UUID
2478        }
2479
2480        /**
2481         * This enum provides allowable options for {@link #setResourceClientIdStrategy(ClientIdStrategyEnum)}
2482         */
2483        public enum ClientIdStrategyEnum {
2484                /**
2485                 * Clients are not allowed to supply IDs for resources that do not
2486                 * already exist
2487                 */
2488                NOT_ALLOWED,
2489
2490                /**
2491                 * Clients may supply IDs but these IDs are not permitted to be purely
2492                 * numeric. In other words, values such as "A", "A1" and "000A" would be considered
2493                 * valid but "123" would not.
2494                 * <p><b>This is the default setting.</b></p>
2495                 */
2496                ALPHANUMERIC,
2497
2498                /**
2499                 * Clients may supply any ID including purely numeric IDs. Note that this setting should
2500                 * only be set on an empty database, or on a database that has always had this setting
2501                 * set as it causes a "forced ID" to be used for all resources.
2502                 * <p>
2503                 * Note that if you use this setting, it is highly recommended that you also
2504                 * set the {@link #setResourceServerIdStrategy(IdStrategyEnum) ResourceServerIdStrategy}
2505                 * to {@link IdStrategyEnum#UUID} in order to avoid any potential for conflicts. Otherwise
2506                 * a database sequence will be used to generate IDs and these IDs can conflict with
2507                 * client-assigned numeric IDs.
2508                 * </p>
2509                 */
2510                ANY
2511        }
2512
2513        public enum TagStorageModeEnum {
2514
2515                /**
2516                 * A separate set of tags is stored for each resource version
2517                 */
2518                VERSIONED,
2519
2520                /**
2521                 * A single set of tags is shared by all resource versions
2522                 */
2523                NON_VERSIONED,
2524
2525                /**
2526                 * Tags are stored directly in the resource body (in the {@literal ResourceHistoryTable}
2527                 * entry for the resource, meaning that they are not indexed separately, and are versioned with the rest
2528                 * of the resource.
2529                 */
2530                INLINE
2531        }
2532}