Merge pull request #776 from sjanic/master

[(master)] Added support for extensions in Meta resource
This commit is contained in:
James Agnew 2018-03-12 07:42:00 -03:00 committed by GitHub
commit ad69625c19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 662 additions and 215 deletions

View File

@ -605,4 +605,29 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
} }
public static final class ExtensionResourceMetadataKey extends ResourceMetadataKeyEnum<ExtensionDt> {
public ExtensionResourceMetadataKey(String url) {
super(url);
}
@Override
public ExtensionDt get(IResource theResource) {
Object retValObj = theResource.getResourceMetadata().get(this);
if (retValObj == null) {
return null;
} else if (retValObj instanceof ExtensionDt) {
return (ExtensionDt) retValObj;
}
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName()
+ "' in resource metadata for key " + this.name() + " - Expected "
+ ExtensionDt.class.getCanonicalName());
}
@Override
public void put(IResource theResource, ExtensionDt theObject) {
theResource.getResourceMetadata().put(this, theObject);
}
}
} }

View File

@ -918,6 +918,18 @@ public abstract class BaseParser implements IParser {
throw new DataFormatException(nextChild + " has no child of type " + theType); throw new DataFormatException(nextChild + " has no child of type " + theType);
} }
protected List<Map.Entry<ResourceMetadataKeyEnum<?>, Object>> getExtensionMetadataKeys(IResource resource) {
List<Map.Entry<ResourceMetadataKeyEnum<?>, Object>> extensionMetadataKeys = new ArrayList<Map.Entry<ResourceMetadataKeyEnum<?>, Object>>();
for (Map.Entry<ResourceMetadataKeyEnum<?>, Object> entry : resource.getResourceMetadata().entrySet()) {
if (entry.getKey() instanceof ResourceMetadataKeyEnum.ExtensionResourceMetadataKey) {
extensionMetadataKeys.add(entry);
}
}
return extensionMetadataKeys;
}
protected static <T> List<T> extractMetadataListNotNull(IResource resource, ResourceMetadataKeyEnum<List<T>> key) { protected static <T> List<T> extractMetadataListNotNull(IResource resource, ResourceMetadataKeyEnum<List<T>> key) {
List<? extends T> securityLabels = key.get(resource); List<? extends T> securityLabels = key.get(resource);
if (securityLabels == null) { if (securityLabels == null) {

View File

@ -45,10 +45,7 @@ import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.io.Writer; import java.io.Writer;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import static ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum.ID_DATATYPE; import static ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum.ID_DATATYPE;
import static ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum.PRIMITIVE_DATATYPE; import static ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum.PRIMITIVE_DATATYPE;
@ -654,8 +651,9 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
if (isBlank(versionIdPart)) { if (isBlank(versionIdPart)) {
versionIdPart = ResourceMetadataKeyEnum.VERSION.get(resource); versionIdPart = ResourceMetadataKeyEnum.VERSION.get(resource);
} }
List<Map.Entry<ResourceMetadataKeyEnum<?>, Object>> extensionMetadataKeys = getExtensionMetadataKeys(resource);
if (super.shouldEncodeResourceMeta(resource) && ElementUtil.isEmpty(versionIdPart, updated, securityLabels, tags, profiles) == false) { if (super.shouldEncodeResourceMeta(resource) && (ElementUtil.isEmpty(versionIdPart, updated, securityLabels, tags, profiles) == false) || !extensionMetadataKeys.isEmpty()) {
beginObject(theEventWriter, "meta"); beginObject(theEventWriter, "meta");
writeOptionalTagWithTextNode(theEventWriter, "versionId", versionIdPart); writeOptionalTagWithTextNode(theEventWriter, "versionId", versionIdPart);
writeOptionalTagWithTextNode(theEventWriter, "lastUpdated", updated); writeOptionalTagWithTextNode(theEventWriter, "lastUpdated", updated);
@ -695,6 +693,8 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
theEventWriter.endArray(); theEventWriter.endArray();
} }
addExtensionMetadata(theResDef, theResource, theContainedResource, theSubResource, extensionMetadataKeys, resDef, theEventWriter);
theEventWriter.endObject(); // end meta theEventWriter.endObject(); // end meta
} }
} }
@ -704,6 +704,23 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
theEventWriter.endObject(); theEventWriter.endObject();
} }
private void addExtensionMetadata(RuntimeResourceDefinition theResDef, IBaseResource theResource,
boolean theContainedResource, boolean theSubResource,
List<Map.Entry<ResourceMetadataKeyEnum<?>, Object>> extensionMetadataKeys,
RuntimeResourceDefinition resDef,
JsonLikeWriter theEventWriter) throws IOException {
if (extensionMetadataKeys.isEmpty()) {
return;
}
ExtensionDt metaResource = new ExtensionDt();
for (Map.Entry<ResourceMetadataKeyEnum<?>, Object> entry : extensionMetadataKeys) {
metaResource.addUndeclaredExtension((ExtensionDt) entry.getValue());
}
encodeCompositeElementToStreamWriter(theResDef, theResource, metaResource, theEventWriter, theContainedResource, theSubResource, new CompositeChildElement(resDef, theSubResource));
}
/** /**
* This is useful only for the two cases where extensions are encoded as direct children (e.g. not in some object * This is useful only for the two cases where extensions are encoded as direct children (e.g. not in some object
* called _name): resource extensions, and extension extensions * called _name): resource extensions, and extension extensions

View File

@ -841,6 +841,25 @@ class ParserState<T> {
} }
} }
@Override
public void enteringNewElementExtension(StartElement theElem, String theUrlAttr, boolean theIsModifier, final String baseServerUrl) {
ResourceMetadataKeyEnum.ExtensionResourceMetadataKey resourceMetadataKeyEnum = new ResourceMetadataKeyEnum.ExtensionResourceMetadataKey(theUrlAttr);
Object metadataValue = myMap.get(resourceMetadataKeyEnum);
ExtensionDt newExtension;
if (metadataValue == null) {
newExtension = new ExtensionDt(theIsModifier);
} else if (metadataValue instanceof ExtensionDt) {
newExtension = (ExtensionDt) metadataValue;
} else {
throw new IllegalStateException("Expected ExtensionDt as custom resource metadata type, got: " + metadataValue.getClass().getSimpleName());
}
newExtension.setUrl(theUrlAttr);
myMap.put(resourceMetadataKeyEnum, newExtension);
ExtensionState newState = new ExtensionState(getPreResourceState(), newExtension);
push(newState);
}
} }
private class MetaVersionElementState extends BaseState { private class MetaVersionElementState extends BaseState {

View File

@ -1,5 +1,40 @@
package ca.uhn.fhir.parser; package ca.uhn.fhir.parser;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
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.verify;
import java.io.IOException;
import java.io.StringReader;
import java.util.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.hamcrest.Matchers;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import org.mockito.internal.stubbing.answers.ThrowsException;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Sets;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.base.composite.BaseCodingDt; import ca.uhn.fhir.model.base.composite.BaseCodingDt;
@ -1886,6 +1921,113 @@ public class JsonParserDstu2Test {
//@formatter:off //@formatter:off
assertEquals("Smith", p.getName().get(0).getGiven().get(0).getValue()); assertEquals("Smith", p.getName().get(0).getGiven().get(0).getValue());
assertExtensionMetadata(p, "fhir-request-method", false, StringDt.class, "POST");
assertExtensionMetadata(p, "fhir-request-uri", false, UriDt.class, "Patient");
assertExtensionMetadata(p, "modified-fhir-request-method", true, StringDt.class, "POST");
assertExtensionMetadata(p, "modified-fhir-request-uri", true, UriDt.class, "Patient");
}
private void assertExtensionMetadata(
BaseResource resource,
String url,
boolean isModifier,
Class<?> expectedType,
String expectedValue) {
ExtensionDt extension = (ExtensionDt) resource.getResourceMetadata().get(new ResourceMetadataKeyEnum.ExtensionResourceMetadataKey(url));
assertThat(extension.getValue(), instanceOf(expectedType));
assertThat(extension.isModifier(), equalTo(isModifier));
assertThat(extension.getValueAsPrimitive().getValueAsString(), equalTo(expectedValue));
}
@Test
public void testEncodeResourceWithExtensionMetadata() throws Exception {
ProcedureRequest procedureRequest = new ProcedureRequest();
procedureRequest.setStatus(ProcedureRequestStatusEnum.ACCEPTED);
ExtensionDt timestamp = new ExtensionDt(false, "http://fhir.sjanic.com/timestamp");
timestamp.addUndeclaredExtension(false, "http://fhir.sjanic.com/timestamp/user", new ResourceReferenceDt("sjanic"));
timestamp.addUndeclaredExtension(false, "http://fhir.sjanic.com/timestamp/instance", new InstantDt("2012-01-01T13:00:00Z"));
timestamp.addUndeclaredExtension(false, "http://fhir.sjanic.com/timestamp/organization", new ResourceReferenceDt("sjanic_org"));
timestamp.addUndeclaredExtension(false, "http://fhir.sjanic.com/timestamp/role", new CodeableConceptDt().addCoding(new CodingDt("sjanic", "Doctor").setDisplay("Doctorin")));
ExtensionDt payment = new ExtensionDt(true, "http://fhir.sjanic.com/procedureRequest/requiresPatientPayment", new BooleanDt(true));
procedureRequest.getResourceMetadata().put(new ResourceMetadataKeyEnum.ExtensionResourceMetadataKey(timestamp.getUrl()), timestamp);
procedureRequest.getResourceMetadata().put(new ResourceMetadataKeyEnum.ExtensionResourceMetadataKey(payment.getUrl()), payment);
String json = ourCtx.newJsonParser().encodeResourceToString(procedureRequest);
// @formatter:off
assertThat(json, stringContainsInOrder(
"\"meta\":{"+
"\"extension\":["+
"{"+
"\"url\":\"http://fhir.sjanic.com/timestamp\","+
"\"extension\":["+
"{"+
"\"url\":\"http://fhir.sjanic.com/timestamp/user\","+
"\"valueReference\":{"+
"\"reference\":\"sjanic\""+
"}"+
"},"+
"{"+
"\"url\":\"http://fhir.sjanic.com/timestamp/instance\","+
"\"valueInstant\":\"2012-01-01T13:00:00Z\""+
"},"+
"{"+
"\"url\":\"http://fhir.sjanic.com/timestamp/organization\","+
"\"valueReference\":{"+
"\"reference\":\"sjanic_org\""+
"}"+
"},"+
"{"+
"\"url\":\"http://fhir.sjanic.com/timestamp/role\","+
"\"valueCodeableConcept\":{"+
"\"coding\":["+
"{"+
"\"system\":\"sjanic\","+
"\"code\":\"Doctor\","+
"\"display\":\"Doctorin\""+
"}"+
"]"+
"}"+
"}"+
"]"+
"}"+
"],"+
"\"modifierExtension\":["+
"{"+
"\"url\":\"http://fhir.sjanic.com/procedureRequest/requiresPatientPayment\","+
"\"valueBoolean\":true"+
"}"+
"]"+
"},"));
// @formatter:on
}
@Test
public void testParseResourceWithExtensionMetadata() 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<String> capt = ArgumentCaptor.forClass(String.class);
verify(peh, Mockito.never()).unknownElement(Mockito.isNull(IParseLocation.class), capt.capture());
assertParsedResourcesExtensionMetadata(p);
}
private void assertParsedResourcesExtensionMetadata(ProcedureRequest resource) throws Exception {
ExtensionDt payment = (ExtensionDt) resource.getResourceMetadata().get(
new ResourceMetadataKeyEnum.ExtensionResourceMetadataKey("http://fhir.sjanic.com/procedureRequest/requiresPatientPayment"));
assertThat(payment.isModifier(), equalTo(true));
assertThat(((BooleanDt)payment.getValue()).getValue(), equalTo(true));
TimestampFields timestampFields = new TimestampFields(resource);
assertThat(timestampFields.user.getReference().getIdPart(), equalTo("sjanic"));
assertThat(timestampFields.instance.getValue(), equalTo(new InstantDt("2012-01-01T13:00:00Z").getValue()));
assertThat(timestampFields.organization.getReference().getIdPart(), equalTo("sjanic_org"));
assertThat(timestampFields.role.getCodingFirstRep().getSystem(), equalTo("sjanic"));
assertThat(timestampFields.role.getCodingFirstRep().getCode(), equalTo("Doctor"));
} }
@Test @Test
@ -1989,4 +2131,189 @@ public class JsonParserDstu2Test {
public static void afterClassClearContext() { public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest(); TestUtil.clearAllStaticFieldsForUnitTest();
} }
/**
* See #537
*/
@Test
public void testEncodeNestedContained() {
Organization org04 = new Organization();
org04.setName("LEVEL04");
Organization org03 = new Organization();
org03.setName("LEVEL03");
org03.getPartOf().setResource(org04);
Organization org02 = new Organization();
org02.setName("LEVEL02");
org02.getPartOf().setResource(org03);
Organization org01 = new Organization();
org01.setName("LEVEL01");
org01.getPartOf().setResource(org02);
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(org01);
ourLog.info(encoded);
assertThat(encoded, stringContainsInOrder("LEVEL02","LEVEL03","LEVEL04","LEVEL01" ));
}
/**
* See #505
*/
@Test
public void testIncludeResourceWhenEncoding() {
Condition condition = new Condition();
condition.setDateRecorded(new DateDt("2011-01-01"));
Goal goal = new Goal();
goal.setId("Goal1");
ResourceReferenceDt resourceReferenceDt = new ResourceReferenceDt(condition);
goal.setAddresses(Collections.singletonList(resourceReferenceDt));
ca.uhn.fhir.model.dstu2.resource.Bundle bundle = new ca.uhn.fhir.model.dstu2.resource.Bundle();
Entry entry = bundle.addEntry();
entry.setResource(goal);
IParser parser = ourCtx.newJsonParser();
String resourceToString = parser.setPrettyPrint(true).encodeResourceToString(bundle);
ourLog.info(resourceToString);
assertThat(resourceToString, containsString("2011-01-01"));
bundle = parser.parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, resourceToString);
assertEquals(1, bundle.getEntry().size());
goal = (Goal) bundle.getEntry().get(0).getResource();
condition = (Condition) goal.getAddresses().get(0).getResource();
assertEquals("2011-01-01", condition.getDateRecordedElement().getValueAsString());
}
/**
* Test for the url generated based on the server config
*/
@Test
public void testGeneratedUrls() {
final IParser jsonParser = ourCtx.newJsonParser().setPrettyPrint(true);
jsonParser.setServerBaseUrl("http://myserver.com");
final CustomPatientDstu2 patient = new CustomPatientDstu2();
patient.setHomeless(new BooleanDt(true));
final String parsedPatient = jsonParser.encodeResourceToString(patient);
assertTrue(parsedPatient.contains("http://myserver.com/StructureDefinition/Patient"));
assertTrue(parsedPatient.contains("http://myserver.com/StructureDefinition/homeless"));
}
/**
* Test for the url generated based on the server config
*/
@Test
public void testCustomUrlExtension() {
final String expected = "{\"resourceType\":\"Patient\",\"extension\":[{\"url\":\"http://www.example.com/petname\",\"valueString\":\"myName\"}]}";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringDt("myName"));
final IParser jsonParser = ourCtx.newJsonParser();
jsonParser.setServerBaseUrl("http://www.example.com");
final String parsedPatient = jsonParser.encodeResourceToString(patient);
System.out.println(parsedPatient);
assertEquals(expected, parsedPatient);
// Parse with string
MyPatientWithCustomUrlExtension newPatient = jsonParser.parseResource(MyPatientWithCustomUrlExtension.class, parsedPatient);
assertEquals("myName", newPatient.getPetName().getValue());
// Parse with stream
newPatient = jsonParser.parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertEquals("myName", newPatient.getPetName().getValue());
//Check no NPE if base server not configure
newPatient = ourCtx.newJsonParser().parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertNull("myName", newPatient.getPetName().getValue());
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@Test
public void testCustomUrlExtensioninBundle() {
final String expected = "{\"resourceType\":\"Bundle\",\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"extension\":[{\"url\":\"http://www.example.com/petname\",\"valueString\":\"myName\"}]}}]}";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringDt("myName"));
final Bundle bundle = new Bundle();
final Entry entry = new Entry();
entry.setResource(patient);
bundle.addEntry(entry);
final IParser jsonParser = ourCtx.newJsonParser();
jsonParser.setServerBaseUrl("http://www.example.com");
final String parsedBundle = jsonParser.encodeResourceToString(bundle);
System.out.println(parsedBundle);
assertEquals(expected, parsedBundle);
// Parse with string
Bundle newBundle = jsonParser.parseResource(Bundle.class, parsedBundle);
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntry().size());
Patient newPatient = (Patient) newBundle.getEntry().get(0).getResource();
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
// Parse with stream
newBundle = jsonParser.parseResource(Bundle.class, new StringReader(parsedBundle));
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntry().size());
newPatient = (Patient) newBundle.getEntry().get(0).getResource();
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@Test
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
String refVal = "http://my.org/FooBar";
Patient fhirPat = new Patient();
fhirPat.addUndeclaredExtension(false, "x1").setValue(new ResourceReferenceDt(refVal));
IParser parser = ourCtx.newJsonParser();
String output = parser.encodeResourceToString(fhirPat);
System.out.println("output: " + output);
// Deserialize then check that valueReference value is still correct
fhirPat = parser.parseResource(Patient.class, output);
List<ExtensionDt> extlst = fhirPat.getUndeclaredExtensionsByUrl("x1");
Assert.assertEquals(1, extlst.size());
Assert.assertEquals(refVal, ((ResourceReferenceDt) extlst.get(0).getValue()).getReference().getValue());
}
private static final class TimestampFields {
ResourceReferenceDt user;
InstantDt instance;
ResourceReferenceDt organization;
CodeableConceptDt role;
TimestampFields(BaseResource resource) {
ExtensionDt timestamp = (ExtensionDt) resource.getResourceMetadata().get(
new ResourceMetadataKeyEnum.ExtensionResourceMetadataKey("http://fhir.sjanic.com/timestamp"));
Map<String, ExtensionDt> timestampFields = new HashMap<>(timestamp.getExtension().size());
for (ExtensionDt extensionDt : timestamp.getExtension()) {
timestampFields.put(extensionDt.getUrl(), extensionDt);
}
user = ((ResourceReferenceDt)timestampFields.get("http://fhir.sjanic.com/timestamp/user").getValue());
instance = (InstantDt) timestampFields.get("http://fhir.sjanic.com/timestamp/instance").getValue();
organization = (ResourceReferenceDt) timestampFields.get("http://fhir.sjanic.com/timestamp/organization").getValue();
role = (CodeableConceptDt) timestampFields.get("http://fhir.sjanic.com/timestamp/role").getValue();
}
}
} }

