001/* 002 * #%L 003 * HAPI FHIR - Core Library 004 * %% 005 * Copyright (C) 2014 - 2024 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.context; 021 022import ca.uhn.fhir.parser.IParser; 023import ca.uhn.fhir.util.CollectionUtil; 024import jakarta.annotation.Nonnull; 025import jakarta.annotation.Nullable; 026 027import java.util.Collection; 028import java.util.Collections; 029import java.util.HashSet; 030import java.util.List; 031import java.util.Set; 032 033/** 034 * This object supplies default configuration to all {@link IParser parser} instances 035 * created by a given {@link FhirContext}. It is accessed using {@link FhirContext#getParserOptions()} 036 * and {@link FhirContext#setParserOptions(ParserOptions)}. 037 * <p> 038 * It is fine to share a ParserOptions instances across multiple context instances. 039 * </p> 040 */ 041public class ParserOptions { 042 043 private boolean myStripVersionsFromReferences = true; 044 private Set<String> myDontStripVersionsFromReferencesAtPaths = Collections.emptySet(); 045 private boolean myOverrideResourceIdWithBundleEntryFullUrl = true; 046 private boolean myAutoContainReferenceTargetsWithNoId = true; 047 private Set<String> myEncodeElementsForSummaryMode = null; 048 private Set<String> myDontEncodeElementsForSummaryMode = null; 049 050 /** 051 * If set to {@literal true} (which is the default), contained resources may be specified by 052 * populating the target (contained) resource directly in {@link org.hl7.fhir.instance.model.api.IBaseReference#setReference(String)} 053 * and the parser will automatically locate it and insert it into <code>Resource.contained</code> when 054 * serializing. This is convenient, but also imposes a performance cost when serializing large numbers 055 * of resources, so this can be disabled if it is not needed. 056 * <p> 057 * If disabled, only resources that are directly placed in <code>Resource.contained</code> will be 058 * serialized. 059 * </p> 060 * 061 * @since 5.7.0 062 */ 063 public boolean isAutoContainReferenceTargetsWithNoId() { 064 return myAutoContainReferenceTargetsWithNoId; 065 } 066 067 /** 068 * If set to {@literal true} (which is the default), contained resources may be specified by 069 * populating the target (contained) resource directly in {@link org.hl7.fhir.instance.model.api.IBaseReference#setReference(String)} 070 * and the parser will automatically locate it and insert it into <code>Resource.contained</code> when 071 * serializing. This is convenient, but also imposes a performance cost when serializing large numbers 072 * of resources, so this can be disabled if it is not needed. 073 * <p> 074 * If disabled, only resources that are directly placed in <code>Resource.contained</code> will be 075 * serialized. 076 * </p> 077 * 078 * @since 5.7.0 079 */ 080 public void setAutoContainReferenceTargetsWithNoId(boolean theAllowAutoContainedReferences) { 081 myAutoContainReferenceTargetsWithNoId = theAllowAutoContainedReferences; 082 } 083 084 /** 085 * If set to <code>true<code> (which is the default), resource references containing a version 086 * will have the version removed when the resource is encoded. This is generally good behaviour because 087 * in most situations, references from one resource to another should be to the resource by ID, not 088 * by ID and version. In some cases though, it may be desirable to preserve the version in resource 089 * links. In that case, this value should be set to <code>false</code>. 090 * 091 * @return Returns the parser instance's configuration setting for stripping versions from resource references when 092 * encoding. Default is <code>true</code>. 093 */ 094 public boolean isStripVersionsFromReferences() { 095 return myStripVersionsFromReferences; 096 } 097 098 /** 099 * If set to <code>true<code> (which is the default), resource references containing a version 100 * will have the version removed when the resource is encoded. This is generally good behaviour because 101 * in most situations, references from one resource to another should be to the resource by ID, not 102 * by ID and version. In some cases though, it may be desirable to preserve the version in resource 103 * links. In that case, this value should be set to <code>false</code>. 104 * <p> 105 * This method provides the ability to globally disable reference encoding. If finer-grained 106 * control is needed, use {@link #setDontStripVersionsFromReferencesAtPaths(String...)} 107 * </p> 108 * 109 * @param theStripVersionsFromReferences Set this to <code>false<code> to prevent the parser from removing 110 * resource versions from references. 111 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together 112 * @see #setDontStripVersionsFromReferencesAtPaths(String...) 113 */ 114 public ParserOptions setStripVersionsFromReferences(boolean theStripVersionsFromReferences) { 115 myStripVersionsFromReferences = theStripVersionsFromReferences; 116 return this; 117 } 118 119 /** 120 * Returns the value supplied to {@link IParser#setDontStripVersionsFromReferencesAtPaths(String...)} 121 * 122 * @see #setDontStripVersionsFromReferencesAtPaths(String...) 123 * @see #setStripVersionsFromReferences(boolean) 124 */ 125 public Set<String> getDontStripVersionsFromReferencesAtPaths() { 126 return myDontStripVersionsFromReferencesAtPaths; 127 } 128 129 /** 130 * If supplied value(s), any resource references at the specified paths will have their 131 * resource versions encoded instead of being automatically stripped during the encoding 132 * process. This setting has no effect on the parsing process. 133 * <p> 134 * This method provides a finer-grained level of control than {@link #setStripVersionsFromReferences(boolean)} 135 * and any paths specified by this method will be encoded even if {@link #setStripVersionsFromReferences(boolean)} 136 * has been set to <code>true</code> (which is the default) 137 * </p> 138 * 139 * @param thePaths A collection of paths for which the resource versions will not be removed automatically 140 * when serializing, e.g. "Patient.managingOrganization" or "AuditEvent.object.reference". Note that 141 * only resource name and field names with dots separating is allowed here (no repetition 142 * indicators, FluentPath expressions, etc.) 143 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together 144 * @see #setStripVersionsFromReferences(boolean) 145 */ 146 public ParserOptions setDontStripVersionsFromReferencesAtPaths(String... thePaths) { 147 if (thePaths == null) { 148 setDontStripVersionsFromReferencesAtPaths((List<String>) null); 149 } else { 150 setDontStripVersionsFromReferencesAtPaths(CollectionUtil.newSet(thePaths)); 151 } 152 return this; 153 } 154 155 /** 156 * If supplied value(s), any resource references at the specified paths will have their 157 * resource versions encoded instead of being automatically stripped during the encoding 158 * process. This setting has no effect on the parsing process. 159 * <p> 160 * This method provides a finer-grained level of control than {@link #setStripVersionsFromReferences(boolean)} 161 * and any paths specified by this method will be encoded even if {@link #setStripVersionsFromReferences(boolean)} 162 * has been set to <code>true</code> (which is the default) 163 * </p> 164 * 165 * @param thePaths A collection of paths for which the resource versions will not be removed automatically 166 * when serializing, e.g. "Patient.managingOrganization" or "AuditEvent.object.reference". Note that 167 * only resource name and field names with dots separating is allowed here (no repetition 168 * indicators, FluentPath expressions, etc.) 169 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together 170 * @see #setStripVersionsFromReferences(boolean) 171 */ 172 @SuppressWarnings("unchecked") 173 public ParserOptions setDontStripVersionsFromReferencesAtPaths(Collection<String> thePaths) { 174 if (thePaths == null) { 175 myDontStripVersionsFromReferencesAtPaths = Collections.emptySet(); 176 } else if (thePaths instanceof HashSet) { 177 myDontStripVersionsFromReferencesAtPaths = (Set<String>) ((HashSet<String>) thePaths).clone(); 178 } else { 179 myDontStripVersionsFromReferencesAtPaths = new HashSet<>(thePaths); 180 } 181 return this; 182 } 183 184 /** 185 * If set to <code>true</code> (which is the default), the Bundle.entry.fullUrl will override the Bundle.entry.resource's 186 * resource id if the fullUrl is defined. This behavior happens when parsing the source data into a Bundle object. Set this 187 * to <code>false</code> if this is not the desired behavior (e.g. the client code wishes to perform additional 188 * validation checks between the fullUrl and the resource id). 189 * 190 * @return Returns the parser instance's configuration setting for overriding resource ids with Bundle.entry.fullUrl when 191 * parsing the source data into a Bundle object. Default is <code>true</code>. 192 */ 193 public boolean isOverrideResourceIdWithBundleEntryFullUrl() { 194 return myOverrideResourceIdWithBundleEntryFullUrl; 195 } 196 197 /** 198 * If set to <code>true</code> (which is the default), the Bundle.entry.fullUrl will override the Bundle.entry.resource's 199 * resource id if the fullUrl is defined. This behavior happens when parsing the source data into a Bundle object. Set this 200 * to <code>false</code> if this is not the desired behavior (e.g. the client code wishes to perform additional 201 * validation checks between the fullUrl and the resource id). 202 * 203 * @param theOverrideResourceIdWithBundleEntryFullUrl Set this to <code>false</code> to prevent the parser from overriding resource ids with the 204 * Bundle.entry.fullUrl 205 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together 206 */ 207 public ParserOptions setOverrideResourceIdWithBundleEntryFullUrl( 208 boolean theOverrideResourceIdWithBundleEntryFullUrl) { 209 myOverrideResourceIdWithBundleEntryFullUrl = theOverrideResourceIdWithBundleEntryFullUrl; 210 return this; 211 } 212 213 /** 214 * This option specifies one or more elements that should be included when the parser is encoding 215 * a resource in {@link IParser#setSummaryMode(boolean) summary mode}, even if the element is not 216 * a part of the base FHIR specification's list of summary elements. Examples of valid values 217 * include: 218 * <ul> 219 * <li><b>Patient.maritalStatus</b> - Encode the entire maritalStatus CodeableConcept, even though Patient.maritalStatus is not a summary element</li> 220 * <li><b>Patient.maritalStatus.text</b> - Encode only the text component of the patient's maritalStatus</li> 221 * <li><b>*.text</b> - Encode the text element on any resource (only the very first position may contain a 222 * wildcard)</li> 223 * </ul> 224 * 225 * @see IParser#setSummaryMode(boolean) 226 * @see IParser#setEncodeElements(Set) Can be used to specify these values for an individual parser instance. 227 * @since 7.4.0 228 */ 229 @SuppressWarnings({"UnusedReturnValue"}) 230 @Nonnull 231 public ParserOptions setEncodeElementsForSummaryMode(@Nonnull String... theEncodeElements) { 232 return setEncodeElementsForSummaryMode(CollectionUtil.newSet(theEncodeElements)); 233 } 234 235 /** 236 * This option specifies one or more elements that should be included when the parser is encoding 237 * a resource in {@link IParser#setSummaryMode(boolean) summary mode}, even if the element is not 238 * a part of the base FHIR specification's list of summary elements. Examples of valid values 239 * include: 240 * <ul> 241 * <li><b>Patient.maritalStatus</b> - Encode the entire maritalStatus CodeableConcept, even though Patient.maritalStatus is not a summary element</li> 242 * <li><b>Patient.maritalStatus.text</b> - Encode only the text component of the patient's maritalStatus</li> 243 * <li><b>*.text</b> - Encode the text element on any resource (only the very first position may contain a 244 * wildcard)</li> 245 * </ul> 246 * 247 * @see IParser#setSummaryMode(boolean) 248 * @see IParser#setEncodeElements(Set) Can be used to specify these values for an individual parser instance. 249 * @since 7.4.0 250 */ 251 @Nonnull 252 public ParserOptions setEncodeElementsForSummaryMode(@Nullable Collection<String> theEncodeElements) { 253 Set<String> encodeElements = null; 254 if (theEncodeElements != null && !theEncodeElements.isEmpty()) { 255 encodeElements = new HashSet<>(theEncodeElements); 256 } 257 myEncodeElementsForSummaryMode = encodeElements; 258 return this; 259 } 260 261 /** 262 * @return Returns the values provided to {@link #setEncodeElementsForSummaryMode(Collection)} 263 * or <code>null</code> 264 * 265 * @since 7.4.0 266 */ 267 @Nullable 268 public Set<String> getEncodeElementsForSummaryMode() { 269 return myEncodeElementsForSummaryMode; 270 } 271 272 /** 273 * This option specifies one or more elements that should be excluded when the parser is encoding 274 * a resource in {@link IParser#setSummaryMode(boolean) summary mode}, even if the element is 275 * a part of the base FHIR specification's list of summary elements. Examples of valid values 276 * include: 277 * <ul> 278 * <li><b>Patient.name</b> - Do not include the patient's name</li> 279 * <li><b>Patient.name.family</b> - Do not include the patient's family name</li> 280 * <li><b>*.name</b> - Do not include the name element on any resource type</li> 281 * </ul> 282 * 283 * @see IParser#setSummaryMode(boolean) 284 * @see IParser#setDontEncodeElements(Collection) Can be used to specify these values for an individual parser instance. 285 * @since 7.4.0 286 */ 287 @SuppressWarnings({"UnusedReturnValue"}) 288 @Nonnull 289 public ParserOptions setDontEncodeElementsForSummaryMode(@Nonnull String... theEncodeElements) { 290 return setDontEncodeElementsForSummaryMode(CollectionUtil.newSet(theEncodeElements)); 291 } 292 293 /** 294 * This option specifies one or more elements that should be excluded when the parser is encoding 295 * a resource in {@link IParser#setSummaryMode(boolean) summary mode}, even if the element is 296 * a part of the base FHIR specification's list of summary elements. Examples of valid values 297 * include: 298 * <ul> 299 * <li><b>Patient.name</b> - Do not include the patient's name</li> 300 * <li><b>Patient.name.family</b> - Do not include the patient's family name</li> 301 * <li><b>*.name</b> - Do not include the name element on any resource type</li> 302 * </ul> 303 * 304 * @see IParser#setSummaryMode(boolean) 305 * @see IParser#setDontEncodeElements(Collection) Can be used to specify these values for an individual parser instance. 306 * @since 7.4.0 307 */ 308 @Nonnull 309 public ParserOptions setDontEncodeElementsForSummaryMode(@Nullable Collection<String> theDontEncodeElements) { 310 Set<String> dontEncodeElements = null; 311 if (theDontEncodeElements != null && !theDontEncodeElements.isEmpty()) { 312 dontEncodeElements = new HashSet<>(theDontEncodeElements); 313 } 314 myDontEncodeElementsForSummaryMode = dontEncodeElements; 315 return this; 316 } 317 318 /** 319 * @return Returns the values provided to {@link #setDontEncodeElementsForSummaryMode(Collection)} 320 * or <code>null</code> 321 * @since 7.4.0 322 */ 323 @Nullable 324 public Set<String> getDontEncodeElementsForSummaryMode() { 325 return myDontEncodeElementsForSummaryMode; 326 } 327}