applying Taha Attari's fix on branch merging to rel_7_4 (#6177)

Co-authored-by: peartree <etienne.poirier@smilecdr.com>
This commit is contained in:
Etienne Poirier 2024-07-31 15:11:15 -04:00 committed by GitHub
parent 76fab69e0e
commit c2d4a2a2e6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 51 additions and 13 deletions

View File

@ -101,7 +101,7 @@ public class FhirTerser {
return newList; return newList;
} }
private ExtensionDt createEmptyExtensionDt(IBaseExtension theBaseExtension, String theUrl) { private ExtensionDt createEmptyExtensionDt(IBaseExtension<?, ?> theBaseExtension, String theUrl) {
return createEmptyExtensionDt(theBaseExtension, false, theUrl); return createEmptyExtensionDt(theBaseExtension, false, theUrl);
} }
@ -122,13 +122,13 @@ public class FhirTerser {
return theSupportsUndeclaredExtensions.addUndeclaredExtension(theIsModifier, theUrl); return theSupportsUndeclaredExtensions.addUndeclaredExtension(theIsModifier, theUrl);
} }
private IBaseExtension createEmptyExtension(IBaseHasExtensions theBaseHasExtensions, String theUrl) { private IBaseExtension<?, ?> createEmptyExtension(IBaseHasExtensions theBaseHasExtensions, String theUrl) {
return (IBaseExtension) theBaseHasExtensions.addExtension().setUrl(theUrl); return (IBaseExtension<?, ?>) theBaseHasExtensions.addExtension().setUrl(theUrl);
} }
private IBaseExtension createEmptyModifierExtension( private IBaseExtension<?, ?> createEmptyModifierExtension(
IBaseHasModifierExtensions theBaseHasModifierExtensions, String theUrl) { IBaseHasModifierExtensions theBaseHasModifierExtensions, String theUrl) {
return (IBaseExtension) return (IBaseExtension<?, ?>)
theBaseHasModifierExtensions.addModifierExtension().setUrl(theUrl); theBaseHasModifierExtensions.addModifierExtension().setUrl(theUrl);
} }
@ -407,7 +407,7 @@ public class FhirTerser {
public String getSinglePrimitiveValueOrNull(IBase theTarget, String thePath) { public String getSinglePrimitiveValueOrNull(IBase theTarget, String thePath) {
return getSingleValue(theTarget, thePath, IPrimitiveType.class) return getSingleValue(theTarget, thePath, IPrimitiveType.class)
.map(t -> t.getValueAsString()) .map(IPrimitiveType::getValueAsString)
.orElse(null); .orElse(null);
} }
@ -487,7 +487,7 @@ public class FhirTerser {
} else { } else {
// DSTU3+ // DSTU3+
final String extensionUrlForLambda = extensionUrl; final String extensionUrlForLambda = extensionUrl;
List<IBaseExtension> extensions = Collections.emptyList(); List<IBaseExtension<?, ?>> extensions = Collections.emptyList();
if (theCurrentObj instanceof IBaseHasExtensions) { if (theCurrentObj instanceof IBaseHasExtensions) {
extensions = ((IBaseHasExtensions) theCurrentObj) extensions = ((IBaseHasExtensions) theCurrentObj)
.getExtension().stream() .getExtension().stream()
@ -505,7 +505,7 @@ public class FhirTerser {
} }
} }
for (IBaseExtension next : extensions) { for (IBaseExtension<?, ?> next : extensions) {
if (theWantedClass.isAssignableFrom(next.getClass())) { if (theWantedClass.isAssignableFrom(next.getClass())) {
retVal.add((T) next); retVal.add((T) next);
} }
@ -581,7 +581,7 @@ public class FhirTerser {
} else { } else {
// DSTU3+ // DSTU3+
final String extensionUrlForLambda = extensionUrl; final String extensionUrlForLambda = extensionUrl;
List<IBaseExtension> extensions = Collections.emptyList(); List<IBaseExtension<?, ?>> extensions = Collections.emptyList();
if (theCurrentObj instanceof IBaseHasModifierExtensions) { if (theCurrentObj instanceof IBaseHasModifierExtensions) {
extensions = ((IBaseHasModifierExtensions) theCurrentObj) extensions = ((IBaseHasModifierExtensions) theCurrentObj)
@ -602,7 +602,7 @@ public class FhirTerser {
} }
} }
for (IBaseExtension next : extensions) { for (IBaseExtension<?, ?> next : extensions) {
if (theWantedClass.isAssignableFrom(next.getClass())) { if (theWantedClass.isAssignableFrom(next.getClass())) {
retVal.add((T) next); retVal.add((T) next);
} }
@ -1203,7 +1203,6 @@ public class FhirTerser {
public void visit(IBase theElement, IModelVisitor2 theVisitor) { public void visit(IBase theElement, IModelVisitor2 theVisitor) {
BaseRuntimeElementDefinition<?> def = myContext.getElementDefinition(theElement.getClass()); BaseRuntimeElementDefinition<?> def = myContext.getElementDefinition(theElement.getClass());
if (def instanceof BaseRuntimeElementCompositeDefinition) { if (def instanceof BaseRuntimeElementCompositeDefinition) {
BaseRuntimeElementCompositeDefinition<?> defComposite = (BaseRuntimeElementCompositeDefinition<?>) def;
visit(theElement, null, def, theVisitor, new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); visit(theElement, null, def, theVisitor, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
} else if (theElement instanceof IBaseExtension) { } else if (theElement instanceof IBaseExtension) {
theVisitor.acceptUndeclaredExtension( theVisitor.acceptUndeclaredExtension(
@ -1562,7 +1561,7 @@ public class FhirTerser {
throw new DataFormatException(Msg.code(1796) + "Invalid path " + thePath + ": Element of type " throw new DataFormatException(Msg.code(1796) + "Invalid path " + thePath + ": Element of type "
+ def.getName() + " has no child named " + nextPart + ". Valid names: " + def.getName() + " has no child named " + nextPart + ". Valid names: "
+ def.getChildrenAndExtension().stream() + def.getChildrenAndExtension().stream()
.map(t -> t.getElementName()) .map(BaseRuntimeChildDefinition::getElementName)
.sorted() .sorted()
.collect(Collectors.joining(", "))); .collect(Collectors.joining(", ")));
} }
@ -1817,7 +1816,18 @@ public class FhirTerser {
if (getResourceToIdMap() == null) { if (getResourceToIdMap() == null) {
return null; return null;
} }
return getResourceToIdMap().get(theNext);
var idFromMap = getResourceToIdMap().get(theNext);
if (idFromMap != null) {
return idFromMap;
} else if (theNext.getIdElement().getIdPart() != null) {
return getResourceToIdMap().values().stream()
.filter(id -> theNext.getIdElement().getIdPart().equals(id.getIdPart()))
.findAny()
.orElse(null);
} else {
return null;
}
} }
private List<IBaseResource> getOrCreateResourceList() { private List<IBaseResource> getOrCreateResourceList() {

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 4837
title: "In the case where a resource was serialized, deserialized, copied and reserialized it resulted in duplication of
contained resources. This has been corrected."

View File

@ -21,6 +21,7 @@ import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.Extension; import org.hl7.fhir.r4.model.Extension;
import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Identifier; import org.hl7.fhir.r4.model.Identifier;
import org.hl7.fhir.r4.model.Library;
import org.hl7.fhir.r4.model.MarkdownType; import org.hl7.fhir.r4.model.MarkdownType;
import org.hl7.fhir.r4.model.Medication; import org.hl7.fhir.r4.model.Medication;
import org.hl7.fhir.r4.model.MedicationAdministration; import org.hl7.fhir.r4.model.MedicationAdministration;
@ -28,6 +29,7 @@ import org.hl7.fhir.r4.model.MedicationRequest;
import org.hl7.fhir.r4.model.Money; import org.hl7.fhir.r4.model.Money;
import org.hl7.fhir.r4.model.Observation; import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Organization;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Patient.LinkType; import org.hl7.fhir.r4.model.Patient.LinkType;
import org.hl7.fhir.r4.model.Practitioner; import org.hl7.fhir.r4.model.Practitioner;
@ -1528,6 +1530,27 @@ public class FhirTerserR4Test {
return retVal; return retVal;
} }
@Test
void copyingAndParsingCreatesDuplicateContainedResources() {
var input = new Library();
var params = new Parameters();
var id = "#expansion-parameters-ecr";
params.setId(id);
params.addParameter("system-version", new StringType("test2"));
var paramsExt = new Extension();
paramsExt.setUrl("test").setValue(new Reference(id));
input.addContained(params);
input.addExtension(paramsExt);
final var parser = FhirContext.forR4Cached().newJsonParser();
var stringified = parser.encodeResourceToString(input);
var parsed = parser.parseResource(stringified);
var copy = ((Library) parsed).copy();
assertEquals(1, copy.getContained().size());
var stringifiedCopy = parser.encodeResourceToString(copy);
var parsedCopy = parser.parseResource(stringifiedCopy);
assertEquals(1, ((Library) parsedCopy).getContained().size());
}
/** /**
* See http://stackoverflow.com/questions/182636/how-to-determine-the-class-of-a-generic-type * See http://stackoverflow.com/questions/182636/how-to-determine-the-class-of-a-generic-type
*/ */