Bump to latest Core version (#1841)

* Start working on bumping core

* Work on tests

* Work on tests

* Bump core definitions

* Bump R5 defs

* Tweak changelog

* Test fix
This commit is contained in:
James Agnew 2020-05-11 12:37:16 -04:00 committed by GitHub
parent 386f395e4b
commit 0c13a65871
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
94 changed files with 59118 additions and 41851 deletions

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Getting Help / Community
url: https://github.com/jamesagnew/hapi-fhir/wiki/Getting-Help
about: Please click here to learn about where to ask questions about HAPI FHIR

View File

@ -184,9 +184,7 @@ class ModelScanner {
}
}
if (blockDefinition == null
//Redundant checking && datatypeDefinition == null && resourceDefinition == null
) {
if (blockDefinition == null) {
throw new ConfigurationException("Resource class[" + theClass.getName() + "] does not contain any valid HAPI-FHIR annotations");
}
}

View File

@ -64,3 +64,9 @@
feature allows data to be segregated using a user defined partitioning strategy. This can be leveraged to take
advantags of native RDBMS partition strategies, and also to implement **multitenant servers**.
"
- item:
issue: "1841"
type: "change"
title: "**Breaking Change**:
The FHIR R5 draft definitions have been updated to the current 'Preview 2' definitions (FHIR 4.4.0).
"

View File

@ -25,6 +25,16 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
</tr>
</thead>
<tbody>
<tr>
<td>HAPI FHIR 5.0.0</td>
<td>JDK8</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-draft">1.0.2</td>
<td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.2</td>
<td class="versions-table-cell-draft">4.0.1</td>
<td class="versions-table-cell-release">4.4.0<span class="download-version-hash"><br/>56b0acf73f</span></td>
</tr>
<tr>
<td>HAPI FHIR 4.2.0</td>
<td>JDK8</td>

View File

@ -39,7 +39,7 @@ public class AbstractJaxRsConformanceProviderR4Test {
headers = new ResteasyHttpHeaders(queryParameters);
providers = new ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider>();
providers = new ConcurrentHashMap<>();
provider = createConformanceProvider(providers);
}

View File

@ -109,25 +109,25 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("non-existing-code").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult, and a code from this value set is required) (codes = http://loinc.org#non-existing-code)", oo.getIssueFirstRep().getDiagnostics());
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a code from this value set is required) (codes = http://loinc.org#non-existing-code)", oo.getIssueFirstRep().getDiagnostics());
// Valid code with no system
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem(null).setCode("CODE3").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult, and a code from this value set is required) (codes = null#CODE3)", oo.getIssueFirstRep().getDiagnostics());
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a code from this value set is required) (codes = null#CODE3)", oo.getIssueFirstRep().getDiagnostics());
// Valid code with wrong system
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://foo").setCode("CODE3").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult, and a code from this value set is required) (codes = http://foo#CODE3)", oo.getIssueFirstRep().getDiagnostics());
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a code from this value set is required) (codes = http://foo#CODE3)", oo.getIssueFirstRep().getDiagnostics());
// Code that exists but isn't in the valueset
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult, and a code from this value set is required) (codes = http://terminology.hl7.org/CodeSystem/observation-category#vital-signs)", oo.getIssueFirstRep().getDiagnostics());
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a code from this value set is required) (codes = http://terminology.hl7.org/CodeSystem/observation-category#vital-signs)", oo.getIssueFirstRep().getDiagnostics());
// Invalid code in built-in VS/CS
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
@ -192,25 +192,25 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("non-existing-code").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult, and a code from this value set is required) (codes = http://loinc.org#non-existing-code)", oo.getIssueFirstRep().getDiagnostics());
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a code from this value set is required) (codes = http://loinc.org#non-existing-code)", oo.getIssueFirstRep().getDiagnostics());
// Valid code with no system
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem(null).setCode("CODE3").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult, and a code from this value set is required) (codes = null#CODE3)", oo.getIssueFirstRep().getDiagnostics());
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a code from this value set is required) (codes = null#CODE3)", oo.getIssueFirstRep().getDiagnostics());
// Valid code with wrong system
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://foo").setCode("CODE3").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult, and a code from this value set is required) (codes = http://foo#CODE3)", oo.getIssueFirstRep().getDiagnostics());
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a code from this value set is required) (codes = http://foo#CODE3)", oo.getIssueFirstRep().getDiagnostics());
// Code that exists but isn't in the valueset
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult, and a code from this value set is required) (codes = http://terminology.hl7.org/CodeSystem/observation-category#vital-signs)", oo.getIssueFirstRep().getDiagnostics());
assertEquals(encode(oo), "None of the codes provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a code from this value set is required) (codes = http://terminology.hl7.org/CodeSystem/observation-category#vital-signs)", oo.getIssueFirstRep().getDiagnostics());
// Invalid code in built-in VS/CS
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
@ -346,7 +346,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
// It would be ok for this to produce 0 issues, or just an information message too
assertEquals(1, OperationOutcomeUtil.getIssueCount(myFhirCtx, oo));
assertEquals("None of the codes provided are in the value set http://hl7.org/fhir/ValueSet/identifier-type (http://hl7.org/fhir/ValueSet/identifier-type, and a code should come from this value set unless it has no suitable code) (codes = http://foo#bar)", OperationOutcomeUtil.getFirstIssueDetails(myFhirCtx, oo));
assertEquals("None of the codes provided are in the value set http://hl7.org/fhir/ValueSet/identifier-type (http://hl7.org/fhir/ValueSet/identifier-type), and a code should come from this value set unless it has no suitable code) (codes = http://foo#bar)", OperationOutcomeUtil.getFirstIssueDetails(myFhirCtx, oo));
}
@ -744,7 +744,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
fail("Didn't fail- response was " + encode);
} catch (PreconditionFailedException e) {
OperationOutcome oo = (OperationOutcome) e.getOperationOutcome();
assertEquals("No response found for required item with id = 'link0'", oo.getIssueFirstRep().getDiagnostics());
assertEquals("No response answer found for required item \"link0\"", oo.getIssueFirstRep().getDiagnostics());
}
}
@ -762,7 +762,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
QuestionnaireResponse qa = new QuestionnaireResponse();
qa.getText().setStatus(Narrative.NarrativeStatus.GENERATED).setDivAsString("<div>aaa</div>");
qa.setStatus(QuestionnaireResponse.QuestionnaireResponseStatus.COMPLETED);
qa.getQuestionnaireElement().setValue("Questionnaire/q");
qa.getQuestionnaireElement().setValue("http://foo/q");
qa.addItem().setLinkId("link1").addAnswer().setValue(new StringType("FOO"));
try {
@ -773,7 +773,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
fail("Didn't fail- response was " + encode);
} catch (PreconditionFailedException e) {
OperationOutcome oo = (OperationOutcome) e.getOperationOutcome();
assertEquals("No response found for required item with id = 'link0'", oo.getIssueFirstRep().getDiagnostics());
assertEquals("No response answer found for required item \"link0\"", oo.getIssueFirstRep().getDiagnostics());
}
}
@ -791,12 +791,16 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
QuestionnaireResponse qa = new QuestionnaireResponse();
qa.getText().setStatus(Narrative.NarrativeStatus.GENERATED).setDivAsString("<div>aaa</div>");
qa.setStatus(QuestionnaireResponse.QuestionnaireResponseStatus.COMPLETED);
qa.getQuestionnaireElement().setValue("Questionnaire/DOES_NOT_EXIST");
qa.getQuestionnaireElement().setValue("http://foo/Questionnaire/DOES_NOT_EXIST");
qa.addItem().setLinkId("link1").addAnswer().setValue(new StringType("FOO"));
MethodOutcome validationOutcome = myQuestionnaireResponseDao.validate(qa, null, null, null, null, null, null);
OperationOutcome oo = (OperationOutcome) validationOutcome.getOperationOutcome();
assertEquals("The questionnaire \"Questionnaire/DOES_NOT_EXIST\" could not be resolved, so no validation can be performed against the base questionnaire", oo.getIssueFirstRep().getDiagnostics());
try {
MethodOutcome validationOutcome = myQuestionnaireResponseDao.validate(qa, null, null, null, null, null, null);
OperationOutcome oo = (OperationOutcome) validationOutcome.getOperationOutcome();
assertEquals("The questionnaire \"http://foo/Questionnaire/DOES_NOT_EXIST\" could not be resolved, so no validation can be performed against the base questionnaire", oo.getIssueFirstRep().getDiagnostics());
} catch (PreconditionFailedException e) {
fail(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
}
}

View File

@ -505,13 +505,13 @@ public abstract class BaseJpaR5Test extends BaseJpaTest {
target = element.addTarget();
target.setCode("45678");
target.setDisplay("Target Code 45678");
target.setRelationship(Enumerations.ConceptMapRelationship.BROADER);
target.setRelationship(Enumerations.ConceptMapRelationship.SOURCEISBROADERTHANTARGET);
// Add a duplicate
target = element.addTarget();
target.setCode("45678");
target.setDisplay("Target Code 45678");
target.setRelationship(Enumerations.ConceptMapRelationship.BROADER);
target.setRelationship(Enumerations.ConceptMapRelationship.SOURCEISBROADERTHANTARGET);
group = conceptMap.addGroup();
group.setSource(CS_URL);
@ -531,7 +531,7 @@ public abstract class BaseJpaR5Test extends BaseJpaTest {
target = element.addTarget();
target.setCode("67890");
target.setDisplay("Target Code 67890");
target.setRelationship(Enumerations.ConceptMapRelationship.BROADER);
target.setRelationship(Enumerations.ConceptMapRelationship.SOURCEISBROADERTHANTARGET);
group = conceptMap.addGroup();
group.setSource(CS_URL_4);
@ -546,7 +546,7 @@ public abstract class BaseJpaR5Test extends BaseJpaTest {
target = element.addTarget();
target.setCode("34567");
target.setDisplay("Target Code 34567");
target.setRelationship(Enumerations.ConceptMapRelationship.NARROWER);
target.setRelationship(Enumerations.ConceptMapRelationship.SOURCEISNARROWERTHANTARGET);
return conceptMap;
}

View File

@ -30,7 +30,7 @@ import org.hl7.fhir.r5.model.Enumerations;
import org.hl7.fhir.r5.model.IdType;
import org.hl7.fhir.r5.model.Observation;
import org.hl7.fhir.r5.model.Subscription;
import org.hl7.fhir.r5.model.Topic;
import org.hl7.fhir.r5.model.SubscriptionTopic;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@ -133,20 +133,19 @@ public abstract class BaseSubscriptionsR5Test extends BaseResourceProviderR5Test
}
protected Subscription newSubscription(String theCriteria, String thePayload) {
Topic topic = new Topic();
SubscriptionTopic topic = new SubscriptionTopic();
topic.getResourceTrigger().getQueryCriteria().setCurrent(theCriteria);
Subscription subscription = new Subscription();
subscription.getTopic().setResource(topic);
subscription.setReason("Monitor new neonatal function (note, age will be determined by the monitor)");
subscription.setStatus(Subscription.SubscriptionStatus.REQUESTED);
subscription.setStatus(Enumerations.SubscriptionState.REQUESTED);
Subscription.SubscriptionChannelComponent channel = subscription.getChannel();
channel.getType().addCoding()
subscription.getChannelType()
.setSystem(CanonicalSubscriptionChannelType.RESTHOOK.getSystem())
.setCode(CanonicalSubscriptionChannelType.RESTHOOK.toCode());
channel.getPayload().setContentType(thePayload);
channel.setEndpoint(ourListenerServerBase);
subscription.setContentType(thePayload);
subscription.setEndpoint(ourListenerServerBase);
return subscription;
}

View File

@ -299,7 +299,6 @@ public class RestHookTestR5Test extends BaseSubscriptionsR5Test {
assertEquals(observation1.getIdElement().getVersionIdPart(), idElement.getVersionIdPart());
subscription1
.getChannel()
.addExtension(JpaConstants.EXT_SUBSCRIPTION_RESTHOOK_STRIP_VERSION_IDS, new BooleanType("true"));
ourLog.info("** About to update subscription");
@ -376,7 +375,6 @@ public class RestHookTestR5Test extends BaseSubscriptionsR5Test {
Subscription subscription = newSubscription(criteria1, payload);
subscription
.getChannel()
.addExtension(JpaConstants.EXT_SUBSCRIPTION_RESTHOOK_DELIVER_LATEST_VERSION, new BooleanType("true"));
ourClient.create().resource(subscription).execute();
@ -439,7 +437,7 @@ public class RestHookTestR5Test extends BaseSubscriptionsR5Test {
Subscription subscriptionTemp = ourClient.read(Subscription.class, subscription2.getId());
Assert.assertNotNull(subscriptionTemp);
Topic topic = (Topic) subscriptionTemp.getTopic().getResource();
SubscriptionTopic topic = (SubscriptionTopic) subscriptionTemp.getTopic().getResource();
topic.getResourceTrigger().getQueryCriteria().setCurrent(criteria1);
ourClient.update().resource(subscriptionTemp).withId(subscriptionTemp.getIdElement()).execute();
@ -521,7 +519,7 @@ public class RestHookTestR5Test extends BaseSubscriptionsR5Test {
Subscription subscriptionTemp = ourClient.read(Subscription.class, subscription2.getId());
Assert.assertNotNull(subscriptionTemp);
Topic topic = (Topic) subscriptionTemp.getTopic().getResource();
SubscriptionTopic topic = (SubscriptionTopic) subscriptionTemp.getTopic().getResource();
topic.getResourceTrigger().getQueryCriteria().setCurrent(criteria1);
ourClient.update().resource(subscriptionTemp).withId(subscriptionTemp.getIdElement()).execute();
@ -599,7 +597,7 @@ public class RestHookTestR5Test extends BaseSubscriptionsR5Test {
Subscription subscriptionTemp = ourClient.read(Subscription.class, subscription2.getId());
Assert.assertNotNull(subscriptionTemp);
Topic topic = (Topic) subscriptionTemp.getTopic().getResource();
SubscriptionTopic topic = (SubscriptionTopic) subscriptionTemp.getTopic().getResource();
topic.getResourceTrigger().getQueryCriteria().setCurrent(criteria1);
ourClient.update().resource(subscriptionTemp).withId(subscriptionTemp.getIdElement()).execute();
waitForQueueToDrain();
@ -727,7 +725,7 @@ public class RestHookTestR5Test extends BaseSubscriptionsR5Test {
Assert.assertNotNull(subscriptionTemp);
String criteriaGood = "Observation?code=SNOMED-CT|" + code + "&_format=xml";
Topic topic = (Topic) subscriptionTemp.getTopic().getResource();
SubscriptionTopic topic = (SubscriptionTopic) subscriptionTemp.getTopic().getResource();
topic.getResourceTrigger().getQueryCriteria().setCurrent(criteriaGood);
ourLog.info("** About to update subscription");
@ -797,9 +795,9 @@ public class RestHookTestR5Test extends BaseSubscriptionsR5Test {
Subscription subscription = createSubscription(criteria1, payload);
waitForActivatedSubscriptionCount(1);
subscription.getChannel().addHeader("X-Foo: FOO");
subscription.getChannel().addHeader("X-Bar: BAR");
subscription.setStatus(Subscription.SubscriptionStatus.REQUESTED);
subscription.addHeader("X-Foo: FOO");
subscription.addHeader("X-Bar: BAR");
subscription.setStatus(Enumerations.SubscriptionState.REQUESTED);
ourClient.update().resource(subscription).execute();
waitForQueueToDrain();
@ -832,7 +830,7 @@ public class RestHookTestR5Test extends BaseSubscriptionsR5Test {
waitForSize(1, ourUpdatedObservations);
// Disable
subscription.setStatus(Subscription.SubscriptionStatus.OFF);
subscription.setStatus(Enumerations.SubscriptionState.OFF);
ourClient.update().resource(subscription).execute();
waitForQueueToDrain();

View File

@ -18,129 +18,126 @@
"author": {
"reference": "Practitioner/PRLoginID"
},
"item": [{
"linkId": "Binder Optimization Assessment Test",
"text": "Binder Optimization Assessment Test",
"item": [{
"linkId": "BINDER OPTIMIZATION ASSESSMENT TEST",
"text": "BINDER OPTIMIZATION ASSESSMENT TEST",
"item": [{
"linkId": "Home Medications",
"text": "Home Medications",
"item": [{
"linkId": "BO_ConsPharm",
"text": "Pharmacist consult",
"answer": [{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "Yes",
"display": "Yes"
}
}]
},
{
"linkId": "BO_ConsTxt",
"text": "Pharmacy consult notes",
"answer": [{
"valueString": "Pharmacy consult notes comes here"
}]
},
{
"linkId": "BO_RecNotCons",
"text": "Recommendation not consistent with binder optimization guidelines",
"answer": [{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "Yes",
"display": "Yes"
}
}],
"item": [{
"linkId": "BO_NotConsDrop",
"text": "Recommendation not consistent with binder optimization guidelines",
"answer": [{
"valueString": "Chewing difficulty,Other"
}],
"item": [{
"linkId": "BO_OtherTxt",
"text": "Other",
"answer": [{
"valueString": "Other difficulty"
}]
}]
},
{
"linkId": "BO_Recommend",
"text": "What is your recommendation",
"answer": [{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCBinderRecommendation",
"code": "Renvela",
"display": "Renvela"
}
}]
}
]
}
]
},
"item": [
{
"linkId": "Binder Optimization Assessment Test",
"text": "Binder Optimization Assessment Test",
"item": [
{
"linkId": "Plan",
"text": "Plan",
"item": [{
"linkId": "BO_CommPres",
"text": "Binder recommendation communicated to prescriber",
"answer": [{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
}
}]
},
"linkId": "BINDER OPTIMIZATION ASSESSMENT TEST",
"text": "BINDER OPTIMIZATION ASSESSMENT TEST",
"item": [
{
"linkId": "BO_ComAssmt",
"text": "Referred to MSW for expressed co-pay concerns",
"answer": [{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
"linkId": "Home Medications",
"text": "Home Medications",
"item": [
{
"linkId": "BO_ConsPharm",
"text": "Pharmacist consult",
"answer": [
{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "Yes",
"display": "Yes"
}
}
]
},
{
"linkId": "BO_ConsTxt",
"text": "Pharmacy consult notes",
"answer": [
{
"valueString": "Pharmacy consult notes comes here"
}
]
},
{
"linkId": "BO_RecNotCons",
"text": "Recommendation not consistent with binder optimization guidelines",
"answer": [
{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "Yes",
"display": "Yes"
}
}
]
}
}]
]
},
{
"linkId": "BO_RefMSW",
"text": "Referred to MSW for potential medication adherence issues",
"answer": [{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
"linkId": "Plan",
"text": "Plan",
"item": [
{
"linkId": "BO_CommPres",
"text": "Binder recommendation communicated to prescriber",
"answer": [
{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
}
}
]
},
{
"linkId": "BO_ComAssmt",
"text": "Referred to MSW for expressed co-pay concerns",
"answer": [
{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
}
}
]
},
{
"linkId": "BO_RefMSW",
"text": "Referred to MSW for potential medication adherence issues",
"answer": [
{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
}
}
]
},
{
"linkId": "BO_AdjHyp",
"text": "Continue adjustments per CMAB Hyperphosphatemia Algorithm",
"answer": [
{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
}
}
]
},
{
"linkId": "BO_AdjTxt",
"text": "Adjustment Text",
"answer": [
{
"valueString": "Adjustment Text comes here"
}
]
}
}]
},
{
"linkId": "BO_AdjHyp",
"text": "Continue adjustments per CMAB Hyperphosphatemia Algorithm",
"answer": [{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
}
}]
},
{
"linkId": "BO_AdjTxt",
"text": "Adjustment Text",
"answer": [{
"valueString": "Adjustment Text comes here"
}]
]
}
]
}
]
}]
}]
}
]
}

