One more parser fix
This commit is contained in:
parent
1ff50cb0db
commit
8c889267e5
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.parser;
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -191,6 +191,11 @@ public abstract class BaseParser implements IParser {
|
|||
// no resources to contain
|
||||
}
|
||||
|
||||
// Make sure we don't reuse local IDs
|
||||
if (existingIdToContainedResource != null) {
|
||||
theContained.addPreExistingLocalIds(existingIdToContainedResource.keySet());
|
||||
}
|
||||
|
||||
{
|
||||
List<IBaseReference> allElements = myContext.newTerser().getAllPopulatedChildElementsOfType(theResource, IBaseReference.class);
|
||||
for (IBaseReference next : allElements) {
|
||||
|
@ -453,6 +458,17 @@ public abstract class BaseParser implements IParser {
|
|||
return myErrorHandler;
|
||||
}
|
||||
|
||||
protected List<Map.Entry<ResourceMetadataKeyEnum<?>, Object>> getExtensionMetadataKeys(IResource resource) {
|
||||
List<Map.Entry<ResourceMetadataKeyEnum<?>, Object>> extensionMetadataKeys = new ArrayList<Map.Entry<ResourceMetadataKeyEnum<?>, Object>>();
|
||||
for (Map.Entry<ResourceMetadataKeyEnum<?>, Object> entry : resource.getResourceMetadata().entrySet()) {
|
||||
if (entry.getKey() instanceof ResourceMetadataKeyEnum.ExtensionResourceMetadataKey) {
|
||||
extensionMetadataKeys.add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
return extensionMetadataKeys;
|
||||
}
|
||||
|
||||
protected String getExtensionUrl(final String extensionUrl) {
|
||||
String url = extensionUrl;
|
||||
if (StringUtils.isNotBlank(extensionUrl) && StringUtils.isNotBlank(myServerBaseUrl)) {
|
||||
|
@ -924,18 +940,6 @@ public abstract class BaseParser implements IParser {
|
|||
throw new DataFormatException(nextChild + " has no child of type " + theType);
|
||||
}
|
||||
|
||||
protected List<Map.Entry<ResourceMetadataKeyEnum<?>, Object>> getExtensionMetadataKeys(IResource resource) {
|
||||
List<Map.Entry<ResourceMetadataKeyEnum<?>, Object>> extensionMetadataKeys = new ArrayList<Map.Entry<ResourceMetadataKeyEnum<?>, Object>>();
|
||||
for (Map.Entry<ResourceMetadataKeyEnum<?>, Object> entry : resource.getResourceMetadata().entrySet()) {
|
||||
if (entry.getKey() instanceof ResourceMetadataKeyEnum.ExtensionResourceMetadataKey) {
|
||||
extensionMetadataKeys.add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
return extensionMetadataKeys;
|
||||
}
|
||||
|
||||
|
||||
protected static <T> List<T> extractMetadataListNotNull(IResource resource, ResourceMetadataKeyEnum<List<T>> key) {
|
||||
List<? extends T> securityLabels = key.get(resource);
|
||||
if (securityLabels == null) {
|
||||
|
@ -1176,11 +1180,12 @@ public abstract class BaseParser implements IParser {
|
|||
static class ContainedResources {
|
||||
private long myNextContainedId = 1;
|
||||
|
||||
private List<IBaseResource> myResources = new ArrayList<>();
|
||||
private IdentityHashMap<IBaseResource, IIdType> myResourceToId = new IdentityHashMap<>();
|
||||
private Set<String> myExistingLocalIds = new HashSet<>();
|
||||
private List<IBaseResource> myResources;
|
||||
private IdentityHashMap<IBaseResource, IIdType> myResourceToId;
|
||||
private Set<String> myPreExistingLocalIds;
|
||||
|
||||
public void addContained(IBaseResource theResource) {
|
||||
initializeMapsIfNeeded();
|
||||
if (myResourceToId.containsKey(theResource)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1199,7 +1204,11 @@ public abstract class BaseParser implements IParser {
|
|||
// See JsonParser#testEncodeResourceWithMixedManualAndAutomaticContainedResourcesLocalFirst
|
||||
// and JsonParser#testEncodeResourceWithMixedManualAndAutomaticContainedResourcesLocalLast
|
||||
// for examples of where this is needed...
|
||||
while (!myExistingLocalIds.add("#" + myNextContainedId)) {
|
||||
while (true) {
|
||||
String nextCandidate = "#" + myNextContainedId;
|
||||
if (myPreExistingLocalIds.add(nextCandidate)) {
|
||||
break;
|
||||
}
|
||||
myNextContainedId++;
|
||||
}
|
||||
newId = new IdDt(myNextContainedId);
|
||||
|
@ -1212,21 +1221,44 @@ public abstract class BaseParser implements IParser {
|
|||
}
|
||||
|
||||
public void addContained(IIdType theId, IBaseResource theResource) {
|
||||
if (myExistingLocalIds.add(theId.getValue())) {
|
||||
initializeMapsIfNeeded();
|
||||
if (!myResourceToId.containsKey(theResource)) {
|
||||
myResourceToId.put(theResource, theId);
|
||||
myResources.add(theResource);
|
||||
}
|
||||
}
|
||||
|
||||
public void addPreExistingLocalIds(Set<String> theIds) {
|
||||
initializeMapsIfNeeded();
|
||||
myPreExistingLocalIds.addAll(theIds);
|
||||
}
|
||||
|
||||
public List<IBaseResource> getContainedResources() {
|
||||
if (myResources == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return myResources;
|
||||
}
|
||||
|
||||
public IIdType getResourceId(IBaseResource theNext) {
|
||||
if (myResourceToId == null) {
|
||||
return null;
|
||||
}
|
||||
return myResourceToId.get(theNext);
|
||||
}
|
||||
|
||||
private void initializeMapsIfNeeded() {
|
||||
if (myResources == null) {
|
||||
myResources = new ArrayList<>();
|
||||
myResourceToId = new IdentityHashMap<>();
|
||||
myPreExistingLocalIds = new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
if (myResourceToId == null) {
|
||||
return true;
|
||||
}
|
||||
return myResourceToId.isEmpty();
|
||||
}
|
||||
|
||||
|
|
|
@ -36,64 +36,6 @@ public class JsonParserR4Test {
|
|||
return b;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeResourceWithMixedManualAndAutomaticContainedResourcesLocalFirst() {
|
||||
|
||||
Observation obs = new Observation();
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.setId("#1");
|
||||
pt.addName().setFamily("FAM");
|
||||
obs.getSubject().setReference("#1");
|
||||
obs.getContained().add(pt);
|
||||
|
||||
Encounter enc = new Encounter();
|
||||
enc.setStatus(Encounter.EncounterStatus.ARRIVED);
|
||||
obs.getContext().setResource(enc);
|
||||
|
||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs);
|
||||
ourLog.info(encoded);
|
||||
|
||||
obs = ourCtx.newJsonParser().parseResource(Observation.class, encoded);
|
||||
assertEquals("#1", obs.getContained().get(0).getId());
|
||||
assertEquals("#2", obs.getContained().get(1).getId());
|
||||
|
||||
pt = (Patient) obs.getSubject().getResource();
|
||||
assertEquals("FAM", pt.getNameFirstRep().getFamily());
|
||||
|
||||
enc = (Encounter) obs.getContext().getResource();
|
||||
assertEquals(Encounter.EncounterStatus.ARRIVED, enc.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeResourceWithMixedManualAndAutomaticContainedResourcesLocalLast() {
|
||||
|
||||
Observation obs = new Observation();
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addName().setFamily("FAM");
|
||||
obs.getSubject().setResource(pt);
|
||||
|
||||
Encounter enc = new Encounter();
|
||||
enc.setId("#1");
|
||||
enc.setStatus(Encounter.EncounterStatus.ARRIVED);
|
||||
obs.getContext().setReference("#1");
|
||||
obs.getContained().add(enc);
|
||||
|
||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs);
|
||||
ourLog.info(encoded);
|
||||
|
||||
obs = ourCtx.newJsonParser().parseResource(Observation.class, encoded);
|
||||
assertEquals("#1", obs.getContained().get(0).getId());
|
||||
assertEquals("#2", obs.getContained().get(1).getId());
|
||||
|
||||
pt = (Patient) obs.getSubject().getResource();
|
||||
assertEquals("FAM", pt.getNameFirstRep().getFamily());
|
||||
|
||||
enc = (Encounter) obs.getContext().getResource();
|
||||
assertEquals(Encounter.EncounterStatus.ARRIVED, enc.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* See #814
|
||||
*/
|
||||
|
@ -190,6 +132,85 @@ public class JsonParserR4Test {
|
|||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">Copy © 1999</div>", p.getText().getDivAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeResourceWithMixedManualAndAutomaticContainedResourcesLocalFirst() {
|
||||
|
||||
Observation obs = new Observation();
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.setId("#1");
|
||||
pt.addName().setFamily("FAM");
|
||||
obs.getSubject().setReference("#1");
|
||||
obs.getContained().add(pt);
|
||||
|
||||
Encounter enc = new Encounter();
|
||||
enc.setStatus(Encounter.EncounterStatus.ARRIVED);
|
||||
obs.getContext().setResource(enc);
|
||||
|
||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs);
|
||||
ourLog.info(encoded);
|
||||
|
||||
obs = ourCtx.newJsonParser().parseResource(Observation.class, encoded);
|
||||
assertEquals("#1", obs.getContained().get(0).getId());
|
||||
assertEquals("#2", obs.getContained().get(1).getId());
|
||||
|
||||
pt = (Patient) obs.getSubject().getResource();
|
||||
assertEquals("FAM", pt.getNameFirstRep().getFamily());
|
||||
|
||||
enc = (Encounter) obs.getContext().getResource();
|
||||
assertEquals(Encounter.EncounterStatus.ARRIVED, enc.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeResourceWithMixedManualAndAutomaticContainedResourcesLocalLast() {
|
||||
|
||||
Observation obs = new Observation();
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addName().setFamily("FAM");
|
||||
obs.getSubject().setResource(pt);
|
||||
|
||||
Encounter enc = new Encounter();
|
||||
enc.setId("#1");
|
||||
enc.setStatus(Encounter.EncounterStatus.ARRIVED);
|
||||
obs.getContext().setReference("#1");
|
||||
obs.getContained().add(enc);
|
||||
|
||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs);
|
||||
ourLog.info(encoded);
|
||||
|
||||
obs = ourCtx.newJsonParser().parseResource(Observation.class, encoded);
|
||||
assertEquals("#1", obs.getContained().get(0).getId());
|
||||
assertEquals("#2", obs.getContained().get(1).getId());
|
||||
|
||||
pt = (Patient) obs.getSubject().getResource();
|
||||
assertEquals("FAM", pt.getNameFirstRep().getFamily());
|
||||
|
||||
enc = (Encounter) obs.getContext().getResource();
|
||||
assertEquals(Encounter.EncounterStatus.ARRIVED, enc.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeResourceWithMixedManualAndAutomaticContainedResourcesLocalLast2() {
|
||||
|
||||
MedicationRequest mr = new MedicationRequest();
|
||||
Practitioner pract = new Practitioner().setActive(true);
|
||||
mr.getRequester().setResource(pract);
|
||||
|
||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(mr);
|
||||
ourLog.info(encoded);
|
||||
mr = ourCtx.newJsonParser().parseResource(MedicationRequest.class, encoded);
|
||||
|
||||
mr.setMedication(new Reference(new Medication().setStatus(Medication.MedicationStatus.ACTIVE)));
|
||||
encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(mr);
|
||||
ourLog.info(encoded);
|
||||
mr = ourCtx.newJsonParser().parseResource(MedicationRequest.class, encoded);
|
||||
|
||||
assertEquals("#2", mr.getContained().get(0).getId());
|
||||
assertEquals("#1", mr.getContained().get(1).getId());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExcludeNothing() {
|
||||
IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||
|
|
Loading…
Reference in New Issue