Fix #369 - FhirTerser cloneInto method fails if target contains extension
This commit is contained in:
parent
635398a754
commit
ee031667c5
|
@ -46,6 +46,14 @@ public class RuntimeChildExtension extends RuntimeChildAny {
|
||||||
public Set<String> getValidChildNames() {
|
public Set<String> getValidChildNames() {
|
||||||
return Collections.singleton(getElementName());
|
return Collections.singleton(getElementName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseRuntimeElementDefinition<?> getChildByName(String theName) {
|
||||||
|
if ("extension".equals(theName) || "modifierExtension".equals(theName)) {
|
||||||
|
return super.getChildByName("extensionExtension");
|
||||||
|
}
|
||||||
|
return super.getChildByName(theName);
|
||||||
|
}
|
||||||
|
|
||||||
// @Override
|
// @Override
|
||||||
// public BaseRuntimeElementDefinition<?> getChildElementDefinitionByDatatype(Class<? extends IBase> theDatatype) {
|
// public BaseRuntimeElementDefinition<?> getChildElementDefinitionByDatatype(Class<? extends IBase> theDatatype) {
|
||||||
|
|
|
@ -43,6 +43,10 @@ public class RuntimeExtensionDtDefinition extends RuntimeCompositeDatatypeDefini
|
||||||
return myChildren;
|
return myChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<BaseRuntimeChildDefinition> getChildrenIncludingUrl() {
|
||||||
|
return super.getChildren();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sealAndInitialize(FhirContext theContext, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
|
public void sealAndInitialize(FhirContext theContext, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
|
||||||
super.sealAndInitialize(theContext, theClassToElementDefinitions);
|
super.sealAndInitialize(theContext, theClassToElementDefinitions);
|
||||||
|
|
|
@ -48,6 +48,7 @@ import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.RuntimeChildChoiceDefinition;
|
import ca.uhn.fhir.context.RuntimeChildChoiceDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeChildDirectResource;
|
import ca.uhn.fhir.context.RuntimeChildDirectResource;
|
||||||
|
import ca.uhn.fhir.context.RuntimeExtensionDtDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||||
import ca.uhn.fhir.model.api.ExtensionDt;
|
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||||
|
@ -88,16 +89,17 @@ public class FhirTerser {
|
||||||
addUndeclaredExtensions(nextExt, theDefinition, theChildDefinition, theCallback);
|
addUndeclaredExtensions(nextExt, theDefinition, theChildDefinition, theCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theElement instanceof IBaseHasExtensions) {
|
// Commented out because FhirTerserDstu3Test#testGetResourceReferenceInExtension
|
||||||
for (IBaseExtension<?, ?> nextExt : ((IBaseHasExtensions)theElement).getExtension()) {
|
// if (theElement instanceof IBaseHasExtensions) {
|
||||||
if (nextExt == null) {
|
// for (IBaseExtension<?, ?> nextExt : ((IBaseHasExtensions)theElement).getExtension()) {
|
||||||
continue;
|
// if (nextExt == null) {
|
||||||
}
|
// continue;
|
||||||
theCallback.acceptElement(nextExt.getValue(), null, theChildDefinition, theDefinition);
|
// }
|
||||||
addUndeclaredExtensions(nextExt, theDefinition, theChildDefinition, theCallback);
|
// theCallback.acceptElement(nextExt.getValue(), null, theChildDefinition, theDefinition);
|
||||||
}
|
// addUndeclaredExtensions(nextExt, theDefinition, theChildDefinition, theCallback);
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
if (theElement instanceof IBaseHasModifierExtensions) {
|
if (theElement instanceof IBaseHasModifierExtensions) {
|
||||||
for (IBaseExtension<?, ?> nextExt : ((IBaseHasModifierExtensions)theElement).getModifierExtension()) {
|
for (IBaseExtension<?, ?> nextExt : ((IBaseHasModifierExtensions)theElement).getModifierExtension()) {
|
||||||
|
@ -137,18 +139,25 @@ public class FhirTerser {
|
||||||
BaseRuntimeElementCompositeDefinition<?> sourceDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(theSource.getClass());
|
BaseRuntimeElementCompositeDefinition<?> sourceDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(theSource.getClass());
|
||||||
BaseRuntimeElementCompositeDefinition<?> targetDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(theTarget.getClass());
|
BaseRuntimeElementCompositeDefinition<?> targetDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(theTarget.getClass());
|
||||||
|
|
||||||
for (BaseRuntimeChildDefinition nextChild : sourceDef.getChildren()) {
|
List<BaseRuntimeChildDefinition> children = sourceDef.getChildren();
|
||||||
|
if (sourceDef instanceof RuntimeExtensionDtDefinition) {
|
||||||
|
children = ((RuntimeExtensionDtDefinition)sourceDef).getChildrenIncludingUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (BaseRuntimeChildDefinition nextChild : children) {
|
||||||
for (IBase nextValue : nextChild.getAccessor().getValues(theSource)) {
|
for (IBase nextValue : nextChild.getAccessor().getValues(theSource)) {
|
||||||
BaseRuntimeChildDefinition targetChild = targetDef.getChildByName(nextChild.getElementName());
|
String elementName = nextChild.getChildNameByDatatype(nextValue.getClass());
|
||||||
|
BaseRuntimeChildDefinition targetChild = targetDef.getChildByName(elementName);
|
||||||
if (targetChild == null) {
|
if (targetChild == null) {
|
||||||
if (theIgnoreMissingFields) {
|
if (theIgnoreMissingFields) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
throw new DataFormatException("Type " + theTarget.getClass().getName() + " does not have a child with name " + nextChild.getElementName());
|
throw new DataFormatException("Type " + theTarget.getClass().getName() + " does not have a child with name " + elementName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IBase target = targetChild.getChildByName(nextChild.getElementName()).newInstance();
|
BaseRuntimeElementDefinition<?> childDef = targetChild.getChildByName(elementName);
|
||||||
|
IBase target = childDef.newInstance();
|
||||||
targetChild.getMutator().addValue(theTarget, target);
|
targetChild.getMutator().addValue(theTarget, target);
|
||||||
cloneInto(nextValue, target, theIgnoreMissingFields);
|
cloneInto(nextValue, target, theIgnoreMissingFields);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import ca.uhn.fhir.model.dstu2.composite.MoneyDt;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.QuantityDt;
|
import ca.uhn.fhir.model.dstu2.composite.QuantityDt;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
import ca.uhn.fhir.model.primitive.MarkdownDt;
|
import ca.uhn.fhir.model.primitive.MarkdownDt;
|
||||||
|
@ -39,28 +40,114 @@ public class FhirTerserDstu2Test {
|
||||||
private static FhirContext ourCtx = FhirContext.forDstu2();
|
private static FhirContext ourCtx = FhirContext.forDstu2();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetResourceReferenceInExtension() {
|
public void testCloneIntoComposite() {
|
||||||
|
QuantityDt source = new QuantityDt();
|
||||||
|
source.setCode("CODE");
|
||||||
|
MoneyDt target = new MoneyDt();
|
||||||
|
|
||||||
|
ourCtx.newTerser().cloneInto(source, target, true);
|
||||||
|
|
||||||
|
assertEquals("CODE", target.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloneIntoCompositeMismatchedFields() {
|
||||||
|
QuantityDt source = new QuantityDt();
|
||||||
|
source.setSystem("SYSTEM");
|
||||||
|
source.setUnit("UNIT");
|
||||||
|
IdentifierDt target = new IdentifierDt();
|
||||||
|
|
||||||
|
ourCtx.newTerser().cloneInto(source, target, true);
|
||||||
|
|
||||||
|
assertEquals("SYSTEM", target.getSystem());
|
||||||
|
|
||||||
|
try {
|
||||||
|
ourCtx.newTerser().cloneInto(source, target, false);
|
||||||
|
fail();
|
||||||
|
} catch (DataFormatException e) {
|
||||||
|
// good
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #369
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCloneIntoExtension() {
|
||||||
|
Patient patient = new Patient();
|
||||||
|
|
||||||
|
patient.addUndeclaredExtension(new ExtensionDt(false, "http://example.com", new StringDt("FOO")));
|
||||||
|
|
||||||
|
Patient target = new Patient();
|
||||||
|
ourCtx.newTerser().cloneInto(patient, target, false);
|
||||||
|
|
||||||
|
List<ExtensionDt> exts = target.getUndeclaredExtensionsByUrl("http://example.com");
|
||||||
|
assertEquals(1, exts.size());
|
||||||
|
assertEquals("FOO", ((StringDt)exts.get(0).getValue()).getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloneIntoPrimitive() {
|
||||||
|
StringDt source = new StringDt("STR");
|
||||||
|
MarkdownDt target = new MarkdownDt();
|
||||||
|
|
||||||
|
ourCtx.newTerser().cloneInto(source, target, true);
|
||||||
|
|
||||||
|
assertEquals("STR", target.getValueAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloneIntoPrimitiveFails() {
|
||||||
|
StringDt source = new StringDt("STR");
|
||||||
|
MoneyDt target = new MoneyDt();
|
||||||
|
|
||||||
|
ourCtx.newTerser().cloneInto(source, target, true);
|
||||||
|
assertTrue(target.isEmpty());
|
||||||
|
|
||||||
|
try {
|
||||||
|
ourCtx.newTerser().cloneInto(source, target, false);
|
||||||
|
fail();
|
||||||
|
} catch (DataFormatException e) {
|
||||||
|
// good
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #369
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCloneIntoValues() {
|
||||||
|
Observation obs = new Observation();
|
||||||
|
obs.setValue(new StringDt("AAA"));
|
||||||
|
obs.setComments("COMMENTS");
|
||||||
|
|
||||||
|
Observation target = new Observation();
|
||||||
|
ourCtx.newTerser().cloneInto(obs, target, false);
|
||||||
|
|
||||||
|
assertEquals("AAA", ((StringDt)obs.getValue()).getValue());
|
||||||
|
assertEquals("COMMENTS", obs.getComments());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAllPopulatedChildElementsOfTypeDescendsIntoContained() {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addName().addFamily("PATIENT");
|
p.addName().addFamily("PATIENT");
|
||||||
|
|
||||||
Organization o = new Organization();
|
Organization o = new Organization();
|
||||||
o.setName("ORG");
|
o.getNameElement().setValue("ORGANIZATION");
|
||||||
ResourceReferenceDt ref = new ResourceReferenceDt(o);
|
p.getContained().getContainedResources().add(o);
|
||||||
ExtensionDt ext = new ExtensionDt(false, "urn:foo", ref);
|
|
||||||
p.addUndeclaredExtension(ext);
|
FhirTerser t = ourCtx.newTerser();
|
||||||
|
List<StringDt> strings = t.getAllPopulatedChildElementsOfType(p, StringDt.class);
|
||||||
|
|
||||||
|
assertEquals(2, strings.size());
|
||||||
|
assertThat(strings, containsInAnyOrder(new StringDt("PATIENT"), new StringDt("ORGANIZATION")));
|
||||||
|
|
||||||
List<IBaseReference> refs = ourCtx.newTerser().getAllPopulatedChildElementsOfType(p, IBaseReference.class);
|
|
||||||
assertEquals(1, refs.size());
|
|
||||||
assertSame(ref, refs.get(0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public static void afterClassClearContext() {
|
|
||||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetAllPopulatedChildElementsOfTypeDoesntDescendIntoEmbedded() {
|
public void testGetAllPopulatedChildElementsOfTypeDoesntDescendIntoEmbedded() {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
|
@ -79,79 +166,21 @@ public class FhirTerserDstu2Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCloneIntoPrimitive() {
|
public void testGetResourceReferenceInExtension() {
|
||||||
StringDt source = new StringDt("STR");
|
|
||||||
MarkdownDt target = new MarkdownDt();
|
|
||||||
|
|
||||||
ourCtx.newTerser().cloneInto(source, target, true);
|
|
||||||
|
|
||||||
assertEquals("STR", target.getValueAsString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCloneIntoPrimitiveFails() {
|
|
||||||
StringDt source = new StringDt("STR");
|
|
||||||
MoneyDt target = new MoneyDt();
|
|
||||||
|
|
||||||
ourCtx.newTerser().cloneInto(source, target, true);
|
|
||||||
assertTrue(target.isEmpty());
|
|
||||||
|
|
||||||
try {
|
|
||||||
ourCtx.newTerser().cloneInto(source, target, false);
|
|
||||||
fail();
|
|
||||||
} catch (DataFormatException e) {
|
|
||||||
// good
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCloneIntoComposite() {
|
|
||||||
QuantityDt source = new QuantityDt();
|
|
||||||
source.setCode("CODE");
|
|
||||||
MoneyDt target = new MoneyDt();
|
|
||||||
|
|
||||||
ourCtx.newTerser().cloneInto(source, target, true);
|
|
||||||
|
|
||||||
assertEquals("CODE", target.getCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCloneIntoCompositeMismatchedFields() {
|
|
||||||
QuantityDt source = new QuantityDt();
|
|
||||||
source.setSystem("SYSTEM");
|
|
||||||
source.setUnit("UNIT");
|
|
||||||
IdentifierDt target = new IdentifierDt();
|
|
||||||
|
|
||||||
ourCtx.newTerser().cloneInto(source, target, true);
|
|
||||||
|
|
||||||
assertEquals("SYSTEM", target.getSystem());
|
|
||||||
|
|
||||||
try {
|
|
||||||
ourCtx.newTerser().cloneInto(source, target, false);
|
|
||||||
fail();
|
|
||||||
} catch (DataFormatException e) {
|
|
||||||
// good
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetAllPopulatedChildElementsOfTypeDescendsIntoContained() {
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addName().addFamily("PATIENT");
|
p.addName().addFamily("PATIENT");
|
||||||
|
|
||||||
Organization o = new Organization();
|
Organization o = new Organization();
|
||||||
o.getNameElement().setValue("ORGANIZATION");
|
o.setName("ORG");
|
||||||
p.getContained().getContainedResources().add(o);
|
ResourceReferenceDt ref = new ResourceReferenceDt(o);
|
||||||
|
ExtensionDt ext = new ExtensionDt(false, "urn:foo", ref);
|
||||||
FhirTerser t = ourCtx.newTerser();
|
p.addUndeclaredExtension(ext);
|
||||||
List<StringDt> strings = t.getAllPopulatedChildElementsOfType(p, StringDt.class);
|
|
||||||
|
|
||||||
assertEquals(2, strings.size());
|
|
||||||
assertThat(strings, containsInAnyOrder(new StringDt("PATIENT"), new StringDt("ORGANIZATION")));
|
|
||||||
|
|
||||||
|
List<IBaseReference> refs = ourCtx.newTerser().getAllPopulatedChildElementsOfType(p, IBaseReference.class);
|
||||||
|
assertEquals(1, refs.size());
|
||||||
|
assertSame(ref, refs.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testVisitWithModelVisitor2() {
|
public void testVisitWithModelVisitor2() {
|
||||||
IModelVisitor2 visitor = mock(IModelVisitor2.class);
|
IModelVisitor2 visitor = mock(IModelVisitor2.class);
|
||||||
|
@ -178,6 +207,11 @@ public class FhirTerserDstu2Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClassClearContext() {
|
||||||
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See http://stackoverflow.com/questions/182636/how-to-determine-the-class-of-a-generic-type
|
* See http://stackoverflow.com/questions/182636/how-to-determine-the-class-of-a-generic-type
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,256 @@
|
||||||
|
package ca.uhn.fhir.util;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hl7.fhir.dstu3.model.Bundle;
|
||||||
|
import org.hl7.fhir.dstu3.model.Extension;
|
||||||
|
import org.hl7.fhir.dstu3.model.Identifier;
|
||||||
|
import org.hl7.fhir.dstu3.model.MarkdownType;
|
||||||
|
import org.hl7.fhir.dstu3.model.Money;
|
||||||
|
import org.hl7.fhir.dstu3.model.Observation;
|
||||||
|
import org.hl7.fhir.dstu3.model.Organization;
|
||||||
|
import org.hl7.fhir.dstu3.model.Patient;
|
||||||
|
import org.hl7.fhir.dstu3.model.Patient.LinkType;
|
||||||
|
import org.hl7.fhir.dstu3.model.Quantity;
|
||||||
|
import org.hl7.fhir.dstu3.model.Reference;
|
||||||
|
import org.hl7.fhir.dstu3.model.StringType;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBase;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseReference;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
|
||||||
|
public class FhirTerserDstu3Test {
|
||||||
|
|
||||||
|
private static FhirContext ourCtx = FhirContext.forDstu3();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloneIntoComposite() {
|
||||||
|
Quantity source = new Quantity();
|
||||||
|
source.setCode("CODE");
|
||||||
|
Money target = new Money();
|
||||||
|
|
||||||
|
ourCtx.newTerser().cloneInto(source, target, true);
|
||||||
|
|
||||||
|
assertEquals("CODE", target.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloneIntoCompositeMismatchedFields() {
|
||||||
|
Quantity source = new Quantity();
|
||||||
|
source.setSystem("SYSTEM");
|
||||||
|
source.setUnit("UNIT");
|
||||||
|
Identifier target = new Identifier();
|
||||||
|
|
||||||
|
ourCtx.newTerser().cloneInto(source, target, true);
|
||||||
|
|
||||||
|
assertEquals("SYSTEM", target.getSystem());
|
||||||
|
|
||||||
|
try {
|
||||||
|
ourCtx.newTerser().cloneInto(source, target, false);
|
||||||
|
fail();
|
||||||
|
} catch (DataFormatException e) {
|
||||||
|
// good
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #369
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCloneIntoExtension() {
|
||||||
|
Patient patient = new Patient();
|
||||||
|
|
||||||
|
patient.addExtension(new Extension("http://example.com", new StringType("FOO")));
|
||||||
|
|
||||||
|
Patient target = new Patient();
|
||||||
|
ourCtx.newTerser().cloneInto(patient, target, false);
|
||||||
|
|
||||||
|
List<Extension> exts = target.getExtensionsByUrl("http://example.com");
|
||||||
|
assertEquals(1, exts.size());
|
||||||
|
assertEquals("FOO", ((StringType)exts.get(0).getValue()).getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloneIntoPrimitive() {
|
||||||
|
StringType source = new StringType("STR");
|
||||||
|
MarkdownType target = new MarkdownType();
|
||||||
|
|
||||||
|
ourCtx.newTerser().cloneInto(source, target, true);
|
||||||
|
|
||||||
|
assertEquals("STR", target.getValueAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloneIntoPrimitiveFails() {
|
||||||
|
StringType source = new StringType("STR");
|
||||||
|
Money target = new Money();
|
||||||
|
|
||||||
|
ourCtx.newTerser().cloneInto(source, target, true);
|
||||||
|
assertTrue(target.isEmpty());
|
||||||
|
|
||||||
|
try {
|
||||||
|
ourCtx.newTerser().cloneInto(source, target, false);
|
||||||
|
fail();
|
||||||
|
} catch (DataFormatException e) {
|
||||||
|
// good
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #369
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCloneIntoValues() {
|
||||||
|
Observation obs = new Observation();
|
||||||
|
obs.setValue(new StringType("AAA"));
|
||||||
|
obs.setComment("COMMENTS");
|
||||||
|
|
||||||
|
Observation target = new Observation();
|
||||||
|
ourCtx.newTerser().cloneInto(obs, target, false);
|
||||||
|
|
||||||
|
assertEquals("AAA", ((StringType)obs.getValue()).getValue());
|
||||||
|
assertEquals("COMMENTS", obs.getComment());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAllPopulatedChildElementsOfTypeDescendsIntoContained() {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.addName().addFamily("PATIENT");
|
||||||
|
|
||||||
|
Organization o = new Organization();
|
||||||
|
o.getNameElement().setValue("ORGANIZATION");
|
||||||
|
p.getContained().add(o);
|
||||||
|
|
||||||
|
FhirTerser t = ourCtx.newTerser();
|
||||||
|
List<StringType> strings = t.getAllPopulatedChildElementsOfType(p, StringType.class);
|
||||||
|
|
||||||
|
assertThat(toStrings(strings), containsInAnyOrder("PATIENT","ORGANIZATION"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAllPopulatedChildElementsOfTypeDoesntDescendIntoEmbedded() {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.addName().addFamily("PATIENT");
|
||||||
|
|
||||||
|
Bundle b = new Bundle();
|
||||||
|
b.addEntry().setResource(p);
|
||||||
|
b.addLink().setRelation("BUNDLE");
|
||||||
|
|
||||||
|
FhirTerser t = ourCtx.newTerser();
|
||||||
|
List<StringType> strings = t.getAllPopulatedChildElementsOfType(b, StringType.class);
|
||||||
|
|
||||||
|
assertEquals(1, strings.size());
|
||||||
|
assertThat(toStrings(strings), containsInAnyOrder("BUNDLE"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetResourceReferenceInExtension() {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.addName().addFamily("PATIENT");
|
||||||
|
|
||||||
|
Organization o = new Organization();
|
||||||
|
o.setName("ORG");
|
||||||
|
Reference ref = new Reference(o);
|
||||||
|
Extension ext = new Extension("urn:foo", ref);
|
||||||
|
p.addExtension(ext);
|
||||||
|
|
||||||
|
FhirTerser t = ourCtx.newTerser();
|
||||||
|
List<IBaseReference> refs = t.getAllPopulatedChildElementsOfType(p, IBaseReference.class);
|
||||||
|
assertEquals(1, refs.size());
|
||||||
|
assertSame(ref, refs.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVisitWithModelVisitor2() {
|
||||||
|
IModelVisitor2 visitor = mock(IModelVisitor2.class);
|
||||||
|
|
||||||
|
ArgumentCaptor<IBase> element = ArgumentCaptor.forClass(IBase.class);
|
||||||
|
ArgumentCaptor<List<IBase>> containingElementPath = ArgumentCaptor.forClass(getListClass(IBase.class));
|
||||||
|
ArgumentCaptor<List<BaseRuntimeChildDefinition>> childDefinitionPath = ArgumentCaptor.forClass(getListClass(BaseRuntimeChildDefinition.class));
|
||||||
|
ArgumentCaptor<List<BaseRuntimeElementDefinition<?>>> elementDefinitionPath = ArgumentCaptor.forClass(getListClass2());
|
||||||
|
when(visitor.acceptElement(element.capture(), containingElementPath.capture(), childDefinitionPath.capture(), elementDefinitionPath.capture())).thenReturn(true);
|
||||||
|
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.addLink().getTypeElement().setValue(LinkType.REFER);
|
||||||
|
ourCtx.newTerser().visit(p, visitor);
|
||||||
|
|
||||||
|
assertEquals(3, element.getAllValues().size());
|
||||||
|
assertSame(p, element.getAllValues().get(0));
|
||||||
|
assertSame(p.getLinkFirstRep(), element.getAllValues().get(1));
|
||||||
|
assertSame(p.getLinkFirstRep().getTypeElement(), element.getAllValues().get(2));
|
||||||
|
|
||||||
|
assertEquals(3, containingElementPath.getAllValues().size());
|
||||||
|
// assertEquals(0, containingElementPath.getAllValues().get(0).size());
|
||||||
|
// assertEquals(1, containingElementPath.getAllValues().get(1).size());
|
||||||
|
// assertEquals(2, containingElementPath.getAllValues().get(2).size());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> toStrings(List<StringType> theStrings) {
|
||||||
|
ArrayList<String> retVal = new ArrayList<String>();
|
||||||
|
for (StringType next : theStrings) {
|
||||||
|
retVal.add(next.getValue());
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClassClearContext() {
|
||||||
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See http://stackoverflow.com/questions/182636/how-to-determine-the-class-of-a-generic-type
|
||||||
|
*/
|
||||||
|
private static <T> Class<List<T>> getListClass(Class<T> theClass) {
|
||||||
|
return new ClassGetter<List<T>>() {
|
||||||
|
}.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See http://stackoverflow.com/questions/182636/how-to-determine-the-class-of-a-generic-type
|
||||||
|
*/
|
||||||
|
private static Class<List<BaseRuntimeElementDefinition<?>>> getListClass2() {
|
||||||
|
return new ClassGetter<List<BaseRuntimeElementDefinition<?>>>() {
|
||||||
|
}.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See http://stackoverflow.com/questions/182636/how-to-determine-the-class-of-a-generic-type
|
||||||
|
*/
|
||||||
|
private static abstract class ClassGetter<T> {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public final Class<T> get() {
|
||||||
|
final ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass();
|
||||||
|
Type type = superclass.getActualTypeArguments()[0];
|
||||||
|
if (type instanceof ParameterizedType) {
|
||||||
|
return (Class<T>) ((ParameterizedType) type).getOwnerType();
|
||||||
|
}
|
||||||
|
return (Class<T>) type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -229,6 +229,11 @@
|
||||||
</ul>
|
</ul>
|
||||||
]]>
|
]]>
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix" issue="369">
|
||||||
|
FhirTerser.cloneInto method failed to clone correctly if the source
|
||||||
|
had any extensions. Thanks to GitHub user @Virdulys for submitting and
|
||||||
|
providing a test case!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="1.5" date="2016-04-20">
|
<release version="1.5" date="2016-04-20">
|
||||||
<action type="fix" issue="339">
|
<action type="fix" issue="339">
|
||||||
|
|
Loading…
Reference in New Issue