add exclusions to terser reference method (#5343)
This commit is contained in:
parent
7e0fa9833c
commit
5411622dee
|
@ -287,9 +287,33 @@ public class FhirTerser {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts all outbound references from a resource
|
||||||
|
*
|
||||||
|
* @param theResource the resource to be analyzed
|
||||||
|
* @return a list of references to other resources
|
||||||
|
*/
|
||||||
public List<ResourceReferenceInfo> getAllResourceReferences(final IBaseResource theResource) {
|
public List<ResourceReferenceInfo> getAllResourceReferences(final IBaseResource theResource) {
|
||||||
|
return getAllResourceReferencesExcluding(theResource, Lists.newArrayList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts all outbound references from a resource, excluding any that are located on black-listed parts of the
|
||||||
|
* resource
|
||||||
|
*
|
||||||
|
* @param theResource the resource to be analyzed
|
||||||
|
* @param thePathsToExclude a list of dot-delimited paths not to include in the result
|
||||||
|
* @return a list of references to other resources
|
||||||
|
*/
|
||||||
|
public List<ResourceReferenceInfo> getAllResourceReferencesExcluding(
|
||||||
|
final IBaseResource theResource, List<String> thePathsToExclude) {
|
||||||
final ArrayList<ResourceReferenceInfo> retVal = new ArrayList<>();
|
final ArrayList<ResourceReferenceInfo> retVal = new ArrayList<>();
|
||||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
||||||
|
List<List<String>> tokenizedPathsToExclude = thePathsToExclude.stream()
|
||||||
|
.map(path -> StringUtils.split(path, "."))
|
||||||
|
.map(Lists::newArrayList)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
visit(newMap(), theResource, theResource, null, null, def, new IModelVisitor() {
|
visit(newMap(), theResource, theResource, null, null, def, new IModelVisitor() {
|
||||||
@Override
|
@Override
|
||||||
public void acceptElement(
|
public void acceptElement(
|
||||||
|
@ -301,6 +325,10 @@ public class FhirTerser {
|
||||||
if (theElement == null || theElement.isEmpty()) {
|
if (theElement == null || theElement.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (thePathToElement != null && pathShouldBeExcluded(tokenizedPathsToExclude, thePathToElement)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (IBaseReference.class.isAssignableFrom(theElement.getClass())) {
|
if (IBaseReference.class.isAssignableFrom(theElement.getClass())) {
|
||||||
retVal.add(new ResourceReferenceInfo(
|
retVal.add(new ResourceReferenceInfo(
|
||||||
myContext, theOuterResource, thePathToElement, (IBaseReference) theElement));
|
myContext, theOuterResource, thePathToElement, (IBaseReference) theElement));
|
||||||
|
@ -310,6 +338,19 @@ public class FhirTerser {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean pathShouldBeExcluded(List<List<String>> theTokenizedPathsToExclude, List<String> thePathToElement) {
|
||||||
|
return theTokenizedPathsToExclude.stream().anyMatch(p -> {
|
||||||
|
// Check whether the path to the element starts with the path to be excluded
|
||||||
|
if (p.size() > thePathToElement.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> prefix = thePathToElement.subList(0, p.size());
|
||||||
|
|
||||||
|
return Objects.equals(p, prefix);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private BaseRuntimeChildDefinition getDefinition(
|
private BaseRuntimeChildDefinition getDefinition(
|
||||||
BaseRuntimeElementCompositeDefinition<?> theCurrentDef, List<String> theSubList) {
|
BaseRuntimeElementCompositeDefinition<?> theCurrentDef, List<String> theSubList) {
|
||||||
BaseRuntimeChildDefinition nextDef = theCurrentDef.getChildByNameOrThrowDataFormatException(theSubList.get(0));
|
BaseRuntimeChildDefinition nextDef = theCurrentDef.getChildByNameOrThrowDataFormatException(theSubList.get(0));
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.hl7.fhir.instance.model.api.IBase;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseReference;
|
import org.hl7.fhir.instance.model.api.IBaseReference;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
import org.hl7.fhir.r4.model.BooleanType;
|
import org.hl7.fhir.r4.model.BooleanType;
|
||||||
import org.hl7.fhir.r4.model.Bundle;
|
import org.hl7.fhir.r4.model.Bundle;
|
||||||
|
@ -32,6 +33,7 @@ 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;
|
||||||
import org.hl7.fhir.r4.model.PrimitiveType;
|
import org.hl7.fhir.r4.model.PrimitiveType;
|
||||||
|
import org.hl7.fhir.r4.model.Provenance;
|
||||||
import org.hl7.fhir.r4.model.Quantity;
|
import org.hl7.fhir.r4.model.Quantity;
|
||||||
import org.hl7.fhir.r4.model.Reference;
|
import org.hl7.fhir.r4.model.Reference;
|
||||||
import org.hl7.fhir.r4.model.ResourceType;
|
import org.hl7.fhir.r4.model.ResourceType;
|
||||||
|
@ -511,6 +513,54 @@ public class FhirTerserR4Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAllResourceReferences() {
|
||||||
|
// setup
|
||||||
|
Provenance p = new Provenance();
|
||||||
|
p.addTarget(new Reference("Observation/1"));
|
||||||
|
p.addTarget(new Reference("Observation/2"));
|
||||||
|
p.setLocation(new Reference("Location/3"));
|
||||||
|
p.getAgentFirstRep().setWho(new Reference("Practitioner/4"));
|
||||||
|
p.getAgentFirstRep().setOnBehalfOf(new Reference("Organization/5"));
|
||||||
|
p.getEntityFirstRep().setWhat(new Reference("DocumentReference/6"));
|
||||||
|
|
||||||
|
// execute
|
||||||
|
FhirTerser t = myCtx.newTerser();
|
||||||
|
List<ResourceReferenceInfo> references = t.getAllResourceReferences(p);
|
||||||
|
|
||||||
|
// validate
|
||||||
|
assertEquals(6, references.size());
|
||||||
|
assertThat(toResourceIds(references), containsInAnyOrder("Observation/1", "Observation/2", "Location/3", "Practitioner/4", "Organization/5", "DocumentReference/6"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAllResourceReferencesExcluding() {
|
||||||
|
// setup
|
||||||
|
Provenance p = new Provenance();
|
||||||
|
p.addTarget(new Reference("Observation/1"));
|
||||||
|
p.addTarget(new Reference("Observation/2"));
|
||||||
|
p.setLocation(new Reference("Location/3"));
|
||||||
|
p.getAgentFirstRep().setWho(new Reference("Practitioner/4"));
|
||||||
|
p.getAgentFirstRep().setOnBehalfOf(new Reference("Organization/5"));
|
||||||
|
p.getEntityFirstRep().setWhat(new Reference("DocumentReference/6"));
|
||||||
|
|
||||||
|
// execute
|
||||||
|
FhirTerser t = myCtx.newTerser();
|
||||||
|
List<ResourceReferenceInfo> references = t.getAllResourceReferencesExcluding(p, List.of("target"));
|
||||||
|
|
||||||
|
// validate
|
||||||
|
assertEquals(4, references.size());
|
||||||
|
assertThat(toResourceIds(references), containsInAnyOrder("Location/3", "Practitioner/4", "Organization/5", "DocumentReference/6"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> toResourceIds(List<ResourceReferenceInfo> references) {
|
||||||
|
return references.stream()
|
||||||
|
.map(ResourceReferenceInfo::getResourceReference)
|
||||||
|
.map(IBaseReference::getReferenceElement)
|
||||||
|
.map(IIdType::getValue)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetResourceReferenceInExtension() {
|
public void testGetResourceReferenceInExtension() {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
|
|
Loading…
Reference in New Issue