View File

@ -1,35 +1,35 @@
{ {
"id": "73b551fb-46f5-4fb8-b735-2399344e9717", "id": "73b551fb-46f5-4fb8-b735-2399344e9717",
"meta": { "meta": {
"extension": [ "extension": [
{ {
"url": "fhir-request-method", "url": "fhir-request-method",
"valueString": "POST" "valueString": "POST"
}, },
{ {
"url": "fhir-request-uri", "url": "fhir-request-uri",
"valueUri": "Patient" "valueUri": "Patient"
} }
], ],
"modifierExtension": [ "modifierExtension": [
{ {
"url": "fhir-request-method", "url": "modified-fhir-request-method",
"valueString": "POST" "valueString": "POST"
}, },
{ {
"url": "fhir-request-uri", "url": "modified-fhir-request-uri",
"valueUri": "Patient" "valueUri": "Patient"
} }
], ],
"versionId": "01e5253d-d258-494c-8d8e-f22ad6d8f19b", "versionId": "01e5253d-d258-494c-8d8e-f22ad6d8f19b",
"lastUpdated": "2016-02-20T11:01:56.155Z" "lastUpdated": "2016-02-20T11:01:56.155Z"
}, },
"name": [ "name": [
{ {
"given": [ "given": [
"Smith" "Smith"
] ]
} }
], ],
"resourceType": "Patient" "resourceType": "Patient"
} }

