FIx a failure in FhirTerser when visiting custom types

This commit is contained in:
James Agnew 2019-09-13 09:11:47 -04:00
parent 0831feb2c3
commit 08835c1615
3 changed files with 56 additions and 9 deletions

View File

@ -728,7 +728,12 @@ public class FhirTerser {
continue;
}
BaseRuntimeElementDefinition<?> childElementDef;
childElementDef = nextChild.getChildElementDefinitionByDatatype(nextValue.getClass());
Class<? extends IBase> valueType = nextValue.getClass();
childElementDef = nextChild.getChildElementDefinitionByDatatype(valueType);
while (childElementDef == null && IBase.class.isAssignableFrom(valueType)) {
childElementDef = nextChild.getChildElementDefinitionByDatatype(valueType);
valueType = (Class<? extends IBase>) valueType.getSuperclass();
}
if (childElementDef == null) {
StringBuilder b = new StringBuilder();

View File

@ -3,12 +3,10 @@ package ca.uhn.fhir.util;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.annotation.Block;
import ca.uhn.fhir.parser.DataFormatException;
import org.hamcrest.Matchers;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import org.hl7.fhir.instance.model.api.IBaseReference;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.*;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.Patient.LinkType;
import org.junit.AfterClass;
@ -20,9 +18,7 @@ import org.slf4j.LoggerFactory;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.containsInAnyOrder;
@ -989,6 +985,43 @@ public class FhirTerserR4Test {
Assert.assertEquals("nestedValue", ((StringType) ((Extension) values.get(0)).getValue()).getValueAsString());
}
@Test
public void testVisitWithCustomSubclass() {
ValueSet.ValueSetExpansionComponent component = new MyValueSetExpansionComponent();
ValueSet vs = new ValueSet();
vs.setExpansion(component);
vs.getExpansion().setIdentifier("http://foo");
Set<String> strings = new HashSet<>();
ourCtx.newTerser().visit(vs, new IModelVisitor() {
@Override
public void acceptElement(IBaseResource theResource, IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
if (theElement instanceof IPrimitiveType) {
strings.add(((IPrimitiveType) theElement).getValueAsString());
}
}
});
assertThat(strings, Matchers.contains("http://foo"));
strings.clear();
ourCtx.newTerser().visit(vs, new IModelVisitor2() {
@Override
public boolean acceptElement(IBase theElement, List<IBase> theContainingElementPath, List<BaseRuntimeChildDefinition> theChildDefinitionPath, List<BaseRuntimeElementDefinition<?>> theElementDefinitionPath) {
if (theElement instanceof IPrimitiveType) {
strings.add(((IPrimitiveType) theElement).getValueAsString());
}
return true;
}
@Override
public boolean acceptUndeclaredExtension(IBaseExtension<?, ?> theNextExt, List<IBase> theContainingElementPath, List<BaseRuntimeChildDefinition> theChildDefinitionPath, List<BaseRuntimeElementDefinition<?>> theElementDefinitionPath) {
return true;
}
});
assertThat(strings, Matchers.contains("http://foo"));
}
@Test
public void testVisitWithModelVisitor2() {
IModelVisitor2 visitor = mock(IModelVisitor2.class);
@ -1038,6 +1071,11 @@ public class FhirTerserR4Test {
}
}
@Block
public static class MyValueSetExpansionComponent extends ValueSet.ValueSetExpansionComponent {
private static final long serialVersionUID = 2624360513249904086L;
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();

View File

@ -133,8 +133,12 @@
and version were still returned to the user. This has been corrected so that no details about
the resource are leaked.
</action>
<action type="fix">
Fix a failure in FhirTerser#visit when fields in model classes being visited contain custom subclasses of the
expected type.
</action>
</release>
<release version="4.0.1" date="2019-09-03" description="Igloo (Point Release)">
<release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)">
<action type="fix">
This release contains no new or updated functionality, but addressed a dependency
version that was left incorrectly requiring a SNAPSHOT maven build of the