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; continue;
} }
BaseRuntimeElementDefinition<?> childElementDef; 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) { if (childElementDef == null) {
StringBuilder b = new StringBuilder(); 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.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition; import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.annotation.Block;
import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.DataFormatException;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.*;
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.r4.model.*; import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.Patient.LinkType; import org.hl7.fhir.r4.model.Patient.LinkType;
import org.junit.AfterClass; import org.junit.AfterClass;
@ -20,9 +18,7 @@ import org.slf4j.LoggerFactory;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
@ -989,6 +985,43 @@ public class FhirTerserR4Test {
Assert.assertEquals("nestedValue", ((StringType) ((Extension) values.get(0)).getValue()).getValueAsString()); 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 @Test
public void testVisitWithModelVisitor2() { public void testVisitWithModelVisitor2() {
IModelVisitor2 visitor = mock(IModelVisitor2.class); 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 @AfterClass
public static void afterClassClearContext() { public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest(); 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 and version were still returned to the user. This has been corrected so that no details about
the resource are leaked. the resource are leaked.
</action> </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>
<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"> <action type="fix">
This release contains no new or updated functionality, but addressed a dependency This release contains no new or updated functionality, but addressed a dependency
version that was left incorrectly requiring a SNAPSHOT maven build of the version that was left incorrectly requiring a SNAPSHOT maven build of the