View File

@ -0,0 +1,47 @@
{
"resourceType": "ProcedureRequest",
"meta": {
"extension": [
{
"url": "http://fhir.sjanic.com/timestamp",
"extension": [
{
"url": "http://fhir.sjanic.com/timestamp/user",
"valueReference": {
"reference": "sjanic"
}
},
{
"url": "http://fhir.sjanic.com/timestamp/instance",
"valueInstant": "2012-01-01T13:00:00Z"
},
{
"url": "http://fhir.sjanic.com/timestamp/organization",
"valueReference": {
"reference": "sjanic_org"
}
},
{
"url": "http://fhir.sjanic.com/timestamp/role",
"valueCodeableConcept": {
"coding": [
{
"system": "sjanic",
"code": "Doctor",
"display": "Doctorin"
}
]
}
}
]
}
],
"modifierExtension": [
{
"url": "http://fhir.sjanic.com/procedureRequest/requiresPatientPayment",
"valueBoolean": true
}
]
},
"status": "accepted"
}

View File

@ -1,105 +1,105 @@
package org.hl7.fhir.dstu3.model.codesystems; package org.hl7.fhir.dstu3.model.codesystems;
/* /*
Copyright (c) 2011+, HL7, Inc. Copyright (c) 2011+, HL7, Inc.
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer. list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to * Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific endorse or promote products derived from this software without specific
prior written permission. prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. POSSIBILITY OF SUCH DAMAGE.
*/ */
// Generated on Sat, Mar 25, 2017 21:03-0400 for FHIR v3.0.0 // Generated on Sat, Mar 25, 2017 21:03-0400 for FHIR v3.0.0
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
public enum DeviceStatus { public enum DeviceStatus {
/** /**
* The Device is available for use. Note: This means for *implanted devices* the device is implanted in the patient. * The Device is available for use. Note: This means for *implanted devices* the device is implanted in the patient.
*/ */
ACTIVE, ACTIVE,
/** /**
* The Device is no longer available for use (e.g. lost, expired, damaged). Note: This means for *implanted devices* the device has been removed from the patient. * The Device is no longer available for use (e.g. lost, expired, damaged). Note: This means for *implanted devices* the device has been removed from the patient.
*/ */
INACTIVE, INACTIVE,
/** /**
* The Device was entered in error and voided. * The Device was entered in error and voided.
*/ */
ENTEREDINERROR, ENTEREDINERROR,
/** /**
* The status of the device has not been determined. * The status of the device has not been determined.
*/ */
UNKNOWN, UNKNOWN,
/** /**
* added to help the parsers * added to help the parsers
*/ */
NULL; NULL;
public static DeviceStatus fromCode(String codeString) throws FHIRException { public static DeviceStatus fromCode(String codeString) throws FHIRException {
if (codeString == null || "".equals(codeString)) if (codeString == null || "".equals(codeString))
return null; return null;
if ("active".equals(codeString)) if ("active".equals(codeString))
return ACTIVE; return ACTIVE;
if ("inactive".equals(codeString)) if ("inactive".equals(codeString))
return INACTIVE; return INACTIVE;
if ("entered-in-error".equals(codeString)) if ("entered-in-error".equals(codeString))
return ENTEREDINERROR; return ENTEREDINERROR;
if ("unknown".equals(codeString)) if ("unknown".equals(codeString))
return UNKNOWN; return UNKNOWN;
throw new FHIRException("Unknown DeviceStatus code '"+codeString+"'"); throw new FHIRException("Unknown DeviceStatus code '"+codeString+"'");
} }
public String toCode() { public String toCode() {
switch (this) { switch (this) {
case ACTIVE: return "active"; case ACTIVE: return "active";
case INACTIVE: return "inactive"; case INACTIVE: return "inactive";
case ENTEREDINERROR: return "entered-in-error"; case ENTEREDINERROR: return "entered-in-error";
case UNKNOWN: return "unknown"; case UNKNOWN: return "unknown";
default: return "?"; default: return "?";
} }
} }
public String getSystem() { public String getSystem() {
return "http://hl7.org/fhir/device-status"; return "http://hl7.org/fhir/device-status";
} }
public String getDefinition() { public String getDefinition() {
switch (this) { switch (this) {
case ACTIVE: return "The Device is available for use. Note: This means for *implanted devices* the device is implanted in the patient."; case ACTIVE: return "The Device is available for use. Note: This means for *implanted devices* the device is implanted in the patient.";
case INACTIVE: return "The Device is no longer available for use (e.g. lost, expired, damaged). Note: This means for *implanted devices* the device has been removed from the patient."; case INACTIVE: return "The Device is no longer available for use (e.g. lost, expired, damaged). Note: This means for *implanted devices* the device has been removed from the patient.";
case ENTEREDINERROR: return "The Device was entered in error and voided."; case ENTEREDINERROR: return "The Device was entered in error and voided.";
case UNKNOWN: return "The status of the device has not been determined."; case UNKNOWN: return "The status of the device has not been determined.";
default: return "?"; default: return "?";
} }
} }
public String getDisplay() { public String getDisplay() {
switch (this) { switch (this) {
case ACTIVE: return "Active"; case ACTIVE: return "Active";
case INACTIVE: return "Inactive"; case INACTIVE: return "Inactive";
case ENTEREDINERROR: return "Entered in Error"; case ENTEREDINERROR: return "Entered in Error";
case UNKNOWN: return "Unknown"; case UNKNOWN: return "Unknown";
default: return "?"; default: return "?";
} }
} }
} }