View File

@ -23,20 +23,20 @@ package ca.uhn.fhir.jpa.subscription.match.registry;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.subscription.match.matcher.matching.SubscriptionMatchingStrategy;
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscriptionChannelType;
import ca.uhn.fhir.jpa.subscription.match.matcher.matching.SubscriptionMatchingStrategy;
import ca.uhn.fhir.model.dstu2.resource.Subscription;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
import org.hl7.fhir.instance.model.api.IBaseMetaType;
import org.hl7.fhir.instance.model.api.IBaseReference;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Extension;
import org.hl7.fhir.r5.model.Coding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -179,7 +179,6 @@ public class SubscriptionCanonicalizer {
case R5: {
org.hl7.fhir.r5.model.Subscription subscription = (org.hl7.fhir.r5.model.Subscription) theSubscription;
return subscription
.getChannel()
.getExtension()
.stream()
.collect(Collectors.groupingBy(t -> t.getUrl(), mapping(t -> t.getValueAsPrimitive().getValueAsString(), toList())));
@ -251,24 +250,24 @@ public class SubscriptionCanonicalizer {
org.hl7.fhir.r5.model.Subscription subscription = (org.hl7.fhir.r5.model.Subscription) theSubscription;
CanonicalSubscription retVal = new CanonicalSubscription();
org.hl7.fhir.r5.model.Subscription.SubscriptionStatus status = subscription.getStatus();
org.hl7.fhir.r5.model.Enumerations.SubscriptionState status = subscription.getStatus();
if (status != null) {
retVal.setStatus(org.hl7.fhir.r4.model.Subscription.SubscriptionStatus.fromCode(status.toCode()));
}
retVal.setChannelType(getChannelType(subscription));
retVal.setCriteriaString(getCriteria(theSubscription));
retVal.setEndpointUrl(subscription.getChannel().getEndpoint());
retVal.setHeaders(subscription.getChannel().getHeader());
retVal.setEndpointUrl(subscription.getEndpoint());
retVal.setHeaders(subscription.getHeader());
retVal.setChannelExtensions(extractExtension(subscription));
retVal.setIdElement(subscription.getIdElement());
retVal.setPayloadString(subscription.getChannel().getPayload().getContentType());
retVal.setPayloadString(subscription.getContentType());
if (retVal.getChannelType() == CanonicalSubscriptionChannelType.EMAIL) {
String from;
String subjectTemplate;
try {
from = subscription.getChannel().getExtensionString(JpaConstants.EXT_SUBSCRIPTION_EMAIL_FROM);
subjectTemplate = subscription.getChannel().getExtensionString(JpaConstants.EXT_SUBSCRIPTION_SUBJECT_TEMPLATE);
from = getExtensionString(subscription, JpaConstants.EXT_SUBSCRIPTION_EMAIL_FROM);
subjectTemplate = getExtensionString(subscription, JpaConstants.EXT_SUBSCRIPTION_SUBJECT_TEMPLATE);
} catch (FHIRException theE) {
throw new ConfigurationException("Failed to extract subscription extension(s): " + theE.getMessage(), theE);
}
@ -280,8 +279,8 @@ public class SubscriptionCanonicalizer {
String stripVersionIds;
String deliverLatestVersion;
try {
stripVersionIds = subscription.getChannel().getExtensionString(JpaConstants.EXT_SUBSCRIPTION_RESTHOOK_STRIP_VERSION_IDS);
deliverLatestVersion = subscription.getChannel().getExtensionString(JpaConstants.EXT_SUBSCRIPTION_RESTHOOK_DELIVER_LATEST_VERSION);
stripVersionIds = getExtensionString(subscription, JpaConstants.EXT_SUBSCRIPTION_RESTHOOK_STRIP_VERSION_IDS);
deliverLatestVersion = getExtensionString(subscription, JpaConstants.EXT_SUBSCRIPTION_RESTHOOK_DELIVER_LATEST_VERSION);
} catch (FHIRException theE) {
throw new ConfigurationException("Failed to extract subscription extension(s): " + theE.getMessage(), theE);
}
@ -300,6 +299,18 @@ public class SubscriptionCanonicalizer {
return retVal;
}
private String getExtensionString(IBaseHasExtensions theBase, String theUrl) {
return theBase
.getExtension()
.stream()
.filter(t -> theUrl.equals(t.getUrl()))
.filter(t -> t.getValue() instanceof IPrimitiveType)
.map(t -> (IPrimitiveType<?>) t.getValue())
.map(t -> t.getValueAsString())
.findFirst()
.orElse(null);
}
@SuppressWarnings("EnumSwitchStatementWhichMissesCases")
public CanonicalSubscriptionChannelType getChannelType(IBaseResource theSubscription) {
CanonicalSubscriptionChannelType retVal = null;
@ -327,11 +338,10 @@ public class SubscriptionCanonicalizer {
break;
}
case R5: {
for (Coding nextTypeCode : ((org.hl7.fhir.r5.model.Subscription) theSubscription).getChannel().getType().getCoding()) {
CanonicalSubscriptionChannelType code = CanonicalSubscriptionChannelType.fromCode(nextTypeCode.getSystem(), nextTypeCode.getCode());
if (code != null) {
retVal = code;
}
org.hl7.fhir.r5.model.Coding nextTypeCode = ((org.hl7.fhir.r5.model.Subscription) theSubscription).getChannelType();
CanonicalSubscriptionChannelType code = CanonicalSubscriptionChannelType.fromCode(nextTypeCode.getSystem(), nextTypeCode.getCode());
if (code != null) {
retVal = code;
}
break;
}
@ -355,7 +365,7 @@ public class SubscriptionCanonicalizer {
retVal = ((org.hl7.fhir.r4.model.Subscription) theSubscription).getCriteria();
break;
case R5:
org.hl7.fhir.r5.model.Topic topic = (org.hl7.fhir.r5.model.Topic) ((org.hl7.fhir.r5.model.Subscription) theSubscription).getTopic().getResource();
org.hl7.fhir.r5.model.SubscriptionTopic topic = (org.hl7.fhir.r5.model.SubscriptionTopic) ((org.hl7.fhir.r5.model.Subscription) theSubscription).getTopic().getResource();
Validate.notNull(topic);
retVal = topic.getResourceTrigger().getQueryCriteria().getCurrent();
break;
@ -372,8 +382,8 @@ public class SubscriptionCanonicalizer {
meta
.getTag()
.stream()
.filter(t->JpaConstants.EXT_SUBSCRIPTION_MATCHING_STRATEGY.equals(t.getSystem()))
.forEach(t->{
.filter(t -> JpaConstants.EXT_SUBSCRIPTION_MATCHING_STRATEGY.equals(t.getSystem()))
.forEach(t -> {
t.setCode(null);
t.setSystem(null);
t.setDisplay(null);

View File

@ -256,7 +256,7 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
if (methodBinding.getQueryName() != null) {
String queryName = bindings.getNamedSearchMethodBindingToName().get(methodBinding);
if (operationNames.add(queryName)) {
rest.addOperation().setName(methodBinding.getQueryName()).setDefinition(("OperationDefinition/" + queryName));
rest.addOperation().setName(methodBinding.getQueryName()).setDefinition((getOperationDefinitionPrefix(theRequestDetails) + "OperationDefinition/" + queryName));
}
} else {
handleNamelessSearchMethodBinding(resource, def, includes, (SearchMethodBinding) nextMethodBinding, theRequestDetails);
@ -266,7 +266,7 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
String opName = bindings.getOperationBindingToName().get(methodBinding);
if (operationNames.add(opName)) {
// Only add each operation (by name) once
rest.addOperation().setName(methodBinding.getName().substring(1)).setDefinition(("OperationDefinition/" + opName));
rest.addOperation().setName(methodBinding.getName().substring(1)).setDefinition((getOperationDefinitionPrefix(theRequestDetails) + "OperationDefinition/" + opName));
}
}
@ -301,7 +301,7 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
String opName = bindings.getOperationBindingToName().get(methodBinding);
if (operationNames.add(opName)) {
ourLog.debug("Found bound operation: {}", opName);
rest.addOperation().setName(methodBinding.getName().substring(1)).setDefinition(("OperationDefinition/" + opName));
rest.addOperation().setName(methodBinding.getName().substring(1)).setDefinition((getOperationDefinitionPrefix(theRequestDetails) + "OperationDefinition/" + opName));
}
}
}
@ -311,6 +311,13 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
return retVal;
}
protected String getOperationDefinitionPrefix(RequestDetails theRequestDetails) {
if (theRequestDetails == null) {
return "";
}
return theRequestDetails.getServerBaseForRequest() + "/";
}
private void handleNamelessSearchMethodBinding(CapabilityStatementRestResourceComponent resource, RuntimeResourceDefinition def, TreeSet<String> includes,
SearchMethodBinding searchMethodBinding, RequestDetails theRequestDetails) {
includes.addAll(searchMethodBinding.getIncludes());

View File

@ -108,6 +108,7 @@ public class ServerCapabilityStatementProviderR4Test {
private RequestDetails createRequestDetails(RestfulServer theServer) {
ServletRequestDetails retVal = new ServletRequestDetails(null);
retVal.setServer(theServer);
retVal.setFhirServerBase("http://localhost/baseR4");
return retVal;
}
@ -116,6 +117,7 @@ public class ServerCapabilityStatementProviderR4Test {
RestfulServer rs = new RestfulServer(ourCtx);
rs.setProviders(new ProviderWithExtendedOperationReturningBundle());
rs.setServerAddressStrategy(new HardcodedServerAddressStrategy("http://localhost/baseR4"));
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
rs.setServerConformanceProvider(sc);
@ -240,6 +242,7 @@ public class ServerCapabilityStatementProviderR4Test {
public void testOperationAcrossMultipleTypes() throws Exception {
RestfulServer rs = new RestfulServer(ourCtx);
rs.setProviders(new MultiTypePatientProvider(), new MultiTypeEncounterProvider());
rs.setServerAddressStrategy(new HardcodedServerAddressStrategy("http://localhost/baseR4"));
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
rs.setServerConformanceProvider(sc);
@ -624,6 +627,7 @@ public class ServerCapabilityStatementProviderR4Test {
public void testSystemLevelNamedQueryWithParameters() throws Exception {
RestfulServer rs = new RestfulServer(ourCtx);
rs.setProviders(new NamedQueryPlainProvider());
rs.setServerAddressStrategy(new HardcodedServerAddressStrategy("http://localhost/baseR4"));
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
rs.setServerConformanceProvider(sc);
@ -668,6 +672,7 @@ public class ServerCapabilityStatementProviderR4Test {
public void testResourceLevelNamedQueryWithParameters() throws Exception {
RestfulServer rs = new RestfulServer(ourCtx);
rs.setProviders(new NamedQueryResourceProvider());
rs.setServerAddressStrategy(new HardcodedServerAddressStrategy("http://localhost/baseR4"));
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
rs.setServerConformanceProvider(sc);
@ -711,6 +716,7 @@ public class ServerCapabilityStatementProviderR4Test {
public void testExtendedOperationAtTypeLevel() throws Exception {
RestfulServer rs = new RestfulServer(ourCtx);
rs.setProviders(new TypeLevelOperationProvider());
rs.setServerAddressStrategy(new HardcodedServerAddressStrategy("http://localhost/baseR4"));
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
rs.setServerConformanceProvider(sc);

View File

@ -15,17 +15,30 @@ import org.hl7.fhir.exceptions.TerminologyServiceException;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.formats.IParser;
import org.hl7.fhir.r5.formats.ParserType;
import org.hl7.fhir.r5.model.*;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.ConceptMap;
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.ResourceType;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.StructureMap;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r5.terminologies.ValueSetExpander;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.utilities.TranslationServices;
import org.hl7.fhir.utilities.cache.NpmPackage;
import org.hl7.fhir.utilities.i18n.I18nBase;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationOptions;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -330,7 +343,7 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
@Override
public <T extends org.hl7.fhir.r5.model.Resource> T fetchResource(Class<T> theClass, String theUri) {
if (myValidationSupport == null) {
if (myValidationSupport == null || theUri == null) {
return null;
} else {
@SuppressWarnings("unchecked")
@ -348,6 +361,11 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
return retVal;
}
@Override
public <T extends Resource> T fetchResource(Class<T> class_, String uri, CanonicalResource canonicalForSource) {
throw new UnsupportedOperationException();
}
@Override
public org.hl7.fhir.r5.model.Resource fetchResourceById(String theType, String theUri) {
throw new UnsupportedOperationException();
@ -363,6 +381,16 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
throw new UnsupportedOperationException();
}
@Override
public void cacheResourceFromPackage(Resource res, PackageVersion packageDetails) throws FHIRException {
throw new UnsupportedOperationException();
}
@Override
public void cachePackage(PackageVersion packageDetails, List<PackageVersion> dependencies) {
throw new UnsupportedOperationException();
}
@Override
public Set<String> getResourceNamesAsSet() {
return myCtx.getResourceNames();
@ -380,7 +408,17 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
@Override
public Map<String, byte[]> getBinaries() {
return null;
throw new UnsupportedOperationException();
}
@Override
public void loadFromPackage(NpmPackage pi, IContextResourceLoader loader, String[] types) throws FileNotFoundException, IOException, FHIRException {
throw new UnsupportedOperationException();
}
@Override
public boolean hasPackage(String id, String ver) {
throw new UnsupportedOperationException();
}
public static ConceptValidationOptions convertConceptValidationOptions(ValidationOptions theOptions) {

View File

@ -90,293 +90,298 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
*/
public class ServerCapabilityStatementProvider extends BaseServerCapabilityStatementProvider implements IServerConformanceProvider<CapabilityStatement> {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerCapabilityStatementProvider.class);
private String myPublisher = "Not provided";
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerCapabilityStatementProvider.class);
private String myPublisher = "Not provided";
/**
* No-arg constructor and setter so that the ServerConformanceProvider can be Spring-wired with the RestfulService avoiding the potential reference cycle that would happen.
*/
public ServerCapabilityStatementProvider() {
super();
}
/**
* No-arg constructor and setter so that the ServerConformanceProvider can be Spring-wired with the RestfulService avoiding the potential reference cycle that would happen.
*/
public ServerCapabilityStatementProvider() {
super();
}
/**
* Constructor - This is intended only for JAX-RS server
*/
public ServerCapabilityStatementProvider(RestfulServerConfiguration theServerConfiguration) {
super(theServerConfiguration);
}
/**
* Constructor - This is intended only for JAX-RS server
*/
public ServerCapabilityStatementProvider(RestfulServerConfiguration theServerConfiguration) {
super(theServerConfiguration);
}
private void checkBindingForSystemOps(CapabilityStatementRestComponent rest, Set<SystemRestfulInteraction> systemOps, BaseMethodBinding<?> nextMethodBinding) {
if (nextMethodBinding.getRestOperationType() != null) {
String sysOpCode = nextMethodBinding.getRestOperationType().getCode();
if (sysOpCode != null) {
SystemRestfulInteraction sysOp;
try {
sysOp = SystemRestfulInteraction.fromCode(sysOpCode);
} catch (FHIRException e) {
return;
}
if (sysOp == null) {
return;
}
if (systemOps.contains(sysOp) == false) {
systemOps.add(sysOp);
rest.addInteraction().setCode(sysOp);
}
}
}
}
private void checkBindingForSystemOps(CapabilityStatementRestComponent rest, Set<SystemRestfulInteraction> systemOps, BaseMethodBinding<?> nextMethodBinding) {
if (nextMethodBinding.getRestOperationType() != null) {
String sysOpCode = nextMethodBinding.getRestOperationType().getCode();
if (sysOpCode != null) {
SystemRestfulInteraction sysOp;
try {
sysOp = SystemRestfulInteraction.fromCode(sysOpCode);
} catch (FHIRException e) {
return;
}
if (sysOp == null) {
return;
}
if (systemOps.contains(sysOp) == false) {
systemOps.add(sysOp);
rest.addInteraction().setCode(sysOp);
}
}
}
}
private DateTimeType conformanceDate(RequestDetails theRequestDetails) {
IPrimitiveType<Date> buildDate = getServerConfiguration(theRequestDetails).getConformanceDate();
if (buildDate != null && buildDate.getValue() != null) {
try {
return new DateTimeType(buildDate.getValueAsString());
} catch (DataFormatException e) {
// fall through
}
}
return DateTimeType.now();
}
private DateTimeType conformanceDate(RequestDetails theRequestDetails) {
IPrimitiveType<Date> buildDate = getServerConfiguration(theRequestDetails).getConformanceDate();
if (buildDate != null && buildDate.getValue() != null) {
try {
return new DateTimeType(buildDate.getValueAsString());
} catch (DataFormatException e) {
// fall through
}
}
return DateTimeType.now();
}
/**
* Gets the value of the "publisher" that will be placed in the generated conformance statement. As this is a mandatory element, the value should not be null (although this is not enforced). The
* value defaults to "Not provided" but may be set to null, which will cause this element to be omitted.
*/
public String getPublisher() {
return myPublisher;
}
/**
* Gets the value of the "publisher" that will be placed in the generated conformance statement. As this is a mandatory element, the value should not be null (although this is not enforced). The
* value defaults to "Not provided" but may be set to null, which will cause this element to be omitted.
*/
public String getPublisher() {
return myPublisher;
}
/**
* Sets the value of the "publisher" that will be placed in the generated conformance statement. As this is a mandatory element, the value should not be null (although this is not enforced). The
* value defaults to "Not provided" but may be set to null, which will cause this element to be omitted.
*/
public void setPublisher(String thePublisher) {
myPublisher = thePublisher;
}
/**
* Sets the value of the "publisher" that will be placed in the generated conformance statement. As this is a mandatory element, the value should not be null (although this is not enforced). The
* value defaults to "Not provided" but may be set to null, which will cause this element to be omitted.
*/
public void setPublisher(String thePublisher) {
myPublisher = thePublisher;
}
@SuppressWarnings("EnumSwitchStatementWhichMissesCases")
@Override
@Metadata
public CapabilityStatement getServerConformance(HttpServletRequest theRequest, RequestDetails theRequestDetails) {
@SuppressWarnings("EnumSwitchStatementWhichMissesCases")
@Override
@Metadata
public CapabilityStatement getServerConformance(HttpServletRequest theRequest, RequestDetails theRequestDetails) {
RestfulServerConfiguration configuration = getServerConfiguration(theRequestDetails);
Bindings bindings = configuration.provideBindings();
RestfulServerConfiguration configuration = getServerConfiguration(theRequestDetails);
Bindings bindings = configuration.provideBindings();
CapabilityStatement retVal = new CapabilityStatement();
CapabilityStatement retVal = new CapabilityStatement();
retVal.setPublisher(myPublisher);
retVal.setDateElement(conformanceDate(theRequestDetails));
retVal.setFhirVersion(Enumerations.FHIRVersion.fromCode(FhirVersionEnum.R5.getFhirVersionString()));
retVal.setPublisher(myPublisher);
retVal.setDateElement(conformanceDate(theRequestDetails));
retVal.setFhirVersion(Enumerations.FHIRVersion.fromCode(FhirVersionEnum.R5.getFhirVersionString()));
ServletContext servletContext = (ServletContext) (theRequest == null ? null : theRequest.getAttribute(RestfulServer.SERVLET_CONTEXT_ATTRIBUTE));
String serverBase = configuration.getServerAddressStrategy().determineServerBase(servletContext, theRequest);
retVal
.getImplementation()
.setUrl(serverBase)
.setDescription(configuration.getImplementationDescription());
ServletContext servletContext = (ServletContext) (theRequest == null ? null : theRequest.getAttribute(RestfulServer.SERVLET_CONTEXT_ATTRIBUTE));
String serverBase = configuration.getServerAddressStrategy().determineServerBase(servletContext, theRequest);
retVal
.getImplementation()
.setUrl(serverBase)
.setDescription(configuration.getImplementationDescription());
retVal.setKind(Enumerations.CapabilityStatementKind.INSTANCE);
retVal.getSoftware().setName(configuration.getServerName());
retVal.getSoftware().setVersion(configuration.getServerVersion());
retVal.addFormat(Constants.CT_FHIR_XML_NEW);
retVal.addFormat(Constants.CT_FHIR_JSON_NEW);
retVal.setStatus(PublicationStatus.ACTIVE);
retVal.setKind(Enumerations.CapabilityStatementKind.INSTANCE);
retVal.getSoftware().setName(configuration.getServerName());
retVal.getSoftware().setVersion(configuration.getServerVersion());
retVal.addFormat(Constants.CT_FHIR_XML_NEW);
retVal.addFormat(Constants.CT_FHIR_JSON_NEW);
retVal.setStatus(PublicationStatus.ACTIVE);
CapabilityStatementRestComponent rest = retVal.addRest();
rest.setMode(Enumerations.RestfulCapabilityMode.SERVER);
CapabilityStatementRestComponent rest = retVal.addRest();
rest.setMode(Enumerations.RestfulCapabilityMode.SERVER);
Set<SystemRestfulInteraction> systemOps = new HashSet<>();
Set<String> operationNames = new HashSet<>();
Set<SystemRestfulInteraction> systemOps = new HashSet<>();
Set<String> operationNames = new HashSet<>();
Map<String, List<BaseMethodBinding<?>>> resourceToMethods = configuration.collectMethodBindings();
Map<String, Class<? extends IBaseResource>> resourceNameToSharedSupertype = configuration.getNameToSharedSupertype();
for (Entry<String, List<BaseMethodBinding<?>>> nextEntry : resourceToMethods.entrySet()) {
Map<String, List<BaseMethodBinding<?>>> resourceToMethods = configuration.collectMethodBindings();
Map<String, Class<? extends IBaseResource>> resourceNameToSharedSupertype = configuration.getNameToSharedSupertype();
for (Entry<String, List<BaseMethodBinding<?>>> nextEntry : resourceToMethods.entrySet()) {
if (nextEntry.getKey().isEmpty() == false) {
Set<TypeRestfulInteraction> resourceOps = new HashSet<>();
CapabilityStatementRestResourceComponent resource = rest.addResource();
String resourceName = nextEntry.getKey();
RuntimeResourceDefinition def;
FhirContext context = configuration.getFhirContext();
if (resourceNameToSharedSupertype.containsKey(resourceName)) {
def = context.getResourceDefinition(resourceNameToSharedSupertype.get(resourceName));
} else {
def = context.getResourceDefinition(resourceName);
}
resource.getTypeElement().setValue(def.getName());
resource.getProfileElement().setValue((def.getResourceProfile(serverBase)));
if (nextEntry.getKey().isEmpty() == false) {
Set<TypeRestfulInteraction> resourceOps = new HashSet<>();
CapabilityStatementRestResourceComponent resource = rest.addResource();
String resourceName = nextEntry.getKey();
RuntimeResourceDefinition def;
FhirContext context = configuration.getFhirContext();
if (resourceNameToSharedSupertype.containsKey(resourceName)) {
def = context.getResourceDefinition(resourceNameToSharedSupertype.get(resourceName));
} else {
def = context.getResourceDefinition(resourceName);
}
resource.getTypeElement().setValue(def.getName());
resource.getProfileElement().setValue((def.getResourceProfile(serverBase)));
TreeSet<String> includes = new TreeSet<>();
TreeSet<String> includes = new TreeSet<>();
// Map<String, CapabilityStatement.RestResourceSearchParam> nameToSearchParam = new HashMap<String,
// CapabilityStatement.RestResourceSearchParam>();
for (BaseMethodBinding<?> nextMethodBinding : nextEntry.getValue()) {
if (nextMethodBinding.getRestOperationType() != null) {
String resOpCode = nextMethodBinding.getRestOperationType().getCode();
if (resOpCode != null) {
TypeRestfulInteraction resOp;
try {
resOp = TypeRestfulInteraction.fromCode(resOpCode);
} catch (Exception e) {
resOp = null;
}
if (resOp != null) {
if (resourceOps.contains(resOp) == false) {
resourceOps.add(resOp);
resource.addInteraction().setCode(resOp);
}
if ("vread".equals(resOpCode)) {
// vread implies read
resOp = TypeRestfulInteraction.READ;
if (resourceOps.contains(resOp) == false) {
resourceOps.add(resOp);
resource.addInteraction().setCode(resOp);
}
}
// Map<String, CapabilityStatement.RestResourceSearchParam> nameToSearchParam = new HashMap<String,
// CapabilityStatement.RestResourceSearchParam>();
for (BaseMethodBinding<?> nextMethodBinding : nextEntry.getValue()) {
if (nextMethodBinding.getRestOperationType() != null) {
String resOpCode = nextMethodBinding.getRestOperationType().getCode();
if (resOpCode != null) {
TypeRestfulInteraction resOp;
try {
resOp = TypeRestfulInteraction.fromCode(resOpCode);
} catch (Exception e) {
resOp = null;
}
if (resOp != null) {
if (resourceOps.contains(resOp) == false) {
resourceOps.add(resOp);
resource.addInteraction().setCode(resOp);
}
if ("vread".equals(resOpCode)) {
// vread implies read
resOp = TypeRestfulInteraction.READ;
if (resourceOps.contains(resOp) == false) {
resourceOps.add(resOp);
resource.addInteraction().setCode(resOp);
}
}
if (nextMethodBinding.isSupportsConditional()) {
switch (resOp) {
case CREATE:
resource.setConditionalCreate(true);
break;
case DELETE:
if (nextMethodBinding.isSupportsConditionalMultiple()) {
resource.setConditionalDelete(ConditionalDeleteStatus.MULTIPLE);
} else {
resource.setConditionalDelete(ConditionalDeleteStatus.SINGLE);
}
break;
case UPDATE:
resource.setConditionalUpdate(true);
break;
default:
break;
}
}
}
}
}
if (nextMethodBinding.isSupportsConditional()) {
switch (resOp) {
case CREATE:
resource.setConditionalCreate(true);
break;
case DELETE:
if (nextMethodBinding.isSupportsConditionalMultiple()) {
resource.setConditionalDelete(ConditionalDeleteStatus.MULTIPLE);
} else {
resource.setConditionalDelete(ConditionalDeleteStatus.SINGLE);
}
break;
case UPDATE:
resource.setConditionalUpdate(true);
break;
default:
break;
}
}
}
}
}
checkBindingForSystemOps(rest, systemOps, nextMethodBinding);
checkBindingForSystemOps(rest, systemOps, nextMethodBinding);
if (nextMethodBinding instanceof SearchMethodBinding) {
SearchMethodBinding methodBinding = (SearchMethodBinding) nextMethodBinding;
if (methodBinding.getQueryName() != null) {
String queryName = bindings.getNamedSearchMethodBindingToName().get(methodBinding);
if (operationNames.add(queryName)) {
rest.addOperation().setName(methodBinding.getQueryName()).setDefinition((getOperationDefinitionPrefix(theRequestDetails) + "OperationDefinition/" + queryName));
}
} else {
handleNamelessSearchMethodBinding(resource, def, includes, (SearchMethodBinding) nextMethodBinding, theRequestDetails);
}
} else if (nextMethodBinding instanceof OperationMethodBinding) {
OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding;
String opName = bindings.getOperationBindingToName().get(methodBinding);
if (operationNames.add(opName)) {
// Only add each operation (by name) once
rest.addOperation().setName(methodBinding.getName().substring(1)).setDefinition((getOperationDefinitionPrefix(theRequestDetails) + "OperationDefinition/" + opName));
}
}
if (nextMethodBinding instanceof SearchMethodBinding) {
SearchMethodBinding methodBinding = (SearchMethodBinding) nextMethodBinding;
if (methodBinding.getQueryName() != null) {
String queryName = bindings.getNamedSearchMethodBindingToName().get(methodBinding);
if (operationNames.add(queryName)) {
rest.addOperation().setName(methodBinding.getQueryName()).setDefinition(("OperationDefinition/" + queryName));
}
} else {
handleNamelessSearchMethodBinding(resource, def, includes, (SearchMethodBinding) nextMethodBinding, theRequestDetails);
}
} else if (nextMethodBinding instanceof OperationMethodBinding) {
OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding;
String opName = bindings.getOperationBindingToName().get(methodBinding);
if (operationNames.add(opName)) {
// Only add each operation (by name) once
rest.addOperation().setName(methodBinding.getName().substring(1)).setDefinition(("OperationDefinition/" + opName));
}
}
resource.getInteraction().sort(new Comparator<ResourceInteractionComponent>() {
@Override
public int compare(ResourceInteractionComponent theO1, ResourceInteractionComponent theO2) {
TypeRestfulInteraction o1 = theO1.getCode();
TypeRestfulInteraction o2 = theO2.getCode();
if (o1 == null && o2 == null) {
return 0;
}
if (o1 == null) {
return 1;
}
if (o2 == null) {
return -1;
}
return o1.ordinal() - o2.ordinal();
}
});
resource.getInteraction().sort(new Comparator<ResourceInteractionComponent>() {
@Override
public int compare(ResourceInteractionComponent theO1, ResourceInteractionComponent theO2) {
TypeRestfulInteraction o1 = theO1.getCode();
TypeRestfulInteraction o2 = theO2.getCode();
if (o1 == null && o2 == null) {
return 0;
}
if (o1 == null) {
return 1;
}
if (o2 == null) {
return -1;
}
return o1.ordinal() - o2.ordinal();
}
});
}
}
for (String nextInclude : includes) {
resource.addSearchInclude(nextInclude);
}
} else {
for (BaseMethodBinding<?> nextMethodBinding : nextEntry.getValue()) {
checkBindingForSystemOps(rest, systemOps, nextMethodBinding);
if (nextMethodBinding instanceof OperationMethodBinding) {
OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding;
String opName = bindings.getOperationBindingToName().get(methodBinding);
if (operationNames.add(opName)) {
ourLog.debug("Found bound operation: {}", opName);
rest.addOperation().setName(methodBinding.getName().substring(1)).setDefinition((getOperationDefinitionPrefix(theRequestDetails) + "OperationDefinition/" + opName));
}
}
}
}
}
for (String nextInclude : includes) {
resource.addSearchInclude(nextInclude);
}
} else {
for (BaseMethodBinding<?> nextMethodBinding : nextEntry.getValue()) {
checkBindingForSystemOps(rest, systemOps, nextMethodBinding);
if (nextMethodBinding instanceof OperationMethodBinding) {
OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding;
String opName = bindings.getOperationBindingToName().get(methodBinding);
if (operationNames.add(opName)) {
ourLog.debug("Found bound operation: {}", opName);
rest.addOperation().setName(methodBinding.getName().substring(1)).setDefinition(("OperationDefinition/" + opName));
}
}
}
}
}
return retVal;
}
return retVal;
}
protected String getOperationDefinitionPrefix(RequestDetails theRequestDetails) {
if (theRequestDetails == null) {
return "";
}
return theRequestDetails.getServerBaseForRequest() + "/";
}
private void handleNamelessSearchMethodBinding(CapabilityStatementRestResourceComponent resource, RuntimeResourceDefinition def, TreeSet<String> includes,
SearchMethodBinding searchMethodBinding, RequestDetails theRequestDetails) {
includes.addAll(searchMethodBinding.getIncludes());
private void handleNamelessSearchMethodBinding(CapabilityStatementRestResourceComponent resource, RuntimeResourceDefinition def, TreeSet<String> includes,
SearchMethodBinding searchMethodBinding, RequestDetails theRequestDetails) {
includes.addAll(searchMethodBinding.getIncludes());
List<IParameter> params = searchMethodBinding.getParameters();
List<SearchParameter> searchParameters = new ArrayList<>();
for (IParameter nextParameter : params) {
if ((nextParameter instanceof SearchParameter)) {
searchParameters.add((SearchParameter) nextParameter);
}
}
sortSearchParameters(searchParameters);
if (!searchParameters.isEmpty()) {
// boolean allOptional = searchParameters.get(0).isRequired() == false;
//
// OperationDefinition query = null;
// if (!allOptional) {
// RestOperation operation = rest.addOperation();
// query = new OperationDefinition();
// operation.setDefinition(new ResourceReferenceDt(query));
// query.getDescriptionElement().setValue(searchMethodBinding.getDescription());
// query.addUndeclaredExtension(false, ExtensionConstants.QUERY_RETURN_TYPE, new CodeDt(resourceName));
// for (String nextInclude : searchMethodBinding.getIncludes()) {
// query.addUndeclaredExtension(false, ExtensionConstants.QUERY_ALLOWED_INCLUDE, new StringDt(nextInclude));
// }
// }
List<IParameter> params = searchMethodBinding.getParameters();
List<SearchParameter> searchParameters = new ArrayList<>();
for (IParameter nextParameter : params) {
if ((nextParameter instanceof SearchParameter)) {
searchParameters.add((SearchParameter) nextParameter);
}
}
sortSearchParameters(searchParameters);
if (!searchParameters.isEmpty()) {
// boolean allOptional = searchParameters.get(0).isRequired() == false;
//
// OperationDefinition query = null;
// if (!allOptional) {
// RestOperation operation = rest.addOperation();
// query = new OperationDefinition();
// operation.setDefinition(new ResourceReferenceDt(query));
// query.getDescriptionElement().setValue(searchMethodBinding.getDescription());
// query.addUndeclaredExtension(false, ExtensionConstants.QUERY_RETURN_TYPE, new CodeDt(resourceName));
// for (String nextInclude : searchMethodBinding.getIncludes()) {
// query.addUndeclaredExtension(false, ExtensionConstants.QUERY_ALLOWED_INCLUDE, new StringDt(nextInclude));
// }
// }
for (SearchParameter nextParameter : searchParameters) {
for (SearchParameter nextParameter : searchParameters) {
String nextParamName = nextParameter.getName();
String nextParamName = nextParameter.getName();
String chain = null;
String nextParamUnchainedName = nextParamName;
if (nextParamName.contains(".")) {
chain = nextParamName.substring(nextParamName.indexOf('.') + 1);
nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.'));
}
String chain = null;
String nextParamUnchainedName = nextParamName;
if (nextParamName.contains(".")) {
chain = nextParamName.substring(nextParamName.indexOf('.') + 1);
nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.'));
}
String nextParamDescription = nextParameter.getDescription();
String nextParamDescription = nextParameter.getDescription();
/*
* If the parameter has no description, default to the one from the resource
*/
if (StringUtils.isBlank(nextParamDescription)) {
RuntimeSearchParam paramDef = def.getSearchParam(nextParamUnchainedName);
if (paramDef != null) {
nextParamDescription = paramDef.getDescription();
}
}
/*
* If the parameter has no description, default to the one from the resource
*/
if (StringUtils.isBlank(nextParamDescription)) {
RuntimeSearchParam paramDef = def.getSearchParam(nextParamUnchainedName);
if (paramDef != null) {
nextParamDescription = paramDef.getDescription();
}
}
CapabilityStatementRestResourceSearchParamComponent param = resource.addSearchParam();
param.setName(nextParamUnchainedName);
CapabilityStatementRestResourceSearchParamComponent param = resource.addSearchParam();
param.setName(nextParamUnchainedName);
// if (StringUtils.isNotBlank(chain)) {
// param.addChain(chain);
@ -390,211 +395,210 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
// }
// }
param.setDocumentation(nextParamDescription);
if (nextParameter.getParamType() != null) {
param.getTypeElement().setValueAsString(nextParameter.getParamType().getCode());
}
for (Class<? extends IBaseResource> nextTarget : nextParameter.getDeclaredTypes()) {
RuntimeResourceDefinition targetDef = getServerConfiguration(theRequestDetails).getFhirContext().getResourceDefinition(nextTarget);
if (targetDef != null) {
ResourceType code;
try {
code = ResourceType.fromCode(targetDef.getName());
} catch (FHIRException e) {
code = null;
}
param.setDocumentation(nextParamDescription);
if (nextParameter.getParamType() != null) {
param.getTypeElement().setValueAsString(nextParameter.getParamType().getCode());
}
for (Class<? extends IBaseResource> nextTarget : nextParameter.getDeclaredTypes()) {
RuntimeResourceDefinition targetDef = getServerConfiguration(theRequestDetails).getFhirContext().getResourceDefinition(nextTarget);
if (targetDef != null) {
ResourceType code;
try {
code = ResourceType.fromCode(targetDef.getName());
} catch (FHIRException e) {
code = null;
}
// if (code != null) {
// param.addTarget(targetDef.getName());
// }
}
}
}
}
}
}
}
}
}
}
@Read(type = OperationDefinition.class)
public OperationDefinition readOperationDefinition(@IdParam IdType theId, RequestDetails theRequestDetails) {
if (theId == null || theId.hasIdPart() == false) {
throw new ResourceNotFoundException(theId);
}
RestfulServerConfiguration configuration = getServerConfiguration(theRequestDetails);
Bindings bindings = configuration.provideBindings();
@Read(type = OperationDefinition.class)
public OperationDefinition readOperationDefinition(@IdParam IdType theId, RequestDetails theRequestDetails) {
if (theId == null || theId.hasIdPart() == false) {
throw new ResourceNotFoundException(theId);
}
RestfulServerConfiguration configuration = getServerConfiguration(theRequestDetails);
Bindings bindings = configuration.provideBindings();
List<OperationMethodBinding> operationBindings = bindings.getOperationNameToBindings().get(theId.getIdPart());
if (operationBindings != null && !operationBindings.isEmpty()) {
return readOperationDefinitionForOperation(operationBindings);
}
List<SearchMethodBinding> searchBindings = bindings.getSearchNameToBindings().get(theId.getIdPart());
if (searchBindings != null && !searchBindings.isEmpty()) {
return readOperationDefinitionForNamedSearch(searchBindings);
}
throw new ResourceNotFoundException(theId);
}
List<OperationMethodBinding> operationBindings = bindings.getOperationNameToBindings().get(theId.getIdPart());
if (operationBindings != null && !operationBindings.isEmpty()) {
return readOperationDefinitionForOperation(operationBindings);
}
List<SearchMethodBinding> searchBindings = bindings.getSearchNameToBindings().get(theId.getIdPart());
if (searchBindings != null && !searchBindings.isEmpty()) {
return readOperationDefinitionForNamedSearch(searchBindings);
}
throw new ResourceNotFoundException(theId);
}
private OperationDefinition readOperationDefinitionForNamedSearch(List<SearchMethodBinding> bindings) {
OperationDefinition op = new OperationDefinition();
op.setStatus(PublicationStatus.ACTIVE);
op.setKind(OperationKind.QUERY);
op.setAffectsState(false);
private OperationDefinition readOperationDefinitionForNamedSearch(List<SearchMethodBinding> bindings) {
OperationDefinition op = new OperationDefinition();
op.setStatus(PublicationStatus.ACTIVE);
op.setKind(OperationKind.QUERY);
op.setAffectsState(false);
op.setSystem(false);
op.setType(false);
op.setInstance(false);
op.setSystem(false);
op.setType(false);
op.setInstance(false);
Set<String> inParams = new HashSet<>();
Set<String> inParams = new HashSet<>();
for (SearchMethodBinding binding : bindings) {
if (isNotBlank(binding.getDescription())) {
op.setDescription(binding.getDescription());
}
if (isBlank(binding.getResourceProviderResourceName())) {
op.setSystem(true);
} else {
op.setType(true);
op.addResourceElement().setValue(binding.getResourceProviderResourceName());
}
op.setCode(binding.getQueryName());
for (IParameter nextParamUntyped : binding.getParameters()) {
if (nextParamUntyped instanceof SearchParameter) {
SearchParameter nextParam = (SearchParameter) nextParamUntyped;
if (!inParams.add(nextParam.getName())) {
continue;
}
OperationDefinitionParameterComponent param = op.addParameter();
param.setUse(Enumerations.OperationParameterUse.IN);
param.setType(Enumerations.FHIRAllTypes.STRING);
param.getSearchTypeElement().setValueAsString(nextParam.getParamType().getCode());
param.setMin(nextParam.isRequired() ? 1 : 0);
param.setMax("1");
param.setName(nextParam.getName());
}
}
for (SearchMethodBinding binding : bindings) {
if (isNotBlank(binding.getDescription())) {
op.setDescription(binding.getDescription());
}
if (isBlank(binding.getResourceProviderResourceName())) {
op.setSystem(true);
} else {
op.setType(true);
op.addResourceElement().setValue(binding.getResourceProviderResourceName());
}
op.setCode(binding.getQueryName());
for (IParameter nextParamUntyped : binding.getParameters()) {
if (nextParamUntyped instanceof SearchParameter) {
SearchParameter nextParam = (SearchParameter) nextParamUntyped;
if (!inParams.add(nextParam.getName())) {
continue;
}
OperationDefinitionParameterComponent param = op.addParameter();
param.setUse(Enumerations.OperationParameterUse.IN);
param.setType(Enumerations.FHIRAllTypes.STRING);
param.getSearchTypeElement().setValueAsString(nextParam.getParamType().getCode());
param.setMin(nextParam.isRequired() ? 1 : 0);
param.setMax("1");
param.setName(nextParam.getName());
}
}
if (isBlank(op.getName())) {
if (isNotBlank(op.getDescription())) {
op.setName(op.getDescription());
} else {
op.setName(op.getCode());
}
}
}
if (isBlank(op.getName())) {
if (isNotBlank(op.getDescription())) {
op.setName(op.getDescription());
} else {
op.setName(op.getCode());
}
}
}
return op;
}
return op;
}
private OperationDefinition readOperationDefinitionForOperation(List<OperationMethodBinding> bindings) {
OperationDefinition op = new OperationDefinition();
op.setStatus(PublicationStatus.ACTIVE);
op.setKind(OperationKind.OPERATION);
op.setAffectsState(false);
private OperationDefinition readOperationDefinitionForOperation(List<OperationMethodBinding> bindings) {
OperationDefinition op = new OperationDefinition();
op.setStatus(PublicationStatus.ACTIVE);
op.setKind(OperationKind.OPERATION);
op.setAffectsState(false);
// We reset these to true below if we find a binding that can handle the level
op.setSystem(false);
op.setType(false);
op.setInstance(false);
// We reset these to true below if we find a binding that can handle the level
op.setSystem(false);
op.setType(false);
op.setInstance(false);
Set<String> inParams = new HashSet<>();
Set<String> outParams = new HashSet<>();
Set<String> inParams = new HashSet<>();
Set<String> outParams = new HashSet<>();
for (OperationMethodBinding sharedDescription : bindings) {
if (isNotBlank(sharedDescription.getDescription())) {
op.setDescription(sharedDescription.getDescription());
}
if (sharedDescription.isCanOperateAtInstanceLevel()) {
op.setInstance(true);
}
if (sharedDescription.isCanOperateAtServerLevel()) {
op.setSystem(true);
}
if (sharedDescription.isCanOperateAtTypeLevel()) {
op.setType(true);
}
if (!sharedDescription.isIdempotent()) {
op.setAffectsState(!sharedDescription.isIdempotent());
}
op.setCode(sharedDescription.getName().substring(1));
if (sharedDescription.isCanOperateAtInstanceLevel()) {
op.setInstance(sharedDescription.isCanOperateAtInstanceLevel());
}
if (sharedDescription.isCanOperateAtServerLevel()) {
op.setSystem(sharedDescription.isCanOperateAtServerLevel());
}
if (isNotBlank(sharedDescription.getResourceName())) {
op.addResourceElement().setValue(sharedDescription.getResourceName());
}
for (OperationMethodBinding sharedDescription : bindings) {
if (isNotBlank(sharedDescription.getDescription())) {
op.setDescription(sharedDescription.getDescription());
}
if (sharedDescription.isCanOperateAtInstanceLevel()) {
op.setInstance(true);
}
if (sharedDescription.isCanOperateAtServerLevel()) {
op.setSystem(true);
}
if (sharedDescription.isCanOperateAtTypeLevel()) {
op.setType(true);
}
if (!sharedDescription.isIdempotent()) {
op.setAffectsState(!sharedDescription.isIdempotent());
}
op.setCode(sharedDescription.getName().substring(1));
if (sharedDescription.isCanOperateAtInstanceLevel()) {
op.setInstance(sharedDescription.isCanOperateAtInstanceLevel());
}
if (sharedDescription.isCanOperateAtServerLevel()) {
op.setSystem(sharedDescription.isCanOperateAtServerLevel());
}
if (isNotBlank(sharedDescription.getResourceName())) {
op.addResourceElement().setValue(sharedDescription.getResourceName());
}
for (IParameter nextParamUntyped : sharedDescription.getParameters()) {
if (nextParamUntyped instanceof OperationParameter) {
OperationParameter nextParam = (OperationParameter) nextParamUntyped;
OperationDefinitionParameterComponent param = op.addParameter();
if (!inParams.add(nextParam.getName())) {
continue;
}
param.setUse(Enumerations.OperationParameterUse.IN);
if (nextParam.getParamType() != null) {
param.setType(Enumerations.FHIRAllTypes.fromCode(nextParam.getParamType()));
}
if (nextParam.getSearchParamType() != null) {
param.getSearchTypeElement().setValueAsString(nextParam.getSearchParamType());
}
param.setMin(nextParam.getMin());
param.setMax(nextParam.getMax() == -1 ? "*" : Integer.toString(nextParam.getMax()));
param.setName(nextParam.getName());
}
}
for (IParameter nextParamUntyped : sharedDescription.getParameters()) {
if (nextParamUntyped instanceof OperationParameter) {
OperationParameter nextParam = (OperationParameter) nextParamUntyped;
OperationDefinitionParameterComponent param = op.addParameter();
if (!inParams.add(nextParam.getName())) {
continue;
}
param.setUse(Enumerations.OperationParameterUse.IN);
if (nextParam.getParamType() != null) {
param.setType(Enumerations.FHIRAllTypes.fromCode(nextParam.getParamType()));
}
if (nextParam.getSearchParamType() != null) {
param.getSearchTypeElement().setValueAsString(nextParam.getSearchParamType());
}
param.setMin(nextParam.getMin());
param.setMax(nextParam.getMax() == -1 ? "*" : Integer.toString(nextParam.getMax()));
param.setName(nextParam.getName());
}
}
for (ReturnType nextParam : sharedDescription.getReturnParams()) {
if (!outParams.add(nextParam.getName())) {
continue;
}
OperationDefinitionParameterComponent param = op.addParameter();
param.setUse(Enumerations.OperationParameterUse.OUT);
if (nextParam.getType() != null) {
param.setType(Enumerations.FHIRAllTypes.fromCode(nextParam.getType()));
}
param.setMin(nextParam.getMin());
param.setMax(nextParam.getMax() == -1 ? "*" : Integer.toString(nextParam.getMax()));
param.setName(nextParam.getName());
}
}
for (ReturnType nextParam : sharedDescription.getReturnParams()) {
if (!outParams.add(nextParam.getName())) {
continue;
}
OperationDefinitionParameterComponent param = op.addParameter();
param.setUse(Enumerations.OperationParameterUse.OUT);
if (nextParam.getType() != null) {
param.setType(Enumerations.FHIRAllTypes.fromCode(nextParam.getType()));
}
param.setMin(nextParam.getMin());
param.setMax(nextParam.getMax() == -1 ? "*" : Integer.toString(nextParam.getMax()));
param.setName(nextParam.getName());
}
}
if (isBlank(op.getName())) {
if (isNotBlank(op.getDescription())) {
op.setName(op.getDescription());
} else {
op.setName(op.getCode());
}
}
if (isBlank(op.getName())) {
if (isNotBlank(op.getDescription())) {
op.setName(op.getDescription());
} else {
op.setName(op.getCode());
}
}
if (op.hasSystem() == false) {
op.setSystem(false);
}
if (op.hasInstance() == false) {
op.setInstance(false);
}
if (op.hasSystem() == false) {
op.setSystem(false);
}
if (op.hasInstance() == false) {
op.setInstance(false);
}
return op;
}
return op;
}
@Override
public void setRestfulServer(RestfulServer theRestfulServer) {
// ignore
}
@Override
public void setRestfulServer(RestfulServer theRestfulServer) {
// ignore
}
private void sortSearchParameters(List<SearchParameter> searchParameters) {
Collections.sort(searchParameters, new Comparator<SearchParameter>() {
@Override
public int compare(SearchParameter theO1, SearchParameter theO2) {
if (theO1.isRequired() == theO2.isRequired()) {
return theO1.getName().compareTo(theO2.getName());
}
if (theO1.isRequired()) {
return -1;
}
return 1;
}
});
}
Collections.sort(searchParameters, new Comparator<SearchParameter>() {
@Override
public int compare(SearchParameter theO1, SearchParameter theO2) {
if (theO1.isRequired() == theO2.isRequired()) {
return theO1.getName().compareTo(theO2.getName());
}
if (theO1.isRequired()) {
return -1;
}
return 1;
}
});
}
}

View File

@ -1,5 +1,5 @@
# This file contains version definitions
# Generated: 2020-01-12T11:10:06.793+08:00
# Generated: 2020-05-11T07:41:23.753-04:00
resource.Account=org.hl7.fhir.r5.model.Account
resource.ActivityDefinition=org.hl7.fhir.r5.model.ActivityDefinition
@ -21,6 +21,7 @@ resource.CareTeam=org.hl7.fhir.r5.model.CareTeam
resource.CatalogEntry=org.hl7.fhir.r5.model.CatalogEntry
resource.ChargeItem=org.hl7.fhir.r5.model.ChargeItem
resource.ChargeItemDefinition=org.hl7.fhir.r5.model.ChargeItemDefinition
resource.Citation=org.hl7.fhir.r5.model.Citation
resource.Claim=org.hl7.fhir.r5.model.Claim
resource.ClaimResponse=org.hl7.fhir.r5.model.ClaimResponse
resource.ClinicalImpression=org.hl7.fhir.r5.model.ClinicalImpression
@ -54,6 +55,7 @@ resource.EnrollmentResponse=org.hl7.fhir.r5.model.EnrollmentResponse
resource.EpisodeOfCare=org.hl7.fhir.r5.model.EpisodeOfCare
resource.EventDefinition=org.hl7.fhir.r5.model.EventDefinition
resource.Evidence=org.hl7.fhir.r5.model.Evidence
resource.EvidenceFocus=org.hl7.fhir.r5.model.EvidenceFocus
resource.EvidenceVariable=org.hl7.fhir.r5.model.EvidenceVariable
resource.ExampleScenario=org.hl7.fhir.r5.model.ExampleScenario
resource.ExplanationOfBenefit=org.hl7.fhir.r5.model.ExplanationOfBenefit
@ -92,6 +94,7 @@ resource.MolecularSequence=org.hl7.fhir.r5.model.MolecularSequence
resource.NamingSystem=org.hl7.fhir.r5.model.NamingSystem
resource.NutritionIntake=org.hl7.fhir.r5.model.NutritionIntake
resource.NutritionOrder=org.hl7.fhir.r5.model.NutritionOrder
resource.NutritionProduct=org.hl7.fhir.r5.model.NutritionProduct
resource.Observation=org.hl7.fhir.r5.model.Observation
resource.ObservationDefinition=org.hl7.fhir.r5.model.ObservationDefinition
resource.OperationDefinition=org.hl7.fhir.r5.model.OperationDefinition
@ -103,6 +106,7 @@ resource.Parameters=org.hl7.fhir.r5.model.Parameters
resource.Patient=org.hl7.fhir.r5.model.Patient
resource.PaymentNotice=org.hl7.fhir.r5.model.PaymentNotice
resource.PaymentReconciliation=org.hl7.fhir.r5.model.PaymentReconciliation
resource.Permission=org.hl7.fhir.r5.model.Permission
resource.Person=org.hl7.fhir.r5.model.Person
resource.PlanDefinition=org.hl7.fhir.r5.model.PlanDefinition
resource.Practitioner=org.hl7.fhir.r5.model.Practitioner
@ -126,6 +130,8 @@ resource.SpecimenDefinition=org.hl7.fhir.r5.model.SpecimenDefinition
resource.StructureDefinition=org.hl7.fhir.r5.model.StructureDefinition
resource.StructureMap=org.hl7.fhir.r5.model.StructureMap
resource.Subscription=org.hl7.fhir.r5.model.Subscription
resource.SubscriptionStatus=org.hl7.fhir.r5.model.SubscriptionStatus
resource.SubscriptionTopic=org.hl7.fhir.r5.model.SubscriptionTopic
resource.Substance=org.hl7.fhir.r5.model.Substance
resource.SubstanceDefinition=org.hl7.fhir.r5.model.SubstanceDefinition
resource.SubstanceNucleicAcid=org.hl7.fhir.r5.model.SubstanceNucleicAcid
@ -139,7 +145,6 @@ resource.Task=org.hl7.fhir.r5.model.Task
resource.TerminologyCapabilities=org.hl7.fhir.r5.model.TerminologyCapabilities
resource.TestReport=org.hl7.fhir.r5.model.TestReport
resource.TestScript=org.hl7.fhir.r5.model.TestScript
resource.Topic=org.hl7.fhir.r5.model.Topic
resource.ValueSet=org.hl7.fhir.r5.model.ValueSet
resource.VerificationResult=org.hl7.fhir.r5.model.VerificationResult
resource.VisionPrescription=org.hl7.fhir.r5.model.VisionPrescription
@ -200,8 +205,8 @@ datatype.dateTime=org.hl7.fhir.r5.model.DateTimeType
datatype.decimal=org.hl7.fhir.r5.model.DecimalType
datatype.id=org.hl7.fhir.r5.model.IdType
datatype.instant=org.hl7.fhir.r5.model.InstantType
datatype.integer=org.hl7.fhir.r5.model.IntegerType
datatype.integer64=org.hl7.fhir.r5.model.Integer64Type
datatype.integer=org.hl7.fhir.r5.model.Integer64Type
datatype.integer.2=org.hl7.fhir.r5.model.IntegerType
datatype.markdown=org.hl7.fhir.r5.model.MarkdownType
datatype.oid=org.hl7.fhir.r5.model.OidType
datatype.positiveInt=org.hl7.fhir.r5.model.PositiveIntType

View File

@ -133,6 +133,7 @@ public class ServerCapabilityStatementProviderR5Test {
RestfulServer rs = new RestfulServer(ourCtx);
rs.setProviders(new ProviderWithExtendedOperationReturningBundle());
rs.setServerAddressStrategy(new HardcodedServerAddressStrategy("http://localhost/baseR4"));
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
rs.setServerConformanceProvider(sc);
@ -257,6 +258,7 @@ public class ServerCapabilityStatementProviderR5Test {
public void testOperationAcrossMultipleTypes() throws Exception {
RestfulServer rs = new RestfulServer(ourCtx);
rs.setProviders(new MultiTypePatientProvider(), new MultiTypeEncounterProvider());
rs.setServerAddressStrategy(new HardcodedServerAddressStrategy("http://localhost/baseR4"));
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
rs.setServerConformanceProvider(sc);
@ -660,6 +662,7 @@ public class ServerCapabilityStatementProviderR5Test {
public void testSystemLevelNamedQueryWithParameters() throws Exception {
RestfulServer rs = new RestfulServer(ourCtx);
rs.setProviders(new NamedQueryPlainProvider());
rs.setServerAddressStrategy(new HardcodedServerAddressStrategy("http://localhost/baseR4"));
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
rs.setServerConformanceProvider(sc);
@ -704,6 +707,7 @@ public class ServerCapabilityStatementProviderR5Test {
public void testResourceLevelNamedQueryWithParameters() throws Exception {
RestfulServer rs = new RestfulServer(ourCtx);
rs.setProviders(new NamedQueryResourceProvider());
rs.setServerAddressStrategy(new HardcodedServerAddressStrategy("http://localhost/baseR4"));
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
rs.setServerConformanceProvider(sc);
@ -747,6 +751,7 @@ public class ServerCapabilityStatementProviderR5Test {
public void testExtendedOperationAtTypeLevel() throws Exception {
RestfulServer rs = new RestfulServer(ourCtx);
rs.setProviders(new TypeLevelOperationProvider());
rs.setServerAddressStrategy(new HardcodedServerAddressStrategy("http://localhost/baseR4"));
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
rs.setServerConformanceProvider(sc);

View File

@ -369,9 +369,7 @@
<element id="BackboneElement.modifierExtension">
<path value="BackboneElement.modifierExtension"></path>
<short value="Extensions that cannot be ignored even if unrecognized"></short>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions.
Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions. Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<comment value="There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone."></comment>
<requirements value="Modifier extensions allow for extensions that *cannot* be safely ignored to be clearly distinguished from the vast majority of extensions which can be safely ignored. This promotes interoperability by eliminating the need for implementers to prohibit the presence of extensions. For further information, see the [definition of modifier extensions](extensibility.html#modifierExtension)."></requirements>
<alias value="extensions"></alias>
@ -433,9 +431,7 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or
<element id="BackboneElement.modifierExtension">
<path value="BackboneElement.modifierExtension"></path>
<short value="Extensions that cannot be ignored even if unrecognized"></short>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions.
Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions. Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<comment value="There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone."></comment>
<requirements value="Modifier extensions allow for extensions that *cannot* be safely ignored to be clearly distinguished from the vast majority of extensions which can be safely ignored. This promotes interoperability by eliminating the need for implementers to prohibit the presence of extensions. For further information, see the [definition of modifier extensions](extensibility.html#modifierExtension)."></requirements>
<alias value="extensions"></alias>
@ -8854,9 +8850,7 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or
<element id="DataRequirement.mustSupport">
<path value="DataRequirement.mustSupport"></path>
<short value="Indicates specific structure elements that are referenced by the knowledge module"></short>
<definition value="Indicates that specific elements of the type are referenced by the knowledge module and must be supported by the consumer in order to obtain an effective evaluation. This does not mean that a value is required for this element, only that the consuming system must understand the element and be able to provide values for it if they are available.
The value of mustSupport SHALL be a FHIRPath resolveable on the type of the DataRequirement. The path SHALL consist only of identifiers, constant indexers, and .resolve() (see the [Simple FHIRPath Profile](fhirpath.html#simple) for full details)."></definition>
<definition value="Indicates that specific elements of the type are referenced by the knowledge module and must be supported by the consumer in order to obtain an effective evaluation. This does not mean that a value is required for this element, only that the consuming system must understand the element and be able to provide values for it if they are available. The value of mustSupport SHALL be a FHIRPath resolveable on the type of the DataRequirement. The path SHALL consist only of identifiers, constant indexers, and .resolve() (see the [Simple FHIRPath Profile](fhirpath.html#simple) for full details)."></definition>
<min value="0"></min>
<max value="*"></max>
<base>
@ -9534,9 +9528,7 @@ The value of mustSupport SHALL be a FHIRPath resolveable on the type of the Data
<element id="DataRequirement.mustSupport">
<path value="DataRequirement.mustSupport"></path>
<short value="Indicates specific structure elements that are referenced by the knowledge module"></short>
<definition value="Indicates that specific elements of the type are referenced by the knowledge module and must be supported by the consumer in order to obtain an effective evaluation. This does not mean that a value is required for this element, only that the consuming system must understand the element and be able to provide values for it if they are available.
The value of mustSupport SHALL be a FHIRPath resolveable on the type of the DataRequirement. The path SHALL consist only of identifiers, constant indexers, and .resolve() (see the [Simple FHIRPath Profile](fhirpath.html#simple) for full details)."></definition>
<definition value="Indicates that specific elements of the type are referenced by the knowledge module and must be supported by the consumer in order to obtain an effective evaluation. This does not mean that a value is required for this element, only that the consuming system must understand the element and be able to provide values for it if they are available. The value of mustSupport SHALL be a FHIRPath resolveable on the type of the DataRequirement. The path SHALL consist only of identifiers, constant indexers, and .resolve() (see the [Simple FHIRPath Profile](fhirpath.html#simple) for full details)."></definition>
<min value="0"></min>
<max value="*"></max>
<type>
@ -10278,9 +10270,7 @@ The value of mustSupport SHALL be a FHIRPath resolveable on the type of the Data
<element id="Dosage.modifierExtension">
<path value="Dosage.modifierExtension"></path>
<short value="Extensions that cannot be ignored even if unrecognized"></short>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions.
Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions. Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<comment value="There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone."></comment>
<requirements value="Modifier extensions allow for extensions that *cannot* be safely ignored to be clearly distinguished from the vast majority of extensions which can be safely ignored. This promotes interoperability by eliminating the need for implementers to prohibit the presence of extensions. For further information, see the [definition of modifier extensions](extensibility.html#modifierExtension)."></requirements>
<alias value="extensions"></alias>
@ -10852,7 +10842,7 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or
<path value="Dosage.doseAndRate.rate[x]"></path>
<short value="Amount of medication per unit of time"></short>
<definition value="Amount of medication per unit of time."></definition>
<comment value="It is possible to supply both a rate and a doseQuantity to provide full details about how the medication is to be administered and supplied. If the rate is intended to change over time, depending on local rules/regulations, each change should be captured as a new version of the MedicationRequest with an updated rate, or captured with a new MedicationRequest with the new rate. It is possible to specify a rate over time (for example, 100 ml/hour) using either the rateRatio and rateQuantity. The rateQuantity approach requires systems to have the capability to parse UCUM grammer where ml/hour is included rather than a specific ratio where the time is specified as the denominator. Where a rate such as 500ml over 2 hours is specified, the use of rateRatio may be more semantically correct than specifying using a rateQuantity of 250 mg/hour."></comment>
<comment value="It is possible to supply both a rate and a doseQuantity to provide full details about how the medication is to be administered and supplied. If the rate is intended to change over time, depending on local rules/regulations, each change should be captured as a new version of the MedicationRequest with an updated rate, or captured with a new MedicationRequest with the new rate. It is possible to specify a rate over time (for example, 100 ml/hour) using either the rateRatio and rateQuantity. The rateQuantity approach requires systems to have the capability to parse UCUM grammer where ml/hour is included rather than a specific ratio where the time is specified as the denominator. Where a rate such as 500ml over 2 hours is specified, the use of rateRatio may be more semantically correct than specifying using a rateQuantity of 250 mg/hour."></comment>
<requirements value="Identifies the speed with which the medication was or will be introduced into the patient. Typically the rate for an infusion e.g. 100 ml per 1 hour or 100 ml/hr. May also be expressed as a rate per unit of time e.g. 500 ml per 2 hours. Other examples: 200 mcg/min or 200 mcg/1 minute; 1 liter/8 hours. Sometimes, a rate can imply duration when expressed as total volume / duration (e.g. 500mL/2 hours implies a duration of 2 hours). However, when rate doesn't imply duration (e.g. 250mL/hour), then the timing.repeat.duration is needed to convey the infuse over time period."></requirements>
<min value="0"></min>
<max value="1"></max>
@ -11294,7 +11284,7 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or
<path value="Dosage.doseAndRate.rate[x]"></path>
<short value="Amount of medication per unit of time"></short>
<definition value="Amount of medication per unit of time."></definition>
<comment value="It is possible to supply both a rate and a doseQuantity to provide full details about how the medication is to be administered and supplied. If the rate is intended to change over time, depending on local rules/regulations, each change should be captured as a new version of the MedicationRequest with an updated rate, or captured with a new MedicationRequest with the new rate. It is possible to specify a rate over time (for example, 100 ml/hour) using either the rateRatio and rateQuantity. The rateQuantity approach requires systems to have the capability to parse UCUM grammer where ml/hour is included rather than a specific ratio where the time is specified as the denominator. Where a rate such as 500ml over 2 hours is specified, the use of rateRatio may be more semantically correct than specifying using a rateQuantity of 250 mg/hour."></comment>
<comment value="It is possible to supply both a rate and a doseQuantity to provide full details about how the medication is to be administered and supplied. If the rate is intended to change over time, depending on local rules/regulations, each change should be captured as a new version of the MedicationRequest with an updated rate, or captured with a new MedicationRequest with the new rate. It is possible to specify a rate over time (for example, 100 ml/hour) using either the rateRatio and rateQuantity. The rateQuantity approach requires systems to have the capability to parse UCUM grammer where ml/hour is included rather than a specific ratio where the time is specified as the denominator. Where a rate such as 500ml over 2 hours is specified, the use of rateRatio may be more semantically correct than specifying using a rateQuantity of 250 mg/hour."></comment>
<requirements value="Identifies the speed with which the medication was or will be introduced into the patient. Typically the rate for an infusion e.g. 100 ml per 1 hour or 100 ml/hr. May also be expressed as a rate per unit of time e.g. 500 ml per 2 hours. Other examples: 200 mcg/min or 200 mcg/1 minute; 1 liter/8 hours. Sometimes, a rate can imply duration when expressed as total volume / duration (e.g. 500mL/2 hours implies a duration of 2 hours). However, when rate doesn't imply duration (e.g. 250mL/hour), then the timing.repeat.duration is needed to convey the infuse over time period."></requirements>
<min value="0"></min>
<max value="1"></max>
@ -12070,9 +12060,7 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or
<element id="ElementDefinition.modifierExtension">
<path value="ElementDefinition.modifierExtension"></path>
<short value="Extensions that cannot be ignored even if unrecognized"></short>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions.
Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions. Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<comment value="There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone."></comment>
<requirements value="Modifier extensions allow for extensions that *cannot* be safely ignored to be clearly distinguished from the vast majority of extensions which can be safely ignored. This promotes interoperability by eliminating the need for implementers to prohibit the presence of extensions. For further information, see the [definition of modifier extensions](extensibility.html#modifierExtension)."></requirements>
<alias value="extensions"></alias>
@ -13646,9 +13634,7 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or
<path value="ElementDefinition.defaultValue[x]"></path>
<short value="Specified value if missing from instance"></short>
<definition value="The value that should be used if there is no value stated in the instance (e.g. 'if not otherwise specified, the abstract is false')."></definition>
<comment value="Specifying a default value means that the property can never been unknown - it must always have a value. Further, the default value can never be changed, or changed in constraints on content models. Defining default values creates many difficulties in implementation (e.g. when is a value missing?). For these reasons, default values are (and should be) used extremely sparingly.
No default values are ever defined in the FHIR specification, nor can they be defined in constraints (&quot;profiles&quot;) on data types or resources. This element only exists so that default values may be defined in logical models."></comment>
<comment value="Specifying a default value means that the property can never been unknown - it must always have a value. Further, the default value can never be changed, or changed in constraints on content models. Defining default values creates many difficulties in implementation (e.g. when is a value missing?). For these reasons, default values are (and should be) used extremely sparingly. No default values are ever defined in the FHIR specification, nor can they be defined in constraints (&quot;profiles&quot;) on data types or resources. This element only exists so that default values may be defined in logical models."></comment>
<min value="0"></min>
<max value="1"></max>
<base>
@ -14073,17 +14059,7 @@ No default values are ever defined in the FHIR specification, nor can they be de
<element id="ElementDefinition.pattern[x]">
<path value="ElementDefinition.pattern[x]"></path>
<short value="Value must have at least these property values"></short>
<definition value="Specifies a value that the value in the instance SHALL follow - that is, any value in the pattern must be found in the instance. Other additional values may be found too. This is effectively constraint by example.
When pattern[x] is used to constrain a primitive, it means that the value provided in the pattern[x] must match the instance value exactly.
When pattern[x] is used to constrain an array, it means that each element provided in the pattern[x] array must (recursively) match at least one element from the instance array.
When pattern[x] is used to constrain a complex object, it means that each property in the pattern must be present in the complex object, and its value must recursively match -- i.e.,
1. If primitive: it must match exactly the pattern value
2. If a complex object: it must match (recursively) the pattern value
3. If an array: it must match (recursively) the pattern value."></definition>
<definition value="Specifies a value that the value in the instance SHALL follow - that is, any value in the pattern must be found in the instance. Other additional values may be found too. This is effectively constraint by example. When pattern[x] is used to constrain a primitive, it means that the value provided in the pattern[x] must match the instance value exactly. When pattern[x] is used to constrain an array, it means that each element provided in the pattern[x] array must (recursively) match at least one element from the instance array. When pattern[x] is used to constrain a complex object, it means that each property in the pattern must be present in the complex object, and its value must recursively match -- i.e., 1. If primitive: it must match exactly the pattern value 2. If a complex object: it must match (recursively) the pattern value 3. If an array: it must match (recursively) the pattern value."></definition>
<comment value="Mostly used for fixing values of CodeableConcept. In general, pattern[x] is not intended for use with primitive types, where is has the same meaning as fixed[x]."></comment>
<min value="0"></min>
<max value="1"></max>
@ -16671,9 +16647,7 @@ When pattern[x] is used to constrain a complex object, it means that each proper
<path value="ElementDefinition.defaultValue[x]"></path>
<short value="Specified value if missing from instance"></short>
<definition value="The value that should be used if there is no value stated in the instance (e.g. 'if not otherwise specified, the abstract is false')."></definition>
<comment value="Specifying a default value means that the property can never been unknown - it must always have a value. Further, the default value can never be changed, or changed in constraints on content models. Defining default values creates many difficulties in implementation (e.g. when is a value missing?). For these reasons, default values are (and should be) used extremely sparingly.
No default values are ever defined in the FHIR specification, nor can they be defined in constraints (&quot;profiles&quot;) on data types or resources. This element only exists so that default values may be defined in logical models."></comment>
<comment value="Specifying a default value means that the property can never been unknown - it must always have a value. Further, the default value can never be changed, or changed in constraints on content models. Defining default values creates many difficulties in implementation (e.g. when is a value missing?). For these reasons, default values are (and should be) used extremely sparingly. No default values are ever defined in the FHIR specification, nor can they be defined in constraints (&quot;profiles&quot;) on data types or resources. This element only exists so that default values may be defined in logical models."></comment>
<min value="0"></min>
<max value="1"></max>
<type>
@ -17042,17 +17016,7 @@ No default values are ever defined in the FHIR specification, nor can they be de
<element id="ElementDefinition.pattern[x]">
<path value="ElementDefinition.pattern[x]"></path>
<short value="Value must have at least these property values"></short>
<definition value="Specifies a value that the value in the instance SHALL follow - that is, any value in the pattern must be found in the instance. Other additional values may be found too. This is effectively constraint by example.
When pattern[x] is used to constrain a primitive, it means that the value provided in the pattern[x] must match the instance value exactly.
When pattern[x] is used to constrain an array, it means that each element provided in the pattern[x] array must (recursively) match at least one element from the instance array.
When pattern[x] is used to constrain a complex object, it means that each property in the pattern must be present in the complex object, and its value must recursively match -- i.e.,
1. If primitive: it must match exactly the pattern value
2. If a complex object: it must match (recursively) the pattern value
3. If an array: it must match (recursively) the pattern value."></definition>
<definition value="Specifies a value that the value in the instance SHALL follow - that is, any value in the pattern must be found in the instance. Other additional values may be found too. This is effectively constraint by example. When pattern[x] is used to constrain a primitive, it means that the value provided in the pattern[x] must match the instance value exactly. When pattern[x] is used to constrain an array, it means that each element provided in the pattern[x] array must (recursively) match at least one element from the instance array. When pattern[x] is used to constrain a complex object, it means that each property in the pattern must be present in the complex object, and its value must recursively match -- i.e., 1. If primitive: it must match exactly the pattern value 2. If a complex object: it must match (recursively) the pattern value 3. If an array: it must match (recursively) the pattern value."></definition>
<comment value="Mostly used for fixing values of CodeableConcept. In general, pattern[x] is not intended for use with primitive types, where is has the same meaning as fixed[x]."></comment>
<min value="0"></min>
<max value="1"></max>
@ -20362,9 +20326,7 @@ When pattern[x] is used to constrain a complex object, it means that each proper
<element id="MarketingStatus.modifierExtension">
<path value="MarketingStatus.modifierExtension"></path>
<short value="Extensions that cannot be ignored even if unrecognized"></short>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions.
Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions. Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<comment value="There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone."></comment>
<requirements value="Modifier extensions allow for extensions that *cannot* be safely ignored to be clearly distinguished from the vast majority of extensions which can be safely ignored. This promotes interoperability by eliminating the need for implementers to prohibit the presence of extensions. For further information, see the [definition of modifier extensions](extensibility.html#modifierExtension)."></requirements>
<alias value="extensions"></alias>
@ -20805,9 +20767,7 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or
<path value="Meta.source"></path>
<short value="Identifies where the resource comes from"></short>
<definition value="A uri that identifies the source system of the resource. This provides a minimal amount of [Provenance](provenance.html#) information that can be used to track or differentiate the source of information in the resource. The source may identify another FHIR server, document, message, database, etc."></definition>
<comment value="In the provenance resource, this corresponds to Provenance.entity.what[x]. The exact use of the source (and the implied Provenance.entity.role) is left to implementer discretion. Only one nominated source is allowed; for additional provenance details, a full Provenance resource should be used.
This element can be used to indicate where the current master source of a resource that has a canonical URL if the resource is no longer hosted at the canonical URL."></comment>
<comment value="In the provenance resource, this corresponds to Provenance.entity.what[x]. The exact use of the source (and the implied Provenance.entity.role) is left to implementer discretion. Only one nominated source is allowed; for additional provenance details, a full Provenance resource should be used. This element can be used to indicate where the current master source of a resource that has a canonical URL if the resource is no longer hosted at the canonical URL."></comment>
<min value="0"></min>
<max value="1"></max>
<base>
@ -20974,9 +20934,7 @@ This element can be used to indicate where the current master source of a resour
<path value="Meta.source"></path>
<short value="Identifies where the resource comes from"></short>
<definition value="A uri that identifies the source system of the resource. This provides a minimal amount of [Provenance](provenance.html#) information that can be used to track or differentiate the source of information in the resource. The source may identify another FHIR server, document, message, database, etc."></definition>
<comment value="In the provenance resource, this corresponds to Provenance.entity.what[x]. The exact use of the source (and the implied Provenance.entity.role) is left to implementer discretion. Only one nominated source is allowed; for additional provenance details, a full Provenance resource should be used.
This element can be used to indicate where the current master source of a resource that has a canonical URL if the resource is no longer hosted at the canonical URL."></comment>
<comment value="In the provenance resource, this corresponds to Provenance.entity.what[x]. The exact use of the source (and the implied Provenance.entity.role) is left to implementer discretion. Only one nominated source is allowed; for additional provenance details, a full Provenance resource should be used. This element can be used to indicate where the current master source of a resource that has a canonical URL if the resource is no longer hosted at the canonical URL."></comment>
<min value="0"></min>
<max value="1"></max>
<type>
@ -22142,9 +22100,7 @@ This element can be used to indicate where the current master source of a resour
<path value="Period"></path>
<short value="Time range defined by start and end date/time"></short>
<definition value="A time period defined by a start and end date and optionally time."></definition>
<comment value="A Period specifies a range of time; the context of use will specify whether the entire range applies (e.g. &quot;the patient was an inpatient of the hospital for this time range&quot;) or one value from the range applies (e.g. &quot;give to the patient between these two times&quot;).
Period is not used for a duration (a measure of elapsed time). See [Duration](datatypes.html#Duration)."></comment>
<comment value="A Period specifies a range of time; the context of use will specify whether the entire range applies (e.g. &quot;the patient was an inpatient of the hospital for this time range&quot;) or one value from the range applies (e.g. &quot;give to the patient between these two times&quot;). Period is not used for a duration (a measure of elapsed time). See [Duration](datatypes.html#Duration)."></comment>
<min value="0"></min>
<max value="*"></max>
<base>
@ -22339,9 +22295,7 @@ Period is not used for a duration (a measure of elapsed time). See [Duration](da
<path value="Period"></path>
<short value="Time range defined by start and end date/time"></short>
<definition value="A time period defined by a start and end date and optionally time."></definition>
<comment value="A Period specifies a range of time; the context of use will specify whether the entire range applies (e.g. &quot;the patient was an inpatient of the hospital for this time range&quot;) or one value from the range applies (e.g. &quot;give to the patient between these two times&quot;).
Period is not used for a duration (a measure of elapsed time). See [Duration](datatypes.html#Duration)."></comment>
<comment value="A Period specifies a range of time; the context of use will specify whether the entire range applies (e.g. &quot;the patient was an inpatient of the hospital for this time range&quot;) or one value from the range applies (e.g. &quot;give to the patient between these two times&quot;). Period is not used for a duration (a measure of elapsed time). See [Duration](datatypes.html#Duration)."></comment>
<min value="0"></min>
<max value="*"></max>
<constraint>
@ -22548,9 +22502,7 @@ Period is not used for a duration (a measure of elapsed time). See [Duration](da
<element id="Population.modifierExtension">
<path value="Population.modifierExtension"></path>
<short value="Extensions that cannot be ignored even if unrecognized"></short>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions.
Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions. Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<comment value="There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone."></comment>
<requirements value="Modifier extensions allow for extensions that *cannot* be safely ignored to be clearly distinguished from the vast majority of extensions which can be safely ignored. This promotes interoperability by eliminating the need for implementers to prohibit the presence of extensions. For further information, see the [definition of modifier extensions](extensibility.html#modifierExtension)."></requirements>
<alias value="extensions"></alias>
@ -22897,9 +22849,7 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or
<element id="ProdCharacteristic.modifierExtension">
<path value="ProdCharacteristic.modifierExtension"></path>
<short value="Extensions that cannot be ignored even if unrecognized"></short>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions.
Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions. Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<comment value="There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone."></comment>
<requirements value="Modifier extensions allow for extensions that *cannot* be safely ignored to be clearly distinguished from the vast majority of extensions which can be safely ignored. This promotes interoperability by eliminating the need for implementers to prohibit the presence of extensions. For further information, see the [definition of modifier extensions](extensibility.html#modifierExtension)."></requirements>
<alias value="extensions"></alias>
@ -23492,9 +23442,7 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or
<element id="ProductShelfLife.modifierExtension">
<path value="ProductShelfLife.modifierExtension"></path>
<short value="Extensions that cannot be ignored even if unrecognized"></short>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions.
Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions. Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<comment value="There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone."></comment>
<requirements value="Modifier extensions allow for extensions that *cannot* be safely ignored to be clearly distinguished from the vast majority of extensions which can be safely ignored. This promotes interoperability by eliminating the need for implementers to prohibit the presence of extensions. For further information, see the [definition of modifier extensions](extensibility.html#modifierExtension)."></requirements>
<alias value="extensions"></alias>
@ -24994,9 +24942,7 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or
<element id="Reference.type">
<path value="Reference.type"></path>
<short value="Type the reference refers to (e.g. &quot;Patient&quot;)"></short>
<definition value="The expected type of the target of the reference. If both Reference.type and Reference.reference are populated and Reference.reference is a FHIR URL, both SHALL be consistent.
The type is the Canonical URL of Resource Definition that is the type this reference refers to. References are URLs that are relative to http://hl7.org/fhir/StructureDefinition/ e.g. &quot;Patient&quot; is a reference to http://hl7.org/fhir/StructureDefinition/Patient. Absolute URLs are only allowed for logical models (and can only be used in references in logical models, not resources)."></definition>
<definition value="The expected type of the target of the reference. If both Reference.type and Reference.reference are populated and Reference.reference is a FHIR URL, both SHALL be consistent. The type is the Canonical URL of Resource Definition that is the type this reference refers to. References are URLs that are relative to http://hl7.org/fhir/StructureDefinition/ e.g. &quot;Patient&quot; is a reference to http://hl7.org/fhir/StructureDefinition/Patient. Absolute URLs are only allowed for logical models (and can only be used in references in logical models, not resources)."></definition>
<comment value="This element is used to indicate the type of the target of the reference. This may be used which ever of the other elements are populated (or not). In some cases, the type of the target may be determined by inspection of the reference (e.g. a RESTful URL) or by resolving the target of the reference; if both the type and a reference is provided, the reference SHALL resolve to a resource of the same type as that specified."></comment>
<min value="0"></min>
<max value="1"></max>
@ -25035,13 +24981,7 @@ The type is the Canonical URL of Resource Definition that is the type this refer
<path value="Reference.identifier"></path>
<short value="Logical reference, when literal reference is not known"></short>
<definition value="An identifier for the target resource. This is used when there is no way to reference the other resource directly, either because the entity it represents is not available through a FHIR server, or because there is no way for the author of the resource to convert a known identifier to an actual location. There is no requirement that a Reference.identifier point to something that is actually exposed as a FHIR instance, but it SHALL point to a business concept that would be expected to be exposed as a FHIR instance, and that instance would need to be of a FHIR resource type allowed by the reference."></definition>
<comment value="When an identifier is provided in place of a reference, any system processing the reference will only be able to resolve the identifier to a reference if it understands the business context in which the identifier is used. Sometimes this is global (e.g. a national identifier) but often it is not. For this reason, none of the useful mechanisms described for working with references (e.g. chaining, includes) are possible, nor should servers be expected to be able resolve the reference. Servers may accept an identifier based reference untouched, resolve it, and/or reject it - see CapabilityStatement.rest.resource.referencePolicy.
When both an identifier and a literal reference are provided, the literal reference is preferred. Applications processing the resource are allowed - but not required - to check that the identifier matches the literal reference
Applications converting a logical reference to a literal reference may choose to leave the logical reference present, or remove it.
Reference is intended to point to a structure that can potentially be expressed as a FHIR resource, though there is no need for it to exist as an actual FHIR resource instance - except in as much as an application wishes to actual find the target of the reference. The content referred to be the identifier must meet the logical constraints implied by any limitations on what resource types are permitted for the reference. For example, it would not be legitimate to send the identifier for a drug prescription if the type were Reference(Observation|DiagnosticReport). One of the use-cases for Reference.identifier is the situation where no FHIR representation exists (where the type is Reference (Any)."></comment>
<comment value="When an identifier is provided in place of a reference, any system processing the reference will only be able to resolve the identifier to a reference if it understands the business context in which the identifier is used. Sometimes this is global (e.g. a national identifier) but often it is not. For this reason, none of the useful mechanisms described for working with references (e.g. chaining, includes) are possible, nor should servers be expected to be able resolve the reference. Servers may accept an identifier based reference untouched, resolve it, and/or reject it - see CapabilityStatement.rest.resource.referencePolicy. When both an identifier and a literal reference are provided, the literal reference is preferred. Applications processing the resource are allowed - but not required - to check that the identifier matches the literal reference Applications converting a logical reference to a literal reference may choose to leave the logical reference present, or remove it. Reference is intended to point to a structure that can potentially be expressed as a FHIR resource, though there is no need for it to exist as an actual FHIR resource instance - except in as much as an application wishes to actual find the target of the reference. The content referred to be the identifier must meet the logical constraints implied by any limitations on what resource types are permitted for the reference. For example, it would not be legitimate to send the identifier for a drug prescription if the type were Reference(Observation|DiagnosticReport). One of the use-cases for Reference.identifier is the situation where no FHIR representation exists (where the type is Reference (Any)."></comment>
<min value="0"></min>
<max value="1"></max>
<base>
@ -25147,9 +25087,7 @@ Reference is intended to point to a structure that can potentially be expressed
<element id="Reference.type">
<path value="Reference.type"></path>
<short value="Type the reference refers to (e.g. &quot;Patient&quot;)"></short>
<definition value="The expected type of the target of the reference. If both Reference.type and Reference.reference are populated and Reference.reference is a FHIR URL, both SHALL be consistent.
The type is the Canonical URL of Resource Definition that is the type this reference refers to. References are URLs that are relative to http://hl7.org/fhir/StructureDefinition/ e.g. &quot;Patient&quot; is a reference to http://hl7.org/fhir/StructureDefinition/Patient. Absolute URLs are only allowed for logical models (and can only be used in references in logical models, not resources)."></definition>
<definition value="The expected type of the target of the reference. If both Reference.type and Reference.reference are populated and Reference.reference is a FHIR URL, both SHALL be consistent. The type is the Canonical URL of Resource Definition that is the type this reference refers to. References are URLs that are relative to http://hl7.org/fhir/StructureDefinition/ e.g. &quot;Patient&quot; is a reference to http://hl7.org/fhir/StructureDefinition/Patient. Absolute URLs are only allowed for logical models (and can only be used in references in logical models, not resources)."></definition>
<comment value="This element is used to indicate the type of the target of the reference. This may be used which ever of the other elements are populated (or not). In some cases, the type of the target may be determined by inspection of the reference (e.g. a RESTful URL) or by resolving the target of the reference; if both the type and a reference is provided, the reference SHALL resolve to a resource of the same type as that specified."></comment>
<min value="0"></min>
<max value="1"></max>
@ -25174,13 +25112,7 @@ The type is the Canonical URL of Resource Definition that is the type this refer
<path value="Reference.identifier"></path>
<short value="Logical reference, when literal reference is not known"></short>
<definition value="An identifier for the target resource. This is used when there is no way to reference the other resource directly, either because the entity it represents is not available through a FHIR server, or because there is no way for the author of the resource to convert a known identifier to an actual location. There is no requirement that a Reference.identifier point to something that is actually exposed as a FHIR instance, but it SHALL point to a business concept that would be expected to be exposed as a FHIR instance, and that instance would need to be of a FHIR resource type allowed by the reference."></definition>
<comment value="When an identifier is provided in place of a reference, any system processing the reference will only be able to resolve the identifier to a reference if it understands the business context in which the identifier is used. Sometimes this is global (e.g. a national identifier) but often it is not. For this reason, none of the useful mechanisms described for working with references (e.g. chaining, includes) are possible, nor should servers be expected to be able resolve the reference. Servers may accept an identifier based reference untouched, resolve it, and/or reject it - see CapabilityStatement.rest.resource.referencePolicy.
When both an identifier and a literal reference are provided, the literal reference is preferred. Applications processing the resource are allowed - but not required - to check that the identifier matches the literal reference
Applications converting a logical reference to a literal reference may choose to leave the logical reference present, or remove it.
Reference is intended to point to a structure that can potentially be expressed as a FHIR resource, though there is no need for it to exist as an actual FHIR resource instance - except in as much as an application wishes to actual find the target of the reference. The content referred to be the identifier must meet the logical constraints implied by any limitations on what resource types are permitted for the reference. For example, it would not be legitimate to send the identifier for a drug prescription if the type were Reference(Observation|DiagnosticReport). One of the use-cases for Reference.identifier is the situation where no FHIR representation exists (where the type is Reference (Any)."></comment>
<comment value="When an identifier is provided in place of a reference, any system processing the reference will only be able to resolve the identifier to a reference if it understands the business context in which the identifier is used. Sometimes this is global (e.g. a national identifier) but often it is not. For this reason, none of the useful mechanisms described for working with references (e.g. chaining, includes) are possible, nor should servers be expected to be able resolve the reference. Servers may accept an identifier based reference untouched, resolve it, and/or reject it - see CapabilityStatement.rest.resource.referencePolicy. When both an identifier and a literal reference are provided, the literal reference is preferred. Applications processing the resource are allowed - but not required - to check that the identifier matches the literal reference Applications converting a logical reference to a literal reference may choose to leave the logical reference present, or remove it. Reference is intended to point to a structure that can potentially be expressed as a FHIR resource, though there is no need for it to exist as an actual FHIR resource instance - except in as much as an application wishes to actual find the target of the reference. The content referred to be the identifier must meet the logical constraints implied by any limitations on what resource types are permitted for the reference. For example, it would not be legitimate to send the identifier for a drug prescription if the type were Reference(Observation|DiagnosticReport). One of the use-cases for Reference.identifier is the situation where no FHIR representation exists (where the type is Reference (Any)."></comment>
<min value="0"></min>
<max value="1"></max>
<type>
@ -26799,9 +26731,7 @@ Reference is intended to point to a structure that can potentially be expressed
<element id="SubstanceAmount.modifierExtension">
<path value="SubstanceAmount.modifierExtension"></path>
<short value="Extensions that cannot be ignored even if unrecognized"></short>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions.
Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions. Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<comment value="There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone."></comment>
<requirements value="Modifier extensions allow for extensions that *cannot* be safely ignored to be clearly distinguished from the vast majority of extensions which can be safely ignored. This promotes interoperability by eliminating the need for implementers to prohibit the presence of extensions. For further information, see the [definition of modifier extensions](extensibility.html#modifierExtension)."></requirements>
<alias value="extensions"></alias>
@ -27214,9 +27144,7 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or
<path value="Timing"></path>
<short value="A timing schedule that specifies an event that may occur multiple times"></short>
<definition value="Specifies an event that may occur multiple times. Timing schedules are used to record when things are planned, expected or requested to occur. The most common usage is in dosage instructions for medications. They are also used when planning care of various kinds, and may be used for reporting the schedule to which past regular activities were carried out."></definition>
<comment value="Describes the occurrence of an event that may occur multiple times. Timing schedules are used for specifying when events are expected or requested to occur, and may also be used to represent the summary of a past or ongoing event. For simplicity, the definitions of Timing components are expressed as 'future' events, but such components can also be used to describe historic or ongoing events.
A Timing schedule can be a list of events and/or criteria for when the event happens, which can be expressed in a structured form and/or as a code. When both event and a repeating specification are provided, the list of events should be understood as an interpretation of the information in the repeat structure."></comment>
<comment value="Describes the occurrence of an event that may occur multiple times. Timing schedules are used for specifying when events are expected or requested to occur, and may also be used to represent the summary of a past or ongoing event. For simplicity, the definitions of Timing components are expressed as 'future' events, but such components can also be used to describe historic or ongoing events. A Timing schedule can be a list of events and/or criteria for when the event happens, which can be expressed in a structured form and/or as a code. When both event and a repeating specification are provided, the list of events should be understood as an interpretation of the information in the repeat structure."></comment>
<min value="0"></min>
<max value="*"></max>
<base>
@ -27323,9 +27251,7 @@ A Timing schedule can be a list of events and/or criteria for when the event hap
<element id="Timing.modifierExtension">
<path value="Timing.modifierExtension"></path>
<short value="Extensions that cannot be ignored even if unrecognized"></short>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions.
Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<definition value="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions. Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)."></definition>
<comment value="There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone."></comment>
<requirements value="Modifier extensions allow for extensions that *cannot* be safely ignored to be clearly distinguished from the vast majority of extensions which can be safely ignored. This promotes interoperability by eliminating the need for implementers to prohibit the presence of extensions. For further information, see the [definition of modifier extensions](extensibility.html#modifierExtension)."></requirements>
<alias value="extensions"></alias>
@ -28095,9 +28021,7 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or
<path value="Timing"></path>
<short value="A timing schedule that specifies an event that may occur multiple times"></short>
<definition value="Specifies an event that may occur multiple times. Timing schedules are used to record when things are planned, expected or requested to occur. The most common usage is in dosage instructions for medications. They are also used when planning care of various kinds, and may be used for reporting the schedule to which past regular activities were carried out."></definition>
<comment value="Describes the occurrence of an event that may occur multiple times. Timing schedules are used for specifying when events are expected or requested to occur, and may also be used to represent the summary of a past or ongoing event. For simplicity, the definitions of Timing components are expressed as 'future' events, but such components can also be used to describe historic or ongoing events.
A Timing schedule can be a list of events and/or criteria for when the event happens, which can be expressed in a structured form and/or as a code. When both event and a repeating specification are provided, the list of events should be understood as an interpretation of the information in the repeat structure."></comment>
<comment value="Describes the occurrence of an event that may occur multiple times. Timing schedules are used for specifying when events are expected or requested to occur, and may also be used to represent the summary of a past or ongoing event. For simplicity, the definitions of Timing components are expressed as 'future' events, but such components can also be used to describe historic or ongoing events. A Timing schedule can be a list of events and/or criteria for when the event happens, which can be expressed in a structured form and/or as a code. When both event and a repeating specification are provided, the list of events should be understood as an interpretation of the information in the repeat structure."></comment>
<min value="0"></min>
<max value="*"></max>
<mapping>

View File

@ -3995,9 +3995,7 @@
<concept>
<code value="trial-use"></code>
<display value="Trial-Use"></display>
<definition value="This content has been well reviewed and is considered by the authors to be ready for use in production systems. It has been subjected to ballot and approved as an official standard. However, it has not yet seen widespread use in production across the full spectrum of environments it is intended to be used in. In some cases, there may be documented known issues that require implementation experience to determine appropriate resolutions for.
Future versions of FHIR may make significant changes to Trial Use content that are not compatible with previously published content."></definition>
<definition value="This content has been well reviewed and is considered by the authors to be ready for use in production systems. It has been subjected to ballot and approved as an official standard. However, it has not yet seen widespread use in production across the full spectrum of environments it is intended to be used in. In some cases, there may be documented known issues that require implementation experience to determine appropriate resolutions for. Future versions of FHIR may make significant changes to Trial Use content that are not compatible with previously published content."></definition>
</concept>
<concept>
<code value="informative"></code>
@ -13704,8 +13702,7 @@ Future versions of FHIR may make significant changes to Trial Use content that a
<concept>
<code value="BiologicallyDerivedProduct"></code>
<display value="BiologicallyDerivedProduct"></display>
<definition value="A material substance originating from a biological entity intended to be transplanted or infused
into another (possibly the same) biological entity."></definition>
<definition value="A material substance originating from a biological entity intended to be transplanted or infused into another (possibly the same) biological entity."></definition>
<designation>
<language value="en"></language>
<use>
@ -16164,9 +16161,7 @@ into another (possibly the same) biological entity."></definition>
<concept>
<code value="MedicationStatement"></code>
<display value="MedicationStatement"></display>
<definition value="A record of a medication that is being consumed by a patient. A MedicationStatement may indicate that the patient may be taking the medication now or has taken the medication in the past or will be taking the medication in the future. The source of this information can be the patient, significant other (such as a family member or spouse), or a clinician. A common scenario where this information is captured is during the history taking process during a patient visit or stay. The medication information may come from sources such as the patient's memory, from a prescription bottle, or from a list of medications the patient, clinician or other party maintains.
The primary difference between a medication statement and a medication administration is that the medication administration has complete administration information and is based on actual administration information from the person who administered the medication. A medication statement is often, if not always, less specific. There is no required date/time when the medication was administered, in fact we only know that a source has reported the patient is taking this medication, where details such as time, quantity, or rate or even medication product may be incomplete or missing or less precise. As stated earlier, the medication statement information may come from the patient's memory, from a prescription bottle or from a list of medications the patient, clinician or other party maintains. Medication administration is more formal and is not missing detailed information."></definition>
<definition value="A record of a medication that is being consumed by a patient. A MedicationStatement may indicate that the patient may be taking the medication now or has taken the medication in the past or will be taking the medication in the future. The source of this information can be the patient, significant other (such as a family member or spouse), or a clinician. A common scenario where this information is captured is during the history taking process during a patient visit or stay. The medication information may come from sources such as the patient's memory, from a prescription bottle, or from a list of medications the patient, clinician or other party maintains. The primary difference between a medication statement and a medication administration is that the medication administration has complete administration information and is based on actual administration information from the person who administered the medication. A medication statement is often, if not always, less specific. There is no required date/time when the medication was administered, in fact we only know that a source has reported the patient is taking this medication, where details such as time, quantity, or rate or even medication product may be incomplete or missing or less precise. As stated earlier, the medication statement information may come from the patient's memory, from a prescription bottle or from a list of medications the patient, clinician or other party maintains. Medication administration is more formal and is not missing detailed information."></definition>
<designation>
<language value="en"></language>
<use>
@ -24395,8 +24390,7 @@ The primary difference between a medication statement and a medication administr
<concept>
<code value="completed"></code>
<display value="Completed"></display>
<definition value="Study is closed to accrual and intervention, i.e. the study is closed to enrollment, all study subjects have completed treatment
or intervention but are still being followed according to the primary objective of the study."></definition>
<definition value="Study is closed to accrual and intervention, i.e. the study is closed to enrollment, all study subjects have completed treatment or intervention but are still being followed according to the primary objective of the study."></definition>
</concept>
<concept>
<code value="disapproved"></code>
@ -29991,7 +29985,7 @@ or intervention but are still being followed according to the primary objective
<concept>
<code value="active"></code>
<display value="Active"></display>
<definition value="The patient is currently at this location, or was between the period specified. A system may update these records when the patient leaves the location to either reserved, or completed."></definition>
<definition value="The patient is currently at this location, or was between the period specified. A system may update these records when the patient leaves the location to either reserved, or completed."></definition>
</concept>
<concept>
<code value="reserved"></code>
@ -30001,7 +29995,7 @@ or intervention but are still being followed according to the primary objective
<concept>
<code value="completed"></code>
<display value="Completed"></display>
<definition value="The patient was at this location during the period specified. Not to be used when the patient is currently at the location."></definition>
<definition value="The patient was at this location during the period specified. Not to be used when the patient is currently at the location."></definition>
</concept>
</CodeSystem>
</resource>
@ -30396,20 +30390,17 @@ or intervention but are still being followed according to the primary objective
<concept>
<code value="1100"></code>
<display value="Unvorhergesehene Inanspruchnahme"></display>
<definition value="From German EBM billing system:
Unvorhergesehene Inanspruchnahme des Vertragsarztes durch einen Patienten;zwischen 19:00 und 22:00 Uhr;an Samstagen, Sonntagen und gesetzlichen Feiertagen, am 24.12. und 31.12. zwischen 07:00 und 19:00 Uhr."></definition>
<definition value="From German EBM billing system: Unvorhergesehene Inanspruchnahme des Vertragsarztes durch einen Patienten;zwischen 19:00 und 22:00 Uhr;an Samstagen, Sonntagen und gesetzlichen Feiertagen, am 24.12. und 31.12. zwischen 07:00 und 19:00 Uhr."></definition>
</concept>
<concept>
<code value="1210"></code>
<display value="Notfallpauschale"></display>
<definition value="From German EBM billing system:
Notfallpauschale im organisierten Not(-fall)dienst und für nicht an der vertragsärztlichen Versorgung teilnehmende Ärzte, Institute und Krankenhäuser bei Inanspruchnahme;zwischen 07:00 und 19:00 Uhr."></definition>
<definition value="From German EBM billing system: Notfallpauschale im organisierten Not(-fall)dienst und für nicht an der vertragsärztlichen Versorgung teilnehmende Ärzte, Institute und Krankenhäuser bei Inanspruchnahme;zwischen 07:00 und 19:00 Uhr."></definition>
</concept>
<concept>
<code value="1320"></code>
<display value="Grundpauschale"></display>
<definition value="From German EBM billing system:
Grundpauschale für Ärzte, Institute und Krankenhäuser, die zur Erbringung von Leistungen innerhalb mindestens eines der Fachgebiete Anästhesiologie, Frauenheilkunde und Geburtshilfe, Haut- und Geschlechtskrankheiten, Mund-, Kiefer- und Gesichtschirurgie und Humangenetik ermächtigt sind."></definition>
<definition value="From German EBM billing system: Grundpauschale für Ärzte, Institute und Krankenhäuser, die zur Erbringung von Leistungen innerhalb mindestens eines der Fachgebiete Anästhesiologie, Frauenheilkunde und Geburtshilfe, Haut- und Geschlechtskrankheiten, Mund-, Kiefer- und Gesichtschirurgie und Humangenetik ermächtigt sind."></definition>
</concept>
</CodeSystem>
</resource>
@ -30588,8 +30579,7 @@ Grundpauschale für Ärzte, Institute und Krankenhäuser, die zur Erbringung von
<concept>
<code value="ineligible"></code>
<display value="Ineligible"></display>
<definition value="A person who did not meet one or more criteria required for participation in a study is considered to have failed screening or
is ineligible for the study."></definition>
<definition value="A person who did not meet one or more criteria required for participation in a study is considered to have failed screening or is ineligible for the study."></definition>
</concept>
<concept>
<code value="not-registered"></code>
@ -30599,8 +30589,7 @@ is ineligible for the study."></definition>
<concept>
<code value="off-study"></code>
<display value="Off-study"></display>
<definition value="A person that has ended their participation on a study either because their treatment/observation is complete or through not
responding, withdrawal, non-compliance and/or adverse event."></definition>
<definition value="A person that has ended their participation on a study either because their treatment/observation is complete or through not responding, withdrawal, non-compliance and/or adverse event."></definition>
</concept>
<concept>
<code value="on-study"></code>
@ -31870,8 +31859,7 @@ responding, withdrawal, non-compliance and/or adverse event."></definition>
<concept>
<code value="waitlist"></code>
<display value="Waitlisted"></display>
<definition value="The appointment has been placed on a waitlist, to be scheduled/confirmed in the future when a slot/service is available.
A specific time might or might not be pre-allocated."></definition>
<definition value="The appointment has been placed on a waitlist, to be scheduled/confirmed in the future when a slot/service is available. A specific time might or might not be pre-allocated."></definition>
</concept>
</CodeSystem>
</resource>
@ -43931,9 +43919,7 @@ A specific time might or might not be pre-allocated."></definition>
</concept>
<concept>
<extension url="http://hl7.org/fhir/StructureDefinition/codesystem-concept-comments">
<valueString value="The definition of is-a is that all the properties of the value are true for the specified property of the code.
Spelling note: &quot;descendant&quot; is a more correct spelling, but the spelling &quot;descendent&quot; is maintained in the code for backwards compatibility reasons"></valueString>
<valueString value="The definition of is-a is that all the properties of the value are true for the specified property of the code. Spelling note: &quot;descendant&quot; is a more correct spelling, but the spelling &quot;descendent&quot; is maintained in the code for backwards compatibility reasons"></valueString>
</extension>
<code value="descendent-of"></code>
<display value="Descendent Of (by subsumption)"></display>
@ -133894,11 +133880,7 @@ Spelling note: &quot;descendant&quot; is a more correct spelling, but the spelli
<value value="http://hl7.org/fhir"></value>
</telecom>
</contact>
<description value="A categorical assessment, providing a rough qualitative interpretation of the observation value, such as normal/ abnormal,low / high, better / worse, susceptible / resistant, expected/ not expected. The value set is intended to be for ANY use where coded representation of an interpretation is needed.
Notes:
This is being communicated in v2.x in OBX-8 (Observation Interpretation), in v3 in ObservationInterpretation (CWE) in R1 (Representative Realm) and in FHIR in Observation.interpretation. Historically these values come from the laboratory domain, and these codes are extensively used. The value set binding is extensible, so codes outside the value set that are needed for interpretation concepts (i.e. particular meanings) that are not included in the value set can be used, and these new codes may also be added to the value set and published in a future version."></description>
<description value="A categorical assessment, providing a rough qualitative interpretation of the observation value, such as “normal”/ “abnormal”,”low” / “high”, “better” / “worse”, “susceptible” / “resistant”, “expected”/ “not expected”. The value set is intended to be for ANY use where coded representation of an interpretation is needed. Notes: This is being communicated in v2.x in OBX-8 (Observation Interpretation), in v3 in ObservationInterpretation (CWE) in R1 (Representative Realm) and in FHIR in Observation.interpretation. Historically these values come from the laboratory domain, and these codes are extensively used. The value set binding is extensible, so codes outside the value set that are needed for interpretation concepts (i.e. particular meanings) that are not included in the value set can be used, and these new codes may also be added to the value set and published in a future version."></description>
<compose>
<include>
<system value="http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation"></system>
@ -135910,9 +135892,7 @@ Spelling note: &quot;descendant&quot; is a more correct spelling, but the spelli
<value value="http://hl7.org/fhir"></value>
</telecom>
</contact>
<description value="This value set defines a base set of codes for country, country subdivision and region for indicating where a resource is intended to be used.
Note: The codes for countries and country subdivisions are taken from [ISO 3166](https://www.iso.org/iso-3166-country-codes.html) while the codes for &quot;supra-national&quot; regions are from [UN Standard country or area codes for statistical use (M49)](http://unstats.un.org/unsd/methods/m49/m49.htm)."></description>
<description value="This value set defines a base set of codes for country, country subdivision and region for indicating where a resource is intended to be used. Note: The codes for countries and country subdivisions are taken from [ISO 3166](https://www.iso.org/iso-3166-country-codes.html) while the codes for &quot;supra-national&quot; regions are from [UN Standard country or area codes for statistical use (M49)](http://unstats.un.org/unsd/methods/m49/m49.htm)."></description>
<compose>
<include>
<system value="urn:iso:std:iso:3166"></system>

View File

@ -30,6 +30,36 @@
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>org.hl7.fhir.validation</artifactId>
<version>${fhir_core_version}</version>
<exclusions>
<exclusion>
<groupId>info.cqframework</groupId>
<artifactId>elm</artifactId>
</exclusion>
<exclusion>
<groupId>info.cqframework</groupId>
<artifactId>cql-to-elm</artifactId>
</exclusion>
<exclusion>
<groupId>info.cqframework</groupId>
<artifactId>quick</artifactId>
</exclusion>
<exclusion>
<groupId>info.cqframework</groupId>
<artifactId>qdm</artifactId>
</exclusion>
<exclusion>
<groupId>info.cqframework</groupId>
<artifactId>cql</artifactId>
</exclusion>
<exclusion>
<groupId>info.cqframework</groupId>
<artifactId>model</artifactId>
</exclusion>
<exclusion>
<groupId>io.javalin</groupId>
<artifactId>javalin</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>

View File

@ -28,12 +28,15 @@ import org.hl7.fhir.r5.terminologies.ValueSetExpander;
import org.hl7.fhir.r5.utils.INarrativeGenerator;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.utilities.TranslationServices;
import org.hl7.fhir.utilities.cache.NpmPackage;
import org.hl7.fhir.utilities.i18n.I18nBase;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.utilities.validation.ValidationOptions;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@ -111,6 +114,16 @@ class VersionSpecificWorkerContextWrapper extends I18nBase implements IWorkerCon
return null;
}
@Override
public void loadFromPackage(NpmPackage pi, IContextResourceLoader loader, String[] types) throws FileNotFoundException, IOException, FHIRException {
}
@Override
public boolean hasPackage(String id, String ver) {
return false;
}
@Override
public void generateSnapshot(StructureDefinition input) throws FHIRException {
if (input.hasSnapshot()) {
@ -172,6 +185,16 @@ class VersionSpecificWorkerContextWrapper extends I18nBase implements IWorkerCon
throw new UnsupportedOperationException();
}
@Override
public void cacheResourceFromPackage(Resource res, PackageVersion packageDetails) throws FHIRException {
}
@Override
public void cachePackage(PackageVersion packageDetails, List<PackageVersion> dependencies) {
}
@Nonnull
private ValidationResult convertValidationResult(@Nullable IValidationSupport.CodeValidationResult theResult) {
ValidationResult retVal = null;
@ -283,6 +306,11 @@ class VersionSpecificWorkerContextWrapper extends I18nBase implements IWorkerCon
return retVal;
}
@Override
public <T extends Resource> T fetchResource(Class<T> class_, String uri, CanonicalResource canonicalForSource) {
throw new UnsupportedOperationException();
}
@Override
public List<org.hl7.fhir.r5.model.ConceptMap> findMapsForSource(String url) {
throw new UnsupportedOperationException();
@ -330,7 +358,7 @@ class VersionSpecificWorkerContextWrapper extends I18nBase implements IWorkerCon
@Override
public void setOverrideVersionNs(String value) {
throw new UnsupportedOperationException();
}
@Override

View File

@ -52,6 +52,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;
import static org.hamcrest.Matchers.containsString;
@ -584,6 +585,20 @@ public class FhirInstanceValidatorDstu3Test {
ValidationResult output = myVal.validateWithResult(next);
List<SingleValidationMessage> errors = logResultsAndReturnNonInformationalOnes(output);
errors = errors
.stream()
.filter(t->{
if (t.getLocationString().contains("example")) {
ourLog.warn("Ignoring error in example path: {}", t);
return false;
} else {
return true;
}
})
.collect(Collectors.toList());;
assertThat("Failed to validate " + i.getFullUrl() + " - " + errors, errors, empty());
}
@ -860,7 +875,8 @@ public class FhirInstanceValidatorDstu3Test {
ValidationResult output = myVal.validateWithResult(input);
List<SingleValidationMessage> res = logResultsAndReturnNonInformationalOnes(output);
assertEquals(output.toString(), 0, res.size());
assertEquals(output.toString(), 1, res.size());
assertEquals("A code with no system has no defined meaning. A system should be provided", output.getMessages().get(0).getMessage());
}
/**
@ -1031,7 +1047,7 @@ public class FhirInstanceValidatorDstu3Test {
ValidationResult output = myVal.validateWithResult(input);
logResultsAndReturnAll(output);
assertEquals(
"The value provided (\"notvalidcode\") is not in the value set http://hl7.org/fhir/ValueSet/observation-status (http://hl7.org/fhir/ValueSet/observation-status, and a code is required from this value set) (error message = Unknown code 'notvalidcode')",
"The value provided (\"notvalidcode\") is not in the value set http://hl7.org/fhir/ValueSet/observation-status (http://hl7.org/fhir/ValueSet/observation-status), and a code is required from this value set) (error message = Unknown code 'notvalidcode')",
output.getMessages().get(0).getMessage());
}
@ -1128,7 +1144,7 @@ public class FhirInstanceValidatorDstu3Test {
assertEquals(1, all.size());
assertEquals("Patient.identifier[0].type", all.get(0).getLocationString());
assertEquals(
"None of the codes provided are in the value set http://hl7.org/fhir/ValueSet/identifier-type (http://hl7.org/fhir/ValueSet/identifier-type, and a code should come from this value set unless it has no suitable code) (codes = http://example.com/foo/bar#bar)",
"None of the codes provided are in the value set http://hl7.org/fhir/ValueSet/identifier-type (http://hl7.org/fhir/ValueSet/identifier-type), and a code should come from this value set unless it has no suitable code) (codes = http://example.com/foo/bar#bar)",
all.get(0).getMessage());
assertEquals(ResultSeverityEnum.WARNING, all.get(0).getSeverity());

View File

@ -364,7 +364,7 @@ public class QuestionnaireResponseValidatorDstu3Test {
ValidationResult errors = myVal.validateWithResult(qa);
ourLog.info(errors.toString());
assertThat(errors.toString(), containsString("No response found for required item with id = 'link0'"));
assertThat(errors.toString(), containsString("No response answer found for required item \"link0\""));
}
@Test
@ -490,7 +490,7 @@ public class QuestionnaireResponseValidatorDstu3Test {
ValidationResult errors = myVal.validateWithResult(qa);
ourLog.info(errors.toString());
assertThat(errors.toString(), containsString("No response found for required item with id = 'link1'"));
assertThat(errors.toString(), containsString(" No response answer found for required item \"link1\""));
}
@Test
@ -541,7 +541,7 @@ public class QuestionnaireResponseValidatorDstu3Test {
qa.addItem().setLinkId("link0").addAnswer().setValue(new Coding("http://foo", "YES", null));
errors = myVal.validateWithResult(qa);
ourLog.info(errors.toString());
assertThat(errors.toString(), containsString("No response found for required item with id = 'link1'"));
assertThat(errors.toString(), containsString("No response answer found for required item \"link1\""));
}
@Test
@ -669,7 +669,7 @@ public class QuestionnaireResponseValidatorDstu3Test {
// Without an answer
ValidationResult errors = myVal.validateWithResult(qr);
assertThat(errors.toString(), containsString("No response found for required item with id = 'link2'"));
assertThat(errors.toString(), containsString("No response answer found for required item \"link2\""));
// With an answer
qr.getItem().get(2).addAnswer().setValue(new StringType("AAA"));
@ -702,6 +702,7 @@ public class QuestionnaireResponseValidatorDstu3Test {
public void testAnswerIsValueCodingWithExtensionInside() {
Questionnaire q = new Questionnaire();
Coding qcoding = new Coding();
qcoding.setSystem("http://foo");
qcoding.setCode("1293");
q.addItem().setLinkId("1B").setRequired(true).setType(CHOICE).addOption().setValue(qcoding);
q.addItem().setLinkId("2B").setType(BOOLEAN).addEnableWhen().setQuestion("1B").setAnswer(qcoding);
@ -711,6 +712,7 @@ public class QuestionnaireResponseValidatorDstu3Test {
qr.getQuestionnaire().setReference(QUESTIONNAIRE_URL);
QuestionnaireResponseItemComponent qrItem = qr.addItem().setLinkId("1B");
Coding coding = new Coding();
coding.setSystem("http://foo");
coding.setCode("1293");
QuestionnaireResponseItemAnswerComponent answer = qrItem.addAnswer();
answer.setValue(coding);
@ -1062,9 +1064,11 @@ public class QuestionnaireResponseValidatorDstu3Test {
qa.addItem().setLinkId("link0").addAnswer().setValue(new Coding().setSystem(null).setCode("code1"));
errors = myVal.validateWithResult(qa);
errors = stripBindingHasNoSourceMessage(errors);
ourLog.info(errors.toString());
assertThat(errors.toString(), containsString("The value provided (null::code1) is not in the options value set in the questionnaire"));
assertThat(errors.toString(), containsString("QuestionnaireResponse.item[0].answer[0]"));
assertEquals(2, errors.getMessages().size());
assertThat(errors.getMessages().get(0).getMessage(), containsString("A code with no system has no defined meaning. A system should be provided"));
assertThat(errors.getMessages().get(0).getLocationString(), containsString("QuestionnaireResponse.item[0].answer[0]"));
assertThat(errors.getMessages().get(1).getMessage(), containsString("The value provided (null::code1) is not in the options value set in the questionnaire"));
assertThat(errors.getMessages().get(1).getLocationString(), containsString("QuestionnaireResponse.item[0].answer[0]"));
qa = new QuestionnaireResponse();
qa.setStatus(QuestionnaireResponseStatus.COMPLETED);
@ -1073,8 +1077,11 @@ public class QuestionnaireResponseValidatorDstu3Test {
errors = myVal.validateWithResult(qa);
errors = stripBindingHasNoSourceMessage(errors);
ourLog.info(errors.toString());
assertThat(errors.toString(), containsString("The value provided (null::code1) is not in the options value set in the questionnaire"));
assertThat(errors.toString(), containsString("QuestionnaireResponse.item[0].answer[0]"));
assertEquals(2, errors.getMessages().size());
assertThat(errors.getMessages().get(0).getMessage(), containsString("A code with no system has no defined meaning. A system should be provided"));
assertThat(errors.getMessages().get(0).getLocationString(), containsString("QuestionnaireResponse.item[0].answer[0]"));
assertThat(errors.getMessages().get(1).getMessage(), containsString("The value provided (null::code1) is not in the options value set in the questionnaire"));
assertThat(errors.getMessages().get(1).getLocationString(), containsString("QuestionnaireResponse.item[0].answer[0]"));
qa = new QuestionnaireResponse();
qa.setStatus(QuestionnaireResponseStatus.COMPLETED);
@ -1114,7 +1121,7 @@ public class QuestionnaireResponseValidatorDstu3Test {
qa.addItem().setLinkId("link0").addAnswer().setValue(new Coding().setDisplay(""));
errors = myVal.validateWithResult(qa);
ourLog.info(errors.toString());
assertThat(errors.toString(), containsString("No response found for required item with id = 'link0'"));
assertThat(errors.toString(), containsString("No response answer found for required item \"link0\""));
}
@Test

View File

@ -10,12 +10,13 @@ import ca.uhn.fhir.validation.ValidationResult;
import org.hamcrest.Matchers;
import org.hl7.fhir.common.hapi.validation.support.InMemoryTerminologyServerValidationSupport;
import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus;
import org.hl7.fhir.dstu3.model.Questionnaire;
import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemType;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
@ -74,7 +75,7 @@ public class QuestionnaireValidatorDstu3Test {
.setType(QuestionnaireItemType.STRING)
.addExtension()
.setUrl(extensionDomainToTest)
.setValue(new Coding(null, "text-box", null));
.setValue(new CodeType("text-box"));
ValidationResult errors = myVal.validateWithResult(q);
ourLog.info(errors.toString());
@ -131,7 +132,7 @@ public class QuestionnaireValidatorDstu3Test {
.setType(QuestionnaireItemType.STRING)
.addExtension()
.setUrl(extensionUrl + "questionnaire-itemControl")
.setValue(new Coding(null, "text-box", null));
.setValue(new CodeType("text-box"));
ValidationResult errors = myVal.validateWithResult(q);

View File

@ -165,7 +165,7 @@ public class ResourceValidatorDstu3Test {
ValidationResult output = val.validateWithResult(p);
List<SingleValidationMessage> all = logResultsAndReturnNonInformationalOnes(output);
assertEquals("None of the codes provided are in the value set http://hl7.org/fhir/ValueSet/marital-status (http://hl7.org/fhir/ValueSet/marital-status, and a code should come from this value set unless it has no suitable code) (codes = http://hl7.org/fhir/v3/MaritalStatus#FOO)", output.getMessages().get(0).getMessage());
assertEquals("None of the codes provided are in the value set http://hl7.org/fhir/ValueSet/marital-status (http://hl7.org/fhir/ValueSet/marital-status), and a code should come from this value set unless it has no suitable code) (codes = http://hl7.org/fhir/v3/MaritalStatus#FOO)", output.getMessages().get(0).getMessage());
assertEquals(ResultSeverityEnum.WARNING, output.getMessages().get(0).getSeverity());
}

View File

@ -605,7 +605,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
ValidationResult output = myVal.validateWithResult(input);
List<SingleValidationMessage> errors = logResultsAndReturnAll(output);
assertEquals(1, errors.size());
assertEquals("None of the codes provided are in the value set http://hl7.org/fhir/ValueSet/report-codes (http://hl7.org/fhir/ValueSet/report-codes, and a code is recommended to come from this value set) (codes = http://loinc.org#1-8)", errors.get(0).getMessage());
assertEquals("None of the codes provided are in the value set http://hl7.org/fhir/ValueSet/report-codes (http://hl7.org/fhir/ValueSet/report-codes), and a code is recommended to come from this value set) (codes = http://loinc.org#1-8)", errors.get(0).getMessage());
}
@Test
@ -1006,7 +1006,8 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
ValidationResult output = myVal.validateWithResult(input);
List<SingleValidationMessage> res = logResultsAndReturnNonInformationalOnes(output);
assertEquals(output.toString(), 0, res.size());
assertEquals(output.toString(), 1, res.size());
assertEquals("A code with no system has no defined meaning. A system should be provided", output.getMessages().get(0).getMessage());
}
/**
@ -1178,7 +1179,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
ValidationResult output = myVal.validateWithResult(input);
logResultsAndReturnAll(output);
assertEquals(
"The value provided (\"notvalidcode\") is not in the value set http://hl7.org/fhir/ValueSet/observation-status|4.0.1 (http://hl7.org/fhir/ValueSet/observation-status, and a code is required from this value set) (error message = Unknown code 'notvalidcode')",
"The value provided (\"notvalidcode\") is not in the value set http://hl7.org/fhir/ValueSet/observation-status|4.0.1 (http://hl7.org/fhir/ValueSet/observation-status), and a code is required from this value set) (error message = Unknown code 'notvalidcode')",
output.getMessages().get(0).getMessage());
}

View File

@ -41,7 +41,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class QuestionnaireResponseValidatorR4Test {
public static final String ID_ICC_QUESTIONNAIRE_SETUP = "Questionnaire/profile";
public static final String ID_ICC_QUESTIONNAIRE_SETUP = "http://example.com/Questionnaire/profile";
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(QuestionnaireResponseValidatorR4Test.class);
private static final String CODE_ICC_SCHOOLTYPE_PT = "PT";
private static final String ID_VS_SCHOOLTYPE = "ValueSet/schooltype";
@ -318,7 +318,7 @@ public class QuestionnaireResponseValidatorR4Test {
ValidationResult errors = myVal.validateWithResult(qa);
ourLog.info(errors.toString());
assertThat(errors.toString(), containsString("No response found for required item with id = 'link0'"));
assertThat(errors.toString(), containsString("No response answer found for required item \"link0\""));
}
@Test
@ -640,7 +640,7 @@ public class QuestionnaireResponseValidatorR4Test {
qa.addItem().setLinkId("link0").addAnswer().setValue(new Coding().setDisplay(""));
errors = myVal.validateWithResult(qa);
ourLog.info(errors.toString());
assertThat(errors.toString(), containsString("No response found for required item with id = 'link0'"));
assertThat(errors.toString(), containsString("No response answer found for required item \"link0\""));
}

View File

@ -11,6 +11,7 @@ import org.hamcrest.Matchers;
import org.hl7.fhir.common.hapi.validation.support.InMemoryTerminologyServerValidationSupport;
import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.Enumerations.PublicationStatus;
@ -55,7 +56,7 @@ public class QuestionnaireValidatorR4Test {
@Test
public void testQuestionnaireWithPredefinedExtensionDomainsForCoding() {
String[] extensionDomainsToTest = new String[] {
String[] extensionDomainsToTest = new String[]{
"http://example.org/questionnaire-color-control-1",
"https://example.org/questionnaire-color-control-2",
"http://acme.com/questionnaire-color-control-3",
@ -72,18 +73,18 @@ public class QuestionnaireValidatorR4Test {
.setType(QuestionnaireItemType.STRING)
.addExtension()
.setUrl(extensionDomainToTest)
.setValue(new Coding(null, "text-box", null));
.setValue(new CodeType("text-box"));
ValidationResult errors = myVal.validateWithResult(q);
ourLog.info(errors.toString());
assertThat(errors.isSuccessful(), Matchers.is(true));
assertThat(errors.getMessages().stream().filter(t->t.getSeverity().ordinal() > ResultSeverityEnum.INFORMATION.ordinal()).collect(Collectors.toList()), Matchers.empty());
assertThat(errors.getMessages().stream().filter(t -> t.getSeverity().ordinal() > ResultSeverityEnum.INFORMATION.ordinal()).collect(Collectors.toList()), Matchers.empty());
}
}
@Test
public void testQuestionnaireWithPredefinedExtensionDomainsForCodeableConcept() {
String[] extensionDomainsToTest = new String[] {
String[] extensionDomainsToTest = new String[]{
"http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl",
};
for (String extensionDomainToTest : extensionDomainsToTest) {
@ -111,7 +112,7 @@ public class QuestionnaireValidatorR4Test {
.setType(QuestionnaireItemType.STRING)
.addExtension()
.setUrl(extensionUrl + "questionnaire-itemControl")
.setValue(new Coding(null, "text-box", null));
.setValue(new CodeType("text-box"));
ValidationResult errors = myVal.validateWithResult(q);

View File

@ -621,8 +621,8 @@ public class FhirInstanceValidatorR5Test {
List<SingleValidationMessage> messages = logResultsAndReturnNonInformationalOnes(output);
assertEquals(output.toString(), 3, messages.size());
assertThat(messages.get(0).getMessage(), containsString("Element must have some content"));
assertThat(messages.get(1).getMessage(), containsString("ele-1: All FHIR elements must have a @value or children [hasValue() or (children().count() > id.count())]"));
assertThat(messages.get(2).getMessage(), containsString("Primitive types must have a value or must have child extensions"));
assertThat(messages.get(1).getMessage(), containsString("Primitive types must have a value or must have child extensions"));
assertThat(messages.get(2).getMessage(), containsString("ele-1: All FHIR elements must have a @value or children [hasValue() or (children().count() > id.count())]"));
}
@Test
@ -657,7 +657,8 @@ public class FhirInstanceValidatorR5Test {
ValidationResult output = myVal.validateWithResult(input);
List<SingleValidationMessage> res = logResultsAndReturnNonInformationalOnes(output);
assertEquals(output.toString(), 0, res.size());
assertEquals(output.toString(), 1, res.size());
assertEquals("A code with no system has no defined meaning. A system should be provided", output.getMessages().get(0).getMessage());
}
@Test
@ -849,7 +850,7 @@ public class FhirInstanceValidatorR5Test {
ValidationResult output = myVal.validateWithResult(input);
logResultsAndReturnAll(output);
assertEquals(
"The value provided (\"notvalidcode\") is not in the value set http://hl7.org/fhir/ValueSet/observation-status|4.2.0 (http://hl7.org/fhir/ValueSet/observation-status, and a code is required from this value set) (error message = Unknown code 'notvalidcode')",
"The value provided (\"notvalidcode\") is not in the value set http://hl7.org/fhir/ValueSet/observation-status|4.4.0 (http://hl7.org/fhir/ValueSet/observation-status), and a code is required from this value set) (error message = Unknown code 'notvalidcode')",
output.getMessages().get(0).getMessage());
}
@ -952,7 +953,7 @@ public class FhirInstanceValidatorR5Test {
assertEquals(1, all.size());
assertEquals("Patient.identifier[0].type", all.get(0).getLocationString());
assertEquals(
"None of the codes provided are in the value set http://hl7.org/fhir/ValueSet/identifier-type (http://hl7.org/fhir/ValueSet/identifier-type, and a code should come from this value set unless it has no suitable code) (codes = http://example.com/foo/bar#bar)",
"None of the codes provided are in the value set http://hl7.org/fhir/ValueSet/identifier-type (http://hl7.org/fhir/ValueSet/identifier-type), and a code should come from this value set unless it has no suitable code) (codes = http://example.com/foo/bar#bar)",
all.get(0).getMessage());
assertEquals(ResultSeverityEnum.WARNING, all.get(0).getSeverity());

View File

@ -42,7 +42,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class QuestionnaireResponseValidatorR5Test {
public static final String ID_ICC_QUESTIONNAIRE_SETUP = "Questionnaire/profile";
public static final String ID_ICC_QUESTIONNAIRE_SETUP = "http://example.com/Questionnaire/profile";
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(QuestionnaireResponseValidatorR5Test.class);
private static final String CODE_ICC_SCHOOLTYPE_PT = "PT";
private static final String ID_VS_SCHOOLTYPE = "ValueSet/schooltype";
@ -322,7 +322,7 @@ public class QuestionnaireResponseValidatorR5Test {
ValidationResult errors = myVal.validateWithResult(qa);
ourLog.info(errors.toString());
assertThat(errors.toString(), containsString("No response found for required item with id = 'link0'"));
assertThat(errors.toString(), containsString("No response answer found for required item \"link0\""));
}
@Test
@ -583,7 +583,7 @@ public class QuestionnaireResponseValidatorR5Test {
qa.addItem().setLinkId("link0").addAnswer().setValue(new Coding().setDisplay(""));
errors = myVal.validateWithResult(qa);
ourLog.info(errors.toString());
assertThat(errors.toString(), containsString("No response found for required item with id = 'link0'"));
assertThat(errors.toString(), containsString("No response answer found for required item \"link0\""));
}

View File

@ -19,129 +19,126 @@
"author": {
"reference": "Practitioner/PRLoginID"
},
"item": [{
"linkId": "Binder Optimization Assessment Test",
"text": "Binder Optimization Assessment Test",
"item": [{
"linkId": "BINDER OPTIMIZATION ASSESSMENT TEST",
"text": "BINDER OPTIMIZATION ASSESSMENT TEST",
"item": [{
"linkId": "Home Medications",
"text": "Home Medications",
"item": [{
"linkId": "BO_ConsPharm",
"text": "Pharmacist consult",
"answer": [{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "Yes",
"display": "Yes"
}
}]
},
{
"linkId": "BO_ConsTxt",
"text": "Pharmacy consult notes",
"answer": [{
"valueString": "Pharmacy consult notes comes here"
}]
},
{
"linkId": "BO_RecNotCons",
"text": "Recommendation not consistent with binder optimization guidelines",
"answer": [{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "Yes",
"display": "Yes"
}
}],
"item": [{
"linkId": "BO_NotConsDrop",
"text": "Recommendation not consistent with binder optimization guidelines",
"answer": [{
"valueString": "Chewing difficulty,Other"
}],
"item": [{
"linkId": "BO_OtherTxt",
"text": "Other",
"answer": [{
"valueString": "Other difficulty"
}]
}]
},
{
"linkId": "BO_Recommend",
"text": "What is your recommendation",
"answer": [{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCBinderRecommendation",
"code": "Renvela",
"display": "Renvela"
}
}]
}
]
}
]
},
"item": [
{
"linkId": "Binder Optimization Assessment Test",
"text": "Binder Optimization Assessment Test",
"item": [
{
"linkId": "Plan",
"text": "Plan",
"item": [{
"linkId": "BO_CommPres",
"text": "Binder recommendation communicated to prescriber",
"answer": [{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
}
}]
},
"linkId": "BINDER OPTIMIZATION ASSESSMENT TEST",
"text": "BINDER OPTIMIZATION ASSESSMENT TEST",
"item": [
{
"linkId": "BO_ComAssmt",
"text": "Referred to MSW for expressed co-pay concerns",
"answer": [{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
"linkId": "Home Medications",
"text": "Home Medications",
"item": [
{
"linkId": "BO_ConsPharm",
"text": "Pharmacist consult",
"answer": [
{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "Yes",
"display": "Yes"
}
}
]
},
{
"linkId": "BO_ConsTxt",
"text": "Pharmacy consult notes",
"answer": [
{
"valueString": "Pharmacy consult notes comes here"
}
]
},
{
"linkId": "BO_RecNotCons",
"text": "Recommendation not consistent with binder optimization guidelines",
"answer": [
{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "Yes",
"display": "Yes"
}
}
]
}
}]
]
},
{
"linkId": "BO_RefMSW",
"text": "Referred to MSW for potential medication adherence issues",
"answer": [{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
"linkId": "Plan",
"text": "Plan",
"item": [
{
"linkId": "BO_CommPres",
"text": "Binder recommendation communicated to prescriber",
"answer": [
{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
}
}
]
},
{
"linkId": "BO_ComAssmt",
"text": "Referred to MSW for expressed co-pay concerns",
"answer": [
{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
}
}
]
},
{
"linkId": "BO_RefMSW",
"text": "Referred to MSW for potential medication adherence issues",
"answer": [
{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
}
}
]
},
{
"linkId": "BO_AdjHyp",
"text": "Continue adjustments per CMAB Hyperphosphatemia Algorithm",
"answer": [
{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
}
}
]
},
{
"linkId": "BO_AdjTxt",
"text": "Adjustment Text",
"answer": [
{
"valueString": "Adjustment Text comes here"
}
]
}
}]
},
{
"linkId": "BO_AdjHyp",
"text": "Continue adjustments per CMAB Hyperphosphatemia Algorithm",
"answer": [{
"valueCoding": {
"system": "http://fkcfhir.org/fhir/cs/FMCYesNoUnk",
"code": "No",
"display": "No"
}
}]
},
{
"linkId": "BO_AdjTxt",
"text": "Adjustment Text",
"answer": [{
"valueString": "Adjustment Text comes here"
}]
]
}
]
}
]
}]
}]
}
]
}

View File

@ -644,7 +644,7 @@
<properties>
<fhir_core_version>4.2.10-SNAPSHOT</fhir_core_version>
<fhir_core_version>4.2.29-SNAPSHOT</fhir_core_version>
<ucum_version>1.0.2</ucum_version>
<surefire_jvm_args>-Dfile.encoding=UTF-8 -Xmx2048m</surefire_jvm_args>