diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/ISupportsUndeclaredExtensions.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/ISupportsUndeclaredExtensions.java index afd252ed349..ee6402578bc 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/ISupportsUndeclaredExtensions.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/ISupportsUndeclaredExtensions.java @@ -20,10 +20,10 @@ package ca.uhn.fhir.model.api; * #L% */ -import java.util.List; - import org.hl7.fhir.instance.model.api.IBaseDatatype; +import java.util.List; + public interface ISupportsUndeclaredExtensions extends IElement { /** @@ -42,7 +42,8 @@ public interface ISupportsUndeclaredExtensions extends IElement { /** * Returns an immutable list containing all extensions (modifier and non-modifier). * - * @see #getUndeclaredExtensions() To return a mutable list which may be used to remove extensions + * @see #getUndeclaredExtensions() To return a mutable list which may be used to remove undeclared non-modifier extensions + * @see #getUndeclaredModifierExtensions() To return a mutable list which may be used to remove undeclared modifier extensions */ List getAllUndeclaredExtensions(); diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/FhirTerser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/FhirTerser.java index ca32e26447c..354d52d6201 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/FhirTerser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/FhirTerser.java @@ -58,7 +58,41 @@ public class FhirTerser { newList.add(theChildDefinition.getElementName()); return newList; } - + + private ExtensionDt createEmptyExtensionDt(IBaseExtension theBaseExtension, String theUrl) { + return createEmptyExtensionDt(theBaseExtension, false, theUrl); + } + + @SuppressWarnings("unchecked") + private ExtensionDt createEmptyExtensionDt(IBaseExtension theBaseExtension, boolean theIsModifier, String theUrl) { + ExtensionDt retVal = new ExtensionDt(theIsModifier, theUrl); + theBaseExtension.getExtension().add(retVal); + return retVal; + } + + private ExtensionDt createEmptyExtensionDt(ISupportsUndeclaredExtensions theSupportsUndeclaredExtensions, String theUrl) { + return createEmptyExtensionDt(theSupportsUndeclaredExtensions, false, theUrl); + } + + private ExtensionDt createEmptyExtensionDt(ISupportsUndeclaredExtensions theSupportsUndeclaredExtensions, boolean theIsModifier, String theUrl) { + return theSupportsUndeclaredExtensions.addUndeclaredExtension(theIsModifier, theUrl); + } + + private IBaseExtension createEmptyExtension(IBaseHasExtensions theBaseHasExtensions, String theUrl) { + return (IBaseExtension) theBaseHasExtensions.addExtension().setUrl(theUrl); + } + + private IBaseExtension createEmptyModifierExtension(IBaseHasModifierExtensions theBaseHasModifierExtensions, String theUrl) { + return (IBaseExtension) theBaseHasModifierExtensions.addModifierExtension().setUrl(theUrl); + } + + private ExtensionDt createEmptyModifierExtensionDt(IBaseExtension theBaseExtension, String theUrl) { + return createEmptyExtensionDt(theBaseExtension, true, theUrl); + } + + private ExtensionDt createEmptyModifierExtensionDt(ISupportsUndeclaredExtensions theSupportsUndeclaredExtensions, String theUrl) { + return createEmptyExtensionDt(theSupportsUndeclaredExtensions, true, theUrl); + } /** * Clones all values from a source object into the equivalent fields in a target object @@ -214,11 +248,11 @@ public class FhirTerser { } private List getValues(BaseRuntimeElementCompositeDefinition theCurrentDef, Object theCurrentObj, List theSubList, Class theWantedClass) { - return getValues(theCurrentDef, theCurrentObj, theSubList, theWantedClass, false); + return getValues(theCurrentDef, theCurrentObj, theSubList, theWantedClass, false, false); } @SuppressWarnings("unchecked") - private List getValues(BaseRuntimeElementCompositeDefinition theCurrentDef, Object theCurrentObj, List theSubList, Class theWantedClass, boolean theCreate) { + private List getValues(BaseRuntimeElementCompositeDefinition theCurrentDef, Object theCurrentObj, List theSubList, Class theWantedClass, boolean theCreate, boolean theAddExtension) { String name = theSubList.get(0); List retVal = new ArrayList<>(); @@ -229,27 +263,35 @@ public class FhirTerser { extensionUrl = extensionUrl.substring(0, endIndex); } - // DSTU2 if (myContext.getVersion().getVersion().isOlderThan(FhirVersionEnum.DSTU3)) { + // DTSU2 + final String extensionDtUrlForLambda = extensionUrl; List extensionDts = Collections.emptyList(); if (theCurrentObj instanceof ISupportsUndeclaredExtensions) { - extensionDts = ((ISupportsUndeclaredExtensions) theCurrentObj).getUndeclaredExtensionsByUrl(extensionUrl); + extensionDts = ((ISupportsUndeclaredExtensions) theCurrentObj).getUndeclaredExtensions() + .stream() + .filter(t -> t.getUrl().equals(extensionDtUrlForLambda)) + .collect(Collectors.toList()); + + if (theAddExtension + && (!(theCurrentObj instanceof IBaseExtension) || (extensionDts.isEmpty() && theSubList.size() == 1))) { + extensionDts.add(createEmptyExtensionDt((ISupportsUndeclaredExtensions) theCurrentObj, extensionUrl)); + } if (extensionDts.isEmpty() && theCreate) { - // We assume the extension is not a modifier extension. - extensionDts = new ArrayList<>(); // Implementation of ISupportsUndeclaredExtensions.getUndeclaredExtensionsByUrl(...) returns unmodifiable list. - ExtensionDt extensionDt = ((ISupportsUndeclaredExtensions) theCurrentObj).addUndeclaredExtension(false, extensionUrl); - extensionDts.add(extensionDt); + extensionDts.add(createEmptyExtensionDt((ISupportsUndeclaredExtensions) theCurrentObj, extensionUrl)); } + } else if (theCurrentObj instanceof IBaseExtension) { extensionDts = ((IBaseExtension) theCurrentObj).getExtension(); + if (theAddExtension + && (extensionDts.isEmpty() && theSubList.size() == 1)) { + extensionDts.add(createEmptyExtensionDt((IBaseExtension) theCurrentObj, extensionUrl)); + } + if (extensionDts.isEmpty() && theCreate) { - // We assume the extension is not a modifier extension. - ExtensionDt extensionDt = new ExtensionDt(); - extensionDt.setUrl(extensionUrl); - ((IBaseExtension) theCurrentObj).getExtension().add(extensionDt); - extensionDts.add(extensionDt); + extensionDts.add(createEmptyExtensionDt((IBaseExtension) theCurrentObj, extensionUrl)); } } @@ -268,10 +310,13 @@ public class FhirTerser { .filter(t -> t.getUrl().equals(extensionUrlForLambda)) .collect(Collectors.toList()); + if (theAddExtension + && (!(theCurrentObj instanceof IBaseExtension) || (extensions.isEmpty() && theSubList.size() == 1))) { + extensions.add(createEmptyExtension((IBaseHasExtensions) theCurrentObj, extensionUrl)); + } + if (extensions.isEmpty() && theCreate) { - IBaseExtension extension = ((IBaseHasExtensions) theCurrentObj).addExtension(); - extension.setUrl(extensionUrl); - extensions.add(extension); + extensions.add(createEmptyExtension((IBaseHasExtensions) theCurrentObj, extensionUrl)); } } @@ -287,7 +332,7 @@ public class FhirTerser { retVal = new ArrayList<>(); for (T nextElement : values) { BaseRuntimeElementCompositeDefinition nextChildDef = (BaseRuntimeElementCompositeDefinition) myContext.getElementDefinition((Class) nextElement.getClass()); - List foundValues = getValues(nextChildDef, nextElement, theSubList.subList(1, theSubList.size()), theWantedClass, theCreate); + List foundValues = getValues(nextChildDef, nextElement, theSubList.subList(1, theSubList.size()), theWantedClass, theCreate, theAddExtension); retVal.addAll(foundValues); } } @@ -302,8 +347,45 @@ public class FhirTerser { extensionUrl = extensionUrl.substring(0, endIndex); } - // DSTU3+ - if (myContext.getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.DSTU3)) { + if (myContext.getVersion().getVersion().isOlderThan(FhirVersionEnum.DSTU3)) { + // DSTU2 + final String extensionDtUrlForLambda = extensionUrl; + List extensionDts = Collections.emptyList(); + if (theCurrentObj instanceof ISupportsUndeclaredExtensions) { + extensionDts = ((ISupportsUndeclaredExtensions) theCurrentObj).getUndeclaredModifierExtensions() + .stream() + .filter(t -> t.getUrl().equals(extensionDtUrlForLambda)) + .collect(Collectors.toList()); + + if (theAddExtension + && (!(theCurrentObj instanceof IBaseExtension) || (extensionDts.isEmpty() && theSubList.size() == 1))) { + extensionDts.add(createEmptyModifierExtensionDt((ISupportsUndeclaredExtensions) theCurrentObj, extensionUrl)); + } + + if (extensionDts.isEmpty() && theCreate) { + extensionDts.add(createEmptyModifierExtensionDt((ISupportsUndeclaredExtensions) theCurrentObj, extensionUrl)); + } + + } else if (theCurrentObj instanceof IBaseExtension) { + extensionDts = ((IBaseExtension) theCurrentObj).getExtension(); + + if (theAddExtension + && (extensionDts.isEmpty() && theSubList.size() == 1)) { + extensionDts.add(createEmptyExtensionDt((IBaseExtension) theCurrentObj, extensionUrl)); + } + + if (extensionDts.isEmpty() && theCreate) { + extensionDts.add(createEmptyExtensionDt((IBaseExtension) theCurrentObj, extensionUrl)); + } + } + + for (ExtensionDt next : extensionDts) { + if (theWantedClass.isAssignableFrom(next.getClass())) { + retVal.add((T) next); + } + } + } else { + // DSTU3+ final String extensionUrlForLambda = extensionUrl; List extensions = Collections.emptyList(); @@ -313,10 +395,13 @@ public class FhirTerser { .filter(t -> t.getUrl().equals(extensionUrlForLambda)) .collect(Collectors.toList()); + if (theAddExtension + && (!(theCurrentObj instanceof IBaseExtension) || (extensions.isEmpty() && theSubList.size() == 1))) { + extensions.add(createEmptyModifierExtension((IBaseHasModifierExtensions) theCurrentObj, extensionUrl)); + } + if (extensions.isEmpty() && theCreate) { - IBaseExtension modifierExtension = ((IBaseHasModifierExtensions) theCurrentObj).addModifierExtension(); - modifierExtension.setUrl(extensionUrl); - extensions.add(modifierExtension); + extensions.add(createEmptyModifierExtension((IBaseHasModifierExtensions) theCurrentObj, extensionUrl)); } } @@ -332,7 +417,7 @@ public class FhirTerser { retVal = new ArrayList<>(); for (T nextElement : values) { BaseRuntimeElementCompositeDefinition nextChildDef = (BaseRuntimeElementCompositeDefinition) myContext.getElementDefinition((Class) nextElement.getClass()); - List foundValues = getValues(nextChildDef, nextElement, theSubList.subList(1, theSubList.size()), theWantedClass, theCreate); + List foundValues = getValues(nextChildDef, nextElement, theSubList.subList(1, theSubList.size()), theWantedClass, theCreate, theAddExtension); retVal.addAll(foundValues); } } @@ -381,7 +466,7 @@ public class FhirTerser { } else { for (IBase nextElement : values) { BaseRuntimeElementCompositeDefinition nextChildDef = (BaseRuntimeElementCompositeDefinition) myContext.getElementDefinition(nextElement.getClass()); - List foundValues = getValues(nextChildDef, nextElement, theSubList.subList(1, theSubList.size()), theWantedClass, theCreate); + List foundValues = getValues(nextChildDef, nextElement, theSubList.subList(1, theSubList.size()), theWantedClass, theCreate, theAddExtension); retVal.addAll(foundValues); } } @@ -392,9 +477,6 @@ public class FhirTerser { * Returns values stored in an element identified by its path. The list of values is of * type {@link Object}. * - *

