diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java index 2b7a6fa8f4c..f4b3b3eca45 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java @@ -26,6 +26,7 @@ import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.api.annotation.Child; import ca.uhn.fhir.model.base.composite.BaseCodingDt; import ca.uhn.fhir.model.base.composite.BaseContainedDt; +import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.narrative.INarrativeGenerator; @@ -736,8 +737,18 @@ public class JsonParser extends BaseParser implements IJsonLikeParser { } theEventWriter.beginObject(); writeOptionalTagWithTextNode(theEventWriter, "url", extension.getUrl()); - String extensionDatatype = myContext.getRuntimeChildUndeclaredExtensionDefinition().getChildNameByDatatype(extension.getValue().getClass()); - writeOptionalTagWithTextNode(theEventWriter, extensionDatatype, extension.getValueAsPrimitive()); + RuntimeChildUndeclaredExtensionDefinition runtimeDefinitions = myContext.getRuntimeChildUndeclaredExtensionDefinition(); + + String extensionDatatype = runtimeDefinitions.getChildNameByDatatype(extension.getValue().getClass()); + if (extension.getValue() instanceof IPrimitiveDatatype) { + writeOptionalTagWithTextNode(theEventWriter, extensionDatatype, extension.getValueAsPrimitive()); + } else { + if (extension.getValue() instanceof BaseResourceReferenceDt) { + writeOptionalTagWithTextNode(theEventWriter, extensionDatatype, ((BaseResourceReferenceDt) extension.getValue()).getReference()); + } else { + throw new IllegalArgumentException("Cannot parse meta extension with type: " + extension.getValue().getClass().getSimpleName()); + } + } theEventWriter.endObject(); } theEventWriter.endArray(); diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java index fab95e21059..194e026cde3 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java @@ -489,6 +489,8 @@ class ParserState { } } else if ("url".equals(theName) && myInstance instanceof ExtensionDt) { ((ExtensionDt) myInstance).setUrl(theValue); + } else if ("value".equals(theName) && myInstance instanceof BaseResourceReferenceDt) { + ((BaseResourceReferenceDt) myInstance).setReference(new IdDt(theValue)); } else { if (myJsonMode) { myErrorHandler.incorrectJsonType(null, myElementName, ValueType.OBJECT, null, ValueType.SCALAR, ScalarType.STRING); diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/JsonParserDstu2Test.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/JsonParserDstu2Test.java index 324d44341b8..f3f9595a988 100644 --- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/JsonParserDstu2Test.java +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/JsonParserDstu2Test.java @@ -22,7 +22,9 @@ import java.io.IOException; import java.io.StringReader; import java.util.*; +import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt; import org.apache.commons.io.IOUtils; +import org.hamcrest.CoreMatchers; import org.hamcrest.Matchers; import org.hl7.fhir.instance.model.api.IIdType; import org.junit.AfterClass; @@ -1719,6 +1721,12 @@ public class JsonParserDstu2Test { addExtensionResourceMetadataKeyToResource(procedureRequest, true, "http://someurl.com/modifier", "SomeValue"); addExtensionResourceMetadataKeyToResource(procedureRequest, true, "http://someurl.com/modifier2", "SomeValue2"); + Organization organization = new Organization(); + organization.setId(new IdDt("Someorganization")); + ExtensionDt extensionDt = new ExtensionDt(false, "http://someurl3.com", new ResourceReferenceDt(organization.getId())); + procedureRequest.getResourceMetadata() + .put(new ResourceMetadataKeyEnum.ExtensionResourceMetadataKey(extensionDt.getUrl()), extensionDt); + String json = ourCtx.newJsonParser().encodeResourceToString(procedureRequest); // @formatter:off @@ -1741,6 +1749,33 @@ public class JsonParserDstu2Test { // @formatter:on } + @Test + public void testParseResourceWithReferenceExtensionMetadata() throws Exception { + String input = IOUtils.toString(getClass().getResourceAsStream("/procedure-request.json")); + IParser parser = ourCtx.newJsonParser(); + IParserErrorHandler peh = mock(IParserErrorHandler.class); + parser.setParserErrorHandler(peh); + + ProcedureRequest p = parser.parseResource(ProcedureRequest.class, input); + + ArgumentCaptor capt = ArgumentCaptor.forClass(String.class); + verify(peh, Mockito.never()).unknownElement(Mockito.isNull(IParseLocation.class), capt.capture()); + assertReferenceExtensionMetadata(p, "http://someurl3.com", false, ResourceReferenceDt.class, "dc0b549a-f852-11e6-bc64-92361f002671"); + } + + private void assertReferenceExtensionMetadata( + BaseResource resource, + String url, + boolean isModifier, + Class expectedType, + String expectedValue) { + ExtensionDt extension = (ExtensionDt) resource.getResourceMetadata().get(new ResourceMetadataKeyEnum.ExtensionResourceMetadataKey(url)); + assertThat(extension.getValue(), CoreMatchers.instanceOf(expectedType)); + assertThat(extension.isModifier(), equalTo(isModifier)); + assertThat(extension.getValue(), CoreMatchers.instanceOf(BaseResourceReferenceDt.class)); + assertThat(((BaseResourceReferenceDt)extension.getValue()).getReference().getIdPart(), equalTo(expectedValue)); + } + @Test(expected = IllegalArgumentException.class) public void testCannotEncodeSubextensionsOnMeta() { ProcedureRequest procedureRequest = new ProcedureRequest(); diff --git a/hapi-fhir-structures-dstu2/src/test/resources/procedure-request.json b/hapi-fhir-structures-dstu2/src/test/resources/procedure-request.json new file mode 100644 index 00000000000..ed498db91aa --- /dev/null +++ b/hapi-fhir-structures-dstu2/src/test/resources/procedure-request.json @@ -0,0 +1,12 @@ +{ + "resourceType": "ProcedureRequest", + "meta": { + "extension": [ + { + "url": "http://someurl3.com", + "valueReference": "Organization/dc0b549a-f852-11e6-bc64-92361f002671" + } + ] + }, + "status": "accepted" +}