View File

@ -1,70 +1,70 @@
package org.hl7.fhir.dstu3.model.codesystems; package org.hl7.fhir.dstu3.model.codesystems;
/* /*
Copyright (c) 2011+, HL7, Inc. Copyright (c) 2011+, HL7, Inc.
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer. list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to * Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific endorse or promote products derived from this software without specific
prior written permission. prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. POSSIBILITY OF SUCH DAMAGE.
*/ */
// Generated on Sat, Mar 25, 2017 21:03-0400 for FHIR v3.0.0 // Generated on Sat, Mar 25, 2017 21:03-0400 for FHIR v3.0.0
import org.hl7.fhir.dstu3.model.EnumFactory; import org.hl7.fhir.dstu3.model.EnumFactory;
public class DeviceStatusEnumFactory implements EnumFactory<DeviceStatus> { public class DeviceStatusEnumFactory implements EnumFactory<DeviceStatus> {
public DeviceStatus fromCode(String codeString) throws IllegalArgumentException { public DeviceStatus fromCode(String codeString) throws IllegalArgumentException {
if (codeString == null || "".equals(codeString)) if (codeString == null || "".equals(codeString))
return null; return null;
if ("active".equals(codeString)) if ("active".equals(codeString))
return DeviceStatus.ACTIVE; return DeviceStatus.ACTIVE;
if ("inactive".equals(codeString)) if ("inactive".equals(codeString))
return DeviceStatus.INACTIVE; return DeviceStatus.INACTIVE;
if ("entered-in-error".equals(codeString)) if ("entered-in-error".equals(codeString))
return DeviceStatus.ENTEREDINERROR; return DeviceStatus.ENTEREDINERROR;
if ("unknown".equals(codeString)) if ("unknown".equals(codeString))
return DeviceStatus.UNKNOWN; return DeviceStatus.UNKNOWN;
throw new IllegalArgumentException("Unknown DeviceStatus code '"+codeString+"'"); throw new IllegalArgumentException("Unknown DeviceStatus code '"+codeString+"'");
} }
public String toCode(DeviceStatus code) { public String toCode(DeviceStatus code) {
if (code == DeviceStatus.ACTIVE) if (code == DeviceStatus.ACTIVE)
return "active"; return "active";
if (code == DeviceStatus.INACTIVE) if (code == DeviceStatus.INACTIVE)
return "inactive"; return "inactive";
if (code == DeviceStatus.ENTEREDINERROR) if (code == DeviceStatus.ENTEREDINERROR)
return "entered-in-error"; return "entered-in-error";
if (code == DeviceStatus.UNKNOWN) if (code == DeviceStatus.UNKNOWN)
return "unknown"; return "unknown";
return "?"; return "?";
} }
public String toSystem(DeviceStatus code) { public String toSystem(DeviceStatus code) {
return code.getSystem(); return code.getSystem();
} }
} }