Fix #814 - Don't create duplicate contained resources
This commit is contained in:
parent
fe140a55dd
commit
0c0b9bd74b
|
@ -38,6 +38,7 @@ import java.util.*;
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
public abstract class BaseParser implements IParser {
|
public abstract class BaseParser implements IParser {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseParser.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseParser.class);
|
||||||
|
@ -156,7 +157,6 @@ public abstract class BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void containResourcesForEncoding(ContainedResources theContained, IBaseResource theResource, IBaseResource theTarget) {
|
private void containResourcesForEncoding(ContainedResources theContained, IBaseResource theResource, IBaseResource theTarget) {
|
||||||
Set<String> allIds = new HashSet<String>();
|
|
||||||
Map<String, IBaseResource> existingIdToContainedResource = null;
|
Map<String, IBaseResource> existingIdToContainedResource = null;
|
||||||
|
|
||||||
if (theTarget instanceof IResource) {
|
if (theTarget instanceof IResource) {
|
||||||
|
@ -167,9 +167,8 @@ public abstract class BaseParser implements IParser {
|
||||||
if (!nextId.startsWith("#")) {
|
if (!nextId.startsWith("#")) {
|
||||||
nextId = '#' + nextId;
|
nextId = '#' + nextId;
|
||||||
}
|
}
|
||||||
allIds.add(nextId);
|
|
||||||
if (existingIdToContainedResource == null) {
|
if (existingIdToContainedResource == null) {
|
||||||
existingIdToContainedResource = new HashMap<String, IBaseResource>();
|
existingIdToContainedResource = new HashMap<>();
|
||||||
}
|
}
|
||||||
existingIdToContainedResource.put(nextId, next);
|
existingIdToContainedResource.put(nextId, next);
|
||||||
}
|
}
|
||||||
|
@ -182,9 +181,8 @@ public abstract class BaseParser implements IParser {
|
||||||
if (!nextId.startsWith("#")) {
|
if (!nextId.startsWith("#")) {
|
||||||
nextId = '#' + nextId;
|
nextId = '#' + nextId;
|
||||||
}
|
}
|
||||||
allIds.add(nextId);
|
|
||||||
if (existingIdToContainedResource == null) {
|
if (existingIdToContainedResource == null) {
|
||||||
existingIdToContainedResource = new HashMap<String, IBaseResource>();
|
existingIdToContainedResource = new HashMap<>();
|
||||||
}
|
}
|
||||||
existingIdToContainedResource.put(nextId, next);
|
existingIdToContainedResource.put(nextId, next);
|
||||||
}
|
}
|
||||||
|
@ -480,7 +478,7 @@ public abstract class BaseParser implements IParser {
|
||||||
@Override
|
@Override
|
||||||
public void setPreferTypes(List<Class<? extends IBaseResource>> thePreferTypes) {
|
public void setPreferTypes(List<Class<? extends IBaseResource>> thePreferTypes) {
|
||||||
if (thePreferTypes != null) {
|
if (thePreferTypes != null) {
|
||||||
ArrayList<Class<? extends IBaseResource>> types = new ArrayList<Class<? extends IBaseResource>>();
|
ArrayList<Class<? extends IBaseResource>> types = new ArrayList<>();
|
||||||
for (Class<? extends IBaseResource> next : thePreferTypes) {
|
for (Class<? extends IBaseResource> next : thePreferTypes) {
|
||||||
if (Modifier.isAbstract(next.getModifiers()) == false) {
|
if (Modifier.isAbstract(next.getModifiers()) == false) {
|
||||||
types.add(next);
|
types.add(next);
|
||||||
|
@ -516,8 +514,7 @@ public abstract class BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<T> newList = new ArrayList<T>();
|
List<T> newList = new ArrayList<>(theProfiles);
|
||||||
newList.addAll(theProfiles);
|
|
||||||
|
|
||||||
BaseRuntimeElementDefinition<?> idElement = myContext.getElementDefinition("id");
|
BaseRuntimeElementDefinition<?> idElement = myContext.getElementDefinition("id");
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -1183,8 +1180,10 @@ public abstract class BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addContained(IIdType theId, IBaseResource theResource) {
|
public void addContained(IIdType theId, IBaseResource theResource) {
|
||||||
myResourceToId.put(theResource, theId);
|
if (!hasId(theId)) {
|
||||||
myResources.add(theResource);
|
myResourceToId.put(theResource, theId);
|
||||||
|
myResources.add(theResource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<IBaseResource> getContainedResources() {
|
public List<IBaseResource> getContainedResources() {
|
||||||
|
@ -1195,6 +1194,15 @@ public abstract class BaseParser implements IParser {
|
||||||
return myResourceToId.get(theNext);
|
return myResourceToId.get(theNext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasId(IIdType theId) {
|
||||||
|
for (IIdType next : myResourceToId.values()) {
|
||||||
|
if (Objects.equals(next.getValue(), theId.getValue())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return myResourceToId.isEmpty();
|
return myResourceToId.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,39 @@ public class JsonParserR4Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See #814
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDuplicateContainedResourcesNotOutputtedTwiceWithManualIdsAndManualAddition() {
|
||||||
|
MedicationDispense md = new MedicationDispense();
|
||||||
|
|
||||||
|
MedicationRequest mr = new MedicationRequest();
|
||||||
|
mr.setId("#MR");
|
||||||
|
md.addAuthorizingPrescription().setResource(mr);
|
||||||
|
|
||||||
|
Medication med = new Medication();
|
||||||
|
med.setId("#MED");
|
||||||
|
|
||||||
|
Reference medRef = new Reference();
|
||||||
|
medRef.setReference("#MED");
|
||||||
|
md.setMedication(medRef);
|
||||||
|
mr.setMedication(medRef);
|
||||||
|
|
||||||
|
md.getContained().add(mr);
|
||||||
|
md.getContained().add(med);
|
||||||
|
|
||||||
|
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(md);
|
||||||
|
ourLog.info(encoded);
|
||||||
|
|
||||||
|
int idx = encoded.indexOf("\"Medication\"");
|
||||||
|
assertNotEquals(-1, idx);
|
||||||
|
|
||||||
|
idx = encoded.indexOf("\"Medication\"", idx + 1);
|
||||||
|
assertEquals(-1, idx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExcludeNothing() {
|
public void testExcludeNothing() {
|
||||||
IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||||
|
|
|
@ -189,6 +189,11 @@
|
||||||
DateParam class now has equals() and hashCode() implementations. Thanks
|
DateParam class now has equals() and hashCode() implementations. Thanks
|
||||||
to Gaetano Gallo for the pull request!
|
to Gaetano Gallo for the pull request!
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix" issue="814">
|
||||||
|
Fix a bug where under certain circumstances, duplicate contained resources
|
||||||
|
could be output by the parser's encode methods. Thanks to
|
||||||
|
Frank Tao for supplying a test case!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.2.0" date="2018-01-13">
|
<release version="3.2.0" date="2018-01-13">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue