Skip to content

Commit

Permalink
Use different logic to identify internal fragments
Browse files Browse the repository at this point in the history
  • Loading branch information
dotasek committed Jan 20, 2025
1 parent 328deeb commit e3fabda
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 15 deletions.
41 changes: 27 additions & 14 deletions hapi-fhir-base/src/main/java/ca/uhn/fhir/util/FhirTerser.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,6 @@ public class FhirTerser {
private static final String USER_DATA_KEY_CONTAIN_RESOURCES_COMPLETED =
FhirTerser.class.getName() + "_CONTAIN_RESOURCES_COMPLETED";

private static final String USER_DATA_KEY_CONTAINED_RESOURCE_ID_GENERATED_BY_TERSER =
FhirTerser.class.getName() + "_CONTAINED_RESOURCE_ID_GENERATED_BY_TERSER";

private final FhirContext myContext;

/**
Expand Down Expand Up @@ -1432,6 +1429,25 @@ public boolean acceptUndeclaredExtension(
});
}

private boolean isInternalFragment(IBaseReference theReference) {
if (!theReference.getReferenceElement().isEmpty()) {
return theReference.getReferenceElement().isLocal();
}
if( theReference.getResource() == null) {
return false;
}
if (theReference.getResource().getIdElement() == null) {
return false;
}
if (theReference.getResource().getIdElement().isAbsolute()) {
return false;
}
if (theReference.getResource().getIdElement().hasResourceType()) {
return false;
}
return true;
}

private void containResourcesForEncoding(
ContainedResources theContained, IBaseResource theResource, boolean theModifyResource) {
List<IBaseReference> allReferences = getAllPopulatedChildElementsOfType(theResource, IBaseReference.class);
Expand All @@ -1444,7 +1460,7 @@ private void containResourcesForEncoding(

for (IBaseReference next : allReferences) {
IBaseResource resource = next.getResource();
if (resource == null && next.getReferenceElement().isLocal()) {
if (resource == null && isInternalFragment(next)) {
if (theContained.hasExistingIdToContainedResource()) {
IBaseResource potentialTarget = theContained
.getExistingIdToContainedResource()
Expand All @@ -1460,7 +1476,7 @@ private void containResourcesForEncoding(
for (IBaseReference next : allReferences) {
IBaseResource resource = next.getResource();
if (resource != null) {
if (resource.getIdElement().isEmpty() || theContained.hasTerserGeneratedContainedId(resource)) {
if (resource.getIdElement().isEmpty() || isInternalFragment(next)) {

IIdType id = theContained.addContained(resource);
if (id == null) {
Expand All @@ -1470,7 +1486,8 @@ private void containResourcesForEncoding(
getContainedResourceList(theResource).add(resource);
next.setReference(id.getValue());
}
if (theContained.hasTerserGeneratedContainedId(resource) && theContained.hasExistingIdToContainedResource()) {
if (isInternalFragment(next)
&& theContained.hasExistingIdToContainedResource()) {
theContained
.getExistingIdToContainedResource()
.remove(resource.getIdElement().getValue());
Expand Down Expand Up @@ -1511,7 +1528,9 @@ public ContainedResources containResources(IBaseResource theResource, OptionsEnu
ContainedResources contained = new ContainedResources();

List<? extends IBaseResource> containedResources = getContainedResourceList(theResource);
containedResources.forEach(contained::addContained);
for (IBaseResource next : containedResources) {
contained.addContained(next);
}

if (myContext.getParserOptions().isAutoContainReferenceTargetsWithNoId()) {
containResourcesForEncoding(contained, theResource, modifyResource);
Expand Down Expand Up @@ -1809,20 +1828,14 @@ public IIdType addContained(IBaseResource theResource) {
if (isBlank(newId.getValue())) {
UUID randomUUID = UUID.randomUUID();
theResource.getIdElement().setValue(randomUUID.toString());
theResource.setUserData(USER_DATA_KEY_CONTAINED_RESOURCE_ID_GENERATED_BY_TERSER, Boolean.TRUE);
//theResource.setUserData(USER_DATA_KEY_CONTAINED_RESOURCE_ID_GENERATED_BY_TERSER, Boolean.TRUE);
newId.setValue("#" + randomUUID);
}

getResourceToIdMap().put(theResource, newId);
getOrCreateResourceList().add(theResource);
return newId;
}

public boolean hasTerserGeneratedContainedId(IBaseResource theResource) {
Object userData = theResource.getUserData(USER_DATA_KEY_CONTAINED_RESOURCE_ID_GENERATED_BY_TERSER);
return userData != null ? (Boolean) userData : false;
}

public void addContained(IIdType theId, IBaseResource theResource) {
if (!getResourceToIdMap().containsKey(theResource)) {
getResourceToIdMap().put(theResource, theId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1676,7 +1676,7 @@ private void cleanUpContainedResourceReferences(
.newTerser()
.containResources(
theResource,
FhirTerser.OptionsEnum. MODIFY_RESOURCE,
FhirTerser.OptionsEnum.MODIFY_RESOURCE,
FhirTerser.OptionsEnum.STORE_AND_REUSE_RESULTS);
}
}
Expand Down

0 comments on commit e3fabda

Please sign in to comment.