001package ca.uhn.fhir.jpa.api.config;
002
003import ca.uhn.fhir.jpa.api.model.WarmCacheEntry;
004import ca.uhn.fhir.jpa.model.entity.ModelConfig;
005import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
006import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
007import ca.uhn.fhir.util.HapiExtensions;
008import com.google.common.annotations.VisibleForTesting;
009import com.google.common.collect.Sets;
010import org.apache.commons.lang3.Validate;
011import org.apache.commons.lang3.time.DateUtils;
012import org.hl7.fhir.dstu2.model.Subscription;
013import org.hl7.fhir.r4.model.Bundle;
014import org.slf4j.Logger;
015import org.slf4j.LoggerFactory;
016
017import java.util.ArrayList;
018import java.util.Arrays;
019import java.util.Collections;
020import java.util.List;
021import java.util.Set;
022import java.util.TreeSet;
023
024/*
025 * #%L
026 * HAPI FHIR JPA API
027 * %%
028 * Copyright (C) 2014 - 2021 Smile CDR, Inc.
029 * %%
030 * Licensed under the Apache License, Version 2.0 (the "License");
031 * you may not use this file except in compliance with the License.
032 * You may obtain a copy of the License at
033 *
034 * http://www.apache.org/licenses/LICENSE-2.0
035 *
036 * Unless required by applicable law or agreed to in writing, software
037 * distributed under the License is distributed on an "AS IS" BASIS,
038 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
039 * See the License for the specific language governing permissions and
040 * limitations under the License.
041 * #L%
042 */
043
044public class DaoConfig {
045
046        /**
047         * Default value for {@link #setReuseCachedSearchResultsForMillis(Long)}: 60000ms (one minute)
048         */
049        public static final Long DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS = DateUtils.MILLIS_PER_MINUTE;
050        /**
051         * Default value for {@link #setTranslationCachesExpireAfterWriteInMinutes(Long)}: 60 minutes
052         *
053         * @see #setTranslationCachesExpireAfterWriteInMinutes(Long)
054         */
055        public static final Long DEFAULT_TRANSLATION_CACHES_EXPIRE_AFTER_WRITE_IN_MINUTES = 60L;
056        /**
057         * See {@link #setStatusBasedReindexingDisabled(boolean)}
058         */
059        public static final String DISABLE_STATUS_BASED_REINDEX = "disable_status_based_reindex";
060        /**
061         * Default {@link #setBundleTypesAllowedForStorage(Set)} value:
062         * <ul>
063         * <li>collection</li>
064         * <li>document</li>
065         * <li>message</li>
066         * </ul>
067         */
068        @SuppressWarnings("WeakerAccess")
069        public static final Set<String> DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE = Collections.unmodifiableSet(new TreeSet<>(Sets.newHashSet(
070                Bundle.BundleType.COLLECTION.toCode(),
071                Bundle.BundleType.DOCUMENT.toCode(),
072                Bundle.BundleType.MESSAGE.toCode()
073        )));
074        // update setter javadoc if default changes
075        public static final int DEFAULT_MAX_EXPANSION_SIZE = 1000;
076        /**
077         * Default value for {@link #setMaximumSearchResultCountInTransaction(Integer)}
078         *
079         * @see #setMaximumSearchResultCountInTransaction(Integer)
080         */
081        private static final Integer DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT_IN_TRANSACTION = null;
082        private static final Integer DEFAULT_MAXIMUM_TRANSACTION_BUNDLE_SIZE = null;
083        private static final Logger ourLog = LoggerFactory.getLogger(DaoConfig.class);
084        private static final int DEFAULT_EXPUNGE_BATCH_SIZE = 800;
085        private static final int DEFAULT_MAXIMUM_DELETE_CONFLICT_COUNT = 60;
086        private IndexEnabledEnum myIndexMissingFieldsEnabled = IndexEnabledEnum.DISABLED;
087        /**
088         * Child Configurations
089         */
090
091        private ModelConfig myModelConfig = new ModelConfig();
092
093        /**
094         * update setter javadoc if default changes
095         */
096        private Long myTranslationCachesExpireAfterWriteInMinutes = DEFAULT_TRANSLATION_CACHES_EXPIRE_AFTER_WRITE_IN_MINUTES;
097        /**
098         * update setter javadoc if default changes
099         */
100        private boolean myAllowInlineMatchUrlReferences = true;
101        private boolean myAllowMultipleDelete;
102        /**
103         * update setter javadoc if default changes
104         */
105        private int myDeferIndexingForCodesystemsOfSize = 100;
106        private boolean myDeleteStaleSearches = true;
107        private boolean myEnforceReferentialIntegrityOnDelete = true;
108        private boolean myUniqueIndexesEnabled = true;
109        private boolean myUniqueIndexesCheckedBeforeSave = true;
110        private boolean myEnforceReferentialIntegrityOnWrite = true;
111        private SearchTotalModeEnum myDefaultTotalMode = null;
112        private int myEverythingIncludesFetchPageSize = 50;
113        /**
114         * update setter javadoc if default changes
115         */
116        private long myExpireSearchResultsAfterMillis = DateUtils.MILLIS_PER_HOUR;
117        /**
118         * update setter javadoc if default changes
119         */
120        private Integer myFetchSizeDefaultMaximum = null;
121        private int myHardTagListLimit = 1000;
122        /**
123         * update setter javadoc if default changes
124         */
125        private boolean myIndexContainedResources = true;
126        private int myMaximumExpansionSize = DEFAULT_MAX_EXPANSION_SIZE;
127        private Integer myMaximumSearchResultCountInTransaction = DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT_IN_TRANSACTION;
128
129        private Integer myMaximumTransactionBundleSize = DEFAULT_MAXIMUM_TRANSACTION_BUNDLE_SIZE;
130        private ResourceEncodingEnum myResourceEncoding = ResourceEncodingEnum.JSONC;
131        /**
132         * update setter javadoc if default changes
133         */
134        private Integer myResourceMetaCountHardLimit = 1000;
135        private Long myReuseCachedSearchResultsForMillis = DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS;
136        private boolean mySchedulingDisabled;
137        private boolean mySuppressUpdatesWithNoChange = true;
138        private boolean myAutoCreatePlaceholderReferenceTargets;
139        private Integer myCacheControlNoStoreMaxResultsUpperLimit = 1000;
140        private Integer myCountSearchResultsUpTo = null;
141        private boolean myStatusBasedReindexingDisabled;
142        private IdStrategyEnum myResourceServerIdStrategy = IdStrategyEnum.SEQUENTIAL_NUMERIC;
143        private boolean myMarkResourcesForReindexingUponSearchParameterChange;
144        private boolean myExpungeEnabled;
145        private boolean myDeleteExpungeEnabled;
146        private int myExpungeBatchSize = DEFAULT_EXPUNGE_BATCH_SIZE;
147        private int myReindexThreadCount;
148        private int myExpungeThreadCount;
149        private Set<String> myBundleTypesAllowedForStorage;
150        private boolean myValidateSearchParameterExpressionsOnSave = true;
151        private List<Integer> mySearchPreFetchThresholds = Arrays.asList(500, 2000, -1);
152        private List<WarmCacheEntry> myWarmCacheEntries = new ArrayList<>();
153        private boolean myDisableHashBasedSearches;
154        private boolean myEnableInMemorySubscriptionMatching = true;
155        private boolean myEnforceReferenceTargetTypes = true;
156        private ClientIdStrategyEnum myResourceClientIdStrategy = ClientIdStrategyEnum.ALPHANUMERIC;
157        private boolean myFilterParameterEnabled = false;
158        private StoreMetaSourceInformationEnum myStoreMetaSourceInformation = StoreMetaSourceInformationEnum.SOURCE_URI_AND_REQUEST_ID;
159        /**
160         * update setter javadoc if default changes
161         */
162        private Integer myMaximumDeleteConflictQueryCount = DEFAULT_MAXIMUM_DELETE_CONFLICT_COUNT;
163        /**
164         * Do not change default of {@code true}!
165         *
166         * @since 4.1.0
167         */
168        private boolean myPreExpandValueSets = true;
169        /**
170         * Do not change default of {@code 0}!
171         *
172         * @since 4.1.0
173         */
174        private int myPreExpandValueSetsDefaultOffset = 0;
175        /**
176         * Do not change default of {@code 1000}!
177         *
178         * @since 4.1.0
179         */
180        private int myPreExpandValueSetsDefaultCount = 1000;
181        /**
182         * Do not change default of {@code 1000}!
183         *
184         * @since 4.1.0
185         */
186        private int myPreExpandValueSetsMaxCount = 1000;
187
188        /**
189         * @since 4.2.0
190         */
191        private boolean myPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets;
192
193        /**
194         * @since 5.0.0
195         */
196        private boolean myDeleteEnabled = true;
197        /**
198         * @since 5.1.0
199         */
200        private boolean myLastNEnabled = false;
201        /**
202         * @since 5.2.0
203         */
204        private boolean myUseLegacySearchBuilder = false;
205
206        /**
207         * Constructor
208         */
209        public DaoConfig() {
210                setSubscriptionEnabled(true);
211                setSubscriptionPollDelay(0);
212                setSubscriptionPurgeInactiveAfterMillis(Long.MAX_VALUE);
213                setMarkResourcesForReindexingUponSearchParameterChange(true);
214                setReindexThreadCount(Runtime.getRuntime().availableProcessors());
215                setExpungeThreadCount(Runtime.getRuntime().availableProcessors());
216                setBundleTypesAllowedForStorage(DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE);
217
218                if ("true".equalsIgnoreCase(System.getProperty(DISABLE_STATUS_BASED_REINDEX))) {
219                        ourLog.info("Status based reindexing is DISABLED");
220                        setStatusBasedReindexingDisabled(true);
221                }
222        }
223
224        /**
225         * If set to <code>true</code> (default is <code>false</code>) the <code>$lastn</code> operation will be enabled for
226         * indexing Observation resources. This operation involves creating a special set of tables in ElasticSearch for
227         * discovering Observation resources. Enabling this setting increases the amount of storage space required, and can
228         * slow write operations, but can be very useful for searching for collections of Observations for some applications.
229         *
230         * @since 5.1.0
231         */
232        public boolean isLastNEnabled() {
233                return myLastNEnabled;
234        }
235
236        /**
237         * If set to <code>true</code> (default is <code>false</code>) the <code>$lastn</code> operation will be enabled for
238         * indexing Observation resources. This operation involves creating a special set of tables in ElasticSearch for
239         * discovering Observation resources. Enabling this setting increases the amount of storage space required, and can
240         * slow write operations, but can be very useful for searching for collections of Observations for some applications.
241         *
242         * @since 5.1.0
243         */
244        public void setLastNEnabled(boolean theLastNEnabled) {
245                myLastNEnabled = theLastNEnabled;
246        }
247
248        /**
249         * This method controls whether to use the new non-hibernate search SQL builder that was introduced in HAPI FHIR 5.2.0.
250         * By default this will be <code>false</code> meaning that the new SQL builder is used. Set to <code>true</code> to use the
251         * legacy SQL builder based on Hibernate.
252         * <p>Note that this method will be removed in HAPI FHIR 5.4.0</p>
253         *
254         * @since 5.3.0
255         */
256        public boolean isUseLegacySearchBuilder() {
257                return myUseLegacySearchBuilder;
258        }
259
260        /**
261         * This method controls whether to use the new non-hibernate search SQL builder that was introduced in HAPI FHIR 5.2.0.
262         * By default this will be <code>false</code> meaning that the new SQL builder is used. Set to <code>true</code> to use the
263         * legacy SQL builder based on Hibernate.
264         * <p>Note that this method will be removed in HAPI FHIR 5.4.0</p>
265         *
266         * @since 5.3.0
267         */
268        public void setUseLegacySearchBuilder(boolean theUseLegacySearchBuilder) {
269                myUseLegacySearchBuilder = theUseLegacySearchBuilder;
270        }
271
272        /**
273         * If set to <code>true</code> (default is true) when a resource is being persisted,
274         * the target resource types of references will be validated to ensure that they
275         * are appropriate for the field containing the reference. This is generally a good idea
276         * because invalid reference target types may not be searchable.
277         */
278        public boolean isEnforceReferenceTargetTypes() {
279                return myEnforceReferenceTargetTypes;
280        }
281
282        /**
283         * If set to <code>true</code> (default is true) when a resource is being persisted,
284         * the target resource types of references will be validated to ensure that they
285         * are appropriate for the field containing the reference. This is generally a good idea
286         * because invalid reference target types may not be searchable.
287         */
288        public void setEnforceReferenceTargetTypes(boolean theEnforceReferenceTargetTypes) {
289                myEnforceReferenceTargetTypes = theEnforceReferenceTargetTypes;
290        }
291
292        /**
293         * If a non-null value is supplied (default is <code>null</code>), a default
294         * for the <code>_total</code> parameter may be specified here. For example,
295         * setting this value to {@link SearchTotalModeEnum#ACCURATE} will force a
296         * count to always be calculated for all searches. This can have a performance impact
297         * since it means that a count query will always be performed, but this is desirable
298         * for some solutions.
299         */
300        public SearchTotalModeEnum getDefaultTotalMode() {
301                return myDefaultTotalMode;
302        }
303
304        /**
305         * If a non-null value is supplied (default is <code>null</code>), a default
306         * for the <code>_total</code> parameter may be specified here. For example,
307         * setting this value to {@link SearchTotalModeEnum#ACCURATE} will force a
308         * count to always be calculated for all searches. This can have a performance impact
309         * since it means that a count query will always be performed, but this is desirable
310         * for some solutions.
311         */
312        public void setDefaultTotalMode(SearchTotalModeEnum theDefaultTotalMode) {
313                myDefaultTotalMode = theDefaultTotalMode;
314        }
315
316        /**
317         * Returns a set of searches that should be kept "warm", meaning that
318         * searches will periodically be performed in the background to
319         * keep results ready for this search
320         */
321        public List<WarmCacheEntry> getWarmCacheEntries() {
322                if (myWarmCacheEntries == null) {
323                        myWarmCacheEntries = new ArrayList<>();
324                }
325                return myWarmCacheEntries;
326        }
327
328        public void setWarmCacheEntries(List<WarmCacheEntry> theWarmCacheEntries) {
329                myWarmCacheEntries = theWarmCacheEntries;
330        }
331
332        /**
333         * If set to <code>true</code> (default is false), the reindexing of search parameters
334         * using a query on the HFJ_RESOURCE.SP_INDEX_STATUS column will be disabled completely.
335         * This query is just not efficient on Oracle and bogs the system down when there are
336         * a lot of resources. A more efficient way of doing this will be introduced
337         * in the next release of HAPI FHIR.
338         *
339         * @since 3.5.0
340         */
341        public boolean isStatusBasedReindexingDisabled() {
342                return myStatusBasedReindexingDisabled;
343        }
344
345        /**
346         * If set to <code>true</code> (default is false), the reindexing of search parameters
347         * using a query on the HFJ_RESOURCE.SP_INDEX_STATUS column will be disabled completely.
348         * This query is just not efficient on Oracle and bogs the system down when there are
349         * a lot of resources. A more efficient way of doing this will be introduced
350         * in the next release of HAPI FHIR.
351         *
352         * @since 3.5.0
353         */
354        public void setStatusBasedReindexingDisabled(boolean theStatusBasedReindexingDisabled) {
355                myStatusBasedReindexingDisabled = theStatusBasedReindexingDisabled;
356        }
357
358        /**
359         * Add a value to the {@link #setTreatReferencesAsLogical(Set) logical references list}.
360         *
361         * @see #setTreatReferencesAsLogical(Set)
362         */
363        public void addTreatReferencesAsLogical(String theTreatReferencesAsLogical) {
364                myModelConfig.addTreatReferencesAsLogical(theTreatReferencesAsLogical);
365        }
366
367        /**
368         * This setting specifies the bundle types (<code>Bundle.type</code>) that
369         * are allowed to be stored as-is on the /Bundle endpoint.
370         *
371         * @see #DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE
372         */
373        public Set<String> getBundleTypesAllowedForStorage() {
374                return myBundleTypesAllowedForStorage;
375        }
376
377        /**
378         * This setting specifies the bundle types (<code>Bundle.type</code>) that
379         * are allowed to be stored as-is on the /Bundle endpoint.
380         *
381         * @see #DEFAULT_BUNDLE_TYPES_ALLOWED_FOR_STORAGE
382         */
383        public void setBundleTypesAllowedForStorage(Set<String> theBundleTypesAllowedForStorage) {
384                Validate.notNull(theBundleTypesAllowedForStorage, "theBundleTypesAllowedForStorage must not be null");
385                myBundleTypesAllowedForStorage = theBundleTypesAllowedForStorage;
386        }
387
388        /**
389         * Specifies the highest number that a client is permitted to use in a
390         * <code>Cache-Control: nostore, max-results=NNN</code>
391         * directive. If the client tries to exceed this limit, the
392         * request will be denied. Defaults to 1000.
393         */
394        public Integer getCacheControlNoStoreMaxResultsUpperLimit() {
395                return myCacheControlNoStoreMaxResultsUpperLimit;
396        }
397
398        /**
399         * Specifies the highest number that a client is permitted to use in a
400         * <code>Cache-Control: nostore, max-results=NNN</code>
401         * directive. If the client tries to exceed this limit, the
402         * request will be denied. Defaults to 1000.
403         */
404        public void setCacheControlNoStoreMaxResultsUpperLimit(Integer theCacheControlNoStoreMaxResults) {
405                myCacheControlNoStoreMaxResultsUpperLimit = theCacheControlNoStoreMaxResults;
406        }
407
408        /**
409         * When searching, if set to a non-null value (default is <code>null</code>) the
410         * search coordinator will attempt to find at least this many results
411         * before returning a response to the client. This parameter mainly affects
412         * whether a "total count" is included in the response bundle for searches that
413         * return large amounts of data.
414         * <p>
415         * For a search that returns 10000 results, if this value is set to
416         * 10000 the search coordinator will find all 10000 results
417         * prior to returning, so the initial response bundle will have the
418         * total set to 10000. If this value is null (or less than 10000)
419         * the response bundle will likely return slightly faster, but will
420         * not include the total. Subsequent page requests will likely
421         * include the total however, if they are performed after the
422         * search coordinator has found all results.
423         * </p>
424         * <p>
425         * Set this value to <code>0</code> to always load all
426         * results before returning.
427         * </p>
428         */
429        public Integer getCountSearchResultsUpTo() {
430                return myCountSearchResultsUpTo;
431        }
432
433        /**
434         * When searching, if set to a non-null value (default is <code>null</code>) the
435         * search coordinator will attempt to find at least this many results
436         * before returning a response to the client. This parameter mainly affects
437         * whether a "total count" is included in the response bundle for searches that
438         * return large amounts of data.
439         * <p>
440         * For a search that returns 10000 results, if this value is set to
441         * 10000 the search coordinator will find all 10000 results
442         * prior to returning, so the initial response bundle will have the
443         * total set to 10000. If this value is null (or less than 10000)
444         * the response bundle will likely return slightly faster, but will
445         * not include the total. Subsequent page requests will likely
446         * include the total however, if they are performed after the
447         * search coordinator has found all results.
448         * </p>
449         * <p>
450         * Set this value to <code>0</code> to always load all
451         * results before returning.
452         * </p>
453         */
454        public void setCountSearchResultsUpTo(Integer theCountSearchResultsUpTo) {
455                myCountSearchResultsUpTo = theCountSearchResultsUpTo;
456        }
457
458        /**
459         * When a code system is added that contains more than this number of codes,
460         * the code system will be indexed later in an incremental process in order to
461         * avoid overwhelming Lucene with a huge number of codes in a single operation.
462         * <p>
463         * Defaults to 100
464         * </p>
465         */
466        public int getDeferIndexingForCodesystemsOfSize() {
467                return myDeferIndexingForCodesystemsOfSize;
468        }
469
470        /**
471         * When a code system is added that contains more than this number of codes,
472         * the code system will be indexed later in an incremental process in order to
473         * avoid overwhelming Lucene with a huge number of codes in a single operation.
474         * <p>
475         * Defaults to 100
476         * </p>
477         */
478        public void setDeferIndexingForCodesystemsOfSize(int theDeferIndexingForCodesystemsOfSize) {
479                myDeferIndexingForCodesystemsOfSize = theDeferIndexingForCodesystemsOfSize;
480        }
481
482        /**
483         * Unlike with normal search queries, $everything queries have their _includes loaded by the main search thread and these included results
484         * 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
485         * as the search results are paged over.
486         * <p>
487         * In order to recursively load _includes, we process the original results in batches of this size. Adjust with caution, increasing this
488         * value may improve performance but may also cause memory issues.
489         * </p>
490         * <p>
491         * The default value is 50
492         * </p>
493         */
494        public int getEverythingIncludesFetchPageSize() {
495                return myEverythingIncludesFetchPageSize;
496        }
497
498        /**
499         * Unlike with normal search queries, $everything queries have their _includes loaded by the main search thread and these included results
500         * 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
501         * as the search results are paged over.
502         * <p>
503         * In order to recursively load _includes, we process the original results in batches of this size. Adjust with caution, increasing this
504         * value may improve performance but may also cause memory issues.
505         * </p>
506         * <p>
507         * The default value is 50
508         * </p>
509         */
510        public void setEverythingIncludesFetchPageSize(int theEverythingIncludesFetchPageSize) {
511                Validate.inclusiveBetween(1, Integer.MAX_VALUE, theEverythingIncludesFetchPageSize);
512                myEverythingIncludesFetchPageSize = theEverythingIncludesFetchPageSize;
513        }
514
515        /**
516         * Sets the number of milliseconds that search results for a given client search
517         * should be preserved before being purged from the database.
518         * <p>
519         * Search results are stored in the database so that they can be paged over multiple
520         * requests. After this
521         * number of milliseconds, they will be deleted from the database, and any paging links
522         * (next/prev links in search response bundles) will become invalid. Defaults to 1 hour.
523         * </p>
524         * <p>
525         * To disable this feature entirely, see {@link #setExpireSearchResults(boolean)}
526         * </p>
527         *
528         * @since 1.5
529         */
530        public long getExpireSearchResultsAfterMillis() {
531                return myExpireSearchResultsAfterMillis;
532        }
533
534        /**
535         * Sets the number of milliseconds that search results for a given client search
536         * should be preserved before being purged from the database.
537         * <p>
538         * Search results are stored in the database so that they can be paged over multiple
539         * requests. After this
540         * number of milliseconds, they will be deleted from the database, and any paging links
541         * (next/prev links in search response bundles) will become invalid. Defaults to 1 hour.
542         * </p>
543         * <p>
544         * To disable this feature entirely, see {@link #setExpireSearchResults(boolean)}
545         * </p>
546         *
547         * @since 1.5
548         */
549        public void setExpireSearchResultsAfterMillis(long theExpireSearchResultsAfterMillis) {
550                myExpireSearchResultsAfterMillis = theExpireSearchResultsAfterMillis;
551        }
552
553        /**
554         * Gets the default maximum number of results to load in a query.
555         * <p>
556         * For example, if the database has a million Patient resources in it, and
557         * the client requests <code>GET /Patient</code>, if this value is set
558         * to a non-null value (default is <code>null</code>) only this number
559         * of results will be fetched. Setting this value appropriately
560         * can be useful to improve performance in some situations.
561         * </p>
562         */
563        public Integer getFetchSizeDefaultMaximum() {
564                return myFetchSizeDefaultMaximum;
565        }
566
567        /**
568         * Gets the default maximum number of results to load in a query.
569         * <p>
570         * For example, if the database has a million Patient resources in it, and
571         * the client requests <code>GET /Patient</code>, if this value is set
572         * to a non-null value (default is <code>null</code>) only this number
573         * of results will be fetched. Setting this value appropriately
574         * can be useful to improve performance in some situations.
575         * </p>
576         */
577        public void setFetchSizeDefaultMaximum(Integer theFetchSizeDefaultMaximum) {
578                myFetchSizeDefaultMaximum = theFetchSizeDefaultMaximum;
579        }
580
581        /**
582         * Gets the maximum number of results to return in a GetTags query (DSTU1 only)
583         */
584        public int getHardTagListLimit() {
585                return myHardTagListLimit;
586        }
587
588        /**
589         * Gets the maximum number of results to return in a GetTags query (DSTU1 only)
590         */
591        public void setHardTagListLimit(int theHardTagListLimit) {
592                myHardTagListLimit = theHardTagListLimit;
593        }
594
595        /**
596         * If set to {@link IndexEnabledEnum#DISABLED} (default is {@link IndexEnabledEnum#DISABLED})
597         * the server will not create search indexes for search parameters with no values in resources.
598         * <p>
599         * Disabling this feature means that the <code>:missing</code> search modifier will not be
600         * supported on the server, but also means that storage and indexing (i.e. writes to the
601         * database) may be much faster on servers which have lots of search parameters and need
602         * to write quickly.
603         * </p>
604         * <p>
605         * This feature may be enabled on servers where supporting the use of the :missing parameter is
606         * of higher importance than raw write performance
607         * </p>
608         */
609        public IndexEnabledEnum getIndexMissingFields() {
610                return myIndexMissingFieldsEnabled;
611        }
612
613        /**
614         * If set to {@link IndexEnabledEnum#DISABLED} (default is {@link IndexEnabledEnum#DISABLED})
615         * the server will not create search indexes for search parameters with no values in resources.
616         * <p>
617         * Disabling this feature means that the <code>:missing</code> search modifier will not be
618         * supported on the server, but also means that storage and indexing (i.e. writes to the
619         * database) may be much faster on servers which have lots of search parameters and need
620         * to write quickly.
621         * </p>
622         * <p>
623         * This feature may be enabled on servers where supporting the use of the :missing parameter is
624         * of higher importance than raw write performance
625         * </p>
626         * <p>
627         * Note that this setting also has an impact on sorting (i.e. using the
628         * <code>_sort</code> parameter on searches): If the server is configured
629         * to not index missing field.
630         * </p>
631         */
632        public void setIndexMissingFields(IndexEnabledEnum theIndexMissingFields) {
633                Validate.notNull(theIndexMissingFields, "theIndexMissingFields must not be null");
634                myIndexMissingFieldsEnabled = theIndexMissingFields;
635        }
636
637        /**
638         * See {@link #setMaximumExpansionSize(int)}
639         */
640        public int getMaximumExpansionSize() {
641                return myMaximumExpansionSize;
642        }
643
644        /**
645         * Sets the maximum number of codes that will be added to an in-memory valueset expansion before
646         * the operation will be failed as too costly. Note that this setting applies only to
647         * in-memory expansions and does not apply to expansions that are being pre-calculated.
648         * <p>
649         * The default value for this setting is 1000.
650         * </p>
651         */
652        public void setMaximumExpansionSize(int theMaximumExpansionSize) {
653                Validate.isTrue(theMaximumExpansionSize > 0, "theMaximumExpansionSize must be > 0");
654                myMaximumExpansionSize = theMaximumExpansionSize;
655        }
656
657        /**
658         * Provides the maximum number of results which may be returned by a search (HTTP GET) which
659         * is executed as a sub-operation within within a FHIR <code>transaction</code> or
660         * <code>batch</code> operation. For example, if this value is set to <code>100</code> and
661         * a FHIR transaction is processed with a sub-request for <code>Patient?gender=male</code>,
662         * the server will throw an error (and the transaction will fail) if there are more than
663         * 100 resources on the server which match this query.
664         * <p>
665         * The default value is <code>null</code>, which means that there is no limit.
666         * </p>
667         */
668        public Integer getMaximumSearchResultCountInTransaction() {
669                return myMaximumSearchResultCountInTransaction;
670        }
671
672        /**
673         * Provides the maximum number of results which may be returned by a search (HTTP GET) which
674         * is executed as a sub-operation within within a FHIR <code>transaction</code> or
675         * <code>batch</code> operation. For example, if this value is set to <code>100</code> and
676         * a FHIR transaction is processed with a sub-request for <code>Patient?gender=male</code>,
677         * the server will throw an error (and the transaction will fail) if there are more than
678         * 100 resources on the server which match this query.
679         * <p>
680         * The default value is <code>null</code>, which means that there is no limit.
681         * </p>
682         */
683        public void setMaximumSearchResultCountInTransaction(Integer theMaximumSearchResultCountInTransaction) {
684                myMaximumSearchResultCountInTransaction = theMaximumSearchResultCountInTransaction;
685        }
686
687        /**
688         * Specifies the maximum number of resources permitted within a single transaction bundle.
689         * If a transaction bundle is submitted with more than this number of resources, it will be
690         * rejected with a PayloadTooLarge exception.
691         * <p>
692         * The default value is <code>null</code>, which means that there is no limit.
693         * </p>
694         */
695        public Integer getMaximumTransactionBundleSize() {
696                return myMaximumTransactionBundleSize;
697        }
698
699        /**
700         * Specifies the maximum number of resources permitted within a single transaction bundle.
701         * If a transaction bundle is submitted with more than this number of resources, it will be
702         * rejected with a PayloadTooLarge exception.
703         * <p>
704         * The default value is <code>null</code>, which means that there is no limit.
705         * </p>
706         */
707        public DaoConfig setMaximumTransactionBundleSize(Integer theMaximumTransactionBundleSize) {
708                myMaximumTransactionBundleSize = theMaximumTransactionBundleSize;
709                return this;
710        }
711
712        /**
713         * This setting controls the number of threads allocated to resource reindexing
714         * (which is only ever used if SearchParameters change, or a manual reindex is
715         * triggered due to a HAPI FHIR upgrade or some other reason).
716         * <p>
717         * The default value is set to the number of available processors
718         * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value
719         * for this setting must be a positive integer.
720         * </p>
721         */
722        public int getReindexThreadCount() {
723                return myReindexThreadCount;
724        }
725
726        /**
727         * This setting controls the number of threads allocated to resource reindexing
728         * (which is only ever used if SearchParameters change, or a manual reindex is
729         * triggered due to a HAPI FHIR upgrade or some other reason).
730         * <p>
731         * The default value is set to the number of available processors
732         * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value
733         * for this setting must be a positive integer.
734         * </p>
735         */
736        public void setReindexThreadCount(int theReindexThreadCount) {
737                myReindexThreadCount = theReindexThreadCount;
738                myReindexThreadCount = Math.max(myReindexThreadCount, 1); // Minimum of 1
739        }
740
741        /**
742         * This setting controls the number of threads allocated to the expunge operation
743         * <p>
744         * The default value is set to the number of available processors
745         * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value
746         * for this setting must be a positive integer.
747         * </p>
748         */
749        public int getExpungeThreadCount() {
750                return myExpungeThreadCount;
751        }
752
753        /**
754         * This setting controls the number of threads allocated to the expunge operation
755         * <p>
756         * The default value is set to the number of available processors
757         * (via <code>Runtime.getRuntime().availableProcessors()</code>). Value
758         * for this setting must be a positive integer.
759         * </p>
760         */
761        public void setExpungeThreadCount(int theExpungeThreadCount) {
762                myExpungeThreadCount = theExpungeThreadCount;
763                myExpungeThreadCount = Math.max(myExpungeThreadCount, 1); // Minimum of 1
764        }
765
766        public ResourceEncodingEnum getResourceEncoding() {
767                return myResourceEncoding;
768        }
769
770        public void setResourceEncoding(ResourceEncodingEnum theResourceEncoding) {
771                myResourceEncoding = theResourceEncoding;
772        }
773
774        /**
775         * If set, an individual resource will not be allowed to have more than the
776         * given number of tags, profiles, and security labels (the limit is for the combined
777         * total for all of these things on an individual resource).
778         * <p>
779         * If set to <code>null</code>, no limit will be applied.
780         * </p>
781         * <p>
782         * The default value for this setting is 1000.
783         * </p>
784         */
785        public Integer getResourceMetaCountHardLimit() {
786                return myResourceMetaCountHardLimit;
787        }
788
789        /**
790         * If set, an individual resource will not be allowed to have more than the
791         * given number of tags, profiles, and security labels (the limit is for the combined
792         * total for all of these things on an individual resource).
793         * <p>
794         * If set to <code>null</code>, no limit will be applied.
795         * </p>
796         * <p>
797         * The default value for this setting is 1000.
798         * </p>
799         */
800        public void setResourceMetaCountHardLimit(Integer theResourceMetaCountHardLimit) {
801                myResourceMetaCountHardLimit = theResourceMetaCountHardLimit;
802        }
803
804        /**
805         * Controls the behaviour when a client-assigned ID is encountered, i.e. an HTTP PUT
806         * on a resource ID that does not already exist in the database.
807         * <p>
808         * Default is {@link ClientIdStrategyEnum#ALPHANUMERIC}
809         * </p>
810         */
811        public ClientIdStrategyEnum getResourceClientIdStrategy() {
812                return myResourceClientIdStrategy;
813        }
814
815        /**
816         * Controls the behaviour when a client-assigned ID is encountered, i.e. an HTTP PUT
817         * on a resource ID that does not already exist in the database.
818         * <p>
819         * Default is {@link ClientIdStrategyEnum#ALPHANUMERIC}
820         * </p>
821         *
822         * @param theResourceClientIdStrategy Must not be <code>null</code>
823         */
824        public void setResourceClientIdStrategy(ClientIdStrategyEnum theResourceClientIdStrategy) {
825                Validate.notNull(theResourceClientIdStrategy, "theClientIdStrategy must not be null");
826                myResourceClientIdStrategy = theResourceClientIdStrategy;
827        }
828
829        /**
830         * This setting configures the strategy to use in generating IDs for newly
831         * created resources on the server. The default is {@link IdStrategyEnum#SEQUENTIAL_NUMERIC}.
832         * <p>
833         * This strategy is only used for server-assigned IDs, i.e. for HTTP POST
834         * where the client is requesing that the server store a new resource and give
835         * it an ID.
836         * </p>
837         */
838        public IdStrategyEnum getResourceServerIdStrategy() {
839                return myResourceServerIdStrategy;
840        }
841
842        /**
843         * This setting configures the strategy to use in generating IDs for newly
844         * created resources on the server. The default is {@link IdStrategyEnum#SEQUENTIAL_NUMERIC}.
845         * <p>
846         * This strategy is only used for server-assigned IDs, i.e. for HTTP POST
847         * where the client is requesing that the server store a new resource and give
848         * it an ID.
849         * </p>
850         *
851         * @param theResourceIdStrategy The strategy. Must not be <code>null</code>.
852         */
853        public void setResourceServerIdStrategy(IdStrategyEnum theResourceIdStrategy) {
854                Validate.notNull(theResourceIdStrategy, "theResourceIdStrategy must not be null");
855                myResourceServerIdStrategy = theResourceIdStrategy;
856        }
857
858        /**
859         * If set to a non {@literal null} value (default is {@link #DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS non null})
860         * if an identical search is requested multiple times within this window, the same results will be returned
861         * to multiple queries. For example, if this value is set to 1 minute and a client searches for all
862         * patients named "smith", and then a second client also performs the same search within 1 minute,
863         * the same cached results will be returned.
864         * <p>
865         * This approach can improve performance, especially under heavy load, but can also mean that
866         * searches may potentially return slightly out-of-date results.
867         * </p>
868         * <p>
869         * Note that if this is set to a non-null value, clients may override this setting by using
870         * the <code>Cache-Control</code> header. If this is set to <code>null</code>, the Cache-Control
871         * header will be ignored.
872         * </p>
873         */
874        public Long getReuseCachedSearchResultsForMillis() {
875                return myReuseCachedSearchResultsForMillis;
876        }
877
878        /**
879         * If set to a non {@literal null} value (default is {@link #DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS non null})
880         * if an identical search is requested multiple times within this window, the same results will be returned
881         * to multiple queries. For example, if this value is set to 1 minute and a client searches for all
882         * patients named "smith", and then a second client also performs the same search within 1 minute,
883         * the same cached results will be returned.
884         * <p>
885         * This approach can improve performance, especially under heavy load, but can also mean that
886         * searches may potentially return slightly out-of-date results.
887         * </p>
888         * <p>
889         * Note that if this is set to a non-null value, clients may override this setting by using
890         * the <code>Cache-Control</code> header. If this is set to <code>null</code>, the Cache-Control
891         * header will be ignored.
892         * </p>
893         */
894        public void setReuseCachedSearchResultsForMillis(Long theReuseCachedSearchResultsForMillis) {
895                myReuseCachedSearchResultsForMillis = theReuseCachedSearchResultsForMillis;
896        }
897
898        /**
899         * Specifies the duration in minutes for which values will be retained after being
900         * written to the terminology translation cache. Defaults to 60.
901         */
902        public Long getTranslationCachesExpireAfterWriteInMinutes() {
903                return myTranslationCachesExpireAfterWriteInMinutes;
904        }
905
906        /**
907         * Specifies the duration in minutes for which values will be retained after being
908         * written to the terminology translation cache. Defaults to 60.
909         */
910        public void setTranslationCachesExpireAfterWriteInMinutes(Long translationCachesExpireAfterWriteInMinutes) {
911                myTranslationCachesExpireAfterWriteInMinutes = translationCachesExpireAfterWriteInMinutes;
912        }
913
914        /**
915         * This setting may be used to advise the server that any references found in
916         * resources that have any of the base URLs given here will be treated as logical
917         * references instead of being treated as real references.
918         * <p>
919         * A logical reference is a reference which is treated as an identifier, and
920         * does not neccesarily resolve. See <a href="http://hl7.org/fhir/references.html">references</a> for
921         * a description of logical references. For example, the valueset
922         * <a href="http://hl7.org/fhir/valueset-quantity-comparator.html">valueset-quantity-comparator</a> is a logical
923         * reference.
924         * </p>
925         * <p>
926         * Values for this field may take either of the following forms:
927         * </p>
928         * <ul>
929         * <li><code>http://example.com/some-url</code> <b>(will be matched exactly)</b></li>
930         * <li><code>http://example.com/some-base*</code> <b>(will match anything beginning with the part before the *)</b></li>
931         * </ul>
932         *
933         * @see ModelConfig#DEFAULT_LOGICAL_BASE_URLS Default values for this property
934         */
935        public Set<String> getTreatReferencesAsLogical() {
936                return myModelConfig.getTreatReferencesAsLogical();
937        }
938
939        /**
940         * This setting may be used to advise the server that any references found in
941         * resources that have any of the base URLs given here will be treated as logical
942         * references instead of being treated as real references.
943         * <p>
944         * A logical reference is a reference which is treated as an identifier, and
945         * does not neccesarily resolve. See <a href="http://hl7.org/fhir/references.html">references</a> for
946         * a description of logical references. For example, the valueset
947         * <a href="http://hl7.org/fhir/valueset-quantity-comparator.html">valueset-quantity-comparator</a> is a logical
948         * reference.
949         * </p>
950         * <p>
951         * Values for this field may take either of the following forms:
952         * </p>
953         * <ul>
954         * <li><code>http://example.com/some-url</code> <b>(will be matched exactly)</b></li>
955         * <li><code>http://example.com/some-base*</code> <b>(will match anything beginning with the part before the *)</b></li>
956         * </ul>
957         *
958         * @see ModelConfig#DEFAULT_LOGICAL_BASE_URLS Default values for this property
959         */
960        public DaoConfig setTreatReferencesAsLogical(Set<String> theTreatReferencesAsLogical) {
961                myModelConfig.setTreatReferencesAsLogical(theTreatReferencesAsLogical);
962                return this;
963        }
964
965        /**
966         * If set to <code>true</code> (default is <code>false</code>) the server will allow
967         * resources to have references to external servers. For example if this server is
968         * running at <code>http://example.com/fhir</code> and this setting is set to
969         * <code>true</code> the server will allow a Patient resource to be saved with a
970         * Patient.organization value of <code>http://foo.com/Organization/1</code>.
971         * <p>
972         * Under the default behaviour if this value has not been changed, the above
973         * resource would be rejected by the server because it requires all references
974         * to be resolvable on the local server.
975         * </p>
976         * <p>
977         * Note that external references will be indexed by the server and may be searched
978         * (e.g. <code>Patient:organization</code>), but
979         * chained searches (e.g. <code>Patient:organization.name</code>) will not work across
980         * these references.
981         * </p>
982         * <p>
983         * It is recommended to also set {@link #setTreatBaseUrlsAsLocal(Set)} if this value
984         * is set to <code>true</code>
985         * </p>
986         *
987         * @see #setTreatBaseUrlsAsLocal(Set)
988         * @see #setAllowExternalReferences(boolean)
989         */
990        public boolean isAllowExternalReferences() {
991                return myModelConfig.isAllowExternalReferences();
992        }
993
994        /**
995         * If set to <code>true</code> (default is <code>false</code>) the server will allow
996         * resources to have references to external servers. For example if this server is
997         * running at <code>http://example.com/fhir</code> and this setting is set to
998         * <code>true</code> the server will allow a Patient resource to be saved with a
999         * Patient.organization value of <code>http://foo.com/Organization/1</code>.
1000         * <p>
1001         * Under the default behaviour if this value has not been changed, the above
1002         * resource would be rejected by the server because it requires all references
1003         * to be resolvable on the local server.
1004         * </p>
1005         * <p>
1006         * Note that external references will be indexed by the server and may be searched
1007         * (e.g. <code>Patient:organization</code>), but
1008         * chained searches (e.g. <code>Patient:organization.name</code>) will not work across
1009         * these references.
1010         * </p>
1011         * <p>
1012         * It is recommended to also set {@link #setTreatBaseUrlsAsLocal(Set)} if this value
1013         * is set to <code>true</code>
1014         * </p>
1015         *
1016         * @see #setTreatBaseUrlsAsLocal(Set)
1017         * @see #setAllowExternalReferences(boolean)
1018         */
1019        public void setAllowExternalReferences(boolean theAllowExternalReferences) {
1020                myModelConfig.setAllowExternalReferences(theAllowExternalReferences);
1021        }
1022
1023        /**
1024         * @see #setAllowInlineMatchUrlReferences(boolean)
1025         */
1026        public boolean isAllowInlineMatchUrlReferences() {
1027                return myAllowInlineMatchUrlReferences;
1028        }
1029
1030        /**
1031         * Should references containing match URLs be resolved and replaced in create and update operations. For
1032         * example, if this property is set to true and a resource is created containing a reference
1033         * to "Patient?identifier=12345", this is reference match URL will be resolved and replaced according
1034         * to the usual match URL rules.
1035         * <p>
1036         * Default is {@literal true} beginning in HAPI FHIR 2.4, since this
1037         * feature is now specified in the FHIR specification. (Previously it
1038         * was an experimental/proposed feature)
1039         * </p>
1040         *
1041         * @since 1.5
1042         */
1043        public void setAllowInlineMatchUrlReferences(boolean theAllowInlineMatchUrlReferences) {
1044                myAllowInlineMatchUrlReferences = theAllowInlineMatchUrlReferences;
1045        }
1046
1047        public boolean isAllowMultipleDelete() {
1048                return myAllowMultipleDelete;
1049        }
1050
1051        public void setAllowMultipleDelete(boolean theAllowMultipleDelete) {
1052                myAllowMultipleDelete = theAllowMultipleDelete;
1053        }
1054
1055        /**
1056         * When creating or updating a resource: If this property is set to <code>true</code>
1057         * (default is <code>false</code>), if the resource has a reference to another resource
1058         * on the local server but that reference does not exist, a placeholder resource will be
1059         * created.
1060         * <p>
1061         * In other words, if an observation with subject <code>Patient/FOO</code> is created, but
1062         * there is no resource called <code>Patient/FOO</code> on the server, this property causes
1063         * an empty patient with ID "FOO" to be created in order to prevent this operation
1064         * from failing.
1065         * </p>
1066         * <p>
1067         * This property can be useful in cases where replication between two servers is wanted.
1068         * Note however that references containing purely numeric IDs will not be auto-created
1069         * as they are never allowed to be client supplied in HAPI FHIR JPA.
1070         * </p>
1071         */
1072        public boolean isAutoCreatePlaceholderReferenceTargets() {
1073                return myAutoCreatePlaceholderReferenceTargets;
1074        }
1075
1076        /**
1077         * When creating or updating a resource: If this property is set to <code>true</code>
1078         * (default is <code>false</code>), if the resource has a reference to another resource
1079         * on the local server but that reference does not exist, a placeholder resource will be
1080         * created.
1081         * <p>
1082         * In other words, if an observation with subject <code>Patient/FOO</code> is created, but
1083         * there is no resource called <code>Patient/FOO</code> on the server, this property causes
1084         * an empty patient with ID "FOO" to be created in order to prevent this operation
1085         * from failing.
1086         * </p>
1087         * <p>
1088         * This property can be useful in cases where replication between two servers is wanted.
1089         * Note however that references containing purely numeric IDs will not be auto-created
1090         * as they are never allowed to be client supplied in HAPI FHIR JPA.
1091         * </p>
1092         */
1093        public void setAutoCreatePlaceholderReferenceTargets(boolean theAutoCreatePlaceholderReferenceTargets) {
1094                myAutoCreatePlaceholderReferenceTargets = theAutoCreatePlaceholderReferenceTargets;
1095        }
1096
1097        /**
1098         * When {@link #setAutoCreatePlaceholderReferenceTargets(boolean)} is enabled, if this
1099         * setting is set to <code>true</code> (default is <code>false</code>) and the source
1100         * reference has an identifier populated, the identifier will be copied to the target
1101         * resource.
1102         * <p>
1103         * When enabled, if an Observation contains a reference like the one below,
1104         * and no existing resource was found that matches the given ID, a new
1105         * one will be created and its <code>Patient.identifier</code> value will be
1106         * populated using the value from <code>Observation.subject.identifier</code>.
1107         * </p>
1108         * <pre>
1109         * {
1110         *   "resourceType": "Observation",
1111         *   "subject": {
1112         *     "reference": "Patient/ABC",
1113         *     "identifier": {
1114         *       "system": "http://foo",
1115         *       "value": "123"
1116         *     }
1117         *   }
1118         * }
1119         * </pre>
1120         * <p>
1121         * This method is often combined with {@link #setAllowInlineMatchUrlReferences(boolean)}.
1122         * </p>
1123         * <p>
1124         * In other words if an Observation contains a reference like the one below,
1125         * and no existing resource was found that matches the given match URL, a new
1126         * one will be created and its <code>Patient.identifier</code> value will be
1127         * populated using the value from <code>Observation.subject.identifier</code>.
1128         * </p>
1129         * <pre>
1130         * {
1131         *   "resourceType": "Observation",
1132         *   "subject": {
1133         *     "reference": "Patient?identifier=http://foo|123",
1134         *     "identifier": {
1135         *       "system": "http://foo",
1136         *       "value": "123"
1137         *     }
1138         *   }
1139         * }
1140         * </pre>
1141         *
1142         * @since 4.2.0
1143         */
1144        public boolean isPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets() {
1145                return myPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets;
1146        }
1147
1148        /**
1149         * When {@link #setAutoCreatePlaceholderReferenceTargets(boolean)} is enabled, if this
1150         * setting is set to <code>true</code> (default is <code>false</code>) and the source
1151         * reference has an identifier populated, the identifier will be copied to the target
1152         * resource.
1153         * <p>
1154         * When enabled, if an Observation contains a reference like the one below,
1155         * and no existing resource was found that matches the given ID, a new
1156         * one will be created and its <code>Patient.identifier</code> value will be
1157         * populated using the value from <code>Observation.subject.identifier</code>.
1158         * </p>
1159         * <pre>
1160         * {
1161         *   "resourceType": "Observation",
1162         *   "subject": {
1163         *     "reference": "Patient/ABC",
1164         *     "identifier": {
1165         *       "system": "http://foo",
1166         *       "value": "123"
1167         *     }
1168         *   }
1169         * }
1170         * </pre>
1171         * <p>
1172         * This method is often combined with {@link #setAllowInlineMatchUrlReferences(boolean)}.
1173         * </p>
1174         * <p>
1175         * In other words if an Observation contains a reference like the one below,
1176         * and no existing resource was found that matches the given match URL, a new
1177         * one will be created and its <code>Patient.identifier</code> value will be
1178         * populated using the value from <code>Observation.subject.identifier</code>.
1179         * </p>
1180         * <pre>
1181         * {
1182         *   "resourceType": "Observation",
1183         *   "subject": {
1184         *     "reference": "Patient?identifier=http://foo|123",
1185         *     "identifier": {
1186         *       "system": "http://foo",
1187         *       "value": "123"
1188         *     }
1189         *   }
1190         * }
1191         * </pre>
1192         *
1193         * @since 4.2.0
1194         */
1195        public void setPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets(boolean thePopulateIdentifierInAutoCreatedPlaceholderReferenceTargets) {
1196                myPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets = thePopulateIdentifierInAutoCreatedPlaceholderReferenceTargets;
1197        }
1198
1199        /**
1200         * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be
1201         * deleted even if other resources currently contain references to them.
1202         * <p>
1203         * This property can cause confusing results for clients of the server since searches, includes,
1204         * and other FHIR features may not behave as expected when referential integrity is not
1205         * preserved. Use this feature with caution.
1206         * </p>
1207         */
1208        public boolean isEnforceReferentialIntegrityOnDelete() {
1209                return myEnforceReferentialIntegrityOnDelete;
1210        }
1211
1212        /**
1213         * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be
1214         * deleted even if other resources currently contain references to them.
1215         * <p>
1216         * This property can cause confusing results for clients of the server since searches, includes,
1217         * and other FHIR features may not behave as expected when referential integrity is not
1218         * preserved. Use this feature with caution.
1219         * </p>
1220         */
1221        public void setEnforceReferentialIntegrityOnDelete(boolean theEnforceReferentialIntegrityOnDelete) {
1222                myEnforceReferentialIntegrityOnDelete = theEnforceReferentialIntegrityOnDelete;
1223        }
1224
1225        /**
1226         * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be
1227         * created or updated even if they contain references to local resources that do not exist.
1228         * <p>
1229         * For example, if a patient contains a reference to managing organization <code>Organization/FOO</code>
1230         * but FOO is not a valid ID for an organization on the server, the operation will be blocked unless
1231         * this propery has been set to <code>false</code>
1232         * </p>
1233         * <p>
1234         * This property can cause confusing results for clients of the server since searches, includes,
1235         * and other FHIR features may not behave as expected when referential integrity is not
1236         * preserved. Use this feature with caution.
1237         * </p>
1238         */
1239        public boolean isEnforceReferentialIntegrityOnWrite() {
1240                return myEnforceReferentialIntegrityOnWrite;
1241        }
1242
1243        /**
1244         * If set to <code>false</code> (default is <code>true</code>) resources will be permitted to be
1245         * created or updated even if they contain references to local resources that do not exist.
1246         * <p>
1247         * For example, if a patient contains a reference to managing organization <code>Organization/FOO</code>
1248         * but FOO is not a valid ID for an organization on the server, the operation will be blocked unless
1249         * this propery has been set to <code>false</code>
1250         * </p>
1251         * <p>
1252         * This property can cause confusing results for clients of the server since searches, includes,
1253         * and other FHIR features may not behave as expected when referential integrity is not
1254         * preserved. Use this feature with caution.
1255         * </p>
1256         */
1257        public void setEnforceReferentialIntegrityOnWrite(boolean theEnforceReferentialIntegrityOnWrite) {
1258                myEnforceReferentialIntegrityOnWrite = theEnforceReferentialIntegrityOnWrite;
1259        }
1260
1261        /**
1262         * If this is set to <code>false</code> (default is <code>true</code>) the stale search deletion
1263         * task will be disabled (meaning that search results will be retained in the database indefinitely). USE WITH CAUTION.
1264         * <p>
1265         * This feature is useful if you want to define your own process for deleting these (e.g. because
1266         * you are running in a cluster)
1267         * </p>
1268         */
1269        public boolean isExpireSearchResults() {
1270                return myDeleteStaleSearches;
1271        }
1272
1273        /**
1274         * If this is set to <code>false</code> (default is <code>true</code>) the stale search deletion
1275         * task will be disabled (meaning that search results will be retained in the database indefinitely). USE WITH CAUTION.
1276         * <p>
1277         * This feature is useful if you want to define your own process for deleting these (e.g. because
1278         * you are running in a cluster)
1279         * </p>
1280         */
1281        public void setExpireSearchResults(boolean theDeleteStaleSearches) {
1282                myDeleteStaleSearches = theDeleteStaleSearches;
1283        }
1284
1285        /**
1286         * If set to <code>true</code> (default is <code>false</code>), the $expunge operation
1287         * will be enabled on this server. This operation is potentially dangerous since it allows
1288         * a client to physically delete data in a way that can not be recovered (without resorting
1289         * to backups).
1290         * <p>
1291         * It is recommended to not enable this setting without appropriate security
1292         * in place on your server to prevent non-administrators from using this
1293         * operation.
1294         * </p>
1295         */
1296        public boolean isExpungeEnabled() {
1297                return myExpungeEnabled;
1298        }
1299
1300        /**
1301         * If set to <code>true</code> (default is <code>false</code>), the _expunge parameter on the DELETE
1302         * operation will be enabled on this server. DELETE _expunge removes all data associated with a resource in a highly performant
1303         * way, skipping most of the the checks that are enforced with usual DELETE operations.  The only check
1304         * that is performed before deleting the resources and their indexes is that no other resources reference the resources about to
1305         * be deleted.  This operation is potentially dangerous since it allows
1306         * a client to physically delete data in a way that can not be recovered (without resorting
1307         * to backups).
1308         * <p>
1309         * It is recommended to not enable this setting without appropriate security
1310         * in place on your server to prevent non-administrators from using this
1311         * operation.
1312         * </p>
1313         */
1314        public void setDeleteExpungeEnabled(boolean theDeleteExpungeEnabled) {
1315                myDeleteExpungeEnabled = theDeleteExpungeEnabled;
1316        }
1317
1318        /**
1319         * If set to <code>true</code> (default is <code>false</code>), the _expunge parameter on the DELETE
1320         * operation will be enabled on this server. DELETE _expunge removes all data associated with a resource in a highly performant
1321         * way, skipping most of the the checks that are enforced with usual DELETE operations.  The only check
1322         * that is performed before deleting the data is that no other resources reference the resources about to
1323         * be deleted.  This operation is potentially dangerous since it allows
1324         * a client to physically delete data in a way that can not be recovered (without resorting
1325         * to backups).
1326         * <p>
1327         * It is recommended to not enable this setting without appropriate security
1328         * in place on your server to prevent non-administrators from using this
1329         * operation.
1330         * </p>
1331         */
1332        public boolean isDeleteExpungeEnabled() {
1333                return myDeleteExpungeEnabled;
1334        }
1335
1336        /**
1337         * If set to <code>true</code> (default is <code>false</code>), the $expunge operation
1338         * will be enabled on this server. This operation is potentially dangerous since it allows
1339         * a client to physically delete data in a way that can not be recovered (without resorting
1340         * to backups).
1341         * <p>
1342         * It is recommended to not enable this setting without appropriate security
1343         * in place on your server to prevent non-administrators from using this
1344         * operation.
1345         * </p>
1346         */
1347        public void setExpungeEnabled(boolean theExpungeEnabled) {
1348                myExpungeEnabled = theExpungeEnabled;
1349        }
1350
1351        /**
1352         * The expunge batch size (default 800) determines the number of records deleted within a single transaction by the
1353         * expunge operation.
1354         */
1355        public int getExpungeBatchSize() {
1356                return myExpungeBatchSize;
1357        }
1358
1359        /**
1360         * The expunge batch size (default 800) determines the number of records deleted within a single transaction by the
1361         * expunge operation.
1362         */
1363        public void setExpungeBatchSize(int theExpungeBatchSize) {
1364                myExpungeBatchSize = theExpungeBatchSize;
1365        }
1366
1367        /**
1368         * Should contained IDs be indexed the same way that non-contained IDs are (default is
1369         * <code>true</code>)
1370         */
1371        public boolean isIndexContainedResources() {
1372                return myIndexContainedResources;
1373        }
1374
1375        /**
1376         * Should contained IDs be indexed the same way that non-contained IDs are (default is
1377         * <code>true</code>)
1378         */
1379        public void setIndexContainedResources(boolean theIndexContainedResources) {
1380                myIndexContainedResources = theIndexContainedResources;
1381        }
1382
1383        /**
1384         * Should resources be marked as needing reindexing when a
1385         * SearchParameter resource is added or changed. This should generally
1386         * be true (which is the default)
1387         */
1388        public boolean isMarkResourcesForReindexingUponSearchParameterChange() {
1389                return myMarkResourcesForReindexingUponSearchParameterChange;
1390        }
1391
1392        /**
1393         * Should resources be marked as needing reindexing when a
1394         * SearchParameter resource is added or changed. This should generally
1395         * be true (which is the default)
1396         */
1397        public void setMarkResourcesForReindexingUponSearchParameterChange(boolean theMarkResourcesForReindexingUponSearchParameterChange) {
1398                myMarkResourcesForReindexingUponSearchParameterChange = theMarkResourcesForReindexingUponSearchParameterChange;
1399        }
1400
1401        public boolean isSchedulingDisabled() {
1402                return mySchedulingDisabled;
1403        }
1404
1405        public void setSchedulingDisabled(boolean theSchedulingDisabled) {
1406                mySchedulingDisabled = theSchedulingDisabled;
1407        }
1408
1409        /**
1410         * If set to {@literal true} (default is true), if a client performs an update which does not actually
1411         * result in any chance to a given resource (e.g. an update where the resource body matches the
1412         * existing resource body in the database) the operation will succeed but a new version (and corresponding history
1413         * entry) will not actually be created. The existing resource version will be returned to the client.
1414         * <p>
1415         * If set to {@literal false}, all updates will result in the creation of a new version
1416         * </p>
1417         */
1418        public boolean isSuppressUpdatesWithNoChange() {
1419                return mySuppressUpdatesWithNoChange;
1420        }
1421
1422        /**
1423         * If set to {@literal true} (default is true), if a client performs an update which does not actually
1424         * result in any chance to a given resource (e.g. an update where the resource body matches the
1425         * existing resource body in the database) the operation will succeed but a new version (and corresponding history
1426         * entry) will not actually be created. The existing resource version will be returned to the client.
1427         * <p>
1428         * If set to {@literal false}, all updates will result in the creation of a new version
1429         * </p>
1430         */
1431        public void setSuppressUpdatesWithNoChange(boolean theSuppressUpdatesWithNoChange) {
1432                mySuppressUpdatesWithNoChange = theSuppressUpdatesWithNoChange;
1433
1434        }
1435
1436        /**
1437         * When using {@link #setUniqueIndexesEnabled(boolean) unique indexes}, if this
1438         * setting is set to <code>true</code> (default is <code>true</code>) the system
1439         * will test for the existence of a particular unique index value prior to saving
1440         * a new one.
1441         * <p>
1442         * This causes friendlier error messages to be generated, but adds an
1443         * extra round-trip to the database for eavh save so it can cause
1444         * a small performance hit.
1445         * </p>
1446         */
1447        public boolean isUniqueIndexesCheckedBeforeSave() {
1448                return myUniqueIndexesCheckedBeforeSave;
1449        }
1450
1451        /**
1452         * When using {@link #setUniqueIndexesEnabled(boolean) unique indexes}, if this
1453         * setting is set to <code>true</code> (default is <code>true</code>) the system
1454         * will test for the existence of a particular unique index value prior to saving
1455         * a new one.
1456         * <p>
1457         * This causes friendlier error messages to be generated, but adds an
1458         * extra round-trip to the database for each save so it can cause
1459         * a small performance hit.
1460         * </p>
1461         */
1462        public void setUniqueIndexesCheckedBeforeSave(boolean theUniqueIndexesCheckedBeforeSave) {
1463                myUniqueIndexesCheckedBeforeSave = theUniqueIndexesCheckedBeforeSave;
1464        }
1465
1466        /**
1467         * If set to <code>true</code> (default is <code>true</code>), indexes will be
1468         * created for search parameters marked as {@link HapiExtensions#EXT_SP_UNIQUE}.
1469         * This is a HAPI FHIR specific extension which can be used to specify that no more than one
1470         * resource can exist which matches a given criteria, using a database constraint to
1471         * enforce this.
1472         */
1473        public boolean isUniqueIndexesEnabled() {
1474                return myUniqueIndexesEnabled;
1475        }
1476
1477        /**
1478         * If set to <code>true</code> (default is <code>true</code>), indexes will be
1479         * created for search parameters marked as {@link HapiExtensions#EXT_SP_UNIQUE}.
1480         * This is a HAPI FHIR specific extension which can be used to specify that no more than one
1481         * resource can exist which matches a given criteria, using a database constraint to
1482         * enforce this.
1483         */
1484        public void setUniqueIndexesEnabled(boolean theUniqueIndexesEnabled) {
1485                myUniqueIndexesEnabled = theUniqueIndexesEnabled;
1486        }
1487
1488        /**
1489         * If <code>true</code> (default is <code>true</code>), before allowing a
1490         * SearchParameter resource to be stored (create, update, etc.) the
1491         * expression will be performed against an empty resource to ensure that
1492         * the FHIRPath executor is able to process it.
1493         * <p>
1494         * This should proabably always be set to true, but is configurable
1495         * in order to support some unit tests.
1496         * </p>
1497         */
1498        public boolean isValidateSearchParameterExpressionsOnSave() {
1499                return myValidateSearchParameterExpressionsOnSave;
1500        }
1501
1502        /**
1503         * If <code>true</code> (default is <code>true</code>), before allowing a
1504         * SearchParameter resource to be stored (create, update, etc.) the
1505         * expression will be performed against an empty resource to ensure that
1506         * the FHIRPath executor is able to process it.
1507         * <p>
1508         * This should proabably always be set to true, but is configurable
1509         * in order to support some unit tests.
1510         * </p>
1511         */
1512        public void setValidateSearchParameterExpressionsOnSave(boolean theValidateSearchParameterExpressionsOnSave) {
1513                myValidateSearchParameterExpressionsOnSave = theValidateSearchParameterExpressionsOnSave;
1514        }
1515
1516        /**
1517         * Do not call this method, it exists only for legacy reasons. It
1518         * will be removed in a future version. Configure the page size on your
1519         * paging provider instead.
1520         *
1521         * @deprecated This method does not do anything. Configure the page size on your
1522         * paging provider instead. Deprecated in HAPI FHIR 2.3 (Jan 2017)
1523         */
1524        @Deprecated
1525        public void setHardSearchLimit(int theHardSearchLimit) {
1526                // this method does nothing
1527        }
1528
1529        /**
1530         * This is the maximum number of resources that will be added to a single page of returned resources. Because of
1531         * includes with wildcards and other possibilities it is possible for a client to make requests that include very
1532         * large amounts of data, so this hard limit can be imposed to prevent runaway requests.
1533         *
1534         * @deprecated Deprecated in HAPI FHIR 3.2.0 as this method doesn't actually do anything
1535         */
1536        @Deprecated
1537        public void setIncludeLimit(@SuppressWarnings("unused") int theIncludeLimit) {
1538                // nothing
1539        }
1540
1541        /**
1542         * @deprecated As of HAPI FHIR 3.0.0, subscriptions no longer use polling for
1543         * detecting changes, so this setting has no effect
1544         */
1545        @Deprecated
1546        public void setSubscriptionEnabled(boolean theSubscriptionEnabled) {
1547                // nothing
1548        }
1549
1550        /**
1551         * @deprecated As of HAPI FHIR 3.0.0, subscriptions no longer use polling for
1552         * detecting changes, so this setting has no effect
1553         */
1554        @Deprecated
1555        public void setSubscriptionPollDelay(long theSubscriptionPollDelay) {
1556                // ignore
1557        }
1558
1559        /**
1560         * @deprecated As of HAPI FHIR 3.0.0, subscriptions no longer use polling for
1561         * detecting changes, so this setting has no effect
1562         */
1563        @Deprecated
1564        public void setSubscriptionPurgeInactiveAfterMillis(Long theMillis) {
1565                // ignore
1566        }
1567
1568        public void setSubscriptionPurgeInactiveAfterSeconds(int theSeconds) {
1569                setSubscriptionPurgeInactiveAfterMillis(theSeconds * DateUtils.MILLIS_PER_SECOND);
1570        }
1571
1572        /**
1573         * This setting sets the number of search results to prefetch. For example, if this list
1574         * is set to [100, 1000, -1] then the server will initially load 100 results and not
1575         * attempt to load more. If the user requests subsequent page(s) of results and goes
1576         * past 100 results, the system will load the next 900 (up to the following threshold of 1000).
1577         * The system will progressively work through these thresholds.
1578         *
1579         * <p>
1580         * A threshold of -1 means to load all results. Note that if the final threshold is a
1581         * number other than <code>-1</code>, the system will never prefetch more than the
1582         * given number.
1583         * </p>
1584         */
1585        public List<Integer> getSearchPreFetchThresholds() {
1586                return mySearchPreFetchThresholds;
1587        }
1588
1589        /**
1590         * This setting sets the number of search results to prefetch. For example, if this list
1591         * is set to [100, 1000, -1] then the server will initially load 100 results and not
1592         * attempt to load more. If the user requests subsequent page(s) of results and goes
1593         * past 100 results, the system will load the next 900 (up to the following threshold of 1000).
1594         * The system will progressively work through these thresholds.
1595         *
1596         * <p>
1597         * A threshold of -1 means to load all results. Note that if the final threshold is a
1598         * number other than <code>-1</code>, the system will never prefetch more than the
1599         * given number.
1600         * </p>
1601         */
1602        public void setSearchPreFetchThresholds(List<Integer> thePreFetchThresholds) {
1603                Validate.isTrue(thePreFetchThresholds.size() > 0, "thePreFetchThresholds must not be empty");
1604                int last = 0;
1605                for (Integer nextInt : thePreFetchThresholds) {
1606                        Validate.isTrue(nextInt > 0 || nextInt == -1, nextInt + " is not a valid prefetch threshold");
1607                        Validate.isTrue(nextInt != last, "Prefetch thresholds must be sequential");
1608                        Validate.isTrue(nextInt > last || nextInt == -1, "Prefetch thresholds must be sequential");
1609                        Validate.isTrue(last != -1, "Prefetch thresholds must be sequential");
1610                        last = nextInt;
1611                }
1612                mySearchPreFetchThresholds = thePreFetchThresholds;
1613        }
1614
1615        /**
1616         * If set to <code>true</code> (default is false) the server will not use
1617         * hash based searches. These searches were introduced in HAPI FHIR 3.5.0
1618         * and are the new default way of searching. However they require a very
1619         * large data migration if an existing system has a large amount of data
1620         * so this setting can be used to use the old search mechanism while data
1621         * is migrated.
1622         *
1623         * @since 3.6.0
1624         */
1625        public boolean getDisableHashBasedSearches() {
1626                return myDisableHashBasedSearches;
1627        }
1628
1629        /**
1630         * If set to <code>true</code> (default is false) the server will not use
1631         * hash based searches. These searches were introduced in HAPI FHIR 3.5.0
1632         * and are the new default way of searching. However they require a very
1633         * large data migration if an existing system has a large amount of data
1634         * so this setting can be used to use the old search mechanism while data
1635         * is migrated.
1636         *
1637         * @since 3.6.0
1638         */
1639        public void setDisableHashBasedSearches(boolean theDisableHashBasedSearches) {
1640                myDisableHashBasedSearches = theDisableHashBasedSearches;
1641        }
1642
1643        /**
1644         * If set to <code>false</code> (default is true) the server will not use
1645         * in-memory subscription searching and instead use the database matcher for all subscription
1646         * criteria matching.
1647         * <p>
1648         * When there are subscriptions registered
1649         * on the server, the default behaviour is to compare the changed resource to the
1650         * subscription criteria directly in-memory without going out to the database.
1651         * Certain types of subscription criteria, e.g. chained references of queries with
1652         * qualifiers or prefixes, are not supported by the in-memory matcher and will fall back
1653         * to a database matcher.
1654         * <p>
1655         * The database matcher performs a query against the
1656         * database by prepending ?id=XYZ to the subscription criteria where XYZ is the id of the changed entity
1657         *
1658         * @since 3.6.1
1659         */
1660
1661        public boolean isEnableInMemorySubscriptionMatching() {
1662                return myEnableInMemorySubscriptionMatching;
1663        }
1664
1665        /**
1666         * If set to <code>false</code> (default is true) the server will not use
1667         * in-memory subscription searching and instead use the database matcher for all subscription
1668         * criteria matching.
1669         * <p>
1670         * When there are subscriptions registered
1671         * on the server, the default behaviour is to compare the changed resource to the
1672         * subscription criteria directly in-memory without going out to the database.
1673         * Certain types of subscription criteria, e.g. chained references of queries with
1674         * qualifiers or prefixes, are not supported by the in-memory matcher and will fall back
1675         * to a database matcher.
1676         * <p>
1677         * The database matcher performs a query against the
1678         * database by prepending ?id=XYZ to the subscription criteria where XYZ is the id of the changed entity
1679         *
1680         * @since 3.6.1
1681         */
1682
1683        public void setEnableInMemorySubscriptionMatching(boolean theEnableInMemorySubscriptionMatching) {
1684                myEnableInMemorySubscriptionMatching = theEnableInMemorySubscriptionMatching;
1685        }
1686
1687        public ModelConfig getModelConfig() {
1688                return myModelConfig;
1689        }
1690
1691        /**
1692         * If enabled, the server will support the use of :contains searches,
1693         * which are helpful but can have adverse effects on performance.
1694         * <p>
1695         * Default is <code>false</code> (Note that prior to HAPI FHIR
1696         * 3.5.0 the default was <code>true</code>)
1697         * </p>
1698         * <p>
1699         * Note: If you change this value after data already has
1700         * already been stored in the database, you must for a reindexing
1701         * of all data in the database or resources may not be
1702         * searchable.
1703         * </p>
1704         */
1705        public boolean isAllowContainsSearches() {
1706                return this.myModelConfig.isAllowContainsSearches();
1707        }
1708
1709        /**
1710         * If enabled, the server will support the use of :contains searches,
1711         * which are helpful but can have adverse effects on performance.
1712         * <p>
1713         * Default is <code>false</code> (Note that prior to HAPI FHIR
1714         * 3.5.0 the default was <code>true</code>)
1715         * </p>
1716         * <p>
1717         * Note: If you change this value after data already has
1718         * already been stored in the database, you must for a reindexing
1719         * of all data in the database or resources may not be
1720         * searchable.
1721         * </p>
1722         */
1723        public void setAllowContainsSearches(boolean theAllowContainsSearches) {
1724                this.myModelConfig.setAllowContainsSearches(theAllowContainsSearches);
1725        }
1726
1727        /**
1728         * This setting may be used to advise the server that any references found in
1729         * resources that have any of the base URLs given here will be replaced with
1730         * simple local references.
1731         * <p>
1732         * For example, if the set contains the value <code>http://example.com/base/</code>
1733         * and a resource is submitted to the server that contains a reference to
1734         * <code>http://example.com/base/Patient/1</code>, the server will automatically
1735         * convert this reference to <code>Patient/1</code>
1736         * </p>
1737         * <p>
1738         * Note that this property has different behaviour from {@link DaoConfig#getTreatReferencesAsLogical()}
1739         * </p>
1740         *
1741         * @see #getTreatReferencesAsLogical()
1742         */
1743        public Set<String> getTreatBaseUrlsAsLocal() {
1744                return myModelConfig.getTreatBaseUrlsAsLocal();
1745        }
1746
1747        /**
1748         * This setting may be used to advise the server that any references found in
1749         * resources that have any of the base URLs given here will be replaced with
1750         * simple local references.
1751         * <p>
1752         * For example, if the set contains the value <code>http://example.com/base/</code>
1753         * and a resource is submitted to the server that contains a reference to
1754         * <code>http://example.com/base/Patient/1</code>, the server will automatically
1755         * convert this reference to <code>Patient/1</code>
1756         * </p>
1757         *
1758         * @param theTreatBaseUrlsAsLocal The set of base URLs. May be <code>null</code>, which
1759         *                                means no references will be treated as external
1760         */
1761        public void setTreatBaseUrlsAsLocal(Set<String> theTreatBaseUrlsAsLocal) {
1762                myModelConfig.setTreatBaseUrlsAsLocal(theTreatBaseUrlsAsLocal);
1763        }
1764
1765        /**
1766         * If set to {@code true} the default search params (i.e. the search parameters that are
1767         * defined by the FHIR specification itself) may be overridden by uploading search
1768         * parameters to the server with the same code as the built-in search parameter.
1769         * <p>
1770         * This can be useful if you want to be able to disable or alter
1771         * the behaviour of the default search parameters.
1772         * </p>
1773         * <p>
1774         * The default value for this setting is {@code false}
1775         * </p>
1776         */
1777        public boolean isDefaultSearchParamsCanBeOverridden() {
1778                return myModelConfig.isDefaultSearchParamsCanBeOverridden();
1779        }
1780
1781        /**
1782         * If set to {@code true} the default search params (i.e. the search parameters that are
1783         * defined by the FHIR specification itself) may be overridden by uploading search
1784         * parameters to the server with the same code as the built-in search parameter.
1785         * <p>
1786         * This can be useful if you want to be able to disable or alter
1787         * the behaviour of the default search parameters.
1788         * </p>
1789         * <p>
1790         * The default value for this setting is {@code false}
1791         * </p>
1792         */
1793        public void setDefaultSearchParamsCanBeOverridden(boolean theDefaultSearchParamsCanBeOverridden) {
1794                myModelConfig.setDefaultSearchParamsCanBeOverridden(theDefaultSearchParamsCanBeOverridden);
1795        }
1796
1797        /**
1798         * This setting indicates which subscription channel types are supported by the server.  Any subscriptions submitted
1799         * to the server matching these types will be activated.
1800         */
1801        public DaoConfig addSupportedSubscriptionType(Subscription.SubscriptionChannelType theSubscriptionChannelType) {
1802                myModelConfig.addSupportedSubscriptionType(theSubscriptionChannelType);
1803                return this;
1804        }
1805
1806        /**
1807         * This setting indicates which subscription channel types are supported by the server.  Any subscriptions submitted
1808         * to the server matching these types will be activated.
1809         *
1810         * @see #addSupportedSubscriptionType(Subscription.SubscriptionChannelType)
1811         */
1812        public Set<Subscription.SubscriptionChannelType> getSupportedSubscriptionTypes() {
1813                return myModelConfig.getSupportedSubscriptionTypes();
1814        }
1815
1816        @VisibleForTesting
1817        public void clearSupportedSubscriptionTypesForUnitTest() {
1818                myModelConfig.clearSupportedSubscriptionTypesForUnitTest();
1819        }
1820
1821        /**
1822         * If e-mail subscriptions are supported, the From address used when sending e-mails
1823         */
1824
1825        public String getEmailFromAddress() {
1826                return myModelConfig.getEmailFromAddress();
1827        }
1828
1829        /**
1830         * If e-mail subscriptions are supported, the From address used when sending e-mails
1831         */
1832
1833        public void setEmailFromAddress(String theEmailFromAddress) {
1834                myModelConfig.setEmailFromAddress(theEmailFromAddress);
1835        }
1836
1837        /**
1838         * If websocket subscriptions are enabled, this defines the context path that listens to them.  Default value "/websocket".
1839         */
1840
1841        public String getWebsocketContextPath() {
1842                return myModelConfig.getWebsocketContextPath();
1843        }
1844
1845        /**
1846         * If websocket subscriptions are enabled, this defines the context path that listens to them.  Default value "/websocket".
1847         */
1848
1849        public void setWebsocketContextPath(String theWebsocketContextPath) {
1850                myModelConfig.setWebsocketContextPath(theWebsocketContextPath);
1851        }
1852
1853        /**
1854         * If set to <code>true</code> the _filter search parameter will be enabled on this server. Note that _filter
1855         * is very powerful, but also potentially dangerous as it can allow a user to create a query for which there
1856         * are no indexes or efficient query plans for the database to leverage while performing the query.
1857         * As a result, this feature is recommended only for servers where the querying applications are known in advance
1858         * and a database administrator can properly tune the database for the resulting queries.
1859         */
1860        public boolean isFilterParameterEnabled() {
1861                return myFilterParameterEnabled;
1862        }
1863
1864        /**
1865         * If set to <code>true</code> the _filter search parameter will be enabled on this server. Note that _filter
1866         * is very powerful, but also potentially dangerous as it can allow a user to create a query for which there
1867         * are no indexes or efficient query plans for the database to leverage while performing the query.
1868         * As a result, this feature is recommended only for servers where the querying applications are known in advance
1869         * and a database administrator can properly tune the database for the resulting queries.
1870         */
1871        public void setFilterParameterEnabled(boolean theFilterParameterEnabled) {
1872                myFilterParameterEnabled = theFilterParameterEnabled;
1873        }
1874
1875        /**
1876         * If enabled, resource source information (<code>Resource.meta.source</code>) will be persisted along with
1877         * each resource. This adds extra table and index space so it should be disabled if it is not being
1878         * used.
1879         * <p>
1880         * Default is {@link StoreMetaSourceInformationEnum#SOURCE_URI_AND_REQUEST_ID}
1881         * </p>
1882         */
1883        public StoreMetaSourceInformationEnum getStoreMetaSourceInformation() {
1884                return myStoreMetaSourceInformation;
1885        }
1886
1887        /**
1888         * If enabled, resource source information (<code>Resource.meta.source</code>) will be persisted along with
1889         * each resource. This adds extra table and index space so it should be disabled if it is not being
1890         * used.
1891         * <p>
1892         * Default is {@link StoreMetaSourceInformationEnum#SOURCE_URI_AND_REQUEST_ID}
1893         * </p>
1894         */
1895        public void setStoreMetaSourceInformation(StoreMetaSourceInformationEnum theStoreMetaSourceInformation) {
1896                Validate.notNull(theStoreMetaSourceInformation, "theStoreMetaSourceInformation must not be null");
1897                myStoreMetaSourceInformation = theStoreMetaSourceInformation;
1898        }
1899
1900        /**
1901         * <p>
1902         * If set to {@code true}, ValueSets and expansions are stored in terminology tables. This is to facilitate
1903         * optimization of the $expand operation on large ValueSets.
1904         * </p>
1905         * <p>
1906         * The default value for this setting is {@code true}.
1907         * </p>
1908         *
1909         * @since 4.1.0
1910         */
1911        public boolean isPreExpandValueSets() {
1912                return myPreExpandValueSets;
1913        }
1914
1915        /**
1916         * <p>
1917         * If set to {@code true}, ValueSets and expansions are stored in terminology tables. This is to facilitate
1918         * optimization of the $expand operation on large ValueSets.
1919         * </p>
1920         * <p>
1921         * The default value for this setting is {@code true}.
1922         * </p>
1923         *
1924         * @since 4.1.0
1925         */
1926        public void setPreExpandValueSets(boolean thePreExpandValueSets) {
1927                myPreExpandValueSets = thePreExpandValueSets;
1928        }
1929
1930        /**
1931         * <p>
1932         * This is the default value of {@code offset} parameter for the ValueSet {@code $expand} operation when
1933         * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}.
1934         * </p>
1935         * <p>
1936         * The default value for this setting is {@code 0}.
1937         * </p>
1938         *
1939         * @since 4.1.0
1940         */
1941        public int getPreExpandValueSetsDefaultOffset() {
1942                return myPreExpandValueSetsDefaultOffset;
1943        }
1944
1945        /**
1946         * <p>
1947         * This is the default value of {@code count} parameter for the ValueSet {@code $expand} operation when
1948         * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}.
1949         * </p>
1950         * <p>
1951         * The default value for this setting is {@code 1000}.
1952         * </p>
1953         *
1954         * @since 4.1.0
1955         */
1956        public int getPreExpandValueSetsDefaultCount() {
1957                return myPreExpandValueSetsDefaultCount;
1958        }
1959
1960        /**
1961         * <p>
1962         * This is the default value of {@code count} parameter for the ValueSet {@code $expand} operation when
1963         * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}.
1964         * </p>
1965         * <p>
1966         * If {@code thePreExpandValueSetsDefaultCount} is greater than
1967         * {@link DaoConfig#getPreExpandValueSetsMaxCount()}, the lesser value is used.
1968         * </p>
1969         * <p>
1970         * The default value for this setting is {@code 1000}.
1971         * </p>
1972         *
1973         * @since 4.1.0
1974         */
1975        public void setPreExpandValueSetsDefaultCount(int thePreExpandValueSetsDefaultCount) {
1976                myPreExpandValueSetsDefaultCount = Math.min(thePreExpandValueSetsDefaultCount, getPreExpandValueSetsMaxCount());
1977        }
1978
1979        /**
1980         * <p>
1981         * This is the max value of {@code count} parameter for the ValueSet {@code $expand} operation when
1982         * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}.
1983         * </p>
1984         * <p>
1985         * The default value for this setting is {@code 1000}.
1986         * </p>
1987         *
1988         * @since 4.1.0
1989         */
1990        public int getPreExpandValueSetsMaxCount() {
1991                return myPreExpandValueSetsMaxCount;
1992        }
1993
1994        /**
1995         * <p>
1996         * This is the max value of {@code count} parameter for the ValueSet {@code $expand} operation when
1997         * {@link DaoConfig#isPreExpandValueSets()} returns {@code true}.
1998         * </p>
1999         * <p>
2000         * If {@code thePreExpandValueSetsMaxCount} is lesser than
2001         * {@link DaoConfig#getPreExpandValueSetsDefaultCount()}, the default {@code count} is lowered to the
2002         * new max {@code count}.
2003         * </p>
2004         * <p>
2005         * The default value for this setting is {@code 1000}.
2006         * </p>
2007         *
2008         * @since 4.1.0
2009         */
2010        public void setPreExpandValueSetsMaxCount(int thePreExpandValueSetsMaxCount) {
2011                myPreExpandValueSetsMaxCount = thePreExpandValueSetsMaxCount;
2012                setPreExpandValueSetsDefaultCount(Math.min(getPreExpandValueSetsDefaultCount(), getPreExpandValueSetsMaxCount()));
2013        }
2014
2015        /**
2016         * This setting should be disabled (set to <code>false</code>) on servers that are not allowing
2017         * deletes. Default is <code>true</code>. If deletes are disabled, some checks for resource
2018         * deletion can be skipped, which improves performance. This is particularly helpful when large
2019         * amounts of data containing client-assigned IDs are being loaded, but it can also improve
2020         * search performance.
2021         *
2022         * @since 5.0.0
2023         */
2024        public boolean isDeleteEnabled() {
2025                return myDeleteEnabled;
2026        }
2027
2028        /**
2029         * This setting should be disabled (set to <code>false</code>) on servers that are not allowing
2030         * deletes. Default is <code>true</code>. If deletes are disabled, some checks for resource
2031         * deletion can be skipped, which improves performance. This is particularly helpful when large
2032         * amounts of data containing client-assigned IDs are being loaded, but it can also improve
2033         * search performance.
2034         *
2035         * @since 5.0.0
2036         */
2037        public void setDeleteEnabled(boolean theDeleteEnabled) {
2038                myDeleteEnabled = theDeleteEnabled;
2039        }
2040
2041        /**
2042         * <p>
2043         * This determines the maximum number of conflicts that should be fetched and handled while retrying a delete of a resource.
2044         * </p>
2045         * <p>
2046         * The default value for this setting is {@code 60}.
2047         * </p>
2048         *
2049         * @since 5.1.0
2050         */
2051        public Integer getMaximumDeleteConflictQueryCount() {
2052                return myMaximumDeleteConflictQueryCount;
2053        }
2054
2055        /**
2056         * <p>
2057         * This determines the maximum number of conflicts that should be fetched and handled while retrying a delete of a resource.
2058         * </p>
2059         * <p>
2060         * The default value for this setting is {@code 60}.
2061         * </p>
2062         *
2063         * @since 5.1.0
2064         */
2065        public void setMaximumDeleteConflictQueryCount(Integer theMaximumDeleteConflictQueryCount) {
2066                myMaximumDeleteConflictQueryCount = theMaximumDeleteConflictQueryCount;
2067        }
2068
2069        /**
2070         * <p>
2071         * This determines whether $binary-access-write operations should first load the InputStream into memory before persisting the
2072         * contents to the database. This needs to be enabled for MS SQL Server as this DB requires that the blob size be known
2073         * in advance.
2074         * </p>
2075         * <p>
2076         * Note that this setting should be enabled with caution as it can lead to significant demands on memory.
2077         * </p>
2078         * <p>
2079         * The default value for this setting is {@code false}.
2080         * </p>
2081         *
2082         * @since 5.1.0
2083         * @deprecated In 5.2.0 this setting no longer does anything
2084         */
2085        @Deprecated
2086        public void setPreloadBlobFromInputStream(Boolean thePreloadBlobFromInputStream) {
2087                // ignore
2088        }
2089
2090        public enum StoreMetaSourceInformationEnum {
2091                NONE(false, false),
2092                SOURCE_URI(true, false),
2093                REQUEST_ID(false, true),
2094                SOURCE_URI_AND_REQUEST_ID(true, true);
2095
2096                private final boolean myStoreSourceUri;
2097                private final boolean myStoreRequestId;
2098
2099                StoreMetaSourceInformationEnum(boolean theStoreSourceUri, boolean theStoreRequestId) {
2100                        myStoreSourceUri = theStoreSourceUri;
2101                        myStoreRequestId = theStoreRequestId;
2102                }
2103
2104                public boolean isStoreSourceUri() {
2105                        return myStoreSourceUri;
2106                }
2107
2108                public boolean isStoreRequestId() {
2109                        return myStoreRequestId;
2110                }
2111        }
2112
2113        public enum IndexEnabledEnum {
2114                ENABLED,
2115                DISABLED
2116        }
2117
2118        /**
2119         * This enum provides allowable options for {@link #setResourceServerIdStrategy(IdStrategyEnum)}
2120         */
2121        public enum IdStrategyEnum {
2122                /**
2123                 * This strategy is the default strategy, and it simply uses a sequential
2124                 * numeric ID for each newly created resource.
2125                 */
2126                SEQUENTIAL_NUMERIC,
2127                /**
2128                 * Each resource will receive a randomly generated UUID
2129                 */
2130                UUID
2131        }
2132
2133        /**
2134         * This enum provides allowable options for {@link #setResourceClientIdStrategy(ClientIdStrategyEnum)}
2135         */
2136        public enum ClientIdStrategyEnum {
2137                /**
2138                 * Clients are not allowed to supply IDs for resources that do not
2139                 * already exist
2140                 */
2141                NOT_ALLOWED,
2142
2143                /**
2144                 * Clients may supply IDs but these IDs are not permitted to be purely
2145                 * numeric. In other words, values such as "A", "A1" and "000A" would be considered
2146                 * valid but "123" would not.
2147                 * <p><b>This is the default setting.</b></p>
2148                 */
2149                ALPHANUMERIC,
2150
2151                /**
2152                 * Clients may supply any ID including purely numeric IDs. Note that this setting should
2153                 * only be set on an empty database, or on a database that has always had this setting
2154                 * set as it causes a "forced ID" to be used for all resources.
2155                 * <p>
2156                 * Note that if you use this setting, it is highly recommended that you also
2157                 * set the {@link #setResourceServerIdStrategy(IdStrategyEnum) ResourceServerIdStrategy}
2158                 * to {@link IdStrategyEnum#UUID} in order to avoid any potential for conflicts. Otherwise
2159                 * a database sequence will be used to generate IDs and these IDs can conflict with
2160                 * client-assigned numeric IDs.
2161                 * </p>
2162                 */
2163                ANY
2164        }
2165
2166}