Note: this method does not support creation of null-valued modifier extensions for - * versions of FHIR prior to DSTU3.

- * * @param theResource The resource instance to be accessed. Must not be null. * @param thePath The path for the element to be accessed. * @return A list of values of type {@link Object}. @@ -409,9 +491,6 @@ public class FhirTerser { * Returns values stored in an element identified by its path. The list of values is of * type {@link Object}. * - *

Note: this method does not support creation of null-valued modifier extensions for - * versions of FHIR prior to DSTU3.

- * * @param theResource The resource instance to be accessed. Must not be null. * @param thePath The path for the element to be accessed. * @param theCreate When set to true, the terser will create a null-valued element where none exists. @@ -425,10 +504,23 @@ public class FhirTerser { /** * Returns values stored in an element identified by its path. The list of values is of - * type theWantedClass. + * type {@link Object}. * - *

Note: this method does not support creation of null-valued modifier extensions for - * versions of FHIR prior to DSTU3.

+ * @param theResource The resource instance to be accessed. Must not be null. + * @param thePath The path for the element to be accessed. + * @param theCreate When set to true, the terser will create a null-valued element where none exists. + * @param theAddExtension When set to true, the terser will add a null-valued extension where one or more such extensions already exist. + * @return A list of values of type {@link Object}. + */ + public List getValues(IBaseResource theResource, String thePath, boolean theCreate, boolean theAddExtension) { + Class wantedClass = Object.class; + + return getValues(theResource, thePath, wantedClass, theCreate, theAddExtension); + } + + /** + * Returns values stored in an element identified by its path. The list of values is of + * type theWantedClass. * * @param theResource The resource instance to be accessed. Must not be null. * @param thePath The path for the element to be accessed. @@ -446,9 +538,6 @@ public class FhirTerser { * Returns values stored in an element identified by its path. The list of values is of * type theWantedClass. * - *

Note: this method does not support creation of null-valued modifier extensions for - * versions of FHIR prior to DSTU3.

- * * @param theResource The resource instance to be accessed. Must not be null. * @param thePath The path for the element to be accessed. * @param theWantedClass The desired class to be returned in a list. @@ -459,7 +548,25 @@ public class FhirTerser { public List getValues(IBaseResource theResource, String thePath, Class theWantedClass, boolean theCreate) { RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource); List parts = parsePath(def, thePath); - return getValues(def, theResource, parts, theWantedClass, theCreate); + return getValues(def, theResource, parts, theWantedClass, theCreate, false); + } + + /** + * Returns values stored in an element identified by its path. The list of values is of + * type theWantedClass. + * + * @param theResource The resource instance to be accessed. Must not be null. + * @param thePath The path for the element to be accessed. + * @param theWantedClass The desired class to be returned in a list. + * @param theCreate When set to true, the terser will create a null-valued element where none exists. + * @param theAddExtension When set to true, the terser will add a null-valued extension where one or more such extensions already exist. + * @param Type declared by theWantedClass + * @return A list of values of type theWantedClass. + */ + public List getValues(IBaseResource theResource, String thePath, Class theWantedClass, boolean theCreate, boolean theAddExtension) { + RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource); + List parts = parsePath(def, thePath); + return getValues(def, theResource, parts, theWantedClass, theCreate, theAddExtension); } private List parsePath(BaseRuntimeElementCompositeDefinition theElementDef, String thePath) { diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/util/FhirTerserDstu2Test.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/util/FhirTerserDstu2Test.java index e66eabdc9cd..f1312e16850 100644 --- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/util/FhirTerserDstu2Test.java +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/util/FhirTerserDstu2Test.java @@ -185,6 +185,7 @@ public class FhirTerserDstu2Test { p.setActive(true); p.addUndeclaredExtension(false, "http://acme.org/extension", new StringDt("value")); p.addUndeclaredExtension(false, "http://acme.org/otherExtension", new StringDt("otherValue")); + p.addUndeclaredExtension(true, "http://acme.org/modifierExtension", new StringDt("modifierValue")); p.addUndeclaredExtension(false, "http://acme.org/parentExtension").addUndeclaredExtension(false, "http://acme.org/childExtension", new StringDt("nestedValue")); System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); @@ -202,6 +203,13 @@ public class FhirTerserDstu2Test { assertEquals("http://acme.org/extension", ((ExtensionDt) values.get(0)).getUrl()); assertEquals("value", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + values = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("modifierValue", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')"); assertEquals(1, values.size()); assertTrue(values.get(0) instanceof IBaseExtension); @@ -216,6 +224,7 @@ public class FhirTerserDstu2Test { p.setActive(true); p.addUndeclaredExtension(false, "http://acme.org/extension", new StringDt("value")); p.addUndeclaredExtension(false, "http://acme.org/otherExtension", new StringDt("otherValue")); + p.addUndeclaredExtension(true, "http://acme.org/modifierExtension", new StringDt("modifierValue")); p.addUndeclaredExtension(false, "http://acme.org/parentExtension").addUndeclaredExtension(false, "http://acme.org/childExtension", new StringDt("nestedValue")); System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); @@ -254,6 +263,24 @@ public class FhirTerserDstu2Test { assertEquals("http://acme.org/extension", ((ExtensionDt) values.get(0)).getUrl()); assertEquals("modifiedValue", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + values = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("modifierValue", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + + ((ExtensionDt) values.get(0)).setValue(new StringDt("modifiedModifierValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + values = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("modifiedModifierValue", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')"); assertEquals(1, values.size()); assertTrue(values.get(0) instanceof IBaseExtension); @@ -279,6 +306,8 @@ public class FhirTerserDstu2Test { p.addUndeclaredExtension(false, "http://acme.org/extension", new StringDt("value1")); p.addUndeclaredExtension(false, "http://acme.org/extension", new StringDt("value2")); p.addUndeclaredExtension(false, "http://acme.org/otherExtension", new StringDt("otherValue")); + p.addUndeclaredExtension(true, "http://acme.org/modifierExtension", new StringDt("modifierValue1")); + p.addUndeclaredExtension(true, "http://acme.org/modifierExtension", new StringDt("modifierValue2")); p.addUndeclaredExtension(false, "http://acme.org/parentExtension").addUndeclaredExtension(false, "http://acme.org/childExtension", new StringDt("nestedValue1")); p.addUndeclaredExtension(false, "http://acme.org/parentExtension").addUndeclaredExtension(false, "http://acme.org/childExtension", new StringDt("nestedValue2")); @@ -295,6 +324,17 @@ public class FhirTerserDstu2Test { assertEquals("http://acme.org/extension", ((ExtensionDt) values.get(1)).getUrl()); assertEquals("value2", ((StringDt) ((ExtensionDt) values.get(1)).getValue()).getValueAsString()); + values = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')"); + assertEquals(2, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("modifierValue1", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(1)).getUrl()); + assertEquals("modifierValue2", ((StringDt) ((ExtensionDt) values.get(1)).getValue()).getValueAsString()); + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')"); assertEquals(2, values.size()); assertTrue(values.get(0) instanceof IBaseExtension); @@ -313,6 +353,7 @@ public class FhirTerserDstu2Test { p.setActive(true); p.addUndeclaredExtension(false, "http://acme.org/extension", new StringDt("value")); p.addUndeclaredExtension(false, "http://acme.org/otherExtension", new StringDt("otherValue")); + p.addUndeclaredExtension(true, "http://acme.org/modifierExtension", new StringDt("modifierValue")); p.addUndeclaredExtension(false, "http://acme.org/parentExtension").addUndeclaredExtension(false, "http://acme.org/childExtension", new StringDt("nestedValue")); System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); @@ -328,6 +369,12 @@ public class FhirTerserDstu2Test { assertEquals("http://acme.org/extension", extValues.get(0).getUrl()); assertEquals("value", ((StringDt) extValues.get(0).getValue()).getValueAsString()); + extValues = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')", ExtensionDt.class); + assertEquals(1, extValues.size()); + assertTrue(extValues.get(0).getValue() instanceof StringDt); + assertEquals("http://acme.org/modifierExtension", extValues.get(0).getUrl()); + assertEquals("modifierValue", ((StringDt) (extValues.get(0).getValue())).getValueAsString()); + extValues = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')", ExtensionDt.class); assertEquals(1, extValues.size()); assertTrue(extValues.get(0).getValue() instanceof StringDt); @@ -341,6 +388,7 @@ public class FhirTerserDstu2Test { p.setActive(true); p.addUndeclaredExtension(false, "http://acme.org/extension", new StringDt("value")); p.addUndeclaredExtension(false, "http://acme.org/otherExtension", new StringDt("otherValue")); + p.addUndeclaredExtension(true, "http://acme.org/modifierExtension", new StringDt("modifierValue")); p.addUndeclaredExtension(false, "http://acme.org/parentExtension").addUndeclaredExtension(false, "http://acme.org/childExtension", new StringDt("nestedValue")); System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); @@ -375,6 +423,22 @@ public class FhirTerserDstu2Test { assertEquals("http://acme.org/extension", extValues.get(0).getUrl()); assertEquals("modifiedValue", ((StringDt) (extValues.get(0).getValue())).getValueAsString()); + extValues = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')", ExtensionDt.class); + assertEquals(1, extValues.size()); + assertTrue(extValues.get(0).getValue() instanceof StringDt); + assertEquals("http://acme.org/modifierExtension", extValues.get(0).getUrl()); + assertEquals("modifierValue", ((StringDt) (extValues.get(0).getValue())).getValueAsString()); + + extValues.get(0).setValue(new StringDt("modifiedModifierValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + extValues = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')", ExtensionDt.class); + assertEquals(1, extValues.size()); + assertTrue(extValues.get(0).getValue() instanceof StringDt); + assertEquals("http://acme.org/modifierExtension", extValues.get(0).getUrl()); + assertEquals("modifiedModifierValue", ((StringDt) (extValues.get(0).getValue())).getValueAsString()); + extValues = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')", ExtensionDt.class); assertEquals(1, extValues.size()); assertTrue(extValues.get(0).getValue() instanceof StringDt); @@ -408,12 +472,125 @@ public class FhirTerserDstu2Test { assertEquals("http://acme.org/extension", extValues.get(0).getUrl()); assertNull(extValues.get(0).getValue()); + extValues = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')", ExtensionDt.class, true); + assertEquals(1, extValues.size()); + assertEquals("http://acme.org/modifierExtension", extValues.get(0).getUrl()); + assertNull(extValues.get(0).getValue()); + extValues = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')", ExtensionDt.class, true); assertEquals(1, extValues.size()); assertEquals("http://acme.org/childExtension", extValues.get(0).getUrl()); assertNull(extValues.get(0).getValue()); } + @Test + public void testGetValuesWithTheAddExtensionAndModify() { + Patient p = new Patient(); + p.setActive(true); + p.addUndeclaredExtension(false, "http://acme.org/extension", new StringDt("value")); + p.addUndeclaredExtension(false, "http://acme.org/otherExtension", new StringDt("otherValue")); + p.addUndeclaredExtension(true, "http://acme.org/modifierExtension", new StringDt("modifierValue")); + p.addUndeclaredExtension(false, "http://acme.org/parentExtension").addUndeclaredExtension(false, "http://acme.org/childExtension", new StringDt("nestedValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + List values = ourCtx.newTerser().getValues(p, "Patient.active"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IPrimitiveType); + assertTrue(values.get(0) instanceof BooleanDt); + assertTrue(((BooleanDt) values.get(0)).getValue()); + + // No change. + values = ourCtx.newTerser().getValues(p, "Patient.active", false, true); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IPrimitiveType); + assertTrue(values.get(0) instanceof BooleanDt); + assertTrue(((BooleanDt) values.get(0)).getValue()); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/extension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/extension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("value", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/extension')", false, true); + assertEquals(2, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/extension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("value", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof ExtensionDt); + assertEquals("http://acme.org/extension", ((ExtensionDt) values.get(1)).getUrl()); + assertNull(((ExtensionDt) values.get(1)).getValue()); + + ((ExtensionDt) values.get(1)).setValue(new StringDt("addedValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof ExtensionDt); + assertEquals("http://acme.org/extension", ((ExtensionDt) values.get(1)).getUrl()); + assertEquals("addedValue", ((StringDt) ((ExtensionDt) values.get(1)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("modifierValue", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')", false, true); + assertEquals(2, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("modifierValue", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(1)).getUrl()); + assertNull(((ExtensionDt) values.get(1)).getValue()); + + ((ExtensionDt) values.get(1)).setValue(new StringDt("addedModifierValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(1)).getUrl()); + assertEquals("addedModifierValue", ((StringDt) ((ExtensionDt) values.get(1)).getValue()).getValueAsString()); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/childExtension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("nestedValue", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')", false, true); + assertEquals(2, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/childExtension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("nestedValue", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof ExtensionDt); + assertEquals("http://acme.org/childExtension", ((ExtensionDt) values.get(1)).getUrl()); + assertNull(((ExtensionDt) values.get(1)).getValue()); + + ((ExtensionDt) values.get(1)).setValue(new StringDt("addedNestedValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof ExtensionDt); + assertEquals("http://acme.org/childExtension", ((ExtensionDt) values.get(1)).getUrl()); + assertEquals("addedNestedValue", ((StringDt) ((ExtensionDt) values.get(1)).getValue()).getValueAsString()); + } + @Test public void testGetValuesWithTheCreate() { Patient p = new Patient(); @@ -433,6 +610,13 @@ public class FhirTerserDstu2Test { assertEquals("http://acme.org/extension", ((ExtensionDt) values.get(0)).getUrl()); assertNull(((ExtensionDt) values.get(0)).getValue()); + values = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')", true); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(0)).getUrl()); + assertNull(((ExtensionDt) values.get(0)).getValue()); + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')", true); assertEquals(1, values.size()); assertTrue(values.get(0) instanceof IBaseExtension); @@ -441,12 +625,119 @@ public class FhirTerserDstu2Test { assertNull(((ExtensionDt) values.get(0)).getValue()); } + @Test + public void testGetValuesWithTheCreateAndTheAddExtensionAndModify() { + Patient p = new Patient(); + p.setActive(true); + p.addUndeclaredExtension(false, "http://acme.org/extension", new StringDt("value")); + p.addUndeclaredExtension(false, "http://acme.org/otherExtension", new StringDt("otherValue")); + p.addUndeclaredExtension(true, "http://acme.org/modifierExtension", new StringDt("modifierValue")); + p.addUndeclaredExtension(false, "http://acme.org/parentExtension").addUndeclaredExtension(false, "http://acme.org/childExtension", new StringDt("nestedValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + List values = ourCtx.newTerser().getValues(p, "Patient.active"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IPrimitiveType); + assertTrue(values.get(0) instanceof BooleanDt); + assertTrue(((BooleanDt) values.get(0)).getValue()); + + // No change. + values = ourCtx.newTerser().getValues(p, "Patient.active", true, true); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IPrimitiveType); + assertTrue(values.get(0) instanceof BooleanDt); + assertTrue(((BooleanDt) values.get(0)).getValue()); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/extension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/extension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("value", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/extension')", true, true); + assertEquals(2, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/extension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("value", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof ExtensionDt); + assertEquals("http://acme.org/extension", ((ExtensionDt) values.get(1)).getUrl()); + assertNull(((ExtensionDt) values.get(1)).getValue()); + + ((ExtensionDt) values.get(1)).setValue(new StringDt("addedValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof ExtensionDt); + assertEquals("http://acme.org/extension", ((ExtensionDt) values.get(1)).getUrl()); + assertEquals("addedValue", ((StringDt) ((ExtensionDt) values.get(1)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("modifierValue", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')", true, true); + assertEquals(2, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("modifierValue", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(1)).getUrl()); + assertNull(((ExtensionDt) values.get(1)).getValue()); + + ((ExtensionDt) values.get(1)).setValue(new StringDt("addedModifierValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(1)).getUrl()); + assertEquals("addedModifierValue", ((StringDt) ((ExtensionDt) values.get(1)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/childExtension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("nestedValue", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')", true, true); + assertEquals(2, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/childExtension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("nestedValue", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof ExtensionDt); + assertEquals("http://acme.org/childExtension", ((ExtensionDt) values.get(1)).getUrl()); + assertNull(((ExtensionDt) values.get(1)).getValue()); + + ((ExtensionDt) values.get(1)).setValue(new StringDt("addedNestedValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof ExtensionDt); + assertEquals("http://acme.org/childExtension", ((ExtensionDt) values.get(1)).getUrl()); + assertEquals("addedNestedValue", ((StringDt) ((ExtensionDt) values.get(1)).getValue()).getValueAsString()); + } + @Test public void testGetValuesWithTheCreateAndNoOverwrite() { Patient p = new Patient(); p.setActive(true); p.addUndeclaredExtension(false, "http://acme.org/extension", new StringDt("value")); p.addUndeclaredExtension(false, "http://acme.org/otherExtension", new StringDt("otherValue")); + p.addUndeclaredExtension(true, "http://acme.org/modifierExtension", new StringDt("modifierValue")); p.addUndeclaredExtension(false, "http://acme.org/parentExtension").addUndeclaredExtension(false, "http://acme.org/childExtension", new StringDt("nestedValue")); System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); @@ -464,6 +755,13 @@ public class FhirTerserDstu2Test { assertEquals("http://acme.org/extension", ((ExtensionDt) values.get(0)).getUrl()); assertEquals("value", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + values = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')", true); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof ExtensionDt); + assertEquals("http://acme.org/modifierExtension", ((ExtensionDt) values.get(0)).getUrl()); + assertEquals("modifierValue", ((StringDt) ((ExtensionDt) values.get(0)).getValue()).getValueAsString()); + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')", true); assertEquals(1, values.size()); assertTrue(values.get(0) instanceof IBaseExtension); diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/util/FhirTerserDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/util/FhirTerserDstu3Test.java index 047256fff6d..b8cece751d7 100644 --- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/util/FhirTerserDstu3Test.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/util/FhirTerserDstu3Test.java @@ -531,6 +531,124 @@ public class FhirTerserDstu3Test { assertNull(extValues.get(0).getValue()); } + @Test + public void testGetValuesWithTheAddExtensionAndModify() { + Patient p = new Patient(); + p.setActive(true); + p.addExtension() + .setUrl("http://acme.org/extension") + .setValue(new StringType("value")); + p.addExtension() + .setUrl("http://acme.org/otherExtension") + .setValue(new StringType("otherValue")); + p.addModifierExtension() + .setUrl("http://acme.org/modifierExtension") + .setValue(new StringType("modifierValue")); + p.addExtension() + .setUrl("http://acme.org/parentExtension") + .addExtension() + .setUrl("http://acme.org/childExtension") + .setValue(new StringType("nestedValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + List values = ourCtx.newTerser().getValues(p, "Patient.active"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof PrimitiveType); + assertTrue(values.get(0) instanceof BooleanType); + assertTrue(((BooleanType) values.get(0)).booleanValue()); + + // No change. + values = ourCtx.newTerser().getValues(p, "Patient.active", false, true); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof PrimitiveType); + assertTrue(values.get(0) instanceof BooleanType); + assertTrue(((BooleanType) values.get(0)).booleanValue()); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/extension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof Extension); + assertEquals("http://acme.org/extension", ((Extension) values.get(0)).getUrl()); + assertEquals("value", ((StringType) ((Extension) values.get(0)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/extension')", false, true); + assertEquals(2, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof Extension); + assertEquals("http://acme.org/extension", ((Extension) values.get(0)).getUrl()); + assertEquals("value", ((StringType) ((Extension) values.get(0)).getValue()).getValueAsString()); + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof Extension); + assertEquals("http://acme.org/extension", ((Extension) values.get(1)).getUrl()); + assertNull(((Extension) values.get(1)).getValue()); + + ((Extension) values.get(1)).setValue(new StringType("addedValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof Extension); + assertEquals("http://acme.org/extension", ((Extension) values.get(1)).getUrl()); + assertEquals("addedValue", ((StringType) ((Extension) values.get(1)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof Extension); + assertEquals("http://acme.org/modifierExtension", ((Extension) values.get(0)).getUrl()); + assertEquals("modifierValue", ((StringType) ((Extension) values.get(0)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')", false, true); + assertEquals(2, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof Extension); + assertEquals("http://acme.org/modifierExtension", ((Extension) values.get(0)).getUrl()); + assertEquals("modifierValue", ((StringType) ((Extension) values.get(0)).getValue()).getValueAsString()); + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof Extension); + assertEquals("http://acme.org/modifierExtension", ((Extension) values.get(1)).getUrl()); + assertNull(((Extension) values.get(1)).getValue()); + + ((Extension) values.get(1)).setValue(new StringType("addedModifierValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof Extension); + assertEquals("http://acme.org/modifierExtension", ((Extension) values.get(1)).getUrl()); + assertEquals("addedModifierValue", ((StringType) ((Extension) values.get(1)).getValue()).getValueAsString()); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof Extension); + assertEquals("http://acme.org/childExtension", ((Extension) values.get(0)).getUrl()); + assertEquals("nestedValue", ((StringType) ((Extension) values.get(0)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')", false, true); + assertEquals(2, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof Extension); + assertEquals("http://acme.org/childExtension", ((Extension) values.get(0)).getUrl()); + assertEquals("nestedValue", ((StringType) ((Extension) values.get(0)).getValue()).getValueAsString()); + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof Extension); + assertEquals("http://acme.org/childExtension", ((Extension) values.get(1)).getUrl()); + assertNull(((Extension) values.get(1)).getValue()); + + ((Extension) values.get(1)).setValue(new StringType("addedNestedValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof Extension); + assertEquals("http://acme.org/childExtension", ((Extension) values.get(1)).getUrl()); + assertEquals("addedNestedValue", ((StringType) ((Extension) values.get(1)).getValue()).getValueAsString()); + } + @Test public void testGetValuesWithTheCreate() { Patient p = new Patient(); @@ -563,6 +681,122 @@ public class FhirTerserDstu3Test { assertNull(((Extension) values.get(0)).getValue()); } + @Test + public void testGetValuesWithTheCreateAndTheAddExtensionAndModify() { + Patient p = new Patient(); + p.setActive(true); + p.addExtension() + .setUrl("http://acme.org/extension") + .setValue(new StringType("value")); + p.addExtension() + .setUrl("http://acme.org/otherExtension") + .setValue(new StringType("otherValue")); + p.addModifierExtension() + .setUrl("http://acme.org/modifierExtension") + .setValue(new StringType("modifierValue")); + p.addExtension() + .setUrl("http://acme.org/parentExtension") + .addExtension() + .setUrl("http://acme.org/childExtension") + .setValue(new StringType("nestedValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + List values = ourCtx.newTerser().getValues(p, "Patient.active"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof PrimitiveType); + assertTrue(values.get(0) instanceof BooleanType); + assertTrue(((BooleanType) values.get(0)).booleanValue()); + + // No change. + values = ourCtx.newTerser().getValues(p, "Patient.active", true, true); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof PrimitiveType); + assertTrue(values.get(0) instanceof BooleanType); + assertTrue(((BooleanType) values.get(0)).booleanValue()); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/extension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof Extension); + assertEquals("http://acme.org/extension", ((Extension) values.get(0)).getUrl()); + assertEquals("value", ((StringType) ((Extension) values.get(0)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/extension')", true, true); + assertEquals(2, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof Extension); + assertEquals("http://acme.org/extension", ((Extension) values.get(0)).getUrl()); + assertEquals("value", ((StringType) ((Extension) values.get(0)).getValue()).getValueAsString()); + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof Extension); + assertEquals("http://acme.org/extension", ((Extension) values.get(1)).getUrl()); + assertNull(((Extension) values.get(1)).getValue()); + + ((Extension) values.get(1)).setValue(new StringType("addedValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof Extension); + assertEquals("http://acme.org/extension", ((Extension) values.get(1)).getUrl()); + assertEquals("addedValue", ((StringType) ((Extension) values.get(1)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof Extension); + assertEquals("http://acme.org/modifierExtension", ((Extension) values.get(0)).getUrl()); + assertEquals("modifierValue", ((StringType) ((Extension) values.get(0)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.modifierExtension('http://acme.org/modifierExtension')", true, true); + assertEquals(2, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof Extension); + assertEquals("http://acme.org/modifierExtension", ((Extension) values.get(0)).getUrl()); + assertEquals("modifierValue", ((StringType) ((Extension) values.get(0)).getValue()).getValueAsString()); + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof Extension); + assertEquals("http://acme.org/modifierExtension", ((Extension) values.get(1)).getUrl()); + assertNull(((Extension) values.get(1)).getValue()); + + ((Extension) values.get(1)).setValue(new StringType("addedModifierValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof Extension); + assertEquals("http://acme.org/modifierExtension", ((Extension) values.get(1)).getUrl()); + assertEquals("addedModifierValue", ((StringType) ((Extension) values.get(1)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')"); + assertEquals(1, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof Extension); + assertEquals("http://acme.org/childExtension", ((Extension) values.get(0)).getUrl()); + assertEquals("nestedValue", ((StringType) ((Extension) values.get(0)).getValue()).getValueAsString()); + + values = ourCtx.newTerser().getValues(p, "Patient.extension('http://acme.org/parentExtension').extension('http://acme.org/childExtension')", true, true); + assertEquals(2, values.size()); + assertTrue(values.get(0) instanceof IBaseExtension); + assertTrue(values.get(0) instanceof Extension); + assertEquals("http://acme.org/childExtension", ((Extension) values.get(0)).getUrl()); + assertEquals("nestedValue", ((StringType) ((Extension) values.get(0)).getValue()).getValueAsString()); + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof Extension); + assertEquals("http://acme.org/childExtension", ((Extension) values.get(1)).getUrl()); + assertNull(((Extension) values.get(1)).getValue()); + + ((Extension) values.get(1)).setValue(new StringType("addedNestedValue")); + + System.out.println(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p)); + + assertTrue(values.get(1) instanceof IBaseExtension); + assertTrue(values.get(1) instanceof Extension); + assertEquals("http://acme.org/childExtension", ((Extension) values.get(1)).getUrl()); + assertEquals("addedNestedValue", ((StringType) ((Extension) values.get(1)).getValue()).getValueAsString()); + } + @Test public void testGetValuesWithTheCreateAndNoOverwrite() { Patient p = new Patient();