Merge branch 'master' into do-20240830-maven-compiler-update
This commit is contained in:
commit
4ab12ab39d
|
@ -1,18 +1,7 @@
|
||||||
## Validator Changes
|
## Validator Changes
|
||||||
|
|
||||||
* Fix expression for con-3 properly (fix validation problem on some condition resources)
|
* no changes
|
||||||
* Fix FHIRPath bug using wrong type on simple elements when checking FHIRPath types
|
|
||||||
* FHIRPath: Allow _ in constant names (per FHIRPath spec)
|
|
||||||
* Fix value set rendering creating wrong references
|
|
||||||
* Fix bug processing value set includes / excludes that are just value sets (no system value)
|
|
||||||
* Alter processing of unknown code systems per discussion at ,https://chat.fhir.org/#narrow/stream/179252-IG-creation/topic/Don't.20error.20when.20you.20can't.20find.20code.20system and implement unknown-codesystems-cause-errors
|
|
||||||
* Improve message for when elements are out of order in profile differentials
|
|
||||||
|
|
||||||
|
|
||||||
## Other code changes
|
## Other code changes
|
||||||
|
|
||||||
* fix problem where profile rendering had spurious 'slices for' nodes everywhere
|
* no changes
|
||||||
* Update SQL-On-FHIR implementation for latest cases, and clone test cases to general test care repository
|
|
||||||
* Fix problem generating value set spreadsheets
|
|
||||||
* fix concurrent modification error processing language translations
|
|
||||||
* Check for null fetcher processing ConceptMaps (#1728)
|
|
Binary file not shown.
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
@ -1,5 +1,5 @@
|
||||||
Locale,Coverage #,Coverage %
|
Locale,Coverage #,Coverage %
|
||||||
de,831,41%
|
de,831,40%
|
||||||
es,714,35%
|
es,714,35%
|
||||||
ja,902,44%
|
ja,902,44%
|
||||||
nl,1989,98%
|
nl,1988,97%
|
||||||
|
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>6.3.26-SNAPSHOT</version>
|
<version>6.3.30-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class Consent30_40 {
|
||||||
tgt.setPolicyRule(new CodeableConcept(c));
|
tgt.setPolicyRule(new CodeableConcept(c));
|
||||||
}
|
}
|
||||||
if (src.hasSecurityLabel() || src.hasPeriod() || src.hasActor() || src.hasAction() || src.hasPurpose() || src.hasDataPeriod() || src.hasData() || src.hasExcept()) {
|
if (src.hasSecurityLabel() || src.hasPeriod() || src.hasActor() || src.hasAction() || src.hasPurpose() || src.hasDataPeriod() || src.hasData() || src.hasExcept()) {
|
||||||
org.hl7.fhir.r4.model.Consent.provisionComponent pc = new org.hl7.fhir.r4.model.Consent.provisionComponent();
|
org.hl7.fhir.r4.model.Consent.ProvisionComponent pc = new org.hl7.fhir.r4.model.Consent.ProvisionComponent();
|
||||||
if (src.hasPeriod())
|
if (src.hasPeriod())
|
||||||
pc.setPeriod(Period30_40.convertPeriod(src.getPeriod()));
|
pc.setPeriod(Period30_40.convertPeriod(src.getPeriod()));
|
||||||
for (org.hl7.fhir.dstu3.model.Consent.ConsentActorComponent t : src.getActor())
|
for (org.hl7.fhir.dstu3.model.Consent.ConsentActorComponent t : src.getActor())
|
||||||
|
@ -104,7 +104,7 @@ public class Consent30_40 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (src.hasProvision()) {
|
if (src.hasProvision()) {
|
||||||
org.hl7.fhir.r4.model.Consent.provisionComponent p = src.getProvision();
|
org.hl7.fhir.r4.model.Consent.ProvisionComponent p = src.getProvision();
|
||||||
if (p.hasPeriod())
|
if (p.hasPeriod())
|
||||||
tgt.setPeriod(Period30_40.convertPeriod(p.getPeriod()));
|
tgt.setPeriod(Period30_40.convertPeriod(p.getPeriod()));
|
||||||
for (org.hl7.fhir.r4.model.Consent.provisionActorComponent t : p.getActor())
|
for (org.hl7.fhir.r4.model.Consent.provisionActorComponent t : p.getActor())
|
||||||
|
@ -117,7 +117,7 @@ public class Consent30_40 {
|
||||||
tgt.setDataPeriod(Period30_40.convertPeriod(p.getDataPeriod()));
|
tgt.setDataPeriod(Period30_40.convertPeriod(p.getDataPeriod()));
|
||||||
for (org.hl7.fhir.r4.model.Consent.provisionDataComponent t : p.getData())
|
for (org.hl7.fhir.r4.model.Consent.provisionDataComponent t : p.getData())
|
||||||
tgt.addData(convertConsentDataComponent(t));
|
tgt.addData(convertConsentDataComponent(t));
|
||||||
for (org.hl7.fhir.r4.model.Consent.provisionComponent t : p.getProvision())
|
for (org.hl7.fhir.r4.model.Consent.ProvisionComponent t : p.getProvision())
|
||||||
tgt.addExcept(convertExceptComponent(t));
|
tgt.addExcept(convertExceptComponent(t));
|
||||||
}
|
}
|
||||||
return tgt;
|
return tgt;
|
||||||
|
@ -369,7 +369,7 @@ public class Consent30_40 {
|
||||||
return tgt;
|
return tgt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public org.hl7.fhir.dstu3.model.Consent.ExceptComponent convertExceptComponent(org.hl7.fhir.r4.model.Consent.provisionComponent src) throws FHIRException {
|
static public org.hl7.fhir.dstu3.model.Consent.ExceptComponent convertExceptComponent(org.hl7.fhir.r4.model.Consent.ProvisionComponent src) throws FHIRException {
|
||||||
if (src == null)
|
if (src == null)
|
||||||
return null;
|
return null;
|
||||||
org.hl7.fhir.dstu3.model.Consent.ExceptComponent tgt = new org.hl7.fhir.dstu3.model.Consent.ExceptComponent();
|
org.hl7.fhir.dstu3.model.Consent.ExceptComponent tgt = new org.hl7.fhir.dstu3.model.Consent.ExceptComponent();
|
||||||
|
@ -393,10 +393,10 @@ public class Consent30_40 {
|
||||||
return tgt;
|
return tgt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public org.hl7.fhir.r4.model.Consent.provisionComponent convertExceptComponent(org.hl7.fhir.dstu3.model.Consent.ExceptComponent src) throws FHIRException {
|
static public org.hl7.fhir.r4.model.Consent.ProvisionComponent convertExceptComponent(org.hl7.fhir.dstu3.model.Consent.ExceptComponent src) throws FHIRException {
|
||||||
if (src == null)
|
if (src == null)
|
||||||
return null;
|
return null;
|
||||||
org.hl7.fhir.r4.model.Consent.provisionComponent tgt = new org.hl7.fhir.r4.model.Consent.provisionComponent();
|
org.hl7.fhir.r4.model.Consent.ProvisionComponent tgt = new org.hl7.fhir.r4.model.Consent.ProvisionComponent();
|
||||||
ConversionContext30_40.INSTANCE.getVersionConvertor_30_40().copyBackboneElement(src,tgt);
|
ConversionContext30_40.INSTANCE.getVersionConvertor_30_40().copyBackboneElement(src,tgt);
|
||||||
if (src.hasType())
|
if (src.hasType())
|
||||||
tgt.setTypeElement(convertConsentExceptType(src.getTypeElement()));
|
tgt.setTypeElement(convertConsentExceptType(src.getTypeElement()));
|
||||||
|
|
|
@ -25,8 +25,10 @@ import org.hl7.fhir.r4.model.StringType;
|
||||||
import org.hl7.fhir.r5.model.CodeType;
|
import org.hl7.fhir.r5.model.CodeType;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingAdditionalComponent;
|
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingAdditionalComponent;
|
||||||
import org.hl7.fhir.r5.model.UsageContext;
|
import org.hl7.fhir.r5.model.UsageContext;
|
||||||
|
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||||
|
|
||||||
public class ElementDefinition40_50 {
|
public class ElementDefinition40_50 {
|
||||||
|
|
||||||
public static org.hl7.fhir.r5.model.ElementDefinition convertElementDefinition(org.hl7.fhir.r4.model.ElementDefinition src) throws FHIRException {
|
public static org.hl7.fhir.r5.model.ElementDefinition convertElementDefinition(org.hl7.fhir.r4.model.ElementDefinition src) throws FHIRException {
|
||||||
if (src == null) return null;
|
if (src == null) return null;
|
||||||
org.hl7.fhir.r5.model.ElementDefinition tgt = new org.hl7.fhir.r5.model.ElementDefinition();
|
org.hl7.fhir.r5.model.ElementDefinition tgt = new org.hl7.fhir.r5.model.ElementDefinition();
|
||||||
|
@ -616,7 +618,7 @@ public class ElementDefinition40_50 {
|
||||||
if (src == null) return null;
|
if (src == null) return null;
|
||||||
org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent tgt = new org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent();
|
org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent tgt = new org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent();
|
||||||
ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyElement(src, tgt,
|
ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyElement(src, tgt,
|
||||||
"http://hl7.org/fhir/5.0/StructureDefinition/extension-ElementDefinition.binding.additional");
|
"http://hl7.org/fhir/5.0/StructureDefinition/extension-ElementDefinition.binding.additional", ToolingExtensions.EXT_BINDING_ADDITIONAL);
|
||||||
if (src.hasStrength()) tgt.setStrengthElement(Enumerations40_50.convertBindingStrength(src.getStrengthElement()));
|
if (src.hasStrength()) tgt.setStrengthElement(Enumerations40_50.convertBindingStrength(src.getStrengthElement()));
|
||||||
if (src.hasDescription()) tgt.setDescriptionElement(String40_50.convertStringToMarkdown(src.getDescriptionElement()));
|
if (src.hasDescription()) tgt.setDescriptionElement(String40_50.convertStringToMarkdown(src.getDescriptionElement()));
|
||||||
if (src.hasValueSet()) tgt.setValueSetElement(Canonical40_50.convertCanonical(src.getValueSetElement()));
|
if (src.hasValueSet()) tgt.setValueSetElement(Canonical40_50.convertCanonical(src.getValueSetElement()));
|
||||||
|
@ -624,6 +626,9 @@ public class ElementDefinition40_50 {
|
||||||
for (org.hl7.fhir.r4.model.Extension ext : src.getExtensionsByUrl("http://hl7.org/fhir/5.0/StructureDefinition/extension-ElementDefinition.binding.additional")) {
|
for (org.hl7.fhir.r4.model.Extension ext : src.getExtensionsByUrl("http://hl7.org/fhir/5.0/StructureDefinition/extension-ElementDefinition.binding.additional")) {
|
||||||
tgt.addAdditional(convertAdditional(ext));
|
tgt.addAdditional(convertAdditional(ext));
|
||||||
}
|
}
|
||||||
|
for (org.hl7.fhir.r4.model.Extension ext : src.getExtensionsByUrl(ToolingExtensions.EXT_BINDING_ADDITIONAL)) {
|
||||||
|
tgt.addAdditional(convertAdditional(ext));
|
||||||
|
}
|
||||||
return tgt;
|
return tgt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,12 +657,12 @@ public class ElementDefinition40_50 {
|
||||||
return tgt;
|
return tgt;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Extension convertAdditional(ElementDefinitionBindingAdditionalComponent src) {
|
private static org.hl7.fhir.r4.model.Extension convertAdditional(ElementDefinitionBindingAdditionalComponent src) {
|
||||||
if (src == null) return null;
|
if (src == null) return null;
|
||||||
Extension tgt = new Extension();
|
org.hl7.fhir.r4.model.Extension tgt = new Extension(ToolingExtensions.EXT_BINDING_ADDITIONAL);
|
||||||
ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyElement(src, tgt);
|
ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyElement(src, tgt);
|
||||||
if (src.hasPurpose()) {
|
if (src.hasPurpose()) {
|
||||||
tgt.addExtension(new Extension("purpose", new CodeType(src.getPurposeElement().primitiveValue())));
|
tgt.addExtension(new Extension("purpose", new org.hl7.fhir.r4.model.CodeType(src.getPurposeElement().primitiveValue())));
|
||||||
}
|
}
|
||||||
if (src.hasValueSet()) {
|
if (src.hasValueSet()) {
|
||||||
tgt.addExtension(new Extension("valueSet", Canonical40_50.convertCanonical(src.getValueSetElement())));
|
tgt.addExtension(new Extension("valueSet", Canonical40_50.convertCanonical(src.getValueSetElement())));
|
||||||
|
|
|
@ -220,7 +220,7 @@ public class Consent40_50 {
|
||||||
return tgt;
|
return tgt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static org.hl7.fhir.r5.model.Consent.ProvisionComponent convertprovisionComponent(org.hl7.fhir.r4.model.Consent.provisionComponent src) throws FHIRException {
|
public static org.hl7.fhir.r5.model.Consent.ProvisionComponent convertprovisionComponent(org.hl7.fhir.r4.model.Consent.ProvisionComponent src) throws FHIRException {
|
||||||
if (src == null)
|
if (src == null)
|
||||||
return null;
|
return null;
|
||||||
org.hl7.fhir.r5.model.Consent.ProvisionComponent tgt = new org.hl7.fhir.r5.model.Consent.ProvisionComponent();
|
org.hl7.fhir.r5.model.Consent.ProvisionComponent tgt = new org.hl7.fhir.r5.model.Consent.ProvisionComponent();
|
||||||
|
@ -242,15 +242,15 @@ public class Consent40_50 {
|
||||||
tgt.setDataPeriod(Period40_50.convertPeriod(src.getDataPeriod()));
|
tgt.setDataPeriod(Period40_50.convertPeriod(src.getDataPeriod()));
|
||||||
for (org.hl7.fhir.r4.model.Consent.provisionDataComponent t : src.getData())
|
for (org.hl7.fhir.r4.model.Consent.provisionDataComponent t : src.getData())
|
||||||
tgt.addData(convertprovisionDataComponent(t));
|
tgt.addData(convertprovisionDataComponent(t));
|
||||||
for (org.hl7.fhir.r4.model.Consent.provisionComponent t : src.getProvision())
|
for (org.hl7.fhir.r4.model.Consent.ProvisionComponent t : src.getProvision())
|
||||||
tgt.addProvision(convertprovisionComponent(t));
|
tgt.addProvision(convertprovisionComponent(t));
|
||||||
return tgt;
|
return tgt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static org.hl7.fhir.r4.model.Consent.provisionComponent convertprovisionComponent(org.hl7.fhir.r5.model.Consent.ProvisionComponent src) throws FHIRException {
|
public static org.hl7.fhir.r4.model.Consent.ProvisionComponent convertprovisionComponent(org.hl7.fhir.r5.model.Consent.ProvisionComponent src) throws FHIRException {
|
||||||
if (src == null)
|
if (src == null)
|
||||||
return null;
|
return null;
|
||||||
org.hl7.fhir.r4.model.Consent.provisionComponent tgt = new org.hl7.fhir.r4.model.Consent.provisionComponent();
|
org.hl7.fhir.r4.model.Consent.ProvisionComponent tgt = new org.hl7.fhir.r4.model.Consent.ProvisionComponent();
|
||||||
ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyBackboneElement(src, tgt);
|
ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyBackboneElement(src, tgt);
|
||||||
// if (src.hasType())
|
// if (src.hasType())
|
||||||
// tgt.setTypeElement(convertConsentProvisionType(src.getTypeElement()));
|
// tgt.setTypeElement(convertConsentProvisionType(src.getTypeElement()));
|
||||||
|
|
|
@ -230,12 +230,6 @@ public class Enumerations40_50 {
|
||||||
case _4_3_0:
|
case _4_3_0:
|
||||||
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion._4_3_0);
|
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion._4_3_0);
|
||||||
break;
|
break;
|
||||||
case _4_3_0_CIBUILD:
|
|
||||||
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion._4_3_0CIBUILD);
|
|
||||||
break;
|
|
||||||
case _4_3_0_SNAPSHOT1:
|
|
||||||
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion._4_3_0SNAPSHOT1);
|
|
||||||
break;
|
|
||||||
case _5_0_0:
|
case _5_0_0:
|
||||||
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion._5_0_0);
|
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion._5_0_0);
|
||||||
break;
|
break;
|
||||||
|
@ -254,6 +248,15 @@ public class Enumerations40_50 {
|
||||||
case _5_0_0DRAFTFINAL:
|
case _5_0_0DRAFTFINAL:
|
||||||
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion._5_0_0DRAFTFINAL);
|
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion._5_0_0DRAFTFINAL);
|
||||||
break;
|
break;
|
||||||
|
case _6_0_0:
|
||||||
|
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion._6_0_0);
|
||||||
|
break;
|
||||||
|
case _6_0_0_BALLOT1:
|
||||||
|
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion._6_0_0_BALLOT1);
|
||||||
|
break;
|
||||||
|
case _6_0_0_BALLOT2:
|
||||||
|
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion._6_0_0_BALLOT2);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion.NULL);
|
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion.NULL);
|
||||||
break;
|
break;
|
||||||
|
@ -342,12 +345,6 @@ public class Enumerations40_50 {
|
||||||
case _4_3_0:
|
case _4_3_0:
|
||||||
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion._4_3_0);
|
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion._4_3_0);
|
||||||
break;
|
break;
|
||||||
case _4_3_0CIBUILD:
|
|
||||||
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion._4_3_0_CIBUILD);
|
|
||||||
break;
|
|
||||||
case _4_3_0SNAPSHOT1:
|
|
||||||
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion._4_3_0_SNAPSHOT1);
|
|
||||||
break;
|
|
||||||
case _5_0_0:
|
case _5_0_0:
|
||||||
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion._5_0_0);
|
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion._5_0_0);
|
||||||
break;
|
break;
|
||||||
|
@ -366,6 +363,15 @@ public class Enumerations40_50 {
|
||||||
case _5_0_0DRAFTFINAL:
|
case _5_0_0DRAFTFINAL:
|
||||||
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion._5_0_0DRAFTFINAL);
|
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion._5_0_0DRAFTFINAL);
|
||||||
break;
|
break;
|
||||||
|
case _6_0_0:
|
||||||
|
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion._6_0_0);
|
||||||
|
break;
|
||||||
|
case _6_0_0_BALLOT1:
|
||||||
|
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion._6_0_0_BALLOT1);
|
||||||
|
break;
|
||||||
|
case _6_0_0_BALLOT2:
|
||||||
|
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion._6_0_0_BALLOT2);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion.NULL);
|
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion.NULL);
|
||||||
|
|
|
@ -33,9 +33,11 @@ import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
|
||||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50;
|
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50;
|
||||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
|
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
|
||||||
import org.hl7.fhir.r5.model.Enumeration;
|
import org.hl7.fhir.r5.model.Enumeration;
|
||||||
|
import org.hl7.fhir.r5.model.Enumerations.FHIRVersion;
|
||||||
import org.hl7.fhir.r5.model.Enumerations.FHIRVersionEnumFactory;
|
import org.hl7.fhir.r5.model.Enumerations.FHIRVersionEnumFactory;
|
||||||
import org.hl7.fhir.r5.model.ImplementationGuide;
|
import org.hl7.fhir.r5.model.ImplementationGuide;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
import org.hl7.fhir.utilities.TextFile;
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.VersionUtilities;
|
import org.hl7.fhir.utilities.VersionUtilities;
|
||||||
|
@ -237,7 +239,7 @@ public class NpmPackageVersionConverter {
|
||||||
return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(VersionConvertorFactory_14_30.convertResource(VersionConvertorFactory_10_30.convertResource(res)));
|
return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(VersionConvertorFactory_14_30.convertResource(VersionConvertorFactory_10_30.convertResource(res)));
|
||||||
} else if (VersionUtilities.isR3Ver(version)) {
|
} else if (VersionUtilities.isR3Ver(version)) {
|
||||||
return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(VersionConvertorFactory_10_30.convertResource(res));
|
return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(VersionConvertorFactory_10_30.convertResource(res));
|
||||||
} else if (VersionUtilities.isR4Ver(version)) {
|
} else if (VersionUtilities.isR4Ver(version) || VersionUtilities.isR4BVer(version)) {
|
||||||
return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(VersionConvertorFactory_10_40.convertResource(res));
|
return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(VersionConvertorFactory_10_40.convertResource(res));
|
||||||
} else if (VersionUtilities.isR5Plus(version)) {
|
} else if (VersionUtilities.isR5Plus(version)) {
|
||||||
return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(VersionConvertorFactory_10_50.convertResource(res));
|
return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(VersionConvertorFactory_10_50.convertResource(res));
|
||||||
|
@ -251,7 +253,7 @@ public class NpmPackageVersionConverter {
|
||||||
return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(res);
|
return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(res);
|
||||||
} else if (VersionUtilities.isR3Ver(version)) {
|
} else if (VersionUtilities.isR3Ver(version)) {
|
||||||
return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(VersionConvertorFactory_14_30.convertResource(res));
|
return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(VersionConvertorFactory_14_30.convertResource(res));
|
||||||
} else if (VersionUtilities.isR4Ver(version)) {
|
} else if (VersionUtilities.isR4Ver(version) || VersionUtilities.isR4BVer(version)) {
|
||||||
return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(VersionConvertorFactory_14_40.convertResource(res));
|
return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(VersionConvertorFactory_14_40.convertResource(res));
|
||||||
} else if (VersionUtilities.isR5Plus(version)) {
|
} else if (VersionUtilities.isR5Plus(version)) {
|
||||||
return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(VersionConvertorFactory_14_50.convertResource(res));
|
return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(VersionConvertorFactory_14_50.convertResource(res));
|
||||||
|
@ -265,7 +267,7 @@ public class NpmPackageVersionConverter {
|
||||||
return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(VersionConvertorFactory_14_30.convertResource(res));
|
return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(VersionConvertorFactory_14_30.convertResource(res));
|
||||||
} else if (VersionUtilities.isR3Ver(version)) {
|
} else if (VersionUtilities.isR3Ver(version)) {
|
||||||
return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(res);
|
return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(res);
|
||||||
} else if (VersionUtilities.isR4Ver(version)) {
|
} else if (VersionUtilities.isR4Ver(version) || VersionUtilities.isR4BVer(version)) {
|
||||||
return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(VersionConvertorFactory_30_40.convertResource(res));
|
return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(VersionConvertorFactory_30_40.convertResource(res));
|
||||||
} else if (VersionUtilities.isR5Plus(version)) {
|
} else if (VersionUtilities.isR5Plus(version)) {
|
||||||
return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(VersionConvertorFactory_30_50.convertResource(res));
|
return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(VersionConvertorFactory_30_50.convertResource(res));
|
||||||
|
@ -279,7 +281,21 @@ public class NpmPackageVersionConverter {
|
||||||
return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(VersionConvertorFactory_14_40.convertResource(res));
|
return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(VersionConvertorFactory_14_40.convertResource(res));
|
||||||
} else if (VersionUtilities.isR3Ver(version)) {
|
} else if (VersionUtilities.isR3Ver(version)) {
|
||||||
return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(VersionConvertorFactory_30_40.convertResource(res, new BaseAdvisor_30_40(false)));
|
return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(VersionConvertorFactory_30_40.convertResource(res, new BaseAdvisor_30_40(false)));
|
||||||
} else if (VersionUtilities.isR4Ver(version)) {
|
} else if (VersionUtilities.isR4Ver(version) || VersionUtilities.isR4BVer(version)) {
|
||||||
|
return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(res);
|
||||||
|
} else if (VersionUtilities.isR5Plus(version)) {
|
||||||
|
return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(VersionConvertorFactory_40_50.convertResource(res));
|
||||||
|
}
|
||||||
|
} else if (VersionUtilities.isR4BVer(currentVersion)) {
|
||||||
|
org.hl7.fhir.r4.model.Resource res = new org.hl7.fhir.r4.formats.JsonParser().parse(cnt);
|
||||||
|
convertResourceR4B(res);
|
||||||
|
if (VersionUtilities.isR2Ver(version)) {
|
||||||
|
return new org.hl7.fhir.dstu2.formats.JsonParser().composeBytes(VersionConvertorFactory_10_40.convertResource(res, new PR2Handler()));
|
||||||
|
} else if (VersionUtilities.isR2BVer(version)) {
|
||||||
|
return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(VersionConvertorFactory_14_40.convertResource(res));
|
||||||
|
} else if (VersionUtilities.isR3Ver(version)) {
|
||||||
|
return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(VersionConvertorFactory_30_40.convertResource(res, new BaseAdvisor_30_40(false)));
|
||||||
|
} else if (VersionUtilities.isR4Ver(version) || VersionUtilities.isR4BVer(version)) {
|
||||||
return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(res);
|
return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(res);
|
||||||
} else if (VersionUtilities.isR5Plus(version)) {
|
} else if (VersionUtilities.isR5Plus(version)) {
|
||||||
return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(VersionConvertorFactory_40_50.convertResource(res));
|
return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(VersionConvertorFactory_40_50.convertResource(res));
|
||||||
|
@ -293,7 +309,7 @@ public class NpmPackageVersionConverter {
|
||||||
return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(VersionConvertorFactory_14_50.convertResource(res));
|
return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(VersionConvertorFactory_14_50.convertResource(res));
|
||||||
} else if (VersionUtilities.isR3Ver(version)) {
|
} else if (VersionUtilities.isR3Ver(version)) {
|
||||||
return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(VersionConvertorFactory_30_50.convertResource(res, new BaseAdvisor_30_50(false)));
|
return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(VersionConvertorFactory_30_50.convertResource(res, new BaseAdvisor_30_50(false)));
|
||||||
} else if (VersionUtilities.isR4Ver(version)) {
|
} else if (VersionUtilities.isR4Ver(version) || VersionUtilities.isR4BVer(version)) {
|
||||||
return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(VersionConvertorFactory_40_50.convertResource(res));
|
return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(VersionConvertorFactory_40_50.convertResource(res));
|
||||||
} else if (VersionUtilities.isR5Plus(version)) {
|
} else if (VersionUtilities.isR5Plus(version)) {
|
||||||
return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(res);
|
return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(res);
|
||||||
|
@ -311,6 +327,10 @@ public class NpmPackageVersionConverter {
|
||||||
org.hl7.fhir.dstu2.model.ImplementationGuide ig = (org.hl7.fhir.dstu2.model.ImplementationGuide) res;
|
org.hl7.fhir.dstu2.model.ImplementationGuide ig = (org.hl7.fhir.dstu2.model.ImplementationGuide) res;
|
||||||
ig.setFhirVersion(version);
|
ig.setFhirVersion(version);
|
||||||
}
|
}
|
||||||
|
if (res instanceof org.hl7.fhir.dstu2.model.StructureDefinition) {
|
||||||
|
org.hl7.fhir.dstu2.model.StructureDefinition sd = (org.hl7.fhir.dstu2.model.StructureDefinition) res;
|
||||||
|
sd.setFhirVersion(version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void convertResourceR2B(org.hl7.fhir.dstu2016may.model.Resource res) {
|
private void convertResourceR2B(org.hl7.fhir.dstu2016may.model.Resource res) {
|
||||||
|
@ -318,6 +338,10 @@ public class NpmPackageVersionConverter {
|
||||||
org.hl7.fhir.dstu2016may.model.ImplementationGuide ig = (org.hl7.fhir.dstu2016may.model.ImplementationGuide) res;
|
org.hl7.fhir.dstu2016may.model.ImplementationGuide ig = (org.hl7.fhir.dstu2016may.model.ImplementationGuide) res;
|
||||||
ig.setFhirVersion(version);
|
ig.setFhirVersion(version);
|
||||||
}
|
}
|
||||||
|
if (res instanceof org.hl7.fhir.dstu2016may.model.StructureDefinition) {
|
||||||
|
org.hl7.fhir.dstu2016may.model.StructureDefinition sd = (org.hl7.fhir.dstu2016may.model.StructureDefinition) res;
|
||||||
|
sd.setFhirVersion(version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void convertResourceR3(org.hl7.fhir.dstu3.model.Resource res) {
|
private void convertResourceR3(org.hl7.fhir.dstu3.model.Resource res) {
|
||||||
|
@ -325,6 +349,10 @@ public class NpmPackageVersionConverter {
|
||||||
org.hl7.fhir.dstu3.model.ImplementationGuide ig = (org.hl7.fhir.dstu3.model.ImplementationGuide) res;
|
org.hl7.fhir.dstu3.model.ImplementationGuide ig = (org.hl7.fhir.dstu3.model.ImplementationGuide) res;
|
||||||
ig.setFhirVersion(version);
|
ig.setFhirVersion(version);
|
||||||
}
|
}
|
||||||
|
if (res instanceof org.hl7.fhir.dstu3.model.StructureDefinition) {
|
||||||
|
org.hl7.fhir.dstu3.model.StructureDefinition sd = (org.hl7.fhir.dstu3.model.StructureDefinition) res;
|
||||||
|
sd.setFhirVersion(version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void convertResourceR4(org.hl7.fhir.r4.model.Resource res) {
|
private void convertResourceR4(org.hl7.fhir.r4.model.Resource res) {
|
||||||
|
@ -334,6 +362,23 @@ public class NpmPackageVersionConverter {
|
||||||
ig.getFhirVersion().add(new org.hl7.fhir.r4.model.Enumeration<>(new org.hl7.fhir.r4.model.Enumerations.FHIRVersionEnumFactory(), version));
|
ig.getFhirVersion().add(new org.hl7.fhir.r4.model.Enumeration<>(new org.hl7.fhir.r4.model.Enumerations.FHIRVersionEnumFactory(), version));
|
||||||
ig.setPackageId(packageId);
|
ig.setPackageId(packageId);
|
||||||
}
|
}
|
||||||
|
if (res instanceof org.hl7.fhir.r4.model.StructureDefinition) {
|
||||||
|
org.hl7.fhir.r4.model.StructureDefinition sd = (org.hl7.fhir.r4.model.StructureDefinition) res;
|
||||||
|
sd.setFhirVersion(org.hl7.fhir.r4.model.Enumerations.FHIRVersion.fromCode(version));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convertResourceR4B(org.hl7.fhir.r4.model.Resource res) {
|
||||||
|
if (res instanceof org.hl7.fhir.r4.model.ImplementationGuide) {
|
||||||
|
org.hl7.fhir.r4.model.ImplementationGuide ig = (org.hl7.fhir.r4.model.ImplementationGuide) res;
|
||||||
|
ig.getFhirVersion().clear();
|
||||||
|
ig.getFhirVersion().add(new org.hl7.fhir.r4.model.Enumeration<>(new org.hl7.fhir.r4.model.Enumerations.FHIRVersionEnumFactory(), version));
|
||||||
|
ig.setPackageId(packageId);
|
||||||
|
}
|
||||||
|
if (res instanceof org.hl7.fhir.r4.model.StructureDefinition) {
|
||||||
|
org.hl7.fhir.r4.model.StructureDefinition sd = (org.hl7.fhir.r4.model.StructureDefinition) res;
|
||||||
|
sd.setFhirVersion(org.hl7.fhir.r4.model.Enumerations.FHIRVersion.fromCode(version));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -344,6 +389,10 @@ public class NpmPackageVersionConverter {
|
||||||
ig.getFhirVersion().add(new Enumeration<>(new FHIRVersionEnumFactory(), version));
|
ig.getFhirVersion().add(new Enumeration<>(new FHIRVersionEnumFactory(), version));
|
||||||
ig.setPackageId(packageId);
|
ig.setPackageId(packageId);
|
||||||
}
|
}
|
||||||
|
if (res instanceof StructureDefinition) {
|
||||||
|
StructureDefinition sd = (StructureDefinition) res;
|
||||||
|
sd.setFhirVersion(FHIRVersion.fromCode(version));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -45,10 +45,10 @@ public class VSACImporter extends OIDBasedValueSetImporter {
|
||||||
|
|
||||||
public static void main(String[] args) throws FHIRException, IOException, ParseException, URISyntaxException {
|
public static void main(String[] args) throws FHIRException, IOException, ParseException, URISyntaxException {
|
||||||
VSACImporter self = new VSACImporter();
|
VSACImporter self = new VSACImporter();
|
||||||
self.process(args[0], args[1], args[2], "true".equals(args[3]));
|
self.process(args[0], args[1], args[2], "true".equals(args[3]), "true".equals(args[4]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void process(String source, String dest, String apiKey, boolean onlyNew) throws FHIRException, IOException, URISyntaxException {
|
private void process(String source, String dest, String apiKey, boolean onlyNew, boolean onlyActive) throws FHIRException, IOException, URISyntaxException {
|
||||||
CSVReader csv = new CSVReader(ManagedFileAccess.inStream(source));
|
CSVReader csv = new CSVReader(ManagedFileAccess.inStream(source));
|
||||||
csv.readHeaders();
|
csv.readHeaders();
|
||||||
Map<String, String> errs = new HashMap<>();
|
Map<String, String> errs = new HashMap<>();
|
||||||
|
@ -75,13 +75,20 @@ public class VSACImporter extends OIDBasedValueSetImporter {
|
||||||
|
|
||||||
System.out.println("Loading");
|
System.out.println("Loading");
|
||||||
List<String> oids = new ArrayList<>();
|
List<String> oids = new ArrayList<>();
|
||||||
|
List<String> allOids = new ArrayList<>();
|
||||||
while (csv.line()) {
|
while (csv.line()) {
|
||||||
String oid = csv.cell("OID");
|
String status = csv.cell("Expansion Status");
|
||||||
if (!onlyNew || !(ManagedFileAccess.file(Utilities.path(dest, "ValueSet-" + oid + ".json")).exists())) {
|
if (!onlyActive || "Active".equals(status)) {
|
||||||
oids.add(oid);
|
String oid = csv.cell("OID");
|
||||||
|
allOids.add(oid);
|
||||||
|
if (!onlyNew || !(ManagedFileAccess.file(Utilities.path(dest, "ValueSet-" + oid + ".json")).exists())) {
|
||||||
|
oids.add(oid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Collections.sort(oids);
|
Collections.sort(oids);
|
||||||
|
System.out.println("Cleaning");
|
||||||
|
cleanValueSets(allOids, dest);
|
||||||
System.out.println("Go: "+oids.size()+" oids");
|
System.out.println("Go: "+oids.size()+" oids");
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
@ -108,6 +115,7 @@ public class VSACImporter extends OIDBasedValueSetImporter {
|
||||||
errs.put(oid, e.getMessage());
|
errs.put(oid, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OperationOutcome oo = new OperationOutcome();
|
OperationOutcome oo = new OperationOutcome();
|
||||||
for (String oid : errs.keySet()) {
|
for (String oid : errs.keySet()) {
|
||||||
oo.addIssue().setSeverity(IssueSeverity.ERROR).setCode(IssueType.EXCEPTION).setDiagnostics(errs.get(oid)).addLocation(oid);
|
oo.addIssue().setSeverity(IssueSeverity.ERROR).setCode(IssueType.EXCEPTION).setDiagnostics(errs.get(oid)).addLocation(oid);
|
||||||
|
@ -116,6 +124,22 @@ public class VSACImporter extends OIDBasedValueSetImporter {
|
||||||
System.out.println("Done. " + i + " ValueSets in "+Utilities.describeDuration(System.currentTimeMillis() - tt));
|
System.out.println("Done. " + i + " ValueSets in "+Utilities.describeDuration(System.currentTimeMillis() - tt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void cleanValueSets(List<String> allOids, String dest) throws IOException {
|
||||||
|
cleanValueSets(allOids, new File(Utilities.path(dest)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanValueSets(List<String> allOids, File file) {
|
||||||
|
for (File f : file.listFiles()) {
|
||||||
|
if (f.getName().startsWith("ValueSet-")) {
|
||||||
|
String oid = f.getName().substring(9).replace(".json", "");
|
||||||
|
if (!allOids.contains(oid)) {
|
||||||
|
f.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private long estimate(int i, int size, long tt) {
|
private long estimate(int i, int size, long tt) {
|
||||||
long elapsed = System.currentTimeMillis() - tt;
|
long elapsed = System.currentTimeMillis() - tt;
|
||||||
long average = elapsed / i;
|
long average = elapsed / i;
|
||||||
|
@ -201,7 +225,7 @@ public class VSACImporter extends OIDBasedValueSetImporter {
|
||||||
}
|
}
|
||||||
vs.setName(makeValidName(vs.getName()));
|
vs.setName(makeValidName(vs.getName()));
|
||||||
JurisdictionUtilities.setJurisdictionCountry(vs.getJurisdiction(), "US");
|
JurisdictionUtilities.setJurisdictionCountry(vs.getJurisdiction(), "US");
|
||||||
new JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(ManagedFileAccess.outStream(Utilities.path(dest, "ValueSet-" + oid + ".json")), vs);
|
new JsonParser().setOutputStyle(OutputStyle.NORMAL).compose(ManagedFileAccess.outStream(Utilities.path(dest, "ValueSet-" + oid + ".json")), vs);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>6.3.26-SNAPSHOT</version>
|
<version>6.3.30-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -683,7 +683,7 @@ public class ClientUtils {
|
||||||
for (Header h : response.getAllHeaders()) {
|
for (Header h : response.getAllHeaders()) {
|
||||||
headers.add(h.toString());
|
headers.add(h.toString());
|
||||||
}
|
}
|
||||||
logger.logResponse(response.getStatusLine().toString(), headers, cnt);
|
logger.logResponse(response.getStatusLine().toString(), headers, cnt, 0);
|
||||||
}
|
}
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>6.3.26-SNAPSHOT</version>
|
<version>6.3.30-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -625,7 +625,7 @@ public class ClientUtils {
|
||||||
for (Header h : response.getAllHeaders()) {
|
for (Header h : response.getAllHeaders()) {
|
||||||
headers.add(h.toString());
|
headers.add(h.toString());
|
||||||
}
|
}
|
||||||
logger.logResponse(response.getStatusLine().toString(), headers, cnt);
|
logger.logResponse(response.getStatusLine().toString(), headers, cnt, 0);
|
||||||
}
|
}
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>6.3.26-SNAPSHOT</version>
|
<version>6.3.30-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.hl7.fhir.dstu3.model;
|
package org.hl7.fhir.dstu3.model;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2011+, HL7, Inc.
|
Copyright (c) 2011+, HL7, Inc.
|
||||||
|
@ -668,12 +669,16 @@ public class Quantity extends Type implements ICompositeType {
|
||||||
public Quantity copy() {
|
public Quantity copy() {
|
||||||
Quantity dst = new Quantity();
|
Quantity dst = new Quantity();
|
||||||
copyValues(dst);
|
copyValues(dst);
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void copyValues(Quantity dst) {
|
||||||
|
super.copyValues(dst);
|
||||||
dst.value = value == null ? null : value.copy();
|
dst.value = value == null ? null : value.copy();
|
||||||
dst.comparator = comparator == null ? null : comparator.copy();
|
dst.comparator = comparator == null ? null : comparator.copy();
|
||||||
dst.unit = unit == null ? null : unit.copy();
|
dst.unit = unit == null ? null : unit.copy();
|
||||||
dst.system = system == null ? null : system.copy();
|
dst.system = system == null ? null : system.copy();
|
||||||
dst.code = code == null ? null : code.copy();
|
dst.code = code == null ? null : code.copy();
|
||||||
return dst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Quantity typedCopy() {
|
protected Quantity typedCopy() {
|
||||||
|
|
|
@ -371,7 +371,7 @@ public class FhirRequestBuilder {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (logger != null) {
|
if (logger != null) {
|
||||||
logger.logResponse(Integer.toString(responseCode), headerList, responseBody);
|
logger.logResponse(Integer.toString(responseCode), headerList, responseBody, 0);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("Error parsing response body passed in to logger ->\n" + e.getLocalizedMessage());
|
System.out.println("Error parsing response body passed in to logger ->\n" + e.getLocalizedMessage());
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package org.hl7.fhir.dstu3.model;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.hl7.fhir.dstu3.formats.JsonParser;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class MedicationAdministrationCopyTest {
|
||||||
|
|
||||||
|
@DisplayName("Test MedicationAdministration copy")
|
||||||
|
@Test
|
||||||
|
public void test() throws IOException {
|
||||||
|
MedicationAdministration beforeCopy = createMedAdminWithDosageDurationExtension();
|
||||||
|
MedicationAdministration afterCopy = beforeCopy.copy();
|
||||||
|
|
||||||
|
System.out.println("---- BEFORE COPY (BEGIN)");
|
||||||
|
System.out.println(new JsonParser().composeString(beforeCopy));
|
||||||
|
System.out.println("---- BEFORE COPY (END)");
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("---- AFTER COPY (BEGIN)");
|
||||||
|
System.out.println(new JsonParser().composeString(afterCopy));
|
||||||
|
System.out.println("---- AFTER COPY (END)");
|
||||||
|
assertTrue(beforeCopy.equalsDeep(afterCopy));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MedicationAdministration createMedAdminWithDosageDurationExtension() {
|
||||||
|
MedicationAdministration resource = new MedicationAdministration();
|
||||||
|
resource.setId("12345");
|
||||||
|
var dosage = new MedicationAdministration.MedicationAdministrationDosageComponent();
|
||||||
|
dosage.setDose((SimpleQuantity) new SimpleQuantity().setValue(40))
|
||||||
|
.addExtension(new Extension()
|
||||||
|
.setUrl("http://duration")
|
||||||
|
.setValue(new Duration().setValue(5340000)));
|
||||||
|
resource.setDosage(dosage);
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
}
|
|
@ -95,13 +95,13 @@ public class FhirRequestBuilderTests {
|
||||||
Mockito.doReturn(parser).when(fhirRequestBuilder).getParser(ArgumentMatchers.eq("json"));
|
Mockito.doReturn(parser).when(fhirRequestBuilder).getParser(ArgumentMatchers.eq("json"));
|
||||||
|
|
||||||
fhirRequestBuilder.unmarshalReference(response, "json");
|
fhirRequestBuilder.unmarshalReference(response, "json");
|
||||||
Mockito.verify(logger).logResponse(ArgumentMatchers.eq("200"), ArgumentMatchers.anyList(), AdditionalMatchers.aryEq(RESPONSE_BODY_STRING.getBytes()));
|
Mockito.verify(logger).logResponse(ArgumentMatchers.eq("200"), ArgumentMatchers.anyList(), AdditionalMatchers.aryEq(RESPONSE_BODY_STRING.getBytes()), ArgumentMatchers.anyLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnmarshallFeedLogging() {
|
public void testUnmarshallFeedLogging() {
|
||||||
fhirRequestBuilder.unmarshalFeed(response, "application/json");
|
fhirRequestBuilder.unmarshalFeed(response, "application/json");
|
||||||
Mockito.verify(logger).logResponse(ArgumentMatchers.eq("200"), ArgumentMatchers.anyList(), AdditionalMatchers.aryEq(RESPONSE_BODY_STRING.getBytes()));
|
Mockito.verify(logger).logResponse(ArgumentMatchers.eq("200"), ArgumentMatchers.anyList(), AdditionalMatchers.aryEq(RESPONSE_BODY_STRING.getBytes()), ArgumentMatchers.anyLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>6.3.26-SNAPSHOT</version>
|
<version>6.3.30-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class HTMLClientLogger implements ToolingClientLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void logResponse(String outcome, List<String> headers, byte[] body) {
|
public void logResponse(String outcome, List<String> headers, byte[] body, long start) {
|
||||||
if (file == null)
|
if (file == null)
|
||||||
return;
|
return;
|
||||||
file.println("<pre>");
|
file.println("<pre>");
|
||||||
|
|
|
@ -8400,15 +8400,15 @@ public class JsonParser extends JsonParserBase {
|
||||||
parseElementProperties(getJObject(json, "_verificationDate"), res.getVerificationDateElement());
|
parseElementProperties(getJObject(json, "_verificationDate"), res.getVerificationDateElement());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Consent.provisionComponent parseConsentprovisionComponent(JsonObject json, Consent owner)
|
protected Consent.ProvisionComponent parseConsentprovisionComponent(JsonObject json, Consent owner)
|
||||||
throws IOException, FHIRFormatError {
|
throws IOException, FHIRFormatError {
|
||||||
Consent.provisionComponent res = new Consent.provisionComponent();
|
Consent.ProvisionComponent res = new Consent.ProvisionComponent();
|
||||||
parseConsentprovisionComponentProperties(json, owner, res);
|
parseConsentprovisionComponentProperties(json, owner, res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void parseConsentprovisionComponentProperties(JsonObject json, Consent owner,
|
protected void parseConsentprovisionComponentProperties(JsonObject json, Consent owner,
|
||||||
Consent.provisionComponent res) throws IOException, FHIRFormatError {
|
Consent.ProvisionComponent res) throws IOException, FHIRFormatError {
|
||||||
parseBackboneElementProperties(json, res);
|
parseBackboneElementProperties(json, res);
|
||||||
if (json.has("type"))
|
if (json.has("type"))
|
||||||
res.setTypeElement(parseEnumeration(json.get("type").getAsString(), Consent.ConsentProvisionType.NULL,
|
res.setTypeElement(parseEnumeration(json.get("type").getAsString(), Consent.ConsentProvisionType.NULL,
|
||||||
|
@ -41383,7 +41383,7 @@ public class JsonParser extends JsonParserBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void composeConsentprovisionComponent(String name, Consent.provisionComponent element) throws IOException {
|
protected void composeConsentprovisionComponent(String name, Consent.ProvisionComponent element) throws IOException {
|
||||||
if (element != null) {
|
if (element != null) {
|
||||||
open(name);
|
open(name);
|
||||||
composeConsentprovisionComponentInner(element);
|
composeConsentprovisionComponentInner(element);
|
||||||
|
@ -41391,7 +41391,7 @@ public class JsonParser extends JsonParserBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void composeConsentprovisionComponentInner(Consent.provisionComponent element) throws IOException {
|
protected void composeConsentprovisionComponentInner(Consent.ProvisionComponent element) throws IOException {
|
||||||
composeBackbone(element);
|
composeBackbone(element);
|
||||||
if (element.hasTypeElement()) {
|
if (element.hasTypeElement()) {
|
||||||
composeEnumerationCore("type", element.getTypeElement(), new Consent.ConsentProvisionTypeEnumFactory(), false);
|
composeEnumerationCore("type", element.getTypeElement(), new Consent.ConsentProvisionTypeEnumFactory(), false);
|
||||||
|
@ -41454,7 +41454,7 @@ public class JsonParser extends JsonParserBase {
|
||||||
;
|
;
|
||||||
if (element.hasProvision()) {
|
if (element.hasProvision()) {
|
||||||
openArray("provision");
|
openArray("provision");
|
||||||
for (Consent.provisionComponent e : element.getProvision())
|
for (Consent.ProvisionComponent e : element.getProvision())
|
||||||
composeConsentprovisionComponent(null, e);
|
composeConsentprovisionComponent(null, e);
|
||||||
closeArray();
|
closeArray();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4917,7 +4917,7 @@ public class RdfParser extends RdfParserBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void composeConsentprovisionComponent(Complex parent, String parentType, String name,
|
protected void composeConsentprovisionComponent(Complex parent, String parentType, String name,
|
||||||
Consent.provisionComponent element, int index) {
|
Consent.ProvisionComponent element, int index) {
|
||||||
if (element == null)
|
if (element == null)
|
||||||
return;
|
return;
|
||||||
Complex t;
|
Complex t;
|
||||||
|
|
|
@ -6924,9 +6924,9 @@ public class XmlParser extends XmlParserBase {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Consent.provisionComponent parseConsentprovisionComponent(XmlPullParser xpp, Consent owner)
|
protected Consent.ProvisionComponent parseConsentprovisionComponent(XmlPullParser xpp, Consent owner)
|
||||||
throws XmlPullParserException, IOException, FHIRFormatError {
|
throws XmlPullParserException, IOException, FHIRFormatError {
|
||||||
Consent.provisionComponent res = new Consent.provisionComponent();
|
Consent.ProvisionComponent res = new Consent.ProvisionComponent();
|
||||||
parseBackboneAttributes(xpp, res);
|
parseBackboneAttributes(xpp, res);
|
||||||
next(xpp);
|
next(xpp);
|
||||||
int eventType = nextNoWhitespace(xpp);
|
int eventType = nextNoWhitespace(xpp);
|
||||||
|
@ -6941,7 +6941,7 @@ public class XmlParser extends XmlParserBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean parseConsentprovisionComponentContent(int eventType, XmlPullParser xpp, Consent owner,
|
protected boolean parseConsentprovisionComponentContent(int eventType, XmlPullParser xpp, Consent owner,
|
||||||
Consent.provisionComponent res) throws XmlPullParserException, IOException, FHIRFormatError {
|
Consent.ProvisionComponent res) throws XmlPullParserException, IOException, FHIRFormatError {
|
||||||
if (eventType == XmlPullParser.START_TAG && xpp.getName().equals("type")) {
|
if (eventType == XmlPullParser.START_TAG && xpp.getName().equals("type")) {
|
||||||
res.setTypeElement(
|
res.setTypeElement(
|
||||||
parseEnumeration(xpp, Consent.ConsentProvisionType.NULL, new Consent.ConsentProvisionTypeEnumFactory()));
|
parseEnumeration(xpp, Consent.ConsentProvisionType.NULL, new Consent.ConsentProvisionTypeEnumFactory()));
|
||||||
|
@ -34008,7 +34008,7 @@ public class XmlParser extends XmlParserBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void composeConsentprovisionComponent(String name, Consent.provisionComponent element) throws IOException {
|
protected void composeConsentprovisionComponent(String name, Consent.ProvisionComponent element) throws IOException {
|
||||||
if (element != null) {
|
if (element != null) {
|
||||||
composeElementAttributes(element);
|
composeElementAttributes(element);
|
||||||
xml.enter(FHIR_NS, name);
|
xml.enter(FHIR_NS, name);
|
||||||
|
@ -34018,7 +34018,7 @@ public class XmlParser extends XmlParserBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void composeConsentprovisionComponentElements(Consent.provisionComponent element) throws IOException {
|
protected void composeConsentprovisionComponentElements(Consent.ProvisionComponent element) throws IOException {
|
||||||
composeBackboneElementElements(element);
|
composeBackboneElementElements(element);
|
||||||
if (element.hasTypeElement())
|
if (element.hasTypeElement())
|
||||||
composeEnumeration("type", element.getTypeElement(), new Consent.ConsentProvisionTypeEnumFactory());
|
composeEnumeration("type", element.getTypeElement(), new Consent.ConsentProvisionTypeEnumFactory());
|
||||||
|
@ -34057,7 +34057,7 @@ public class XmlParser extends XmlParserBase {
|
||||||
composeConsentprovisionDataComponent("data", e);
|
composeConsentprovisionDataComponent("data", e);
|
||||||
}
|
}
|
||||||
if (element.hasProvision()) {
|
if (element.hasProvision()) {
|
||||||
for (Consent.provisionComponent e : element.getProvision())
|
for (Consent.ProvisionComponent e : element.getProvision())
|
||||||
composeConsentprovisionComponent("provision", e);
|
composeConsentprovisionComponent("provision", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1221,7 +1221,7 @@ public class Consent extends DomainResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Block()
|
@Block()
|
||||||
public static class provisionComponent extends BackboneElement implements IBaseBackboneElement {
|
public static class ProvisionComponent extends BackboneElement implements IBaseBackboneElement {
|
||||||
/**
|
/**
|
||||||
* Action to take - permit or deny - when the rule conditions are met. Not
|
* Action to take - permit or deny - when the rule conditions are met. Not
|
||||||
* permitted in root rule, required in all nested rules.
|
* permitted in root rule, required in all nested rules.
|
||||||
|
@ -1314,16 +1314,16 @@ public class Consent extends DomainResource {
|
||||||
* Rules which provide exceptions to the base rule or subrules.
|
* Rules which provide exceptions to the base rule or subrules.
|
||||||
*/
|
*/
|
||||||
@Child(name = "provision", type = {
|
@Child(name = "provision", type = {
|
||||||
provisionComponent.class }, order = 11, min = 0, max = Child.MAX_UNLIMITED, modifier = false, summary = false)
|
ProvisionComponent.class }, order = 11, min = 0, max = Child.MAX_UNLIMITED, modifier = false, summary = false)
|
||||||
@Description(shortDefinition = "Nested Exception Rules", formalDefinition = "Rules which provide exceptions to the base rule or subrules.")
|
@Description(shortDefinition = "Nested Exception Rules", formalDefinition = "Rules which provide exceptions to the base rule or subrules.")
|
||||||
protected List<provisionComponent> provision;
|
protected List<ProvisionComponent> provision;
|
||||||
|
|
||||||
private static final long serialVersionUID = -1280172451L;
|
private static final long serialVersionUID = -1280172451L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
public provisionComponent() {
|
public ProvisionComponent() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1357,7 +1357,7 @@ public class Consent extends DomainResource {
|
||||||
* extensions. The accessor "getType" gives direct access to the
|
* extensions. The accessor "getType" gives direct access to the
|
||||||
* value
|
* value
|
||||||
*/
|
*/
|
||||||
public provisionComponent setTypeElement(Enumeration<ConsentProvisionType> value) {
|
public ProvisionComponent setTypeElement(Enumeration<ConsentProvisionType> value) {
|
||||||
this.type = value;
|
this.type = value;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -1374,7 +1374,7 @@ public class Consent extends DomainResource {
|
||||||
* @param value Action to take - permit or deny - when the rule conditions are
|
* @param value Action to take - permit or deny - when the rule conditions are
|
||||||
* met. Not permitted in root rule, required in all nested rules.
|
* met. Not permitted in root rule, required in all nested rules.
|
||||||
*/
|
*/
|
||||||
public provisionComponent setType(ConsentProvisionType value) {
|
public ProvisionComponent setType(ConsentProvisionType value) {
|
||||||
if (value == null)
|
if (value == null)
|
||||||
this.type = null;
|
this.type = null;
|
||||||
else {
|
else {
|
||||||
|
@ -1404,7 +1404,7 @@ public class Consent extends DomainResource {
|
||||||
/**
|
/**
|
||||||
* @param value {@link #period} (The timeframe in this rule is valid.)
|
* @param value {@link #period} (The timeframe in this rule is valid.)
|
||||||
*/
|
*/
|
||||||
public provisionComponent setPeriod(Period value) {
|
public ProvisionComponent setPeriod(Period value) {
|
||||||
this.period = value;
|
this.period = value;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -1423,7 +1423,7 @@ public class Consent extends DomainResource {
|
||||||
/**
|
/**
|
||||||
* @return Returns a reference to <code>this</code> for easy method chaining
|
* @return Returns a reference to <code>this</code> for easy method chaining
|
||||||
*/
|
*/
|
||||||
public provisionComponent setActor(List<provisionActorComponent> theActor) {
|
public ProvisionComponent setActor(List<provisionActorComponent> theActor) {
|
||||||
this.actor = theActor;
|
this.actor = theActor;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -1445,7 +1445,7 @@ public class Consent extends DomainResource {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public provisionComponent addActor(provisionActorComponent t) { // 3
|
public ProvisionComponent addActor(provisionActorComponent t) { // 3
|
||||||
if (t == null)
|
if (t == null)
|
||||||
return this;
|
return this;
|
||||||
if (this.actor == null)
|
if (this.actor == null)
|
||||||
|
@ -1477,7 +1477,7 @@ public class Consent extends DomainResource {
|
||||||
/**
|
/**
|
||||||
* @return Returns a reference to <code>this</code> for easy method chaining
|
* @return Returns a reference to <code>this</code> for easy method chaining
|
||||||
*/
|
*/
|
||||||
public provisionComponent setAction(List<CodeableConcept> theAction) {
|
public ProvisionComponent setAction(List<CodeableConcept> theAction) {
|
||||||
this.action = theAction;
|
this.action = theAction;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -1499,7 +1499,7 @@ public class Consent extends DomainResource {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public provisionComponent addAction(CodeableConcept t) { // 3
|
public ProvisionComponent addAction(CodeableConcept t) { // 3
|
||||||
if (t == null)
|
if (t == null)
|
||||||
return this;
|
return this;
|
||||||
if (this.action == null)
|
if (this.action == null)
|
||||||
|
@ -1533,7 +1533,7 @@ public class Consent extends DomainResource {
|
||||||
/**
|
/**
|
||||||
* @return Returns a reference to <code>this</code> for easy method chaining
|
* @return Returns a reference to <code>this</code> for easy method chaining
|
||||||
*/
|
*/
|
||||||
public provisionComponent setSecurityLabel(List<Coding> theSecurityLabel) {
|
public ProvisionComponent setSecurityLabel(List<Coding> theSecurityLabel) {
|
||||||
this.securityLabel = theSecurityLabel;
|
this.securityLabel = theSecurityLabel;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -1555,7 +1555,7 @@ public class Consent extends DomainResource {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public provisionComponent addSecurityLabel(Coding t) { // 3
|
public ProvisionComponent addSecurityLabel(Coding t) { // 3
|
||||||
if (t == null)
|
if (t == null)
|
||||||
return this;
|
return this;
|
||||||
if (this.securityLabel == null)
|
if (this.securityLabel == null)
|
||||||
|
@ -1589,7 +1589,7 @@ public class Consent extends DomainResource {
|
||||||
/**
|
/**
|
||||||
* @return Returns a reference to <code>this</code> for easy method chaining
|
* @return Returns a reference to <code>this</code> for easy method chaining
|
||||||
*/
|
*/
|
||||||
public provisionComponent setPurpose(List<Coding> thePurpose) {
|
public ProvisionComponent setPurpose(List<Coding> thePurpose) {
|
||||||
this.purpose = thePurpose;
|
this.purpose = thePurpose;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -1611,7 +1611,7 @@ public class Consent extends DomainResource {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public provisionComponent addPurpose(Coding t) { // 3
|
public ProvisionComponent addPurpose(Coding t) { // 3
|
||||||
if (t == null)
|
if (t == null)
|
||||||
return this;
|
return this;
|
||||||
if (this.purpose == null)
|
if (this.purpose == null)
|
||||||
|
@ -1646,7 +1646,7 @@ public class Consent extends DomainResource {
|
||||||
/**
|
/**
|
||||||
* @return Returns a reference to <code>this</code> for easy method chaining
|
* @return Returns a reference to <code>this</code> for easy method chaining
|
||||||
*/
|
*/
|
||||||
public provisionComponent setClass_(List<Coding> theClass_) {
|
public ProvisionComponent setClass_(List<Coding> theClass_) {
|
||||||
this.class_ = theClass_;
|
this.class_ = theClass_;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -1668,7 +1668,7 @@ public class Consent extends DomainResource {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public provisionComponent addClass_(Coding t) { // 3
|
public ProvisionComponent addClass_(Coding t) { // 3
|
||||||
if (t == null)
|
if (t == null)
|
||||||
return this;
|
return this;
|
||||||
if (this.class_ == null)
|
if (this.class_ == null)
|
||||||
|
@ -1701,7 +1701,7 @@ public class Consent extends DomainResource {
|
||||||
/**
|
/**
|
||||||
* @return Returns a reference to <code>this</code> for easy method chaining
|
* @return Returns a reference to <code>this</code> for easy method chaining
|
||||||
*/
|
*/
|
||||||
public provisionComponent setCode(List<CodeableConcept> theCode) {
|
public ProvisionComponent setCode(List<CodeableConcept> theCode) {
|
||||||
this.code = theCode;
|
this.code = theCode;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -1723,7 +1723,7 @@ public class Consent extends DomainResource {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public provisionComponent addCode(CodeableConcept t) { // 3
|
public ProvisionComponent addCode(CodeableConcept t) { // 3
|
||||||
if (t == null)
|
if (t == null)
|
||||||
return this;
|
return this;
|
||||||
if (this.code == null)
|
if (this.code == null)
|
||||||
|
@ -1764,7 +1764,7 @@ public class Consent extends DomainResource {
|
||||||
* @param value {@link #dataPeriod} (Clinical or Operational Relevant period of
|
* @param value {@link #dataPeriod} (Clinical or Operational Relevant period of
|
||||||
* time that bounds the data controlled by this rule.)
|
* time that bounds the data controlled by this rule.)
|
||||||
*/
|
*/
|
||||||
public provisionComponent setDataPeriod(Period value) {
|
public ProvisionComponent setDataPeriod(Period value) {
|
||||||
this.dataPeriod = value;
|
this.dataPeriod = value;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -1782,7 +1782,7 @@ public class Consent extends DomainResource {
|
||||||
/**
|
/**
|
||||||
* @return Returns a reference to <code>this</code> for easy method chaining
|
* @return Returns a reference to <code>this</code> for easy method chaining
|
||||||
*/
|
*/
|
||||||
public provisionComponent setData(List<provisionDataComponent> theData) {
|
public ProvisionComponent setData(List<provisionDataComponent> theData) {
|
||||||
this.data = theData;
|
this.data = theData;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -1804,7 +1804,7 @@ public class Consent extends DomainResource {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public provisionComponent addData(provisionDataComponent t) { // 3
|
public ProvisionComponent addData(provisionDataComponent t) { // 3
|
||||||
if (t == null)
|
if (t == null)
|
||||||
return this;
|
return this;
|
||||||
if (this.data == null)
|
if (this.data == null)
|
||||||
|
@ -1828,16 +1828,16 @@ public class Consent extends DomainResource {
|
||||||
* @return {@link #provision} (Rules which provide exceptions to the base rule
|
* @return {@link #provision} (Rules which provide exceptions to the base rule
|
||||||
* or subrules.)
|
* or subrules.)
|
||||||
*/
|
*/
|
||||||
public List<provisionComponent> getProvision() {
|
public List<ProvisionComponent> getProvision() {
|
||||||
if (this.provision == null)
|
if (this.provision == null)
|
||||||
this.provision = new ArrayList<provisionComponent>();
|
this.provision = new ArrayList<ProvisionComponent>();
|
||||||
return this.provision;
|
return this.provision;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns a reference to <code>this</code> for easy method chaining
|
* @return Returns a reference to <code>this</code> for easy method chaining
|
||||||
*/
|
*/
|
||||||
public provisionComponent setProvision(List<provisionComponent> theProvision) {
|
public ProvisionComponent setProvision(List<ProvisionComponent> theProvision) {
|
||||||
this.provision = theProvision;
|
this.provision = theProvision;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -1845,25 +1845,25 @@ public class Consent extends DomainResource {
|
||||||
public boolean hasProvision() {
|
public boolean hasProvision() {
|
||||||
if (this.provision == null)
|
if (this.provision == null)
|
||||||
return false;
|
return false;
|
||||||
for (provisionComponent item : this.provision)
|
for (ProvisionComponent item : this.provision)
|
||||||
if (!item.isEmpty())
|
if (!item.isEmpty())
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public provisionComponent addProvision() { // 3
|
public ProvisionComponent addProvision() { // 3
|
||||||
provisionComponent t = new provisionComponent();
|
ProvisionComponent t = new ProvisionComponent();
|
||||||
if (this.provision == null)
|
if (this.provision == null)
|
||||||
this.provision = new ArrayList<provisionComponent>();
|
this.provision = new ArrayList<ProvisionComponent>();
|
||||||
this.provision.add(t);
|
this.provision.add(t);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public provisionComponent addProvision(provisionComponent t) { // 3
|
public ProvisionComponent addProvision(ProvisionComponent t) { // 3
|
||||||
if (t == null)
|
if (t == null)
|
||||||
return this;
|
return this;
|
||||||
if (this.provision == null)
|
if (this.provision == null)
|
||||||
this.provision = new ArrayList<provisionComponent>();
|
this.provision = new ArrayList<ProvisionComponent>();
|
||||||
this.provision.add(t);
|
this.provision.add(t);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -1872,7 +1872,7 @@ public class Consent extends DomainResource {
|
||||||
* @return The first repetition of repeating field {@link #provision}, creating
|
* @return The first repetition of repeating field {@link #provision}, creating
|
||||||
* it if it does not already exist
|
* it if it does not already exist
|
||||||
*/
|
*/
|
||||||
public provisionComponent getProvisionFirstRep() {
|
public ProvisionComponent getProvisionFirstRep() {
|
||||||
if (getProvision().isEmpty()) {
|
if (getProvision().isEmpty()) {
|
||||||
addProvision();
|
addProvision();
|
||||||
}
|
}
|
||||||
|
@ -2027,7 +2027,7 @@ public class Consent extends DomainResource {
|
||||||
this.getData().add((provisionDataComponent) value); // provisionDataComponent
|
this.getData().add((provisionDataComponent) value); // provisionDataComponent
|
||||||
return value;
|
return value;
|
||||||
case -547120939: // provision
|
case -547120939: // provision
|
||||||
this.getProvision().add((provisionComponent) value); // provisionComponent
|
this.getProvision().add((ProvisionComponent) value); // provisionComponent
|
||||||
return value;
|
return value;
|
||||||
default:
|
default:
|
||||||
return super.setProperty(hash, name, value);
|
return super.setProperty(hash, name, value);
|
||||||
|
@ -2059,7 +2059,7 @@ public class Consent extends DomainResource {
|
||||||
} else if (name.equals("data")) {
|
} else if (name.equals("data")) {
|
||||||
this.getData().add((provisionDataComponent) value);
|
this.getData().add((provisionDataComponent) value);
|
||||||
} else if (name.equals("provision")) {
|
} else if (name.equals("provision")) {
|
||||||
this.getProvision().add((provisionComponent) value);
|
this.getProvision().add((ProvisionComponent) value);
|
||||||
} else
|
} else
|
||||||
return super.setProperty(name, value);
|
return super.setProperty(name, value);
|
||||||
return value;
|
return value;
|
||||||
|
@ -2088,7 +2088,7 @@ public class Consent extends DomainResource {
|
||||||
} else if (name.equals("data")) {
|
} else if (name.equals("data")) {
|
||||||
this.getData().remove((provisionDataComponent) value);
|
this.getData().remove((provisionDataComponent) value);
|
||||||
} else if (name.equals("provision")) {
|
} else if (name.equals("provision")) {
|
||||||
this.getProvision().remove((provisionComponent) value);
|
this.getProvision().remove((ProvisionComponent) value);
|
||||||
} else
|
} else
|
||||||
super.removeChild(name, value);
|
super.removeChild(name, value);
|
||||||
|
|
||||||
|
@ -2186,13 +2186,13 @@ public class Consent extends DomainResource {
|
||||||
return super.addChild(name);
|
return super.addChild(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public provisionComponent copy() {
|
public ProvisionComponent copy() {
|
||||||
provisionComponent dst = new provisionComponent();
|
ProvisionComponent dst = new ProvisionComponent();
|
||||||
copyValues(dst);
|
copyValues(dst);
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyValues(provisionComponent dst) {
|
public void copyValues(ProvisionComponent dst) {
|
||||||
super.copyValues(dst);
|
super.copyValues(dst);
|
||||||
dst.type = type == null ? null : type.copy();
|
dst.type = type == null ? null : type.copy();
|
||||||
dst.period = period == null ? null : period.copy();
|
dst.period = period == null ? null : period.copy();
|
||||||
|
@ -2240,8 +2240,8 @@ public class Consent extends DomainResource {
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
if (provision != null) {
|
if (provision != null) {
|
||||||
dst.provision = new ArrayList<provisionComponent>();
|
dst.provision = new ArrayList<ProvisionComponent>();
|
||||||
for (provisionComponent i : provision)
|
for (ProvisionComponent i : provision)
|
||||||
dst.provision.add(i.copy());
|
dst.provision.add(i.copy());
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -2251,9 +2251,9 @@ public class Consent extends DomainResource {
|
||||||
public boolean equalsDeep(Base other_) {
|
public boolean equalsDeep(Base other_) {
|
||||||
if (!super.equalsDeep(other_))
|
if (!super.equalsDeep(other_))
|
||||||
return false;
|
return false;
|
||||||
if (!(other_ instanceof provisionComponent))
|
if (!(other_ instanceof ProvisionComponent))
|
||||||
return false;
|
return false;
|
||||||
provisionComponent o = (provisionComponent) other_;
|
ProvisionComponent o = (ProvisionComponent) other_;
|
||||||
return compareDeep(type, o.type, true) && compareDeep(period, o.period, true) && compareDeep(actor, o.actor, true)
|
return compareDeep(type, o.type, true) && compareDeep(period, o.period, true) && compareDeep(actor, o.actor, true)
|
||||||
&& compareDeep(action, o.action, true) && compareDeep(securityLabel, o.securityLabel, true)
|
&& compareDeep(action, o.action, true) && compareDeep(securityLabel, o.securityLabel, true)
|
||||||
&& compareDeep(purpose, o.purpose, true) && compareDeep(class_, o.class_, true)
|
&& compareDeep(purpose, o.purpose, true) && compareDeep(class_, o.class_, true)
|
||||||
|
@ -2265,9 +2265,9 @@ public class Consent extends DomainResource {
|
||||||
public boolean equalsShallow(Base other_) {
|
public boolean equalsShallow(Base other_) {
|
||||||
if (!super.equalsShallow(other_))
|
if (!super.equalsShallow(other_))
|
||||||
return false;
|
return false;
|
||||||
if (!(other_ instanceof provisionComponent))
|
if (!(other_ instanceof ProvisionComponent))
|
||||||
return false;
|
return false;
|
||||||
provisionComponent o = (provisionComponent) other_;
|
ProvisionComponent o = (ProvisionComponent) other_;
|
||||||
return compareValues(type, o.type, true);
|
return compareValues(type, o.type, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3002,7 +3002,7 @@ public class Consent extends DomainResource {
|
||||||
*/
|
*/
|
||||||
@Child(name = "provision", type = {}, order = 12, min = 0, max = 1, modifier = false, summary = true)
|
@Child(name = "provision", type = {}, order = 12, min = 0, max = 1, modifier = false, summary = true)
|
||||||
@Description(shortDefinition = "Constraints to the base Consent.policyRule", formalDefinition = "An exception to the base policy of this consent. An exception can be an addition or removal of access permissions.")
|
@Description(shortDefinition = "Constraints to the base Consent.policyRule", formalDefinition = "An exception to the base policy of this consent. An exception can be an addition or removal of access permissions.")
|
||||||
protected provisionComponent provision;
|
protected ProvisionComponent provision;
|
||||||
|
|
||||||
private static final long serialVersionUID = 206528051L;
|
private static final long serialVersionUID = 206528051L;
|
||||||
|
|
||||||
|
@ -3669,12 +3669,12 @@ public class Consent extends DomainResource {
|
||||||
* @return {@link #provision} (An exception to the base policy of this consent.
|
* @return {@link #provision} (An exception to the base policy of this consent.
|
||||||
* An exception can be an addition or removal of access permissions.)
|
* An exception can be an addition or removal of access permissions.)
|
||||||
*/
|
*/
|
||||||
public provisionComponent getProvision() {
|
public ProvisionComponent getProvision() {
|
||||||
if (this.provision == null)
|
if (this.provision == null)
|
||||||
if (Configuration.errorOnAutoCreate())
|
if (Configuration.errorOnAutoCreate())
|
||||||
throw new Error("Attempt to auto-create Consent.provision");
|
throw new Error("Attempt to auto-create Consent.provision");
|
||||||
else if (Configuration.doAutoCreate())
|
else if (Configuration.doAutoCreate())
|
||||||
this.provision = new provisionComponent(); // cc
|
this.provision = new ProvisionComponent(); // cc
|
||||||
return this.provision;
|
return this.provision;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3687,7 +3687,7 @@ public class Consent extends DomainResource {
|
||||||
* consent. An exception can be an addition or removal of access
|
* consent. An exception can be an addition or removal of access
|
||||||
* permissions.)
|
* permissions.)
|
||||||
*/
|
*/
|
||||||
public Consent setProvision(provisionComponent value) {
|
public Consent setProvision(ProvisionComponent value) {
|
||||||
this.provision = value;
|
this.provision = value;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -3883,7 +3883,7 @@ public class Consent extends DomainResource {
|
||||||
this.getVerification().add((ConsentVerificationComponent) value); // ConsentVerificationComponent
|
this.getVerification().add((ConsentVerificationComponent) value); // ConsentVerificationComponent
|
||||||
return value;
|
return value;
|
||||||
case -547120939: // provision
|
case -547120939: // provision
|
||||||
this.provision = (provisionComponent) value; // provisionComponent
|
this.provision = (ProvisionComponent) value; // provisionComponent
|
||||||
return value;
|
return value;
|
||||||
default:
|
default:
|
||||||
return super.setProperty(hash, name, value);
|
return super.setProperty(hash, name, value);
|
||||||
|
@ -3919,7 +3919,7 @@ public class Consent extends DomainResource {
|
||||||
} else if (name.equals("verification")) {
|
} else if (name.equals("verification")) {
|
||||||
this.getVerification().add((ConsentVerificationComponent) value);
|
this.getVerification().add((ConsentVerificationComponent) value);
|
||||||
} else if (name.equals("provision")) {
|
} else if (name.equals("provision")) {
|
||||||
this.provision = (provisionComponent) value; // provisionComponent
|
this.provision = (ProvisionComponent) value; // provisionComponent
|
||||||
} else
|
} else
|
||||||
return super.setProperty(name, value);
|
return super.setProperty(name, value);
|
||||||
return value;
|
return value;
|
||||||
|
@ -3952,7 +3952,7 @@ public class Consent extends DomainResource {
|
||||||
} else if (name.equals("verification")) {
|
} else if (name.equals("verification")) {
|
||||||
this.getVerification().remove((ConsentVerificationComponent) value);
|
this.getVerification().remove((ConsentVerificationComponent) value);
|
||||||
} else if (name.equals("provision")) {
|
} else if (name.equals("provision")) {
|
||||||
this.provision = (provisionComponent) value; // provisionComponent
|
this.provision = (ProvisionComponent) value; // provisionComponent
|
||||||
} else
|
} else
|
||||||
super.removeChild(name, value);
|
super.removeChild(name, value);
|
||||||
|
|
||||||
|
@ -4064,7 +4064,7 @@ public class Consent extends DomainResource {
|
||||||
} else if (name.equals("verification")) {
|
} else if (name.equals("verification")) {
|
||||||
return addVerification();
|
return addVerification();
|
||||||
} else if (name.equals("provision")) {
|
} else if (name.equals("provision")) {
|
||||||
this.provision = new provisionComponent();
|
this.provision = new ProvisionComponent();
|
||||||
return this.provision;
|
return this.provision;
|
||||||
} else
|
} else
|
||||||
return super.addChild(name);
|
return super.addChild(name);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -64,7 +64,7 @@ public class FhirLoggingInterceptor implements Interceptor {
|
||||||
headerMap.keySet().forEach(key -> headerMap.get(key).forEach(value -> headerList.add(key + ":" + value)));
|
headerMap.keySet().forEach(key -> headerMap.get(key).forEach(value -> headerList.add(key + ":" + value)));
|
||||||
|
|
||||||
if (logger != null) {
|
if (logger != null) {
|
||||||
logger.logResponse(Integer.toString(response.code()), headerList, bodyBytes);
|
logger.logResponse(Integer.toString(response.code()), headerList, bodyBytes, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reading byte[] clears body. Need to recreate.
|
// Reading byte[] clears body. Need to recreate.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>6.3.26-SNAPSHOT</version>
|
<version>6.3.30-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class HTMLClientLogger extends BaseLogger implements ToolingClientLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void logResponse(String outcome, List<String> headers, byte[] body) {
|
public void logResponse(String outcome, List<String> headers, byte[] body, long start) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
System.out.println(" txlog resp: " + outcome + " " + present(body));
|
System.out.println(" txlog resp: " + outcome + " " + present(body));
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class TextClientLogger extends BaseLogger implements ToolingClientLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void logResponse(String outcome, List<String> headers, byte[] body) {
|
public void logResponse(String outcome, List<String> headers, byte[] body, long start) {
|
||||||
if (file == null)
|
if (file == null)
|
||||||
return;
|
return;
|
||||||
file.println("\r\n\r\nResponse: \r\n");
|
file.println("\r\n\r\nResponse: \r\n");
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class FhirLoggingInterceptor implements Interceptor {
|
||||||
headerMap.keySet().forEach(key -> headerMap.get(key).forEach(value -> headerList.add(key + ":" + value)));
|
headerMap.keySet().forEach(key -> headerMap.get(key).forEach(value -> headerList.add(key + ":" + value)));
|
||||||
|
|
||||||
if (logger != null) {
|
if (logger != null) {
|
||||||
logger.logResponse(Integer.toString(response.code()), headerList, bodyBytes);
|
logger.logResponse(Integer.toString(response.code()), headerList, bodyBytes, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reading byte[] clears body. Need to recreate.
|
// Reading byte[] clears body. Need to recreate.
|
||||||
|
|
|
@ -134,6 +134,6 @@ class ClientTest {
|
||||||
server.takeRequest();
|
server.takeRequest();
|
||||||
Mockito.verify(mockLogger, Mockito.times(1)).logRequest(Mockito.anyString(), Mockito.anyString(), Mockito.anyList(),
|
Mockito.verify(mockLogger, Mockito.times(1)).logRequest(Mockito.anyString(), Mockito.anyString(), Mockito.anyList(),
|
||||||
Mockito.any());
|
Mockito.any());
|
||||||
Mockito.verify(mockLogger, Mockito.times(1)).logResponse(Mockito.anyString(), Mockito.anyList(), Mockito.any());
|
Mockito.verify(mockLogger, Mockito.times(1)).logResponse(Mockito.anyString(), Mockito.anyList(), Mockito.any(), Mockito.anyLong());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>6.3.26-SNAPSHOT</version>
|
<version>6.3.30-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -413,11 +413,10 @@ public class ProfileUtilities {
|
||||||
// note that ProfileUtilities are used re-entrantly internally, so nothing with process state can be here
|
// note that ProfileUtilities are used re-entrantly internally, so nothing with process state can be here
|
||||||
private final IWorkerContext context;
|
private final IWorkerContext context;
|
||||||
private FHIRPathEngine fpe;
|
private FHIRPathEngine fpe;
|
||||||
private List<ValidationMessage> messages;
|
private List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
|
||||||
private List<String> snapshotStack = new ArrayList<String>();
|
private List<String> snapshotStack = new ArrayList<String>();
|
||||||
private ProfileKnowledgeProvider pkp;
|
private ProfileKnowledgeProvider pkp;
|
||||||
// private boolean igmode;
|
// private boolean igmode;
|
||||||
private boolean exception;
|
|
||||||
private ValidationOptions terminologyServiceOptions = new ValidationOptions(FhirPublication.R5);
|
private ValidationOptions terminologyServiceOptions = new ValidationOptions(FhirPublication.R5);
|
||||||
private boolean newSlicingProcessing;
|
private boolean newSlicingProcessing;
|
||||||
private String defWebRoot;
|
private String defWebRoot;
|
||||||
|
@ -431,11 +430,16 @@ public class ProfileUtilities {
|
||||||
private MappingMergeModeOption mappingMergeMode = MappingMergeModeOption.APPEND;
|
private MappingMergeModeOption mappingMergeMode = MappingMergeModeOption.APPEND;
|
||||||
private boolean forPublication;
|
private boolean forPublication;
|
||||||
private List<StructureDefinition> obligationProfiles = new ArrayList<>();
|
private List<StructureDefinition> obligationProfiles = new ArrayList<>();
|
||||||
|
private boolean wantThrowExceptions;
|
||||||
|
|
||||||
public ProfileUtilities(IWorkerContext context, List<ValidationMessage> messages, ProfileKnowledgeProvider pkp, FHIRPathEngine fpe) {
|
public ProfileUtilities(IWorkerContext context, List<ValidationMessage> messages, ProfileKnowledgeProvider pkp, FHIRPathEngine fpe) {
|
||||||
super();
|
super();
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.messages = messages;
|
if (messages != null) {
|
||||||
|
this.messages = messages;
|
||||||
|
} else {
|
||||||
|
wantThrowExceptions = true;
|
||||||
|
}
|
||||||
this.pkp = pkp;
|
this.pkp = pkp;
|
||||||
|
|
||||||
this.fpe = fpe;
|
this.fpe = fpe;
|
||||||
|
@ -447,7 +451,11 @@ public class ProfileUtilities {
|
||||||
public ProfileUtilities(IWorkerContext context, List<ValidationMessage> messages, ProfileKnowledgeProvider pkp) {
|
public ProfileUtilities(IWorkerContext context, List<ValidationMessage> messages, ProfileKnowledgeProvider pkp) {
|
||||||
super();
|
super();
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.messages = messages;
|
if (messages != null) {
|
||||||
|
this.messages = messages;
|
||||||
|
} else {
|
||||||
|
wantThrowExceptions = true;
|
||||||
|
}
|
||||||
this.pkp = pkp;
|
this.pkp = pkp;
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
this.fpe = new FHIRPathEngine(context, this);
|
this.fpe = new FHIRPathEngine(context, this);
|
||||||
|
@ -789,7 +797,7 @@ public class ProfileUtilities {
|
||||||
ce++;
|
ce++;
|
||||||
if (e.hasId()) {
|
if (e.hasId()) {
|
||||||
String msg = "No match found for "+e.getId()+" in the generated snapshot: check that the path and definitions are legal in the differential (including order)";
|
String msg = "No match found for "+e.getId()+" in the generated snapshot: check that the path and definitions are legal in the differential (including order)";
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, "StructureDefinition.differential.element["+i+"]", msg, ValidationMessage.IssueSeverity.ERROR));
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, "StructureDefinition.differential.element["+i+"]", msg, ValidationMessage.IssueSeverity.ERROR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -862,19 +870,19 @@ public class ProfileUtilities {
|
||||||
slice.getFocus().setMin(count);
|
slice.getFocus().setMin(count);
|
||||||
} else {
|
} else {
|
||||||
String msg = "The slice definition for "+slice.getFocus().getId()+" has a minimum of "+slice.getFocus().getMin()+" but the slices add up to a minimum of "+count;
|
String msg = "The slice definition for "+slice.getFocus().getId()+" has a minimum of "+slice.getFocus().getMin()+" but the slices add up to a minimum of "+count;
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE,
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE,
|
||||||
"StructureDefinition.snapshot.element["+slice.getIndex()+"]", msg, forPublication ? ValidationMessage.IssueSeverity.ERROR : ValidationMessage.IssueSeverity.INFORMATION).setIgnorableError(true));
|
"StructureDefinition.snapshot.element["+slice.getIndex()+"]", msg, forPublication ? ValidationMessage.IssueSeverity.ERROR : ValidationMessage.IssueSeverity.INFORMATION).setIgnorableError(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
count = slice.checkMax();
|
count = slice.checkMax();
|
||||||
if (count > -1 && repeats) {
|
if (count > -1 && repeats) {
|
||||||
String msg = "The slice definition for "+slice.getFocus().getId()+" has a maximum of "+slice.getFocus().getMax()+" but the slices add up to a maximum of "+count+". Check that this is what is intended";
|
String msg = "The slice definition for "+slice.getFocus().getId()+" has a maximum of "+slice.getFocus().getMax()+" but the slices add up to a maximum of "+count+". Check that this is what is intended";
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE,
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE,
|
||||||
"StructureDefinition.snapshot.element["+slice.getIndex()+"]", msg, ValidationMessage.IssueSeverity.INFORMATION));
|
"StructureDefinition.snapshot.element["+slice.getIndex()+"]", msg, ValidationMessage.IssueSeverity.INFORMATION));
|
||||||
}
|
}
|
||||||
if (!slice.checkMinMax()) {
|
if (!slice.checkMinMax()) {
|
||||||
String msg = "The slice definition for "+slice.getFocus().getId()+" has a maximum of "+slice.getFocus().getMax()+" which is less than the minimum of "+slice.getFocus().getMin();
|
String msg = "The slice definition for "+slice.getFocus().getId()+" has a maximum of "+slice.getFocus().getMax()+" which is less than the minimum of "+slice.getFocus().getMin();
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE,
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE,
|
||||||
"StructureDefinition.snapshot.element["+slice.getIndex()+"]", msg, ValidationMessage.IssueSeverity.WARNING));
|
"StructureDefinition.snapshot.element["+slice.getIndex()+"]", msg, ValidationMessage.IssueSeverity.WARNING));
|
||||||
}
|
}
|
||||||
slices.remove(s);
|
slices.remove(s);
|
||||||
|
@ -885,13 +893,13 @@ public class ProfileUtilities {
|
||||||
}
|
}
|
||||||
if (ed.hasSliceName() && !slices.containsKey(ed.getPath())) {
|
if (ed.hasSliceName() && !slices.containsKey(ed.getPath())) {
|
||||||
String msg = "The element "+ed.getId()+" launches straight into slicing without the slicing being set up properly first";
|
String msg = "The element "+ed.getId()+" launches straight into slicing without the slicing being set up properly first";
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE,
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE,
|
||||||
"StructureDefinition.snapshot.element["+i+"]", msg, ValidationMessage.IssueSeverity.ERROR).setIgnorableError(true));
|
"StructureDefinition.snapshot.element["+i+"]", msg, ValidationMessage.IssueSeverity.ERROR).setIgnorableError(true));
|
||||||
}
|
}
|
||||||
if (ed.hasSliceName() && slices.containsKey(ed.getPath())) {
|
if (ed.hasSliceName() && slices.containsKey(ed.getPath())) {
|
||||||
if (!slices.get(ed.getPath()).count(ed, ed.getSliceName())) {
|
if (!slices.get(ed.getPath()).count(ed, ed.getSliceName())) {
|
||||||
String msg = "Duplicate slice name "+ed.getSliceName()+" on "+ed.getId()+" (["+i+"])";
|
String msg = "Duplicate slice name "+ed.getSliceName()+" on "+ed.getId()+" (["+i+"])";
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE,
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE,
|
||||||
"StructureDefinition.snapshot.element["+i+"]", msg, ValidationMessage.IssueSeverity.ERROR).setIgnorableError(true));
|
"StructureDefinition.snapshot.element["+i+"]", msg, ValidationMessage.IssueSeverity.ERROR).setIgnorableError(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -910,10 +918,8 @@ public class ProfileUtilities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sd == null) {
|
if (sd == null) {
|
||||||
if (messages != null) {
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE,
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE,
|
|
||||||
"StructureDefinition.snapshot.element["+i+"]", "The type of profile "+u.getValue()+" cannot be checked as the profile is not known", IssueSeverity.WARNING));
|
"StructureDefinition.snapshot.element["+i+"]", "The type of profile "+u.getValue()+" cannot be checked as the profile is not known", IssueSeverity.WARNING));
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
String wt = t.getWorkingCode();
|
String wt = t.getWorkingCode();
|
||||||
if (ed.getPath().equals("Bundle.entry.response.outcome")) {
|
if (ed.getPath().equals("Bundle.entry.response.outcome")) {
|
||||||
|
@ -1012,13 +1018,15 @@ public class ProfileUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleError(String url, String msg) {
|
private void handleError(String url, String msg) {
|
||||||
if (exception)
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url, msg, ValidationMessage.IssueSeverity.ERROR));
|
||||||
throw new DefinitionException(msg);
|
|
||||||
else
|
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url, msg, ValidationMessage.IssueSeverity.ERROR));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addMessage(ValidationMessage msg) {
|
||||||
|
messages.add(msg);
|
||||||
|
if (msg.getLevel() == IssueSeverity.ERROR && wantThrowExceptions) {
|
||||||
|
throw new DefinitionException(msg.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void copyInheritedExtensions(StructureDefinition base, StructureDefinition derived, String webUrl) {
|
private void copyInheritedExtensions(StructureDefinition base, StructureDefinition derived, String webUrl) {
|
||||||
|
@ -2249,7 +2257,7 @@ public class ProfileUtilities {
|
||||||
* Not sure we have enough information here to do the check properly. Might be better done when we're sorting the profile?
|
* Not sure we have enough information here to do the check properly. Might be better done when we're sorting the profile?
|
||||||
|
|
||||||
if (i != start && result.isEmpty() && !path.startsWith(context.getElement().get(start).getPath()))
|
if (i != start && result.isEmpty() && !path.startsWith(context.getElement().get(start).getPath()))
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, IssueType.VALUE, "StructureDefinition.differential.element["+Integer.toString(start)+"]", "Error: unknown element '"+context.getElement().get(start).getPath()+"' (or it is out of order) in profile '"+url+"' (looking for '"+path+"')", IssueSeverity.WARNING));
|
addMessage(new ValidationMessage(Source.ProfileValidator, IssueType.VALUE, "StructureDefinition.differential.element["+Integer.toString(start)+"]", "Error: unknown element '"+context.getElement().get(start).getPath()+"' (or it is out of order) in profile '"+url+"' (looking for '"+path+"')", IssueSeverity.WARNING));
|
||||||
|
|
||||||
*/
|
*/
|
||||||
result.add(context.getElement().get(i));
|
result.add(context.getElement().get(i));
|
||||||
|
@ -2529,7 +2537,7 @@ public class ProfileUtilities {
|
||||||
if (derived.hasMinElement()) {
|
if (derived.hasMinElement()) {
|
||||||
if (!Base.compareDeep(derived.getMinElement(), base.getMinElement(), false)) {
|
if (!Base.compareDeep(derived.getMinElement(), base.getMinElement(), false)) {
|
||||||
if (derived.getMin() < base.getMin() && !derived.hasSliceName()) // in a slice, minimum cardinality rules do not apply
|
if (derived.getMin() < base.getMin() && !derived.hasSliceName()) // in a slice, minimum cardinality rules do not apply
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+source.getPath(), "Element "+base.getPath()+": derived min ("+Integer.toString(derived.getMin())+") cannot be less than the base min ("+Integer.toString(base.getMin())+") in "+srcSD.getVersionedUrl(), ValidationMessage.IssueSeverity.ERROR));
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+source.getPath(), "Element "+base.getPath()+": derived min ("+Integer.toString(derived.getMin())+") cannot be less than the base min ("+Integer.toString(base.getMin())+") in "+srcSD.getVersionedUrl(), ValidationMessage.IssueSeverity.ERROR));
|
||||||
base.setMinElement(derived.getMinElement().copy());
|
base.setMinElement(derived.getMinElement().copy());
|
||||||
} else if (trimDifferential)
|
} else if (trimDifferential)
|
||||||
derived.setMinElement(null);
|
derived.setMinElement(null);
|
||||||
|
@ -2540,7 +2548,7 @@ public class ProfileUtilities {
|
||||||
if (derived.hasMaxElement()) {
|
if (derived.hasMaxElement()) {
|
||||||
if (!Base.compareDeep(derived.getMaxElement(), base.getMaxElement(), false)) {
|
if (!Base.compareDeep(derived.getMaxElement(), base.getMaxElement(), false)) {
|
||||||
if (isLargerMax(derived.getMax(), base.getMax()))
|
if (isLargerMax(derived.getMax(), base.getMax()))
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+source.getPath(), "Element "+base.getPath()+": derived max ("+derived.getMax()+") cannot be greater than the base max ("+base.getMax()+")", ValidationMessage.IssueSeverity.ERROR));
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+source.getPath(), "Element "+base.getPath()+": derived max ("+derived.getMax()+") cannot be greater than the base max ("+base.getMax()+")", ValidationMessage.IssueSeverity.ERROR));
|
||||||
base.setMaxElement(derived.getMaxElement().copy());
|
base.setMaxElement(derived.getMaxElement().copy());
|
||||||
} else if (trimDifferential)
|
} else if (trimDifferential)
|
||||||
derived.setMaxElement(null);
|
derived.setMaxElement(null);
|
||||||
|
@ -2642,7 +2650,7 @@ public class ProfileUtilities {
|
||||||
}
|
}
|
||||||
if (!(base.hasMustSupportElement() && Base.compareDeep(base.getMustSupportElement(), mse, false))) {
|
if (!(base.hasMustSupportElement() && Base.compareDeep(base.getMustSupportElement(), mse, false))) {
|
||||||
if (base.hasMustSupport() && base.getMustSupport() && !derived.getMustSupport()) {
|
if (base.hasMustSupport() && base.getMustSupport() && !derived.getMustSupport()) {
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Illegal constraint [must-support = false] when [must-support = true] in the base profile", ValidationMessage.IssueSeverity.ERROR));
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Illegal constraint [must-support = false] when [must-support = true] in the base profile", ValidationMessage.IssueSeverity.ERROR));
|
||||||
}
|
}
|
||||||
base.setMustSupportElement(mse);
|
base.setMustSupportElement(mse);
|
||||||
} else if (trimDifferential)
|
} else if (trimDifferential)
|
||||||
|
@ -2654,7 +2662,7 @@ public class ProfileUtilities {
|
||||||
if (derived.hasMustHaveValueElement()) {
|
if (derived.hasMustHaveValueElement()) {
|
||||||
if (!(base.hasMustHaveValueElement() && Base.compareDeep(derived.getMustHaveValueElement(), base.getMustHaveValueElement(), false))) {
|
if (!(base.hasMustHaveValueElement() && Base.compareDeep(derived.getMustHaveValueElement(), base.getMustHaveValueElement(), false))) {
|
||||||
if (base.hasMustHaveValue() && base.getMustHaveValue() && !derived.getMustHaveValue()) {
|
if (base.hasMustHaveValue() && base.getMustHaveValue() && !derived.getMustHaveValue()) {
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Illegal constraint [must-have-value = false] when [must-have-value = true] in the base profile", ValidationMessage.IssueSeverity.ERROR));
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Illegal constraint [must-have-value = false] when [must-have-value = true] in the base profile", ValidationMessage.IssueSeverity.ERROR));
|
||||||
}
|
}
|
||||||
base.setMustHaveValueElement(derived.getMustHaveValueElement().copy());
|
base.setMustHaveValueElement(derived.getMustHaveValueElement().copy());
|
||||||
} else if (trimDifferential)
|
} else if (trimDifferential)
|
||||||
|
@ -2721,25 +2729,25 @@ public class ProfileUtilities {
|
||||||
|
|
||||||
if (!base.hasBinding() || !Base.compareDeep(derived.getBinding(), base.getBinding(), false)) {
|
if (!base.hasBinding() || !Base.compareDeep(derived.getBinding(), base.getBinding(), false)) {
|
||||||
if (base.hasBinding() && base.getBinding().getStrength() == BindingStrength.REQUIRED && derived.getBinding().getStrength() != BindingStrength.REQUIRED)
|
if (base.hasBinding() && base.getBinding().getStrength() == BindingStrength.REQUIRED && derived.getBinding().getStrength() != BindingStrength.REQUIRED)
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "illegal attempt to change the binding on "+derived.getPath()+" from "+base.getBinding().getStrength().toCode()+" to "+derived.getBinding().getStrength().toCode(), ValidationMessage.IssueSeverity.ERROR));
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "illegal attempt to change the binding on "+derived.getPath()+" from "+base.getBinding().getStrength().toCode()+" to "+derived.getBinding().getStrength().toCode(), ValidationMessage.IssueSeverity.ERROR));
|
||||||
// throw new DefinitionException("StructureDefinition "+pn+" at "+derived.getPath()+": illegal attempt to change a binding from "+base.getBinding().getStrength().toCode()+" to "+derived.getBinding().getStrength().toCode());
|
// throw new DefinitionException("StructureDefinition "+pn+" at "+derived.getPath()+": illegal attempt to change a binding from "+base.getBinding().getStrength().toCode()+" to "+derived.getBinding().getStrength().toCode());
|
||||||
else if (base.hasBinding() && derived.hasBinding() && base.getBinding().getStrength() == BindingStrength.REQUIRED && base.getBinding().hasValueSet() && derived.getBinding().hasValueSet()) {
|
else if (base.hasBinding() && derived.hasBinding() && base.getBinding().getStrength() == BindingStrength.REQUIRED && base.getBinding().hasValueSet() && derived.getBinding().hasValueSet()) {
|
||||||
ValueSet baseVs = context.findTxResource(ValueSet.class, base.getBinding().getValueSet(), srcSD);
|
ValueSet baseVs = context.findTxResource(ValueSet.class, base.getBinding().getValueSet(), srcSD);
|
||||||
ValueSet contextVs = context.findTxResource(ValueSet.class, derived.getBinding().getValueSet(), derivedSrc);
|
ValueSet contextVs = context.findTxResource(ValueSet.class, derived.getBinding().getValueSet(), derivedSrc);
|
||||||
if (baseVs == null) {
|
if (baseVs == null) {
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+base.getPath(), "Binding "+base.getBinding().getValueSet()+" could not be located", ValidationMessage.IssueSeverity.WARNING));
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+base.getPath(), "Binding "+base.getBinding().getValueSet()+" could not be located", ValidationMessage.IssueSeverity.WARNING));
|
||||||
} else if (contextVs == null) {
|
} else if (contextVs == null) {
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Binding "+derived.getBinding().getValueSet()+" could not be located", ValidationMessage.IssueSeverity.WARNING));
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Binding "+derived.getBinding().getValueSet()+" could not be located", ValidationMessage.IssueSeverity.WARNING));
|
||||||
} else {
|
} else {
|
||||||
ValueSetExpansionOutcome expBase = context.expandVS(baseVs, true, false);
|
ValueSetExpansionOutcome expBase = context.expandVS(baseVs, true, false);
|
||||||
ValueSetExpansionOutcome expDerived = context.expandVS(contextVs, true, false);
|
ValueSetExpansionOutcome expDerived = context.expandVS(contextVs, true, false);
|
||||||
if (expBase.getValueset() == null)
|
if (expBase.getValueset() == null)
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+base.getPath(), "Binding "+base.getBinding().getValueSet()+" could not be expanded", ValidationMessage.IssueSeverity.WARNING));
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+base.getPath(), "Binding "+base.getBinding().getValueSet()+" could not be expanded", ValidationMessage.IssueSeverity.WARNING));
|
||||||
else if (expDerived.getValueset() == null)
|
else if (expDerived.getValueset() == null)
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Binding "+derived.getBinding().getValueSet()+" could not be expanded", ValidationMessage.IssueSeverity.WARNING));
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Binding "+derived.getBinding().getValueSet()+" could not be expanded", ValidationMessage.IssueSeverity.WARNING));
|
||||||
else if (ToolingExtensions.hasExtension(expBase.getValueset().getExpansion(), ToolingExtensions.EXT_EXP_TOOCOSTLY)) {
|
else if (ToolingExtensions.hasExtension(expBase.getValueset().getExpansion(), ToolingExtensions.EXT_EXP_TOOCOSTLY)) {
|
||||||
if (ToolingExtensions.hasExtension(expDerived.getValueset().getExpansion(), ToolingExtensions.EXT_EXP_TOOCOSTLY) || expDerived.getValueset().getExpansion().getContains().size() > 100) {
|
if (ToolingExtensions.hasExtension(expDerived.getValueset().getExpansion(), ToolingExtensions.EXT_EXP_TOOCOSTLY) || expDerived.getValueset().getExpansion().getContains().size() > 100) {
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Unable to check if "+derived.getBinding().getValueSet()+" is a proper subset of " +base.getBinding().getValueSet()+" - base value set is too large to check", ValidationMessage.IssueSeverity.WARNING));
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Unable to check if "+derived.getBinding().getValueSet()+" is a proper subset of " +base.getBinding().getValueSet()+" - base value set is too large to check", ValidationMessage.IssueSeverity.WARNING));
|
||||||
} else {
|
} else {
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
for (ValueSetExpansionContainsComponent cc : expDerived.getValueset().getExpansion().getContains()) {
|
for (ValueSetExpansionContainsComponent cc : expDerived.getValueset().getExpansion().getContains()) {
|
||||||
|
@ -2750,11 +2758,11 @@ public class ProfileUtilities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Binding "+derived.getBinding().getValueSet()+" is not a subset of binding "+base.getBinding().getValueSet(), ValidationMessage.IssueSeverity.ERROR));
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Binding "+derived.getBinding().getValueSet()+" is not a subset of binding "+base.getBinding().getValueSet(), ValidationMessage.IssueSeverity.ERROR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!isSubset(expBase.getValueset(), expDerived.getValueset()))
|
} else if (!isSubset(expBase.getValueset(), expDerived.getValueset()))
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Binding "+derived.getBinding().getValueSet()+" is not a subset of binding "+base.getBinding().getValueSet(), ValidationMessage.IssueSeverity.ERROR));
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Binding "+derived.getBinding().getValueSet()+" is not a subset of binding "+base.getBinding().getValueSet(), ValidationMessage.IssueSeverity.ERROR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ElementDefinitionBindingComponent d = derived.getBinding();
|
ElementDefinitionBindingComponent d = derived.getBinding();
|
||||||
|
@ -2915,7 +2923,7 @@ public class ProfileUtilities {
|
||||||
|
|
||||||
private ElementDefinitionBindingAdditionalComponent getMatchingAdditionalBinding(ElementDefinitionBindingComponent nb,ElementDefinitionBindingAdditionalComponent ab) {
|
private ElementDefinitionBindingAdditionalComponent getMatchingAdditionalBinding(ElementDefinitionBindingComponent nb,ElementDefinitionBindingAdditionalComponent ab) {
|
||||||
for (ElementDefinitionBindingAdditionalComponent t : nb.getAdditional()) {
|
for (ElementDefinitionBindingAdditionalComponent t : nb.getAdditional()) {
|
||||||
if (t.getValueSet() != null && t.getValueSet().equals(ab.getValueSet()) && t.getPurpose() == ab.getPurpose()) {
|
if (t.getValueSet() != null && t.getValueSet().equals(ab.getValueSet()) && t.getPurpose() == ab.getPurpose() && !ab.hasUsage()) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2965,11 +2973,7 @@ public class ProfileUtilities {
|
||||||
if (tgtOk) {
|
if (tgtOk) {
|
||||||
ok = true;
|
ok = true;
|
||||||
} else {
|
} else {
|
||||||
if (messages == null) {
|
addMessage(new ValidationMessage(Source.InstanceValidator, IssueType.BUSINESSRULE, derived.getPath(), context.formatMessage(I18nConstants.ERROR_AT__THE_TARGET_PROFILE__IS_NOT__VALID_CONSTRAINT_ON_THE_BASE_, purl, derived.getPath(), url, td.getTargetProfile()), IssueSeverity.ERROR));
|
||||||
throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT__THE_TARGET_PROFILE__IS_NOT__VALID_CONSTRAINT_ON_THE_BASE_, purl, derived.getPath(), url, td.getTargetProfile()));
|
|
||||||
} else {
|
|
||||||
messages.add(new ValidationMessage(Source.InstanceValidator, IssueType.BUSINESSRULE, derived.getPath(), "The target profile " + u.getValue() + " is not a valid constraint on the base (" + td.getTargetProfile() + ") at " + derived.getPath(), IssueSeverity.ERROR));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2989,9 +2993,7 @@ public class ProfileUtilities {
|
||||||
}
|
}
|
||||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, url);
|
StructureDefinition sd = context.fetchResource(StructureDefinition.class, url);
|
||||||
if (sd == null) {
|
if (sd == null) {
|
||||||
if (messages != null) {
|
addMessage(new ValidationMessage(Source.InstanceValidator, IssueType.BUSINESSRULE, path, "Cannot check whether the target profile " + url + " on "+dPath+" is valid constraint on the base because it is not known", IssueSeverity.WARNING));
|
||||||
messages.add(new ValidationMessage(Source.InstanceValidator, IssueType.BUSINESSRULE, path, "Cannot check whether the target profile " + url + " on "+dPath+" is valid constraint on the base because it is not known", IssueSeverity.WARNING));
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (sd.hasBaseDefinition() && sdConformsToTargets(path, dPath, sd.getBaseDefinition(), td)) {
|
if (sd.hasBaseDefinition() && sdConformsToTargets(path, dPath, sd.getBaseDefinition(), td)) {
|
||||||
|
@ -3022,7 +3024,7 @@ public class ProfileUtilities {
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
messages.add(new ValidationMessage(Source.InstanceValidator, IssueType.CONFLICT, dest.getId(), "The "+fieldName+" value has type '"+ft+"' which is not valid (valid "+Utilities.pluralize("type", dest.getType().size())+": "+types.toString()+")", IssueSeverity.ERROR));
|
addMessage(new ValidationMessage(Source.InstanceValidator, IssueType.CONFLICT, dest.getId(), "The "+fieldName+" value has type '"+ft+"' which is not valid (valid "+Utilities.pluralize("type", dest.getType().size())+": "+types.toString()+")", IssueSeverity.ERROR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3936,10 +3938,7 @@ public class ProfileUtilities {
|
||||||
}
|
}
|
||||||
ed.setId(bs);
|
ed.setId(bs);
|
||||||
if (idList.containsKey(bs)) {
|
if (idList.containsKey(bs)) {
|
||||||
if (exception || messages == null) {
|
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, name+"."+bs, context.formatMessage(I18nConstants.SAME_ID_ON_MULTIPLE_ELEMENTS__IN_, bs, idList.get(bs), ed.getPath(), name), ValidationMessage.IssueSeverity.ERROR));
|
||||||
throw new DefinitionException(context.formatMessage(I18nConstants.SAME_ID_ON_MULTIPLE_ELEMENTS__IN_, bs, idList.get(bs), ed.getPath(), name));
|
|
||||||
} else
|
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, name+"."+bs, "Duplicate Element id "+bs, ValidationMessage.IssueSeverity.ERROR));
|
|
||||||
}
|
}
|
||||||
idList.put(bs, ed.getPath());
|
idList.put(bs, ed.getPath());
|
||||||
if (ed.hasContentReference() && ed.getContentReference().startsWith("#")) {
|
if (ed.hasContentReference() && ed.getContentReference().startsWith("#")) {
|
||||||
|
@ -4315,12 +4314,12 @@ public class ProfileUtilities {
|
||||||
|
|
||||||
|
|
||||||
public boolean isThrowException() {
|
public boolean isThrowException() {
|
||||||
return exception;
|
return wantThrowExceptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setThrowException(boolean exception) {
|
public void setThrowException(boolean exception) {
|
||||||
this.exception = exception;
|
this.wantThrowExceptions = exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4578,7 +4577,10 @@ public class ProfileUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessages(List<ValidationMessage> messages) {
|
public void setMessages(List<ValidationMessage> messages) {
|
||||||
this.messages = messages;
|
if (messages != null) {
|
||||||
|
this.messages = messages;
|
||||||
|
wantThrowExceptions = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, List<Property>> propertyCache = new HashMap<>();
|
private Map<String, List<Property>> propertyCache = new HashMap<>();
|
||||||
|
|
|
@ -1276,9 +1276,9 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValidationResult validateCode(final ValidationOptions optionsArg, String path, final Coding code, final ValueSet vs, final ValidationContextCarrier ctxt) {
|
public ValidationResult validateCode(final ValidationOptions optionsArg, String path, final Coding code, final ValueSet vs, final ValidationContextCarrier ctxt) {
|
||||||
|
|
||||||
ValidationOptions options = optionsArg != null ? optionsArg : ValidationOptions.defaults();
|
ValidationOptions options = optionsArg != null ? optionsArg : ValidationOptions.defaults();
|
||||||
|
|
||||||
if (code.hasSystem()) {
|
if (code.hasSystem()) {
|
||||||
codeSystemsUsed.add(code.getSystem());
|
codeSystemsUsed.add(code.getSystem());
|
||||||
}
|
}
|
||||||
|
@ -1303,6 +1303,9 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
||||||
// ok, first we try to validate locally
|
// ok, first we try to validate locally
|
||||||
try {
|
try {
|
||||||
ValueSetValidator vsc = constructValueSetCheckerSimple(options, vs, ctxt);
|
ValueSetValidator vsc = constructValueSetCheckerSimple(options, vs, ctxt);
|
||||||
|
if (vsc.getOpContext() != null) {
|
||||||
|
vsc.getOpContext().note("Validate "+code.toString()+" @ "+path+" against "+(vs == null ? "null" : vs.getVersionedUrl()));
|
||||||
|
}
|
||||||
vsc.setUnknownSystems(unknownSystems);
|
vsc.setUnknownSystems(unknownSystems);
|
||||||
vsc.setThrowToServer(options.isUseServer() && terminologyClientManager.hasClient());
|
vsc.setThrowToServer(options.isUseServer() && terminologyClientManager.hasClient());
|
||||||
if (!ValueSetUtilities.isServerSide(code.getSystem())) {
|
if (!ValueSetUtilities.isServerSide(code.getSystem())) {
|
||||||
|
@ -1471,15 +1474,15 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ValueSetExpander constructValueSetExpanderSimple(ValidationOptions options) {
|
protected ValueSetExpander constructValueSetExpanderSimple(ValidationOptions options) {
|
||||||
return new ValueSetExpander(this, new TerminologyOperationContext(this, options)).setDebug(logger.isDebugLogging());
|
return new ValueSetExpander(this, new TerminologyOperationContext(this, options, "expansion")).setDebug(logger.isDebugLogging());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ValueSetValidator constructValueSetCheckerSimple(ValidationOptions options, ValueSet vs, ValidationContextCarrier ctxt) {
|
protected ValueSetValidator constructValueSetCheckerSimple(ValidationOptions options, ValueSet vs, ValidationContextCarrier ctxt) {
|
||||||
return new ValueSetValidator(this, new TerminologyOperationContext(this, options), options, vs, ctxt, expParameters, terminologyClientManager);
|
return new ValueSetValidator(this, new TerminologyOperationContext(this, options, "validation"), options, vs, ctxt, expParameters, terminologyClientManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ValueSetValidator constructValueSetCheckerSimple( ValidationOptions options, ValueSet vs) {
|
protected ValueSetValidator constructValueSetCheckerSimple( ValidationOptions options, ValueSet vs) {
|
||||||
return new ValueSetValidator(this, new TerminologyOperationContext(this, options), options, vs, expParameters, terminologyClientManager);
|
return new ValueSetValidator(this, new TerminologyOperationContext(this, options, "validation"), options, vs, expParameters, terminologyClientManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Parameters constructParameters(TerminologyClientContext tcd, ValueSet vs, boolean hierarchical) {
|
protected Parameters constructParameters(TerminologyClientContext tcd, ValueSet vs, boolean hierarchical) {
|
||||||
|
@ -1643,7 +1646,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
||||||
Parameters pIn = constructParameters(options, code);
|
Parameters pIn = constructParameters(options, code);
|
||||||
res = validateOnServer(tc, vs, pIn, options);
|
res = validateOnServer(tc, vs, pIn, options);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
res = new ValidationResult(IssueSeverity.ERROR, e.getMessage() == null ? e.getClass().getName() : e.getMessage(), null).setTxLink(txLog == null ? null : txLog.getLastId());
|
issues.clear();
|
||||||
|
OperationOutcomeIssueComponent iss = new OperationOutcomeIssueComponent(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR, org.hl7.fhir.r5.model.OperationOutcome.IssueType.EXCEPTION);
|
||||||
|
iss.getDetails().setText(e.getMessage());
|
||||||
|
issues.add(iss);
|
||||||
|
res = new ValidationResult(IssueSeverity.ERROR, e.getMessage() == null ? e.getClass().getName() : e.getMessage(), issues).setTxLink(txLog == null ? null : txLog.getLastId()).setErrorClass(TerminologyServiceErrorClass.SERVER_ERROR);
|
||||||
}
|
}
|
||||||
if (cachingAllowed) {
|
if (cachingAllowed) {
|
||||||
txCache.cacheValidation(cacheToken, res, TerminologyCache.PERMANENT);
|
txCache.cacheValidation(cacheToken, res, TerminologyCache.PERMANENT);
|
||||||
|
@ -1779,6 +1786,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
||||||
if (options.isDisplayWarningMode()) {
|
if (options.isDisplayWarningMode()) {
|
||||||
pin.addParameter("mode","lenient-display-validation");
|
pin.addParameter("mode","lenient-display-validation");
|
||||||
}
|
}
|
||||||
|
pin.addParameter("diagnostics", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean addDependentResources(TerminologyClientContext tc, Parameters pin, ValueSet vs) {
|
private boolean addDependentResources(TerminologyClientContext tc, Parameters pin, ValueSet vs) {
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class HTMLClientLogger extends BaseLogger implements ToolingClientLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void logResponse(String outcome, List<String> headers, byte[] body) {
|
public void logResponse(String outcome, List<String> headers, byte[] body, long start) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
System.out.println(" txlog resp: " +outcome+" "+present(body));
|
System.out.println(" txlog resp: " +outcome+" "+present(body));
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,10 +76,10 @@ public class TextClientLogger extends BaseLogger implements ToolingClientLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void logResponse(String outcome, List<String> headers, byte[] body) {
|
public void logResponse(String outcome, List<String> headers, byte[] body, long length) {
|
||||||
if (file == null)
|
if (file == null)
|
||||||
return;
|
return;
|
||||||
file.println("\r\n\r\nResponse: \r\n");
|
file.println("\r\n\r\nResponse ("+Utilities.describeDuration(length)+"): \r\n");
|
||||||
file.println(outcome);
|
file.println(outcome);
|
||||||
for (String s : headers)
|
for (String s : headers)
|
||||||
file.println(s);
|
file.println(s);
|
||||||
|
|
|
@ -162,6 +162,7 @@ public class Element extends Base implements NamedItem {
|
||||||
private FhirFormat format;
|
private FhirFormat format;
|
||||||
private Object nativeObject;
|
private Object nativeObject;
|
||||||
private List<SliceDefinition> sliceDefinitions;
|
private List<SliceDefinition> sliceDefinitions;
|
||||||
|
private boolean elided;
|
||||||
|
|
||||||
public Element(String name) {
|
public Element(String name) {
|
||||||
super();
|
super();
|
||||||
|
@ -1429,6 +1430,8 @@ public class Element extends Base implements NamedItem {
|
||||||
public Base copy() {
|
public Base copy() {
|
||||||
Element element = new Element(this);
|
Element element = new Element(this);
|
||||||
this.copyValues(element);
|
this.copyValues(element);
|
||||||
|
if (this.isElided())
|
||||||
|
element.setElided(true);
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1638,4 +1641,11 @@ public class Element extends Base implements NamedItem {
|
||||||
return FhirPublication.fromCode(property.getStructure().getVersion());
|
return FhirPublication.fromCode(property.getStructure().getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setElided(boolean elided) {
|
||||||
|
this.elided = elided;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isElided() {
|
||||||
|
return this.elided;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -62,6 +62,7 @@ import org.hl7.fhir.r5.formats.JsonCreatorDirect;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
|
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||||
import org.hl7.fhir.utilities.StringPair;
|
import org.hl7.fhir.utilities.StringPair;
|
||||||
import org.hl7.fhir.utilities.TextFile;
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
|
@ -85,6 +86,8 @@ public class JsonParser extends ParserBase {
|
||||||
|
|
||||||
private JsonCreator json;
|
private JsonCreator json;
|
||||||
private boolean allowComments;
|
private boolean allowComments;
|
||||||
|
private boolean elideElements;
|
||||||
|
// private boolean suppressResourceType;
|
||||||
|
|
||||||
private Element baseElement;
|
private Element baseElement;
|
||||||
private boolean markedXhtml;
|
private boolean markedXhtml;
|
||||||
|
@ -782,7 +785,8 @@ public class JsonParser extends ParserBase {
|
||||||
}
|
}
|
||||||
checkComposeComments(e);
|
checkComposeComments(e);
|
||||||
json.beginObject();
|
json.beginObject();
|
||||||
prop("resourceType", e.getType(), null);
|
// if (!isSuppressResourceType())
|
||||||
|
prop("resourceType", e.getType(), null);
|
||||||
Set<String> done = new HashSet<String>();
|
Set<String> done = new HashSet<String>();
|
||||||
for (Element child : e.getChildren()) {
|
for (Element child : e.getChildren()) {
|
||||||
compose(e.getName(), e, done, child);
|
compose(e.getName(), e, done, child);
|
||||||
|
@ -807,7 +811,8 @@ public class JsonParser extends ParserBase {
|
||||||
checkComposeComments(e);
|
checkComposeComments(e);
|
||||||
json.beginObject();
|
json.beginObject();
|
||||||
|
|
||||||
prop("resourceType", e.getType(), linkResolver == null ? null : linkResolver.resolveProperty(e.getProperty()));
|
// if (!isSuppressResourceType())
|
||||||
|
prop("resourceType", e.getType(), linkResolver == null ? null : linkResolver.resolveProperty(e.getProperty()));
|
||||||
Set<String> done = new HashSet<String>();
|
Set<String> done = new HashSet<String>();
|
||||||
for (Element child : e.getChildren()) {
|
for (Element child : e.getChildren()) {
|
||||||
compose(e.getName(), e, done, child);
|
compose(e.getName(), e, done, child);
|
||||||
|
@ -821,15 +826,50 @@ public class JsonParser extends ParserBase {
|
||||||
if (wantCompose(path, child)) {
|
if (wantCompose(path, child)) {
|
||||||
boolean isList = child.hasElementProperty() ? child.getElementProperty().isList() : child.getProperty().isList();
|
boolean isList = child.hasElementProperty() ? child.getElementProperty().isList() : child.getProperty().isList();
|
||||||
if (!isList) {// for specials, ignore the cardinality of the stated type
|
if (!isList) {// for specials, ignore the cardinality of the stated type
|
||||||
compose(path, child);
|
if (child.isElided() && isElideElements() && json.canElide())
|
||||||
|
json.elide();
|
||||||
|
else
|
||||||
|
compose(path, child);
|
||||||
} else if (!done.contains(child.getName())) {
|
} else if (!done.contains(child.getName())) {
|
||||||
done.add(child.getName());
|
done.add(child.getName());
|
||||||
List<Element> list = e.getChildrenByName(child.getName());
|
List<Element> list = e.getChildrenByName(child.getName());
|
||||||
composeList(path, list);
|
if (child.getProperty().getDefinition().hasExtension(ToolingExtensions.EXT_JSON_PROP_KEY))
|
||||||
|
composeKeyList(path, list);
|
||||||
|
else
|
||||||
|
composeList(path, list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void composeKeyList(String path, List<Element> list) throws IOException {
|
||||||
|
String keyName = list.get(0).getProperty().getDefinition().getExtensionString(ToolingExtensions.EXT_JSON_PROP_KEY);
|
||||||
|
json.name(list.get(0).getName());
|
||||||
|
json.beginObject();
|
||||||
|
for (Element e: list) {
|
||||||
|
Element key = null;
|
||||||
|
Element value = null;
|
||||||
|
for (Element child: e.getChildren()) {
|
||||||
|
if (child.getName().equals(keyName))
|
||||||
|
key = child;
|
||||||
|
else
|
||||||
|
value = child;
|
||||||
|
}
|
||||||
|
if (value.isPrimitive())
|
||||||
|
primitiveValue(key.getValue(), value);
|
||||||
|
else {
|
||||||
|
json.name(key.getValue());
|
||||||
|
checkComposeComments(e);
|
||||||
|
json.beginObject();
|
||||||
|
Set<String> done = new HashSet<String>();
|
||||||
|
for (Element child : value.getChildren()) {
|
||||||
|
compose(value.getName(), value, done, child);
|
||||||
|
}
|
||||||
|
json.endObject();
|
||||||
|
compose(path + "." + key.getValue(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
json.endObject();
|
||||||
|
}
|
||||||
|
|
||||||
private void composeList(String path, List<Element> list) throws IOException {
|
private void composeList(String path, List<Element> list) throws IOException {
|
||||||
// there will be at least one element
|
// there will be at least one element
|
||||||
|
@ -847,7 +887,9 @@ public class JsonParser extends ParserBase {
|
||||||
if (prim) {
|
if (prim) {
|
||||||
openArray(name, linkResolver == null ? null : linkResolver.resolveProperty(list.get(0).getProperty()));
|
openArray(name, linkResolver == null ? null : linkResolver.resolveProperty(list.get(0).getProperty()));
|
||||||
for (Element item : list) {
|
for (Element item : list) {
|
||||||
if (item.hasValue()) {
|
if (item.isElided() && json.canElide())
|
||||||
|
json.elide();
|
||||||
|
else if (item.hasValue()) {
|
||||||
if (linkResolver != null && item.getProperty().isReference()) {
|
if (linkResolver != null && item.getProperty().isReference()) {
|
||||||
String ref = linkResolver.resolveReference(getReferenceForElement(item));
|
String ref = linkResolver.resolveReference(getReferenceForElement(item));
|
||||||
if (ref != null) {
|
if (ref != null) {
|
||||||
|
@ -866,7 +908,9 @@ public class JsonParser extends ParserBase {
|
||||||
openArray(name, linkResolver == null ? null : linkResolver.resolveProperty(list.get(0).getProperty()));
|
openArray(name, linkResolver == null ? null : linkResolver.resolveProperty(list.get(0).getProperty()));
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Element item : list) {
|
for (Element item : list) {
|
||||||
if (item.hasChildren()) {
|
if (item.isElided() && json.canElide())
|
||||||
|
json.elide();
|
||||||
|
else if (item.hasChildren()) {
|
||||||
open(null,null);
|
open(null,null);
|
||||||
if (item.getProperty().isResource()) {
|
if (item.getProperty().isResource()) {
|
||||||
prop("resourceType", item.getType(), linkResolver == null ? null : linkResolver.resolveType(item.getType()));
|
prop("resourceType", item.getType(), linkResolver == null ? null : linkResolver.resolveType(item.getType()));
|
||||||
|
@ -933,9 +977,10 @@ public class JsonParser extends ParserBase {
|
||||||
json.externalLink(ref);
|
json.externalLink(ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> done = new HashSet<String>();
|
Set<String> done = new HashSet<String>();
|
||||||
for (Element child : element.getChildren()) {
|
for (Element child : element.getChildren()) {
|
||||||
compose(path+"."+element.getName(), element, done, child);
|
compose(path + "." + element.getName(), element, done, child);
|
||||||
}
|
}
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
@ -951,5 +996,23 @@ public class JsonParser extends ParserBase {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isElideElements() {
|
||||||
|
return elideElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonParser setElideElements(boolean elideElements) {
|
||||||
|
this.elideElements = elideElements;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
public boolean isSuppressResourceType() {
|
||||||
|
return suppressResourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonParser setSuppressResourceType(boolean suppressResourceType) {
|
||||||
|
this.suppressResourceType = suppressResourceType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
|
@ -94,6 +94,7 @@ import org.xml.sax.XMLReader;
|
||||||
public class XmlParser extends ParserBase {
|
public class XmlParser extends ParserBase {
|
||||||
private boolean allowXsiLocation;
|
private boolean allowXsiLocation;
|
||||||
private String version;
|
private String version;
|
||||||
|
private boolean elideElements;
|
||||||
|
|
||||||
public XmlParser(IWorkerContext context) {
|
public XmlParser(IWorkerContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
@ -805,92 +806,125 @@ public class XmlParser extends ParserBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void composeElement(IXMLWriter xml, Element element, String elementName, boolean root) throws IOException, FHIRException {
|
private void composeElement(IXMLWriter xml, Element element, String elementName, boolean root) throws IOException, FHIRException {
|
||||||
if (showDecorations) {
|
if (!(isElideElements() && element.isElided())) {
|
||||||
@SuppressWarnings("unchecked")
|
if (showDecorations) {
|
||||||
List<ElementDecoration> decorations = (List<ElementDecoration>) element.getUserData("fhir.decorations");
|
@SuppressWarnings("unchecked")
|
||||||
if (decorations != null)
|
List<ElementDecoration> decorations = (List<ElementDecoration>) element.getUserData("fhir.decorations");
|
||||||
for (ElementDecoration d : decorations)
|
if (decorations != null)
|
||||||
xml.decorate(d);
|
for (ElementDecoration d : decorations)
|
||||||
}
|
xml.decorate(d);
|
||||||
for (String s : element.getComments()) {
|
}
|
||||||
xml.comment(s, true);
|
for (String s : element.getComments()) {
|
||||||
|
xml.comment(s, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (isText(element.getProperty())) {
|
if (isText(element.getProperty())) {
|
||||||
if (linkResolver != null)
|
if (isElideElements() && element.isElided() && xml.canElide())
|
||||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
xml.elide();
|
||||||
xml.enter(element.getProperty().getXmlNamespace(),elementName);
|
else {
|
||||||
if (linkResolver != null && element.getProperty().isReference()) {
|
if (linkResolver != null)
|
||||||
String ref = linkResolver.resolveReference(getReferenceForElement(element));
|
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||||
if (ref != null) {
|
xml.enter(element.getProperty().getXmlNamespace(),elementName);
|
||||||
xml.externalLink(ref);
|
if (linkResolver != null && element.getProperty().isReference()) {
|
||||||
|
String ref = linkResolver.resolveReference(getReferenceForElement(element));
|
||||||
|
if (ref != null) {
|
||||||
|
xml.externalLink(ref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
xml.text(element.getValue());
|
||||||
|
xml.exit(element.getProperty().getXmlNamespace(),elementName);
|
||||||
}
|
}
|
||||||
xml.text(element.getValue());
|
|
||||||
xml.exit(element.getProperty().getXmlNamespace(),elementName);
|
|
||||||
} else if (!element.hasChildren() && !element.hasValue()) {
|
} else if (!element.hasChildren() && !element.hasValue()) {
|
||||||
if (element.getExplicitType() != null)
|
if (isElideElements() && element.isElided() && xml.canElide())
|
||||||
xml.attribute("xsi:type", element.getExplicitType());
|
xml.elide();
|
||||||
xml.element(elementName);
|
else {
|
||||||
|
if (element.getExplicitType() != null)
|
||||||
|
xml.attribute("xsi:type", element.getExplicitType());
|
||||||
|
xml.element(elementName);
|
||||||
|
}
|
||||||
} else if (element.isPrimitive() || (element.hasType() && isPrimitive(element.getType()))) {
|
} else if (element.isPrimitive() || (element.hasType() && isPrimitive(element.getType()))) {
|
||||||
if (element.getType().equals("xhtml")) {
|
if (element.getType().equals("xhtml")) {
|
||||||
String rawXhtml = element.getValue();
|
if (isElideElements() && element.isElided() && xml.canElide())
|
||||||
if (isCdaText(element.getProperty())) {
|
xml.elide();
|
||||||
new CDANarrativeFormat().convert(xml, new XhtmlParser().parseFragment(rawXhtml));
|
else {
|
||||||
} else {
|
String rawXhtml = element.getValue();
|
||||||
xml.escapedText(rawXhtml);
|
if (isCdaText(element.getProperty())) {
|
||||||
if (!markedXhtml) {
|
new CDANarrativeFormat().convert(xml, new XhtmlParser().parseFragment(rawXhtml));
|
||||||
xml.anchor("end-xhtml");
|
} else {
|
||||||
markedXhtml = true;
|
xml.escapedText(rawXhtml);
|
||||||
|
if (!markedXhtml) {
|
||||||
|
xml.anchor("end-xhtml");
|
||||||
|
markedXhtml = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (isText(element.getProperty())) {
|
} else if (isText(element.getProperty())) {
|
||||||
if (linkResolver != null)
|
if (isElideElements() && element.isElided() && xml.canElide())
|
||||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
xml.elide();
|
||||||
xml.text(element.getValue());
|
else {
|
||||||
} else {
|
|
||||||
setXsiTypeIfIsTypeAttr(xml, element);
|
|
||||||
if (element.hasValue()) {
|
|
||||||
if (linkResolver != null)
|
if (linkResolver != null)
|
||||||
xml.link(linkResolver.resolveType(element.getType()));
|
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||||
xml.attribute("value", element.getValue());
|
xml.text(element.getValue());
|
||||||
}
|
}
|
||||||
if (linkResolver != null)
|
} else {
|
||||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
if (isElideElements() && element.isElided())
|
||||||
if (element.hasChildren()) {
|
xml.attributeElide();
|
||||||
xml.enter(element.getProperty().getXmlNamespace(), elementName);
|
else {
|
||||||
if (linkResolver != null && element.getProperty().isReference()) {
|
setXsiTypeIfIsTypeAttr(xml, element);
|
||||||
String ref = linkResolver.resolveReference(getReferenceForElement(element));
|
if (element.hasValue()) {
|
||||||
if (ref != null) {
|
if (linkResolver != null)
|
||||||
xml.externalLink(ref);
|
xml.link(linkResolver.resolveType(element.getType()));
|
||||||
}
|
xml.attribute("value", element.getValue());
|
||||||
}
|
}
|
||||||
for (Element child : element.getChildren())
|
if (linkResolver != null)
|
||||||
composeElement(xml, child, child.getName(), false);
|
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||||
xml.exit(element.getProperty().getXmlNamespace(),elementName);
|
if (element.hasChildren()) {
|
||||||
} else
|
xml.enter(element.getProperty().getXmlNamespace(), elementName);
|
||||||
xml.element(elementName);
|
if (linkResolver != null && element.getProperty().isReference()) {
|
||||||
|
String ref = linkResolver.resolveReference(getReferenceForElement(element));
|
||||||
|
if (ref != null) {
|
||||||
|
xml.externalLink(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Element child : element.getChildren())
|
||||||
|
composeElement(xml, child, child.getName(), false);
|
||||||
|
xml.exit(element.getProperty().getXmlNamespace(),elementName);
|
||||||
|
} else
|
||||||
|
xml.element(elementName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setXsiTypeIfIsTypeAttr(xml, element);
|
if (isElideElements() && element.isElided() && xml.canElide())
|
||||||
Set<String> handled = new HashSet<>();
|
xml.elide();
|
||||||
|
else {
|
||||||
|
setXsiTypeIfIsTypeAttr(xml, element);
|
||||||
|
Set<String> handled = new HashSet<>();
|
||||||
for (Element child : element.getChildren()) {
|
for (Element child : element.getChildren()) {
|
||||||
if (!handled.contains(child.getName()) && isAttr(child.getProperty()) && wantCompose(element.getPath(), child)) {
|
if (!handled.contains(child.getName()) && isAttr(child.getProperty()) && wantCompose(element.getPath(), child)) {
|
||||||
handled.add(child.getName());
|
handled.add(child.getName());
|
||||||
String av = child.getValue();
|
if (isElideElements() && child.isElided())
|
||||||
if (child.getProperty().isList()) {
|
xml.attributeElide();
|
||||||
for (Element c2 : element.getChildren()) {
|
else {
|
||||||
if (c2 != child && c2.getName().equals(child.getName())) {
|
String av = child.getValue();
|
||||||
av = av + " "+c2.getValue();
|
if (child.getProperty().isList()) {
|
||||||
|
for (Element c2 : element.getChildren()) {
|
||||||
|
if (c2 != child && c2.getName().equals(child.getName())) {
|
||||||
|
if (c2.isElided())
|
||||||
|
av = av + " ...";
|
||||||
|
else
|
||||||
|
av = av + " " + c2.getValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (linkResolver != null)
|
||||||
|
xml.link(linkResolver.resolveType(child.getType()));
|
||||||
|
if (ToolingExtensions.hasExtension(child.getProperty().getDefinition(), ToolingExtensions.EXT_DATE_FORMAT))
|
||||||
|
av = convertForDateFormatToExternal(ToolingExtensions.readStringExtension(child.getProperty().getDefinition(), ToolingExtensions.EXT_DATE_FORMAT), av);
|
||||||
|
xml.attribute(child.getProperty().getXmlNamespace(), child.getProperty().getXmlName(), av);
|
||||||
}
|
}
|
||||||
if (linkResolver != null)
|
|
||||||
xml.link(linkResolver.resolveType(child.getType()));
|
|
||||||
if (ToolingExtensions.hasExtension(child.getProperty().getDefinition(), ToolingExtensions.EXT_DATE_FORMAT))
|
|
||||||
av = convertForDateFormatToExternal(ToolingExtensions.readStringExtension(child.getProperty().getDefinition(), ToolingExtensions.EXT_DATE_FORMAT), av);
|
|
||||||
xml.attribute(child.getProperty().getXmlNamespace(),child.getProperty().getXmlName(), av);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!element.getProperty().getDefinition().hasExtension(ToolingExtensions.EXT_ID_CHOICE_GROUP)) {
|
if (!element.getProperty().getDefinition().hasExtension(ToolingExtensions.EXT_ID_CHOICE_GROUP)) {
|
||||||
if (linkResolver != null)
|
if (linkResolver != null)
|
||||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||||
|
@ -914,12 +948,16 @@ public class XmlParser extends ParserBase {
|
||||||
}
|
}
|
||||||
for (Element child : element.getChildren()) {
|
for (Element child : element.getChildren()) {
|
||||||
if (wantCompose(element.getPath(), child)) {
|
if (wantCompose(element.getPath(), child)) {
|
||||||
if (isText(child.getProperty())) {
|
if (isElideElements() && child.isElided() && xml.canElide())
|
||||||
if (linkResolver != null)
|
xml.elide();
|
||||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
else {
|
||||||
xml.text(child.getValue());
|
if (isText(child.getProperty())) {
|
||||||
} else if (!isAttr(child.getProperty())) {
|
if (linkResolver != null)
|
||||||
composeElement(xml, child, child.getName(), false);
|
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||||
|
xml.text(child.getValue());
|
||||||
|
} else if (!isAttr(child.getProperty())) {
|
||||||
|
composeElement(xml, child, child.getName(), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1034,4 +1072,13 @@ public class XmlParser extends ParserBase {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isElideElements() {
|
||||||
|
return elideElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setElideElements(boolean elideElements) {
|
||||||
|
this.elideElements = elideElements;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
package org.hl7.fhir.r5.formats;
|
package org.hl7.fhir.r5.formats;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2011+, HL7, Inc.
|
Copyright (c) 2011+, HL7, Inc.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
@ -28,47 +28,49 @@ package org.hl7.fhir.r5.formats;
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Facade to GSON writer, or something that imposes property ordering first
|
* Facade to GSON writer, or something that imposes property ordering first
|
||||||
*
|
*
|
||||||
* @author Grahame
|
* @author Grahame
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface JsonCreator {
|
public interface JsonCreator {
|
||||||
|
|
||||||
void comment(String comment);
|
void comment(String comment);
|
||||||
|
|
||||||
void beginObject() throws IOException;
|
void beginObject() throws IOException;
|
||||||
|
|
||||||
void endObject() throws IOException;
|
void endObject() throws IOException;
|
||||||
|
|
||||||
void nullValue() throws IOException;
|
void nullValue() throws IOException;
|
||||||
|
|
||||||
void name(String name) throws IOException;
|
void name(String name) throws IOException;
|
||||||
|
|
||||||
void value(String value) throws IOException;
|
void value(String value) throws IOException;
|
||||||
|
|
||||||
void value(Boolean value) throws IOException;
|
void value(Boolean value) throws IOException;
|
||||||
|
|
||||||
void value(BigDecimal value) throws IOException;
|
void value(BigDecimal value) throws IOException;
|
||||||
void valueNum(String value) throws IOException; // allow full control of representation
|
void valueNum(String value) throws IOException; // allow full control of representation
|
||||||
|
|
||||||
void value(Integer value) throws IOException;
|
void value(Integer value) throws IOException;
|
||||||
|
|
||||||
void beginArray() throws IOException;
|
void beginArray() throws IOException;
|
||||||
|
|
||||||
void endArray() throws IOException;
|
void endArray() throws IOException;
|
||||||
|
|
||||||
void finish() throws IOException;
|
void finish() throws IOException;
|
||||||
|
|
||||||
// only used by an creator that actually produces xhtml
|
// only used by an creator that actually produces xhtml
|
||||||
void link(String href);
|
void link(String href);
|
||||||
void anchor(String string);
|
void anchor(String string);
|
||||||
void externalLink(String string);
|
void externalLink(String string);
|
||||||
|
void elide();
|
||||||
|
boolean canElide();
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
package org.hl7.fhir.r5.formats;
|
package org.hl7.fhir.r5.formats;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2011+, HL7, Inc.
|
Copyright (c) 2011+, HL7, Inc.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
@ -28,257 +28,264 @@ package org.hl7.fhir.r5.formats;
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
public class JsonCreatorCanonical implements JsonCreator {
|
public class JsonCreatorCanonical implements JsonCreator {
|
||||||
|
|
||||||
public class JsonCanValue {
|
public class JsonCanValue {
|
||||||
String name;
|
String name;
|
||||||
private JsonCanValue(String name) {
|
private JsonCanValue(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class JsonCanNumberValue extends JsonCanValue {
|
private class JsonCanNumberValue extends JsonCanValue {
|
||||||
private BigDecimal value;
|
private BigDecimal value;
|
||||||
private JsonCanNumberValue(String name, BigDecimal value) {
|
private JsonCanNumberValue(String name, BigDecimal value) {
|
||||||
super(name);
|
super(name);
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class JsonCanPresentedNumberValue extends JsonCanValue {
|
private class JsonCanPresentedNumberValue extends JsonCanValue {
|
||||||
private String value;
|
private String value;
|
||||||
private JsonCanPresentedNumberValue(String name, String value) {
|
private JsonCanPresentedNumberValue(String name, String value) {
|
||||||
super(name);
|
super(name);
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class JsonCanIntegerValue extends JsonCanValue {
|
private class JsonCanIntegerValue extends JsonCanValue {
|
||||||
private Integer value;
|
private Integer value;
|
||||||
private JsonCanIntegerValue(String name, Integer value) {
|
private JsonCanIntegerValue(String name, Integer value) {
|
||||||
super(name);
|
super(name);
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class JsonCanBooleanValue extends JsonCanValue {
|
private class JsonCanBooleanValue extends JsonCanValue {
|
||||||
private Boolean value;
|
private Boolean value;
|
||||||
private JsonCanBooleanValue(String name, Boolean value) {
|
private JsonCanBooleanValue(String name, Boolean value) {
|
||||||
super(name);
|
super(name);
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class JsonCanStringValue extends JsonCanValue {
|
private class JsonCanStringValue extends JsonCanValue {
|
||||||
private String value;
|
private String value;
|
||||||
private JsonCanStringValue(String name, String value) {
|
private JsonCanStringValue(String name, String value) {
|
||||||
super(name);
|
super(name);
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class JsonCanNullValue extends JsonCanValue {
|
private class JsonCanNullValue extends JsonCanValue {
|
||||||
private JsonCanNullValue(String name) {
|
private JsonCanNullValue(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class JsonCanObject extends JsonCanValue {
|
public class JsonCanObject extends JsonCanValue {
|
||||||
|
|
||||||
boolean array;
|
boolean array;
|
||||||
List<JsonCanValue> children = new ArrayList<JsonCanValue>();
|
List<JsonCanValue> children = new ArrayList<JsonCanValue>();
|
||||||
|
|
||||||
public JsonCanObject(String name, boolean array) {
|
public JsonCanObject(String name, boolean array) {
|
||||||
super(name);
|
super(name);
|
||||||
this.array = array;
|
this.array = array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addProp(JsonCanValue obj) {
|
public void addProp(JsonCanValue obj) {
|
||||||
children.add(obj);
|
children.add(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack<JsonCanObject> stack;
|
Stack<JsonCanObject> stack;
|
||||||
JsonCanObject root;
|
JsonCanObject root;
|
||||||
JsonCreatorDirect jj;
|
JsonCreatorDirect jj;
|
||||||
String name;
|
String name;
|
||||||
|
|
||||||
public JsonCreatorCanonical(OutputStreamWriter osw) {
|
public JsonCreatorCanonical(OutputStreamWriter osw) {
|
||||||
stack = new Stack<JsonCreatorCanonical.JsonCanObject>();
|
stack = new Stack<JsonCreatorCanonical.JsonCanObject>();
|
||||||
jj = new JsonCreatorDirect(osw, false, false);
|
jj = new JsonCreatorDirect(osw, false, false);
|
||||||
name = null;
|
name = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String takeName() {
|
private String takeName() {
|
||||||
String res = name;
|
String res = name;
|
||||||
name = null;
|
name = null;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beginObject() throws IOException {
|
public void beginObject() throws IOException {
|
||||||
JsonCanObject obj = new JsonCanObject(takeName(), false);
|
JsonCanObject obj = new JsonCanObject(takeName(), false);
|
||||||
if (stack.isEmpty())
|
if (stack.isEmpty())
|
||||||
root = obj;
|
root = obj;
|
||||||
else
|
else
|
||||||
stack.peek().addProp(obj);
|
stack.peek().addProp(obj);
|
||||||
stack.push(obj);
|
stack.push(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endObject() throws IOException {
|
public void endObject() throws IOException {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nullValue() throws IOException {
|
public void nullValue() throws IOException {
|
||||||
stack.peek().addProp(new JsonCanNullValue(takeName()));
|
stack.peek().addProp(new JsonCanNullValue(takeName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void name(String name) throws IOException {
|
public void name(String name) throws IOException {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void value(String value) throws IOException {
|
public void value(String value) throws IOException {
|
||||||
stack.peek().addProp(new JsonCanStringValue(takeName(), value));
|
stack.peek().addProp(new JsonCanStringValue(takeName(), value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void value(Boolean value) throws IOException {
|
public void value(Boolean value) throws IOException {
|
||||||
stack.peek().addProp(new JsonCanBooleanValue(takeName(), value));
|
stack.peek().addProp(new JsonCanBooleanValue(takeName(), value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void value(BigDecimal value) throws IOException {
|
public void value(BigDecimal value) throws IOException {
|
||||||
stack.peek().addProp(new JsonCanNumberValue(takeName(), value));
|
stack.peek().addProp(new JsonCanNumberValue(takeName(), value));
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void valueNum(String value) throws IOException {
|
public void valueNum(String value) throws IOException {
|
||||||
stack.peek().addProp(new JsonCanPresentedNumberValue(takeName(), value));
|
stack.peek().addProp(new JsonCanPresentedNumberValue(takeName(), value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void value(Integer value) throws IOException {
|
public void value(Integer value) throws IOException {
|
||||||
stack.peek().addProp(new JsonCanIntegerValue(takeName(), value));
|
stack.peek().addProp(new JsonCanIntegerValue(takeName(), value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beginArray() throws IOException {
|
public void beginArray() throws IOException {
|
||||||
JsonCanObject obj = new JsonCanObject(takeName(), true);
|
JsonCanObject obj = new JsonCanObject(takeName(), true);
|
||||||
if (!stack.isEmpty())
|
if (!stack.isEmpty())
|
||||||
stack.peek().addProp(obj);
|
stack.peek().addProp(obj);
|
||||||
stack.push(obj);
|
stack.push(obj);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endArray() throws IOException {
|
public void endArray() throws IOException {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finish() throws IOException {
|
public void finish() throws IOException {
|
||||||
writeObject(root);
|
writeObject(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeObject(JsonCanObject obj) throws IOException {
|
private void writeObject(JsonCanObject obj) throws IOException {
|
||||||
jj.beginObject();
|
jj.beginObject();
|
||||||
List<String> names = new ArrayList<String>();
|
List<String> names = new ArrayList<String>();
|
||||||
for (JsonCanValue v : obj.children)
|
for (JsonCanValue v : obj.children)
|
||||||
names.add(v.name);
|
names.add(v.name);
|
||||||
Collections.sort(names);
|
Collections.sort(names);
|
||||||
for (String n : names) {
|
for (String n : names) {
|
||||||
jj.name(n);
|
jj.name(n);
|
||||||
JsonCanValue v = getPropForName(n, obj.children);
|
JsonCanValue v = getPropForName(n, obj.children);
|
||||||
if (v instanceof JsonCanNumberValue)
|
if (v instanceof JsonCanNumberValue)
|
||||||
jj.value(((JsonCanNumberValue) v).value);
|
jj.value(((JsonCanNumberValue) v).value);
|
||||||
else if (v instanceof JsonCanPresentedNumberValue)
|
else if (v instanceof JsonCanPresentedNumberValue)
|
||||||
jj.valueNum(((JsonCanPresentedNumberValue) v).value);
|
jj.valueNum(((JsonCanPresentedNumberValue) v).value);
|
||||||
else if (v instanceof JsonCanIntegerValue)
|
else if (v instanceof JsonCanIntegerValue)
|
||||||
jj.value(((JsonCanIntegerValue) v).value);
|
jj.value(((JsonCanIntegerValue) v).value);
|
||||||
else if (v instanceof JsonCanBooleanValue)
|
else if (v instanceof JsonCanBooleanValue)
|
||||||
jj.value(((JsonCanBooleanValue) v).value);
|
jj.value(((JsonCanBooleanValue) v).value);
|
||||||
else if (v instanceof JsonCanStringValue)
|
else if (v instanceof JsonCanStringValue)
|
||||||
jj.value(((JsonCanStringValue) v).value);
|
jj.value(((JsonCanStringValue) v).value);
|
||||||
else if (v instanceof JsonCanNullValue)
|
else if (v instanceof JsonCanNullValue)
|
||||||
jj.nullValue();
|
jj.nullValue();
|
||||||
else if (v instanceof JsonCanObject) {
|
else if (v instanceof JsonCanObject) {
|
||||||
JsonCanObject o = (JsonCanObject) v;
|
JsonCanObject o = (JsonCanObject) v;
|
||||||
if (o.array)
|
if (o.array)
|
||||||
writeArray(o);
|
writeArray(o);
|
||||||
else
|
else
|
||||||
writeObject(o);
|
writeObject(o);
|
||||||
} else
|
} else
|
||||||
throw new Error("not possible");
|
throw new Error("not possible");
|
||||||
}
|
}
|
||||||
jj.endObject();
|
jj.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonCanValue getPropForName(String name, List<JsonCanValue> children) {
|
private JsonCanValue getPropForName(String name, List<JsonCanValue> children) {
|
||||||
for (JsonCanValue child : children)
|
for (JsonCanValue child : children)
|
||||||
if (child.name.equals(name))
|
if (child.name.equals(name))
|
||||||
return child;
|
return child;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeArray(JsonCanObject arr) throws IOException {
|
private void writeArray(JsonCanObject arr) throws IOException {
|
||||||
jj.beginArray();
|
jj.beginArray();
|
||||||
for (JsonCanValue v : arr.children) {
|
for (JsonCanValue v : arr.children) {
|
||||||
if (v instanceof JsonCanNumberValue)
|
if (v instanceof JsonCanNumberValue)
|
||||||
jj.value(((JsonCanNumberValue) v).value);
|
jj.value(((JsonCanNumberValue) v).value);
|
||||||
else if (v instanceof JsonCanIntegerValue)
|
else if (v instanceof JsonCanIntegerValue)
|
||||||
jj.value(((JsonCanIntegerValue) v).value);
|
jj.value(((JsonCanIntegerValue) v).value);
|
||||||
else if (v instanceof JsonCanBooleanValue)
|
else if (v instanceof JsonCanBooleanValue)
|
||||||
jj.value(((JsonCanBooleanValue) v).value);
|
jj.value(((JsonCanBooleanValue) v).value);
|
||||||
else if (v instanceof JsonCanStringValue)
|
else if (v instanceof JsonCanStringValue)
|
||||||
jj.value(((JsonCanStringValue) v).value);
|
jj.value(((JsonCanStringValue) v).value);
|
||||||
else if (v instanceof JsonCanNullValue)
|
else if (v instanceof JsonCanNullValue)
|
||||||
jj.nullValue();
|
jj.nullValue();
|
||||||
else if (v instanceof JsonCanObject) {
|
else if (v instanceof JsonCanObject) {
|
||||||
JsonCanObject o = (JsonCanObject) v;
|
JsonCanObject o = (JsonCanObject) v;
|
||||||
if (o.array)
|
if (o.array)
|
||||||
writeArray(o);
|
writeArray(o);
|
||||||
else
|
else
|
||||||
writeObject(o);
|
writeObject(o);
|
||||||
} else
|
} else
|
||||||
throw new Error("not possible");
|
throw new Error("not possible");
|
||||||
}
|
}
|
||||||
jj.endArray();
|
jj.endArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void comment(String content) {
|
public void comment(String content) {
|
||||||
// canonical JSON ignores comments
|
// canonical JSON ignores comments
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void link(String href) {
|
public void link(String href) {
|
||||||
// not used
|
// not used
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void anchor(String name) {
|
public void anchor(String name) {
|
||||||
// not used
|
// not used
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void externalLink(String string) {
|
public void externalLink(String string) {
|
||||||
// not used
|
// not used
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canElide() { return false; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void elide() {
|
||||||
|
// not used
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
package org.hl7.fhir.r5.formats;
|
package org.hl7.fhir.r5.formats;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2011+, HL7, Inc.
|
Copyright (c) 2011+, HL7, Inc.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
@ -28,219 +28,227 @@ package org.hl7.fhir.r5.formats;
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A little implementation of a json write to replace Gson .... because Gson screws up decimal values, and *we care*
|
* A little implementation of a json write to replace Gson .... because Gson screws up decimal values, and *we care*
|
||||||
*
|
*
|
||||||
* @author Grahame Grieve
|
* @author Grahame Grieve
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class JsonCreatorDirect implements JsonCreator {
|
public class JsonCreatorDirect implements JsonCreator {
|
||||||
|
|
||||||
private Writer writer;
|
private Writer writer;
|
||||||
private boolean pretty;
|
private boolean pretty;
|
||||||
private boolean comments;
|
private boolean comments;
|
||||||
private boolean named;
|
private boolean named;
|
||||||
private List<Boolean> valued = new ArrayList<Boolean>();
|
private List<Boolean> valued = new ArrayList<Boolean>();
|
||||||
private int indent;
|
private int indent;
|
||||||
private List<String> commentList = new ArrayList<>();
|
private List<String> commentList = new ArrayList<>();
|
||||||
|
|
||||||
public JsonCreatorDirect(Writer writer, boolean pretty, boolean comments) {
|
public JsonCreatorDirect(Writer writer, boolean pretty, boolean comments) {
|
||||||
super();
|
super();
|
||||||
this.writer = writer;
|
this.writer = writer;
|
||||||
this.pretty = pretty;
|
this.pretty = pretty;
|
||||||
this.comments = pretty && comments;
|
this.comments = pretty && comments;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void comment(String content) {
|
public void comment(String content) {
|
||||||
if (comments) {
|
if (comments) {
|
||||||
commentList.add(content);
|
commentList.add(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beginObject() throws IOException {
|
public void beginObject() throws IOException {
|
||||||
checkState();
|
checkState();
|
||||||
writer.write("{");
|
writer.write("{");
|
||||||
stepIn();
|
stepIn();
|
||||||
if (!valued.isEmpty()) {
|
if (!valued.isEmpty()) {
|
||||||
valued.set(0, true);
|
valued.set(0, true);
|
||||||
}
|
}
|
||||||
valued.add(0, false);
|
valued.add(0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void commitComments() throws IOException {
|
private void commitComments() throws IOException {
|
||||||
if (comments) {
|
if (comments) {
|
||||||
for (String s : commentList) {
|
for (String s : commentList) {
|
||||||
writer.write("// ");
|
writer.write("// ");
|
||||||
writer.write(s);
|
writer.write(s);
|
||||||
writer.write("\r\n");
|
writer.write("\r\n");
|
||||||
for (int i = 0; i < indent; i++) {
|
for (int i = 0; i < indent; i++) {
|
||||||
writer.write(" ");
|
writer.write(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commentList.clear();
|
commentList.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void stepIn() throws IOException {
|
public void stepIn() throws IOException {
|
||||||
if (pretty) {
|
if (pretty) {
|
||||||
indent++;
|
indent++;
|
||||||
writer.write("\r\n");
|
writer.write("\r\n");
|
||||||
for (int i = 0; i < indent; i++) {
|
for (int i = 0; i < indent; i++) {
|
||||||
writer.write(" ");
|
writer.write(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stepOut() throws IOException {
|
public void stepOut() throws IOException {
|
||||||
if (pretty) {
|
if (pretty) {
|
||||||
indent--;
|
indent--;
|
||||||
writer.write("\r\n");
|
writer.write("\r\n");
|
||||||
for (int i = 0; i < indent; i++) {
|
for (int i = 0; i < indent; i++) {
|
||||||
writer.write(" ");
|
writer.write(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkState() throws IOException {
|
private void checkState() throws IOException {
|
||||||
commitComments();
|
commitComments();
|
||||||
if (named) {
|
if (named) {
|
||||||
if (pretty)
|
if (pretty)
|
||||||
writer.write(" : ");
|
writer.write(" : ");
|
||||||
else
|
else
|
||||||
writer.write(":");
|
writer.write(":");
|
||||||
named = false;
|
named = false;
|
||||||
}
|
}
|
||||||
if (!valued.isEmpty() && valued.get(0)) {
|
if (!valued.isEmpty() && valued.get(0)) {
|
||||||
writer.write(",");
|
writer.write(",");
|
||||||
if (pretty) {
|
if (pretty) {
|
||||||
writer.write("\r\n");
|
writer.write("\r\n");
|
||||||
for (int i = 0; i < indent; i++) {
|
for (int i = 0; i < indent; i++) {
|
||||||
writer.write(" ");
|
writer.write(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
valued.set(0, false);
|
valued.set(0, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endObject() throws IOException {
|
public void endObject() throws IOException {
|
||||||
stepOut();
|
stepOut();
|
||||||
writer.write("}");
|
writer.write("}");
|
||||||
valued.remove(0);
|
valued.remove(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nullValue() throws IOException {
|
public void nullValue() throws IOException {
|
||||||
checkState();
|
checkState();
|
||||||
writer.write("null");
|
writer.write("null");
|
||||||
valued.set(0, true);
|
valued.set(0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void name(String name) throws IOException {
|
public void name(String name) throws IOException {
|
||||||
checkState();
|
checkState();
|
||||||
writer.write("\""+name+"\"");
|
writer.write("\""+name+"\"");
|
||||||
named = true;
|
named = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void value(String value) throws IOException {
|
public void value(String value) throws IOException {
|
||||||
checkState();
|
checkState();
|
||||||
writer.write("\""+Utilities.escapeJson(value)+"\"");
|
writer.write("\""+Utilities.escapeJson(value)+"\"");
|
||||||
valued.set(0, true);
|
valued.set(0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void value(Boolean value) throws IOException {
|
public void value(Boolean value) throws IOException {
|
||||||
checkState();
|
checkState();
|
||||||
if (value == null)
|
if (value == null)
|
||||||
writer.write("null");
|
writer.write("null");
|
||||||
else if (value.booleanValue())
|
else if (value.booleanValue())
|
||||||
writer.write("true");
|
writer.write("true");
|
||||||
else
|
else
|
||||||
writer.write("false");
|
writer.write("false");
|
||||||
valued.set(0, true);
|
valued.set(0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void value(BigDecimal value) throws IOException {
|
public void value(BigDecimal value) throws IOException {
|
||||||
checkState();
|
checkState();
|
||||||
if (value == null)
|
if (value == null)
|
||||||
writer.write("null");
|
writer.write("null");
|
||||||
else
|
else
|
||||||
writer.write(value.toString());
|
writer.write(value.toString());
|
||||||
valued.set(0, true);
|
valued.set(0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void valueNum(String value) throws IOException {
|
public void valueNum(String value) throws IOException {
|
||||||
checkState();
|
checkState();
|
||||||
if (value == null)
|
if (value == null)
|
||||||
writer.write("null");
|
writer.write("null");
|
||||||
else
|
else
|
||||||
writer.write(value);
|
writer.write(value);
|
||||||
valued.set(0, true);
|
valued.set(0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void value(Integer value) throws IOException {
|
public void value(Integer value) throws IOException {
|
||||||
checkState();
|
checkState();
|
||||||
if (value == null)
|
if (value == null)
|
||||||
writer.write("null");
|
writer.write("null");
|
||||||
else
|
else
|
||||||
writer.write(value.toString());
|
writer.write(value.toString());
|
||||||
valued.set(0, true);
|
valued.set(0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beginArray() throws IOException {
|
public void beginArray() throws IOException {
|
||||||
checkState();
|
checkState();
|
||||||
writer.write("[");
|
writer.write("[");
|
||||||
if (!valued.isEmpty()) {
|
if (!valued.isEmpty()) {
|
||||||
valued.set(0, true);
|
valued.set(0, true);
|
||||||
}
|
}
|
||||||
valued.add(0, false);
|
valued.add(0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endArray() throws IOException {
|
public void endArray() throws IOException {
|
||||||
writer.write("]");
|
writer.write("]");
|
||||||
valued.remove(0);
|
valued.remove(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finish() throws IOException {
|
public void finish() throws IOException {
|
||||||
writer.flush();
|
writer.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void link(String href) {
|
public void link(String href) {
|
||||||
// not used
|
// not used
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void anchor(String name) {
|
public void anchor(String name) {
|
||||||
// not used
|
// not used
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void externalLink(String string) {
|
public void externalLink(String string) {
|
||||||
// not used
|
// not used
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canElide() { return false; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void elide() {
|
||||||
|
// not used
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
package org.hl7.fhir.r5.formats;
|
package org.hl7.fhir.r5.formats;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2011+, HL7, Inc.
|
Copyright (c) 2011+, HL7, Inc.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
@ -28,103 +28,111 @@ package org.hl7.fhir.r5.formats;
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
|
||||||
public class JsonCreatorGson implements JsonCreator {
|
public class JsonCreatorGson implements JsonCreator {
|
||||||
|
|
||||||
JsonWriter gson;
|
JsonWriter gson;
|
||||||
|
|
||||||
public JsonCreatorGson(OutputStreamWriter osw) {
|
public JsonCreatorGson(OutputStreamWriter osw) {
|
||||||
gson = new JsonWriter(osw);
|
gson = new JsonWriter(osw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beginObject() throws IOException {
|
public void beginObject() throws IOException {
|
||||||
gson.beginObject();
|
gson.beginObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endObject() throws IOException {
|
public void endObject() throws IOException {
|
||||||
gson.endObject();
|
gson.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nullValue() throws IOException {
|
public void nullValue() throws IOException {
|
||||||
gson.nullValue();
|
gson.nullValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void name(String name) throws IOException {
|
public void name(String name) throws IOException {
|
||||||
gson.name(name);
|
gson.name(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void value(String value) throws IOException {
|
public void value(String value) throws IOException {
|
||||||
gson.value(value);
|
gson.value(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void value(Boolean value) throws IOException {
|
public void value(Boolean value) throws IOException {
|
||||||
gson.value(value);
|
gson.value(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void value(BigDecimal value) throws IOException {
|
public void value(BigDecimal value) throws IOException {
|
||||||
gson.value(value);
|
gson.value(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void value(Integer value) throws IOException {
|
public void value(Integer value) throws IOException {
|
||||||
gson.value(value);
|
gson.value(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beginArray() throws IOException {
|
public void beginArray() throws IOException {
|
||||||
gson.beginArray();
|
gson.beginArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endArray() throws IOException {
|
public void endArray() throws IOException {
|
||||||
gson.endArray();
|
gson.endArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finish() {
|
public void finish() {
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void link(String href) {
|
public void link(String href) {
|
||||||
// not used
|
// not used
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void valueNum(String value) throws IOException {
|
public void valueNum(String value) throws IOException {
|
||||||
value(new BigDecimal(value));
|
value(new BigDecimal(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void anchor(String name) {
|
public void anchor(String name) {
|
||||||
// not used
|
// not used
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void comment(String content) {
|
public void comment(String content) {
|
||||||
// gson (dense json) ignores comments
|
// gson (dense json) ignores comments
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void externalLink(String string) {
|
public void externalLink(String string) {
|
||||||
// not used
|
// not used
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void elide() {
|
||||||
|
// not used
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canElide() { return false;}
|
||||||
|
|
||||||
}
|
}
|
|
@ -36,7 +36,7 @@ public class AdditionalBindingsRenderer {
|
||||||
private String valueSet;
|
private String valueSet;
|
||||||
private String doco;
|
private String doco;
|
||||||
private String docoShort;
|
private String docoShort;
|
||||||
private UsageContext usage;
|
private List<UsageContext> usages = new ArrayList<UsageContext>();
|
||||||
private boolean any = false;
|
private boolean any = false;
|
||||||
private boolean isUnchanged = false;
|
private boolean isUnchanged = false;
|
||||||
private boolean matched = false;
|
private boolean matched = false;
|
||||||
|
@ -72,7 +72,7 @@ public class AdditionalBindingsRenderer {
|
||||||
isUnchanged = isUnchanged && ((valueSet==null && compare.valueSet==null) || valueSet.equals(compare.valueSet));
|
isUnchanged = isUnchanged && ((valueSet==null && compare.valueSet==null) || valueSet.equals(compare.valueSet));
|
||||||
isUnchanged = isUnchanged && ((doco==null && compare.doco==null) || doco.equals(compare.doco));
|
isUnchanged = isUnchanged && ((doco==null && compare.doco==null) || doco.equals(compare.doco));
|
||||||
isUnchanged = isUnchanged && ((docoShort==null && compare.docoShort==null) || docoShort.equals(compare.docoShort));
|
isUnchanged = isUnchanged && ((docoShort==null && compare.docoShort==null) || docoShort.equals(compare.docoShort));
|
||||||
isUnchanged = isUnchanged && ((usage==null && compare.usage==null) || usage.equals(compare.usage));
|
isUnchanged = isUnchanged && ((usages==null && compare.usages==null) || usages.equals(compare.usages));
|
||||||
return isUnchanged;
|
return isUnchanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,8 +174,12 @@ public class AdditionalBindingsRenderer {
|
||||||
abr.purpose = ext.getExtensionString("purpose");
|
abr.purpose = ext.getExtensionString("purpose");
|
||||||
abr.valueSet = ext.getExtensionString("valueSet");
|
abr.valueSet = ext.getExtensionString("valueSet");
|
||||||
abr.doco = ext.getExtensionString("documentation");
|
abr.doco = ext.getExtensionString("documentation");
|
||||||
abr.docoShort = ext.getExtensionString("shortDoco");
|
abr.docoShort = ext.getExtensionString("shortDoco");
|
||||||
abr.usage = (ext.hasExtension("usage")) && ext.getExtensionByUrl("usage").hasValueUsageContext() ? ext.getExtensionByUrl("usage").getValueUsageContext() : null;
|
for (Extension x : ext.getExtensionsByUrl("usage")) {
|
||||||
|
if (x.hasValueUsageContext()) {
|
||||||
|
abr.usages.add(x.getValueUsageContext());
|
||||||
|
}
|
||||||
|
}
|
||||||
abr.any = "any".equals(ext.getExtensionString("scope"));
|
abr.any = "any".equals(ext.getExtensionString("scope"));
|
||||||
abr.isUnchanged = ext.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS);
|
abr.isUnchanged = ext.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS);
|
||||||
return abr;
|
return abr;
|
||||||
|
@ -187,7 +191,7 @@ public class AdditionalBindingsRenderer {
|
||||||
abr.valueSet = ab.getValueSet();
|
abr.valueSet = ab.getValueSet();
|
||||||
abr.doco = ab.getDocumentation();
|
abr.doco = ab.getDocumentation();
|
||||||
abr.docoShort = ab.getShortDoco();
|
abr.docoShort = ab.getShortDoco();
|
||||||
abr.usage = ab.hasUsage() ? ab.getUsageFirstRep() : null;
|
abr.usages.addAll(ab.getUsage());
|
||||||
abr.any = ab.getAny();
|
abr.any = ab.getAny();
|
||||||
abr.isUnchanged = ab.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS);
|
abr.isUnchanged = ab.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS);
|
||||||
return abr;
|
return abr;
|
||||||
|
@ -220,7 +224,7 @@ public class AdditionalBindingsRenderer {
|
||||||
boolean any = false;
|
boolean any = false;
|
||||||
for (AdditionalBindingDetail binding : bindings) {
|
for (AdditionalBindingDetail binding : bindings) {
|
||||||
doco = doco || binding.getDoco(fullDoco)!=null || (binding.compare!=null && binding.compare.getDoco(fullDoco)!=null);
|
doco = doco || binding.getDoco(fullDoco)!=null || (binding.compare!=null && binding.compare.getDoco(fullDoco)!=null);
|
||||||
usage = usage || binding.usage != null || (binding.compare!=null && binding.compare.usage!=null);
|
usage = usage || !binding.usages.isEmpty() || (binding.compare!=null && !binding.compare.usages.isEmpty());
|
||||||
any = any || binding.any || (binding.compare!=null && binding.compare.any);
|
any = any || binding.any || (binding.compare!=null && binding.compare.any);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,9 +287,12 @@ public class AdditionalBindingsRenderer {
|
||||||
renderPurpose(purpose, binding.compare.purpose);
|
renderPurpose(purpose, binding.compare.purpose);
|
||||||
}
|
}
|
||||||
if (usage) {
|
if (usage) {
|
||||||
if (binding.usage != null) {
|
if (!binding.usages.isEmpty()) {
|
||||||
// TODO: This isn't rendered at all yet. Ideally, we want it to render with comparison...
|
XhtmlNode td = tr.td();
|
||||||
new DataRenderer(context).renderBase(new RenderingStatus(), tr.td(), binding.usage);
|
for (UsageContext uc : binding.usages) {
|
||||||
|
td.sep(", ");
|
||||||
|
new DataRenderer(context).renderBase(new RenderingStatus(), td, uc);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tr.td();
|
tr.td();
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
||||||
import org.hl7.fhir.r5.renderers.utils.ResourceWrapper;
|
import org.hl7.fhir.r5.renderers.utils.ResourceWrapper;
|
||||||
import org.hl7.fhir.r5.terminologies.JurisdictionUtilities;
|
import org.hl7.fhir.r5.terminologies.JurisdictionUtilities;
|
||||||
|
import org.hl7.fhir.r5.terminologies.utilities.SnomedUtilities;
|
||||||
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
|
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
|
||||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||||
|
@ -1177,8 +1178,8 @@ public class DataRenderer extends Renderer implements CodeResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getLinkForSystem(String system, String version) {
|
private String getLinkForSystem(String system, String version) {
|
||||||
if ("http://snomed.info/sct".equals(system)) {
|
if ("http://snomed.info/sct".equals(system)) {
|
||||||
return "https://browser.ihtsdotools.org/";
|
return "https://browser.ihtsdotools.org/";
|
||||||
} else if ("http://loinc.org".equals(system)) {
|
} else if ("http://loinc.org".equals(system)) {
|
||||||
return "https://loinc.org/";
|
return "https://loinc.org/";
|
||||||
} else if ("http://unitsofmeasure.org".equals(system)) {
|
} else if ("http://unitsofmeasure.org".equals(system)) {
|
||||||
|
@ -1198,11 +1199,7 @@ public class DataRenderer extends Renderer implements CodeResolver {
|
||||||
|
|
||||||
protected String getLinkForCode(String system, String version, String code) {
|
protected String getLinkForCode(String system, String version, String code) {
|
||||||
if ("http://snomed.info/sct".equals(system)) {
|
if ("http://snomed.info/sct".equals(system)) {
|
||||||
if (!Utilities.noString(code)) {
|
return SnomedUtilities.getSctLink(version, code, context.getContext().getExpansionParameters());
|
||||||
return "http://snomed.info/id/"+code;
|
|
||||||
} else {
|
|
||||||
return "https://browser.ihtsdotools.org/";
|
|
||||||
}
|
|
||||||
} else if ("http://loinc.org".equals(system)) {
|
} else if ("http://loinc.org".equals(system)) {
|
||||||
if (!Utilities.noString(code)) {
|
if (!Utilities.noString(code)) {
|
||||||
return "https://loinc.org/"+code;
|
return "https://loinc.org/"+code;
|
||||||
|
@ -1301,7 +1298,11 @@ public class DataRenderer extends Renderer implements CodeResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderCoding(RenderingStatus status, XhtmlNode x, ResourceWrapper c) {
|
protected void renderCoding(RenderingStatus status, XhtmlNode x, ResourceWrapper c) {
|
||||||
|
renderCoding(status, x, c, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void renderCoding(RenderingStatus status, XhtmlNode x, ResourceWrapper c, boolean details) {
|
||||||
String s = "";
|
String s = "";
|
||||||
if (c.has("display"))
|
if (c.has("display"))
|
||||||
s = context.getTranslated(c.child("display"));
|
s = context.getTranslated(c.child("display"));
|
||||||
|
@ -1311,10 +1312,13 @@ public class DataRenderer extends Renderer implements CodeResolver {
|
||||||
if (Utilities.noString(s))
|
if (Utilities.noString(s))
|
||||||
s = c.primitiveValue("code");
|
s = c.primitiveValue("code");
|
||||||
|
|
||||||
if (context.isTechnicalMode()) {
|
if (context.isTechnicalMode() && details) {
|
||||||
x.addText(s+" "+context.formatPhrase(RenderingContext.DATA_REND_DETAILS_STATED, displaySystem(c.primitiveValue("system")), c.primitiveValue("code"), " = '", lookupCode(c.primitiveValue("system"), c.primitiveValue("version"), c.primitiveValue("code")), c.primitiveValue("display"), "')"));
|
String d = c.primitiveValue("display") == null ? lookupCode(c.primitiveValue("system"), c.primitiveValue("version"), c.primitiveValue("code")): c.primitiveValue("display");
|
||||||
} else
|
d = context.formatPhrase(d == null || d.equals(c.primitiveValue("code")) ? RenderingContext.DATA_REND_DETAILS_STATED_ND : RenderingContext.DATA_REND_DETAILS_STATED, displaySystem(c.primitiveValue("system")), c.primitiveValue("code"), d);
|
||||||
x.span(null, "{"+c.primitiveValue("system")+" "+c.primitiveValue("code")+"}").addText(s);
|
x.addText(s+" "+d);
|
||||||
|
} else {
|
||||||
|
x.span(null, "{"+c.primitiveValue("system")+" "+c.primitiveValue("code")+"}").addText(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String displayCodeableConcept(ResourceWrapper cc) {
|
public String displayCodeableConcept(ResourceWrapper cc) {
|
||||||
|
@ -1860,8 +1864,8 @@ public class DataRenderer extends Renderer implements CodeResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void renderUsageContext(RenderingStatus status, XhtmlNode x, ResourceWrapper u) throws FHIRFormatError, DefinitionException, IOException {
|
public void renderUsageContext(RenderingStatus status, XhtmlNode x, ResourceWrapper u) throws FHIRFormatError, DefinitionException, IOException {
|
||||||
renderCoding(status, x, u.child("code"));
|
renderCoding(status, x, u.child("code"), false);
|
||||||
x.tx(": ");
|
x.tx(" = ");
|
||||||
renderDataType(status, x, u.child("value"));
|
renderDataType(status, x, u.child("value"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetUtilities;
|
import org.hl7.fhir.r5.terminologies.ValueSetUtilities;
|
||||||
import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome;
|
import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome;
|
||||||
import org.hl7.fhir.r5.terminologies.utilities.CodingValidationRequest;
|
import org.hl7.fhir.r5.terminologies.utilities.CodingValidationRequest;
|
||||||
|
import org.hl7.fhir.r5.terminologies.utilities.SnomedUtilities;
|
||||||
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
|
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
|
||||||
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
||||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||||
|
@ -750,9 +751,9 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
||||||
if (cs == null) {
|
if (cs == null) {
|
||||||
return "?cs-n?";
|
return "?cs-n?";
|
||||||
}
|
}
|
||||||
String ref = (String) cs.getUserData("filename");
|
String ref = cs.getWebPath();
|
||||||
if (ref == null) {
|
if (ref == null) {
|
||||||
ref = (String) cs.getWebPath();
|
ref = cs.getUserString("filename");
|
||||||
}
|
}
|
||||||
return ref == null ? null : ref.replace("\\", "/");
|
return ref == null ? null : ref.replace("\\", "/");
|
||||||
}
|
}
|
||||||
|
@ -825,7 +826,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
||||||
}
|
}
|
||||||
String s = Utilities.padLeft("", '\u00A0', i*2);
|
String s = Utilities.padLeft("", '\u00A0', i*2);
|
||||||
td.attribute("style", "white-space:nowrap").addText(s);
|
td.attribute("style", "white-space:nowrap").addText(s);
|
||||||
addCodeToTable(c.getAbstract(), c.getSystem(), c.getCode(), c.getDisplay(), td);
|
addCodeToTable(c.getAbstract(), c.getSystem(), c.getVersion(), c.getCode(), c.getDisplay(), td);
|
||||||
td = tr.td();
|
td = tr.td();
|
||||||
td.addText(c.getSystem());
|
td.addText(c.getSystem());
|
||||||
td = tr.td();
|
td = tr.td();
|
||||||
|
@ -863,7 +864,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
||||||
first = false;
|
first = false;
|
||||||
XhtmlNode span = td.span(null, mapping.comp.getRelationship().toString());
|
XhtmlNode span = td.span(null, mapping.comp.getRelationship().toString());
|
||||||
span.addText(getCharForRelationship(mapping.comp));
|
span.addText(getCharForRelationship(mapping.comp));
|
||||||
addRefToCode(td, mapping.group.getTarget(), m.getLink(), mapping.comp.getCode());
|
addRefToCode(td, mapping.group.getTarget(), null, m.getLink(), mapping.comp.getCode());
|
||||||
if (!Utilities.noString(mapping.comp.getComment()))
|
if (!Utilities.noString(mapping.comp.getComment()))
|
||||||
td.i().tx("("+mapping.comp.getComment()+")");
|
td.i().tx("("+mapping.comp.getComment()+")");
|
||||||
}
|
}
|
||||||
|
@ -900,13 +901,13 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCodeToTable(boolean isAbstract, String system, String code, String display, XhtmlNode td) {
|
private void addCodeToTable(boolean isAbstract, String system, String version, String code, String display, XhtmlNode td) {
|
||||||
CodeSystem e = getContext().getWorker().fetchCodeSystem(system);
|
CodeSystem e = getContext().getWorker().fetchCodeSystem(system);
|
||||||
if (e == null || (e.getContent() != org.hl7.fhir.r5.model.Enumerations.CodeSystemContentMode.COMPLETE && e.getContent() != org.hl7.fhir.r5.model.Enumerations.CodeSystemContentMode.FRAGMENT)) {
|
if (e == null || (e.getContent() != org.hl7.fhir.r5.model.Enumerations.CodeSystemContentMode.COMPLETE && e.getContent() != org.hl7.fhir.r5.model.Enumerations.CodeSystemContentMode.FRAGMENT)) {
|
||||||
if (isAbstract)
|
if (isAbstract)
|
||||||
td.i().setAttribute("title", context.formatPhrase(RenderingContext.VS_ABSTRACT_CODE_HINT)).addText(code);
|
td.i().setAttribute("title", context.formatPhrase(RenderingContext.VS_ABSTRACT_CODE_HINT)).addText(code);
|
||||||
else if ("http://snomed.info/sct".equals(system)) {
|
else if ("http://snomed.info/sct".equals(system)) {
|
||||||
td.ah(context.prefixLocalHref(sctLink(code))).addText(code);
|
td.ah(context.prefixLocalHref(SnomedUtilities.getSctLink(version, code, context.getContext().getExpansionParameters()))).addText(code);
|
||||||
} else if ("http://loinc.org".equals(system)) {
|
} else if ("http://loinc.org".equals(system)) {
|
||||||
td.ah(context.prefixLocalHref(LoincLinker.getLinkForCode(code))).addText(code);
|
td.ah(context.prefixLocalHref(LoincLinker.getLinkForCode(code))).addText(code);
|
||||||
} else
|
} else
|
||||||
|
@ -928,15 +929,8 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addRefToCode(XhtmlNode td, String target, String vslink, String code, String version) {
|
||||||
public String sctLink(String code) {
|
addCodeToTable(false, target, version, code, null, td);
|
||||||
// if (snomedEdition != null)
|
|
||||||
// http://browser.ihtsdotools.org/?perspective=full&conceptId1=428041000124106&edition=us-edition&release=v20180301&server=https://prod-browser-exten.ihtsdotools.org/api/snomed&langRefset=900000000000509007
|
|
||||||
return "http://snomed.info/id/"+code;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addRefToCode(XhtmlNode td, String target, String vslink, String code) {
|
|
||||||
addCodeToTable(false, target, code, null, td);
|
|
||||||
// CodeSystem cs = getContext().getWorker().fetchCodeSystem(target);
|
// CodeSystem cs = getContext().getWorker().fetchCodeSystem(target);
|
||||||
// String cslink = getCsRef(cs);
|
// String cslink = getCsRef(cs);
|
||||||
// String link = cslink != null ? cslink+"#"+cs.getId()+"-"+code : vslink+"#"+code;
|
// String link = cslink != null ? cslink+"#"+cs.getId()+"-"+code : vslink+"#"+code;
|
||||||
|
@ -1212,10 +1206,10 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
||||||
}
|
}
|
||||||
addMapHeaders(addTableHeaderRowStandard(t, false, true, hasDefinition, hasComments, false, false, null, langs, designations, doDesignations), maps);
|
addMapHeaders(addTableHeaderRowStandard(t, false, true, hasDefinition, hasComments, false, false, null, langs, designations, doDesignations), maps);
|
||||||
for (ConceptReferenceComponent c : inc.getConcept()) {
|
for (ConceptReferenceComponent c : inc.getConcept()) {
|
||||||
renderConcept(inc, langs, doDesignations, maps, designations, definitions, t, hasComments, hasDefinition, c);
|
renderConcept(inc, langs, doDesignations, maps, designations, definitions, t, hasComments, hasDefinition, c, inc.getVersion());
|
||||||
}
|
}
|
||||||
for (Base b : VersionComparisonAnnotation.getDeleted(inc, "concept" )) {
|
for (Base b : VersionComparisonAnnotation.getDeleted(inc, "concept" )) {
|
||||||
renderConcept(inc, langs, doDesignations, maps, designations, definitions, t, hasComments, hasDefinition, (ConceptReferenceComponent) b);
|
renderConcept(inc, langs, doDesignations, maps, designations, definitions, t, hasComments, hasDefinition, (ConceptReferenceComponent) b, inc.getVersion());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (inc.getFilter().size() > 0) {
|
if (inc.getFilter().size() > 0) {
|
||||||
|
@ -1312,11 +1306,11 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
||||||
|
|
||||||
private void renderConcept(ConceptSetComponent inc, List<String> langs, boolean doDesignations,
|
private void renderConcept(ConceptSetComponent inc, List<String> langs, boolean doDesignations,
|
||||||
List<UsedConceptMap> maps, Map<String, String> designations, Map<String, ConceptDefinitionComponent> definitions,
|
List<UsedConceptMap> maps, Map<String, String> designations, Map<String, ConceptDefinitionComponent> definitions,
|
||||||
XhtmlNode t, boolean hasComments, boolean hasDefinition, ConceptReferenceComponent c) {
|
XhtmlNode t, boolean hasComments, boolean hasDefinition, ConceptReferenceComponent c, String version) {
|
||||||
XhtmlNode tr = t.tr();
|
XhtmlNode tr = t.tr();
|
||||||
XhtmlNode td = renderStatusRow(c, t, tr);
|
XhtmlNode td = renderStatusRow(c, t, tr);
|
||||||
ConceptDefinitionComponent cc = definitions == null ? null : definitions.get(c.getCode());
|
ConceptDefinitionComponent cc = definitions == null ? null : definitions.get(c.getCode());
|
||||||
addCodeToTable(false, inc.getSystem(), c.getCode(), c.hasDisplay()? c.getDisplay() : cc != null ? cc.getDisplay() : "", td);
|
addCodeToTable(false, inc.getSystem(), version, c.getCode(), c.hasDisplay()? c.getDisplay() : cc != null ? cc.getDisplay() : "", td);
|
||||||
|
|
||||||
td = tr.td();
|
td = tr.td();
|
||||||
if (!Utilities.noString(c.getDisplay()))
|
if (!Utilities.noString(c.getDisplay()))
|
||||||
|
@ -1355,7 +1349,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
||||||
first = false;
|
first = false;
|
||||||
XhtmlNode span = td.span(null, mapping.comp.getRelationship().toString());
|
XhtmlNode span = td.span(null, mapping.comp.getRelationship().toString());
|
||||||
span.addText(getCharForRelationship(mapping.comp));
|
span.addText(getCharForRelationship(mapping.comp));
|
||||||
addRefToCode(td, mapping.group.getTarget(), m.getLink(), mapping.comp.getCode());
|
addRefToCode(td, mapping.group.getTarget(), m.getLink(), mapping.comp.getCode(), version);
|
||||||
if (!Utilities.noString(mapping.comp.getComment()))
|
if (!Utilities.noString(mapping.comp.getComment()))
|
||||||
td.i().tx("("+mapping.comp.getComment()+")");
|
td.i().tx("("+mapping.comp.getComment()+")");
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,8 @@ public class TerminologyClientContext {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean canUseCacheId;
|
||||||
|
|
||||||
private ITerminologyClient client;
|
private ITerminologyClient client;
|
||||||
private boolean initialised = false;
|
private boolean initialised = false;
|
||||||
private CapabilityStatement capabilitiesStatementQuick;
|
private CapabilityStatement capabilitiesStatementQuick;
|
||||||
|
@ -180,7 +182,7 @@ public class TerminologyClientContext {
|
||||||
txCache.cacheTerminologyCapabilities(getAddress(), txcaps);
|
txCache.cacheTerminologyCapabilities(getAddress(), txcaps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (txcaps != null) {
|
if (txcaps != null && TerminologyClientContext.canUseCacheId) {
|
||||||
for (TerminologyCapabilitiesExpansionParameterComponent t : txcaps.getExpansion().getParameter()) {
|
for (TerminologyCapabilitiesExpansionParameterComponent t : txcaps.getExpansion().getParameter()) {
|
||||||
if ("cache-id".equals(t.getName())) {
|
if ("cache-id".equals(t.getName())) {
|
||||||
setTxCaching(true);
|
setTxCaching(true);
|
||||||
|
@ -206,6 +208,13 @@ public class TerminologyClientContext {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return client.getAddress();
|
return client.getAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isCanUseCacheId() {
|
||||||
|
return canUseCacheId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setCanUseCacheId(boolean canUseCacheId) {
|
||||||
|
TerminologyClientContext.canUseCacheId = canUseCacheId;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
||||||
private ValueSetExpansionContainsComponent addCode(WorkingContext wc, String system, String code, String display, String dispLang, ValueSetExpansionContainsComponent parent, List<ConceptDefinitionDesignationComponent> designations, Parameters expParams,
|
private ValueSetExpansionContainsComponent addCode(WorkingContext wc, String system, String code, String display, String dispLang, ValueSetExpansionContainsComponent parent, List<ConceptDefinitionDesignationComponent> designations, Parameters expParams,
|
||||||
boolean isAbstract, boolean inactive, List<ValueSet> filters, boolean noInactive, boolean deprecated, List<ValueSetExpansionPropertyComponent> vsProp,
|
boolean isAbstract, boolean inactive, List<ValueSet> filters, boolean noInactive, boolean deprecated, List<ValueSetExpansionPropertyComponent> vsProp,
|
||||||
List<ConceptPropertyComponent> csProps, CodeSystem cs, List<org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent> expProps, List<Extension> csExtList, List<Extension> vsExtList, ValueSetExpansionComponent exp) throws ETooCostly {
|
List<ConceptPropertyComponent> csProps, CodeSystem cs, List<org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent> expProps, List<Extension> csExtList, List<Extension> vsExtList, ValueSetExpansionComponent exp) throws ETooCostly {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("addCode"+code);
|
||||||
|
|
||||||
if (filters != null && !filters.isEmpty() && !filterContainsCode(filters, system, code, exp))
|
if (filters != null && !filters.isEmpty() && !filterContainsCode(filters, system, code, exp))
|
||||||
return null;
|
return null;
|
||||||
|
@ -447,7 +447,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCodeAndDescendents(WorkingContext wc, ValueSetExpansionContainsComponent focus, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps, ValueSet vsSrc, ValueSetExpansionComponent exp) throws FHIRException, ETooCostly {
|
private void addCodeAndDescendents(WorkingContext wc, ValueSetExpansionContainsComponent focus, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps, ValueSet vsSrc, ValueSetExpansionComponent exp) throws FHIRException, ETooCostly {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("addCodeAndDescendents");
|
||||||
focus.checkNoModifiers("Expansion.contains", "expanding");
|
focus.checkNoModifiers("Expansion.contains", "expanding");
|
||||||
ValueSetExpansionContainsComponent np = null;
|
ValueSetExpansionContainsComponent np = null;
|
||||||
for (String code : getCodesForConcept(focus, expParams)) {
|
for (String code : getCodesForConcept(focus, expParams)) {
|
||||||
|
@ -497,7 +497,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
||||||
|
|
||||||
private void addCodeAndDescendents(WorkingContext wc, CodeSystem cs, String system, ConceptDefinitionComponent def, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters,
|
private void addCodeAndDescendents(WorkingContext wc, CodeSystem cs, String system, ConceptDefinitionComponent def, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters,
|
||||||
ConceptDefinitionComponent exclusion, ConceptFilter filterFunc, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps, List<WorkingContext> otherFilters, ValueSetExpansionComponent exp) throws FHIRException, ETooCostly {
|
ConceptDefinitionComponent exclusion, ConceptFilter filterFunc, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps, List<WorkingContext> otherFilters, ValueSetExpansionComponent exp) throws FHIRException, ETooCostly {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("addCodeAndDescendents");
|
||||||
def.checkNoModifiers("Code in Code System", "expanding");
|
def.checkNoModifiers("Code in Code System", "expanding");
|
||||||
if (exclusion != null) {
|
if (exclusion != null) {
|
||||||
if (exclusion.getCode().equals(def.getCode()))
|
if (exclusion.getCode().equals(def.getCode()))
|
||||||
|
@ -528,7 +528,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
||||||
|
|
||||||
private void excludeCodeAndDescendents(WorkingContext wc, CodeSystem cs, String system, ConceptDefinitionComponent def, Parameters expParams, List<ValueSet> filters,
|
private void excludeCodeAndDescendents(WorkingContext wc, CodeSystem cs, String system, ConceptDefinitionComponent def, Parameters expParams, List<ValueSet> filters,
|
||||||
ConceptDefinitionComponent exclusion, ConceptFilter filterFunc, List<WorkingContext> otherFilters, ValueSetExpansionComponent exp) throws FHIRException, ETooCostly {
|
ConceptDefinitionComponent exclusion, ConceptFilter filterFunc, List<WorkingContext> otherFilters, ValueSetExpansionComponent exp) throws FHIRException, ETooCostly {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("excludeCodeAndDescendents");
|
||||||
def.checkNoModifiers("Code in Code System", "expanding");
|
def.checkNoModifiers("Code in Code System", "expanding");
|
||||||
if (exclusion != null) {
|
if (exclusion != null) {
|
||||||
if (exclusion.getCode().equals(def.getCode()))
|
if (exclusion.getCode().equals(def.getCode()))
|
||||||
|
@ -596,7 +596,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void excludeCodes(WorkingContext wc, ConceptSetComponent exc, Parameters expParams, ValueSetExpansionComponent exp, ValueSet vs) throws FHIRException, FileNotFoundException, ETooCostly, IOException {
|
private void excludeCodes(WorkingContext wc, ConceptSetComponent exc, Parameters expParams, ValueSetExpansionComponent exp, ValueSet vs) throws FHIRException, FileNotFoundException, ETooCostly, IOException {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("excludeCodes");
|
||||||
exc.checkNoModifiers("Compose.exclude", "expanding");
|
exc.checkNoModifiers("Compose.exclude", "expanding");
|
||||||
if (exc.hasSystem() && exc.getConcept().size() == 0 && exc.getFilter().size() == 0) {
|
if (exc.hasSystem() && exc.getConcept().size() == 0 && exc.getFilter().size() == 0) {
|
||||||
wc.getExcludeSystems().add(exc.getSystem());
|
wc.getExcludeSystems().add(exc.getSystem());
|
||||||
|
@ -639,7 +639,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void excludeCodes(WorkingContext wc, ValueSetExpansionComponent expand) {
|
private void excludeCodes(WorkingContext wc, ValueSetExpansionComponent expand) {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("excludeCodes");
|
||||||
for (ValueSetExpansionContainsComponent c : expand.getContains()) {
|
for (ValueSetExpansionContainsComponent c : expand.getContains()) {
|
||||||
excludeCode(wc, c.getSystem(), c.getCode());
|
excludeCode(wc, c.getSystem(), c.getCode());
|
||||||
}
|
}
|
||||||
|
@ -959,7 +959,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyExpansion(WorkingContext wc,List<ValueSetExpansionContainsComponent> list) {
|
public void copyExpansion(WorkingContext wc,List<ValueSetExpansionContainsComponent> list) {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("copyExpansion");
|
||||||
for (ValueSetExpansionContainsComponent cc : list) {
|
for (ValueSetExpansionContainsComponent cc : list) {
|
||||||
ValueSetExpansionContainsComponent n = new ValueSet.ValueSetExpansionContainsComponent();
|
ValueSetExpansionContainsComponent n = new ValueSet.ValueSetExpansionContainsComponent();
|
||||||
n.setSystem(cc.getSystem());
|
n.setSystem(cc.getSystem());
|
||||||
|
@ -988,7 +988,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
||||||
|
|
||||||
private int copyImportContains(List<ValueSetExpansionContainsComponent> list, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filter, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps, ValueSet vsSrc, ValueSetExpansionComponent exp) throws FHIRException, ETooCostly {
|
private int copyImportContains(List<ValueSetExpansionContainsComponent> list, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filter, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps, ValueSet vsSrc, ValueSetExpansionComponent exp) throws FHIRException, ETooCostly {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("copyImportContains");
|
||||||
for (ValueSetExpansionContainsComponent c : list) {
|
for (ValueSetExpansionContainsComponent c : list) {
|
||||||
c.checkNoModifiers("Imported Expansion in Code System", "expanding");
|
c.checkNoModifiers("Imported Expansion in Code System", "expanding");
|
||||||
ValueSetExpansionContainsComponent np = addCode(dwc, c.getSystem(), c.getCode(), c.getDisplay(), vsSrc.getLanguage(), parent, null, expParams, c.getAbstract(), c.getInactive(),
|
ValueSetExpansionContainsComponent np = addCode(dwc, c.getSystem(), c.getCode(), c.getDisplay(), vsSrc.getLanguage(), parent, null, expParams, c.getAbstract(), c.getInactive(),
|
||||||
|
@ -1002,7 +1002,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void includeCodes(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, boolean heirarchical, boolean noInactive, List<Extension> extensions, ValueSet valueSet) throws ETooCostly, FileNotFoundException, IOException, FHIRException, CodeSystemProviderExtension {
|
private void includeCodes(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, boolean heirarchical, boolean noInactive, List<Extension> extensions, ValueSet valueSet) throws ETooCostly, FileNotFoundException, IOException, FHIRException, CodeSystemProviderExtension {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("includeCodes");
|
||||||
inc.checkNoModifiers("Compose.include", "expanding");
|
inc.checkNoModifiers("Compose.include", "expanding");
|
||||||
List<ValueSet> imports = new ArrayList<ValueSet>();
|
List<ValueSet> imports = new ArrayList<ValueSet>();
|
||||||
for (CanonicalType imp : inc.getValueSet()) {
|
for (CanonicalType imp : inc.getValueSet()) {
|
||||||
|
@ -1033,7 +1033,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doServerIncludeCodes(ConceptSetComponent inc, boolean heirarchical, ValueSetExpansionComponent exp, List<ValueSet> imports, Parameters expParams, List<Extension> extensions, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps) throws FHIRException, CodeSystemProviderExtension, ETooCostly {
|
private void doServerIncludeCodes(ConceptSetComponent inc, boolean heirarchical, ValueSetExpansionComponent exp, List<ValueSet> imports, Parameters expParams, List<Extension> extensions, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps) throws FHIRException, CodeSystemProviderExtension, ETooCostly {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("doServerIncludeCodes");
|
||||||
CodeSystemProvider csp = CodeSystemProvider.factory(inc.getSystem());
|
CodeSystemProvider csp = CodeSystemProvider.factory(inc.getSystem());
|
||||||
if (csp != null) {
|
if (csp != null) {
|
||||||
csp.includeCodes(inc, heirarchical, exp, imports, expParams, extensions, noInactive, vsProps);
|
csp.includeCodes(inc, heirarchical, exp, imports, expParams, extensions, noInactive, vsProps);
|
||||||
|
@ -1075,7 +1075,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
||||||
|
|
||||||
|
|
||||||
public void doInternalIncludeCodes(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, List<ValueSet> imports, CodeSystem cs, boolean noInactive, Resource vsSrc) throws NoTerminologyServiceException, TerminologyServiceException, FHIRException, ETooCostly {
|
public void doInternalIncludeCodes(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, List<ValueSet> imports, CodeSystem cs, boolean noInactive, Resource vsSrc) throws NoTerminologyServiceException, TerminologyServiceException, FHIRException, ETooCostly {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("doInternalIncludeCodes");
|
||||||
if (cs == null) {
|
if (cs == null) {
|
||||||
if (context.isNoTerminologyServer())
|
if (context.isNoTerminologyServer())
|
||||||
throw failTSE("Unable to find code system " + inc.getSystem().toString());
|
throw failTSE("Unable to find code system " + inc.getSystem().toString());
|
||||||
|
@ -1160,7 +1160,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
||||||
private void processFilter(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, List<ValueSet> imports, CodeSystem cs, boolean noInactive,
|
private void processFilter(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, List<ValueSet> imports, CodeSystem cs, boolean noInactive,
|
||||||
ConceptSetFilterComponent fc, WorkingContext wc, List<WorkingContext> filters, boolean exclude)
|
ConceptSetFilterComponent fc, WorkingContext wc, List<WorkingContext> filters, boolean exclude)
|
||||||
throws ETooCostly {
|
throws ETooCostly {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("processFilter");
|
||||||
if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISA) {
|
if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISA) {
|
||||||
// special: all codes in the target code system under the value
|
// special: all codes in the target code system under the value
|
||||||
ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
|
ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
|
||||||
|
@ -1213,7 +1213,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
||||||
if (isNotBlank(def.getDisplay()) && isNotBlank(fc.getValue())) {
|
if (isNotBlank(def.getDisplay()) && isNotBlank(fc.getValue())) {
|
||||||
if (def.getDisplay().contains(fc.getValue()) && passesOtherFilters(filters, cs, def.getCode())) {
|
if (def.getDisplay().contains(fc.getValue()) && passesOtherFilters(filters, cs, def.getCode())) {
|
||||||
for (String code : getCodesForConcept(def, expParams)) {
|
for (String code : getCodesForConcept(def, expParams)) {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("processFilter2");
|
||||||
if (exclude) {
|
if (exclude) {
|
||||||
excludeCode(wc, inc.getSystem(), code);
|
excludeCode(wc, inc.getSystem(), code);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
package org.hl7.fhir.r5.terminologies.utilities;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r5.model.Parameters;
|
||||||
|
import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
|
||||||
|
|
||||||
|
//URL: http://snomed.info/sct/[module]/version/[e.g. 20150131]'
|
||||||
|
//International: 900000000000207008
|
||||||
|
//US: 731000124108
|
||||||
|
//Australia: 32506021000036107
|
||||||
|
//Belgium: 11000172109
|
||||||
|
//Canada: 20611000087101
|
||||||
|
//Spain: 449081005
|
||||||
|
//Denmark: 554471000005108
|
||||||
|
//Netherlands: 11000146104
|
||||||
|
//Sweden: 45991000052106
|
||||||
|
//Switzerland: 2011000195101
|
||||||
|
//UK: 83821000000107
|
||||||
|
//IPS: 827022005
|
||||||
|
|
||||||
|
public class SnomedUtilities {
|
||||||
|
|
||||||
|
public static String getVersionFromParameters(Parameters p, String version) {
|
||||||
|
for (ParametersParameterComponent pp : p.getParameter()) {
|
||||||
|
switch (pp.getName()) {
|
||||||
|
case "system-version" :
|
||||||
|
if (version == null) {
|
||||||
|
return pp.getValue().primitiveValue();
|
||||||
|
}
|
||||||
|
case "force-system-version":
|
||||||
|
return pp.getValue().primitiveValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getEditionFromVersion(String version) {
|
||||||
|
if (version == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (version.startsWith("http://snomed.info/sct/")) {
|
||||||
|
version = version.substring(23);
|
||||||
|
}
|
||||||
|
if (version.contains("/")) {
|
||||||
|
version = version.substring(0, version.indexOf("/"));
|
||||||
|
}
|
||||||
|
if (Utilities.existsInList(version, "900000000000207008", "731000124108", "32506021000036107", "11000172109", "20611000087101",
|
||||||
|
"449081005", "554471000005108", "11000146104", "45991000052106", "2011000195101", "83821000000107", "827022005")) {
|
||||||
|
return version;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSctLink(String version, String code, Parameters p) {
|
||||||
|
if (!Utilities.noString(code)) {
|
||||||
|
version = SnomedUtilities.getVersionFromParameters(p, version);
|
||||||
|
String edId = SnomedUtilities.getEditionFromVersion(version);
|
||||||
|
if (edId != null) {
|
||||||
|
// if there's a version that's an edition, then:
|
||||||
|
// http://snomed.info/sct/11000172109/id//371305003
|
||||||
|
return "http://snomed.info/sct/"+edId+"/id/"+code;
|
||||||
|
} else {
|
||||||
|
// no, version:
|
||||||
|
return "http://snomed.info/id/"+code;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "https://browser.ihtsdotools.org/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -302,22 +302,26 @@ public class TerminologyCache {
|
||||||
this.lock = lock;
|
this.lock = lock;
|
||||||
if (folder == null) {
|
if (folder == null) {
|
||||||
folder = Utilities.path("[tmp]", "default-tx-cache");
|
folder = Utilities.path("[tmp]", "default-tx-cache");
|
||||||
|
} else if ("n/a".equals(folder)) {
|
||||||
|
// this is a weird way to do things but it maintains the legacy interface
|
||||||
|
folder = null;
|
||||||
}
|
}
|
||||||
this.folder = folder;
|
this.folder = folder;
|
||||||
requestCount = 0;
|
requestCount = 0;
|
||||||
hitCount = 0;
|
hitCount = 0;
|
||||||
networkCount = 0;
|
networkCount = 0;
|
||||||
|
|
||||||
|
if (folder != null) {
|
||||||
File f = ManagedFileAccess.file(folder);
|
File f = ManagedFileAccess.file(folder);
|
||||||
if (!f.exists()) {
|
if (!f.exists()) {
|
||||||
Utilities.createDirectory(folder);
|
Utilities.createDirectory(folder);
|
||||||
|
}
|
||||||
|
if (!f.exists()) {
|
||||||
|
throw new IOException("Unable to create terminology cache at "+folder);
|
||||||
|
}
|
||||||
|
checkVersion();
|
||||||
|
load();
|
||||||
}
|
}
|
||||||
if (!f.exists()) {
|
|
||||||
throw new IOException("Unable to create terminology cache at "+folder);
|
|
||||||
}
|
|
||||||
checkVersion();
|
|
||||||
load();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkVersion() throws IOException {
|
private void checkVersion() throws IOException {
|
||||||
|
@ -361,7 +365,9 @@ public class TerminologyCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clear() throws IOException {
|
private void clear() throws IOException {
|
||||||
Utilities.clearDirectory(folder);
|
if (folder != null) {
|
||||||
|
Utilities.clearDirectory(folder);
|
||||||
|
}
|
||||||
caches.clear();
|
caches.clear();
|
||||||
vsCache.clear();
|
vsCache.clear();
|
||||||
csCache.clear();
|
csCache.clear();
|
||||||
|
@ -1039,7 +1045,7 @@ public class TerminologyCache {
|
||||||
|
|
||||||
public SourcedValueSet getValueSet(String canonical) {
|
public SourcedValueSet getValueSet(String canonical) {
|
||||||
SourcedValueSetEntry sp = vsCache.get(canonical);
|
SourcedValueSetEntry sp = vsCache.get(canonical);
|
||||||
if (sp == null) {
|
if (sp == null || folder == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
@ -1052,7 +1058,7 @@ public class TerminologyCache {
|
||||||
|
|
||||||
public SourcedCodeSystem getCodeSystem(String canonical) {
|
public SourcedCodeSystem getCodeSystem(String canonical) {
|
||||||
SourcedCodeSystemEntry sp = csCache.get(canonical);
|
SourcedCodeSystemEntry sp = csCache.get(canonical);
|
||||||
if (sp == null) {
|
if (sp == null || folder == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
@ -1073,7 +1079,9 @@ public class TerminologyCache {
|
||||||
} else {
|
} else {
|
||||||
String uuid = Utilities.makeUuidLC();
|
String uuid = Utilities.makeUuidLC();
|
||||||
String fn = "vs-"+uuid+".json";
|
String fn = "vs-"+uuid+".json";
|
||||||
new JsonParser().compose(ManagedFileAccess.outStream(Utilities.path(folder, fn)), svs.getVs());
|
if (folder != null) {
|
||||||
|
new JsonParser().compose(ManagedFileAccess.outStream(Utilities.path(folder, fn)), svs.getVs());
|
||||||
|
}
|
||||||
vsCache.put(canonical, new SourcedValueSetEntry(svs.getServer(), fn));
|
vsCache.put(canonical, new SourcedValueSetEntry(svs.getServer(), fn));
|
||||||
}
|
}
|
||||||
org.hl7.fhir.utilities.json.model.JsonObject j = new org.hl7.fhir.utilities.json.model.JsonObject();
|
org.hl7.fhir.utilities.json.model.JsonObject j = new org.hl7.fhir.utilities.json.model.JsonObject();
|
||||||
|
@ -1090,7 +1098,9 @@ public class TerminologyCache {
|
||||||
j.add(k, e);
|
j.add(k, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
org.hl7.fhir.utilities.json.parser.JsonParser.compose(j, ManagedFileAccess.file(Utilities.path(folder, "vs-externals.json")), true);
|
if (folder != null) {
|
||||||
|
org.hl7.fhir.utilities.json.parser.JsonParser.compose(j, ManagedFileAccess.file(Utilities.path(folder, "vs-externals.json")), true);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -1106,7 +1116,9 @@ public class TerminologyCache {
|
||||||
} else {
|
} else {
|
||||||
String uuid = Utilities.makeUuidLC();
|
String uuid = Utilities.makeUuidLC();
|
||||||
String fn = "cs-"+uuid+".json";
|
String fn = "cs-"+uuid+".json";
|
||||||
new JsonParser().compose(ManagedFileAccess.outStream(Utilities.path(folder, fn)), scs.getCs());
|
if (folder != null) {
|
||||||
|
new JsonParser().compose(ManagedFileAccess.outStream(Utilities.path(folder, fn)), scs.getCs());
|
||||||
|
}
|
||||||
csCache.put(canonical, new SourcedCodeSystemEntry(scs.getServer(), fn));
|
csCache.put(canonical, new SourcedCodeSystemEntry(scs.getServer(), fn));
|
||||||
}
|
}
|
||||||
org.hl7.fhir.utilities.json.model.JsonObject j = new org.hl7.fhir.utilities.json.model.JsonObject();
|
org.hl7.fhir.utilities.json.model.JsonObject j = new org.hl7.fhir.utilities.json.model.JsonObject();
|
||||||
|
@ -1123,7 +1135,9 @@ public class TerminologyCache {
|
||||||
j.add(k, e);
|
j.add(k, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
org.hl7.fhir.utilities.json.parser.JsonParser.compose(j, ManagedFileAccess.file(Utilities.path(folder, "cs-externals.json")), true);
|
if (folder != null) {
|
||||||
|
org.hl7.fhir.utilities.json.parser.JsonParser.compose(j, ManagedFileAccess.file(Utilities.path(folder, "cs-externals.json")), true);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import org.hl7.fhir.exceptions.TerminologyServiceException;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.model.OperationOutcome.IssueType;
|
import org.hl7.fhir.r5.model.OperationOutcome.IssueType;
|
||||||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyOperationContext.TerminologyServiceProtectionException;
|
import org.hl7.fhir.r5.terminologies.utilities.TerminologyOperationContext.TerminologyServiceProtectionException;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||||
|
|
||||||
|
@ -38,16 +39,22 @@ public class TerminologyOperationContext {
|
||||||
public static boolean debugging = java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments().toString().indexOf("-agentlib:jdwp") > 0;
|
public static boolean debugging = java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments().toString().indexOf("-agentlib:jdwp") > 0;
|
||||||
private static final int EXPANSION_DEAD_TIME_SECS = 60;
|
private static final int EXPANSION_DEAD_TIME_SECS = 60;
|
||||||
private long deadTime;
|
private long deadTime;
|
||||||
|
private int nestCount = 0;
|
||||||
|
private long startTime;
|
||||||
private List<String> contexts = new ArrayList<>();
|
private List<String> contexts = new ArrayList<>();
|
||||||
private IWorkerContext worker;
|
private IWorkerContext worker;
|
||||||
private boolean original;
|
private boolean original;
|
||||||
private ValidationOptions options;
|
private ValidationOptions options;
|
||||||
|
private String name;
|
||||||
|
private List<String> notes = new ArrayList<>();
|
||||||
|
|
||||||
public TerminologyOperationContext(IWorkerContext worker, ValidationOptions options) {
|
public TerminologyOperationContext(IWorkerContext worker, ValidationOptions options, String name) {
|
||||||
super();
|
super();
|
||||||
this.worker = worker;
|
this.worker = worker;
|
||||||
this.original = true;
|
this.original = true;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
this.name = name;
|
||||||
|
this.startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
if (EXPANSION_DEAD_TIME_SECS == 0 || debugging) {
|
if (EXPANSION_DEAD_TIME_SECS == 0 || debugging) {
|
||||||
deadTime = 0;
|
deadTime = 0;
|
||||||
|
@ -56,22 +63,33 @@ public class TerminologyOperationContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TerminologyOperationContext(ValidationOptions options) {
|
private TerminologyOperationContext(ValidationOptions options, String name) {
|
||||||
super();
|
super();
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
this.name = name;
|
||||||
|
this.startTime = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TerminologyOperationContext copy() {
|
public TerminologyOperationContext copy() {
|
||||||
TerminologyOperationContext ret = new TerminologyOperationContext(this.options);
|
TerminologyOperationContext ret = new TerminologyOperationContext(this.options, name);
|
||||||
ret.worker = worker;
|
ret.worker = worker;
|
||||||
ret.contexts.addAll(contexts);
|
ret.contexts.addAll(contexts);
|
||||||
ret.deadTime = deadTime;
|
ret.deadTime = deadTime;
|
||||||
|
ret.notes = notes;
|
||||||
|
ret.startTime = startTime;
|
||||||
|
ret.nestCount = nestCount + 1;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deadCheck() {
|
public void deadCheck(String note) {
|
||||||
|
note(note);
|
||||||
if (deadTime != 0 && System.currentTimeMillis() > deadTime) {
|
if (deadTime != 0 && System.currentTimeMillis() > deadTime) {
|
||||||
throw new TerminologyServiceProtectionException(worker.formatMessage(I18nConstants.VALUESET_TOO_COSTLY_TIME, contexts.get(0), EXPANSION_DEAD_TIME_SECS), TerminologyServiceErrorClass.TOO_COSTLY, IssueType.TOOCOSTLY);
|
System.out.println();
|
||||||
|
System.out.println("Operation took too long - longer than "+(deadTime - startTime)+"ms");
|
||||||
|
for (String s : notes) {
|
||||||
|
System.out.println(s);
|
||||||
|
}
|
||||||
|
throw new TerminologyServiceProtectionException(worker.formatMessage(I18nConstants.VALUESET_TOO_COSTLY_TIME, contexts.get(0), EXPANSION_DEAD_TIME_SECS, name+" (local)"), TerminologyServiceErrorClass.TOO_COSTLY, IssueType.TOOCOSTLY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,5 +108,8 @@ public class TerminologyOperationContext {
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void note(String s) {
|
||||||
|
s = Utilities.padLeft("", ' ', nestCount)+" "+(System.currentTimeMillis() - startTime)+" "+s;
|
||||||
|
notes.add(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class ValueSetProcessBase {
|
||||||
protected IWorkerContext context;
|
protected IWorkerContext context;
|
||||||
protected TerminologyOperationContext opContext;
|
protected TerminologyOperationContext opContext;
|
||||||
protected List<String> requiredSupplements = new ArrayList<>();
|
protected List<String> requiredSupplements = new ArrayList<>();
|
||||||
|
|
||||||
protected ValueSetProcessBase(IWorkerContext context, TerminologyOperationContext opContext) {
|
protected ValueSetProcessBase(IWorkerContext context, TerminologyOperationContext opContext) {
|
||||||
super();
|
super();
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
@ -229,7 +229,11 @@ public class ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TerminologyOperationContext getOpContext() {
|
||||||
|
return opContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected AlternateCodesProcessingRules altCodeParams = new AlternateCodesProcessingRules(false);
|
protected AlternateCodesProcessingRules altCodeParams = new AlternateCodesProcessingRules(false);
|
||||||
protected AlternateCodesProcessingRules allAltCodes = new AlternateCodesProcessingRules(true);
|
protected AlternateCodesProcessingRules allAltCodes = new AlternateCodesProcessingRules(true);
|
||||||
|
|
|
@ -175,11 +175,15 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyseValueSet() {
|
private void analyseValueSet() {
|
||||||
|
opContext.note("analyse");
|
||||||
if (valueset != null) {
|
if (valueset != null) {
|
||||||
|
opContext.note("vs = "+valueset.getVersionedUrl());
|
||||||
opContext.seeContext(valueset.getVersionedUrl());
|
opContext.seeContext(valueset.getVersionedUrl());
|
||||||
for (Extension s : valueset.getExtensionsByUrl(ExtensionConstants.EXT_VSSUPPLEMENT)) {
|
for (Extension s : valueset.getExtensionsByUrl(ExtensionConstants.EXT_VSSUPPLEMENT)) {
|
||||||
requiredSupplements.add(s.getValue().primitiveValue());
|
requiredSupplements.add(s.getValue().primitiveValue());
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
opContext.note("vs = null");
|
||||||
}
|
}
|
||||||
|
|
||||||
altCodeParams.seeParameters(expansionProfile);
|
altCodeParams.seeParameters(expansionProfile);
|
||||||
|
@ -187,17 +191,18 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
if (localContext != null) {
|
if (localContext != null) {
|
||||||
if (valueset != null) {
|
if (valueset != null) {
|
||||||
for (ConceptSetComponent i : valueset.getCompose().getInclude()) {
|
for (ConceptSetComponent i : valueset.getCompose().getInclude()) {
|
||||||
analyseComponent(i);
|
analyseComponent(i, "inc"+i);
|
||||||
}
|
}
|
||||||
for (ConceptSetComponent i : valueset.getCompose().getExclude()) {
|
for (ConceptSetComponent i : valueset.getCompose().getExclude()) {
|
||||||
analyseComponent(i);
|
analyseComponent(i, "exc"+i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
opContext.note("analysed");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyseComponent(ConceptSetComponent i) {
|
private void analyseComponent(ConceptSetComponent i, String name) {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("analyse Component "+name);
|
||||||
if (i.getSystemElement().hasExtension(ToolingExtensions.EXT_VALUESET_SYSTEM)) {
|
if (i.getSystemElement().hasExtension(ToolingExtensions.EXT_VALUESET_SYSTEM)) {
|
||||||
String ref = i.getSystemElement().getExtensionString(ToolingExtensions.EXT_VALUESET_SYSTEM);
|
String ref = i.getSystemElement().getExtensionString(ToolingExtensions.EXT_VALUESET_SYSTEM);
|
||||||
if (ref.startsWith("#")) {
|
if (ref.startsWith("#")) {
|
||||||
|
@ -219,11 +224,15 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValidationResult validateCode(String path, CodeableConcept code) throws FHIRException {
|
public ValidationResult validateCode(String path, CodeableConcept code) throws FHIRException {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("validate "+code.toString());
|
||||||
checkValueSetOptions();
|
checkValueSetOptions();
|
||||||
|
|
||||||
// first, we validate the codings themselves
|
// first, we validate the codings themselves
|
||||||
ValidationProcessInfo info = new ValidationProcessInfo();
|
ValidationProcessInfo info = new ValidationProcessInfo();
|
||||||
|
|
||||||
|
if (throwToServer) {
|
||||||
|
checkValueSetLoad(info);
|
||||||
|
}
|
||||||
|
|
||||||
CodeableConcept vcc = new CodeableConcept();
|
CodeableConcept vcc = new CodeableConcept();
|
||||||
List<ValidationResult> resList = new ArrayList<>();
|
List<ValidationResult> resList = new ArrayList<>();
|
||||||
|
@ -395,6 +404,45 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkValueSetLoad(ValidationProcessInfo info) {
|
||||||
|
int serverCount = getServerLoad(info);
|
||||||
|
// There's a trade off here: if we're going to hit the server inside the components, then
|
||||||
|
// the amount of value set collateral we send is limited, but we pay the price of hitting
|
||||||
|
// the server multiple times. If, on the other hand, we give up on that, and hit the server
|
||||||
|
// directly, we have to send value set collateral (though we cache at the higher level)
|
||||||
|
//
|
||||||
|
// the cutoff value is chosen experimentally
|
||||||
|
if (serverCount > 2) {
|
||||||
|
throw new VSCheckerException("This value set is better processed on the server for performance reasons", null, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getServerLoad(ValidationProcessInfo info) {
|
||||||
|
int serverCount = 0;
|
||||||
|
if (valueset != null) {
|
||||||
|
for (ConceptSetComponent inc : valueset.getCompose().getInclude()) {
|
||||||
|
serverCount = serverCount + checkValueSetLoad(inc, info);
|
||||||
|
}
|
||||||
|
for (ConceptSetComponent inc : valueset.getCompose().getExclude()) {
|
||||||
|
serverCount = serverCount + checkValueSetLoad(inc, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return serverCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int checkValueSetLoad(ConceptSetComponent inc, ValidationProcessInfo info) {
|
||||||
|
int serverCount = 0;
|
||||||
|
for (UriType uri : inc.getValueSet()) {
|
||||||
|
ValueSetValidator vsv = getVs(uri.getValue(), info);
|
||||||
|
serverCount += vsv.getServerLoad(info);
|
||||||
|
}
|
||||||
|
CodeSystem cs = resolveCodeSystem(inc.getSystem(), inc.getVersion());
|
||||||
|
if (cs == null || (cs.getContent() != CodeSystemContentMode.COMPLETE && cs.getContent() != CodeSystemContentMode.FRAGMENT)) {
|
||||||
|
serverCount++;
|
||||||
|
}
|
||||||
|
return serverCount;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean checkRequiredSupplements(ValidationProcessInfo info) {
|
private boolean checkRequiredSupplements(ValidationProcessInfo info) {
|
||||||
if (!requiredSupplements.isEmpty()) {
|
if (!requiredSupplements.isEmpty()) {
|
||||||
String msg= context.formatMessagePlural(requiredSupplements.size(), I18nConstants.VALUESET_SUPPLEMENT_MISSING, CommaSeparatedStringBuilder.build(requiredSupplements));
|
String msg= context.formatMessagePlural(requiredSupplements.size(), I18nConstants.VALUESET_SUPPLEMENT_MISSING, CommaSeparatedStringBuilder.build(requiredSupplements));
|
||||||
|
@ -466,7 +514,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValidationResult validateCode(String path, Coding code) throws FHIRException {
|
public ValidationResult validateCode(String path, Coding code) throws FHIRException {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("validate "+code.toString());
|
||||||
checkValueSetOptions();
|
checkValueSetOptions();
|
||||||
|
|
||||||
String warningMessage = null;
|
String warningMessage = null;
|
||||||
|
@ -798,7 +846,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
|
|
||||||
private ValidationResult findCodeInExpansion(Coding code, List<ValueSetExpansionContainsComponent> contains) {
|
private ValidationResult findCodeInExpansion(Coding code, List<ValueSetExpansionContainsComponent> contains) {
|
||||||
for (ValueSetExpansionContainsComponent containsComponent: contains) {
|
for (ValueSetExpansionContainsComponent containsComponent: contains) {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("findCodeInExpansion");
|
||||||
if (containsComponent.getSystem().equals(code.getSystem()) && containsComponent.getCode().equals(code.getCode())) {
|
if (containsComponent.getSystem().equals(code.getSystem()) && containsComponent.getCode().equals(code.getCode())) {
|
||||||
ConceptDefinitionComponent ccd = new ConceptDefinitionComponent();
|
ConceptDefinitionComponent ccd = new ConceptDefinitionComponent();
|
||||||
ccd.setCode(containsComponent.getCode());
|
ccd.setCode(containsComponent.getCode());
|
||||||
|
@ -825,7 +873,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
|
|
||||||
private boolean checkExpansion(Coding code, List<ValueSetExpansionContainsComponent> contains, VersionInfo vi) {
|
private boolean checkExpansion(Coding code, List<ValueSetExpansionContainsComponent> contains, VersionInfo vi) {
|
||||||
for (ValueSetExpansionContainsComponent containsComponent: contains) {
|
for (ValueSetExpansionContainsComponent containsComponent: contains) {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("checkExpansion: "+code.toString());
|
||||||
if (containsComponent.hasSystem() && containsComponent.hasCode() && containsComponent.getSystem().equals(code.getSystem()) && containsComponent.getCode().equals(code.getCode())) {
|
if (containsComponent.hasSystem() && containsComponent.hasCode() && containsComponent.getSystem().equals(code.getSystem()) && containsComponent.getCode().equals(code.getCode())) {
|
||||||
vi.setExpansionVersion(containsComponent.getVersion());
|
vi.setExpansionVersion(containsComponent.getVersion());
|
||||||
return true;
|
return true;
|
||||||
|
@ -882,7 +930,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ConceptDefinitionDesignationComponent ds : cc.getDesignation()) {
|
for (ConceptDefinitionDesignationComponent ds : cc.getDesignation()) {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("validateCode1 "+ds.toString());
|
||||||
if (isOkLanguage(ds.getLanguage())) {
|
if (isOkLanguage(ds.getLanguage())) {
|
||||||
b.append("'"+ds.getValue()+"' ("+ds.getLanguage()+")");
|
b.append("'"+ds.getValue()+"' ("+ds.getLanguage()+")");
|
||||||
if (code.getDisplay().equalsIgnoreCase(ds.getValue())) {
|
if (code.getDisplay().equalsIgnoreCase(ds.getValue())) {
|
||||||
|
@ -904,7 +952,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ConceptReferenceDesignationComponent ds : vs.getCc().getDesignation()) {
|
for (ConceptReferenceDesignationComponent ds : vs.getCc().getDesignation()) {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("validateCode2 "+ds.toString());
|
||||||
if (isOkLanguage(ds.getLanguage())) {
|
if (isOkLanguage(ds.getLanguage())) {
|
||||||
b.append("'"+ds.getValue()+"'");
|
b.append("'"+ds.getValue()+"'");
|
||||||
if (code.getDisplay().equalsIgnoreCase(ds.getValue())) {
|
if (code.getDisplay().equalsIgnoreCase(ds.getValue())) {
|
||||||
|
@ -1009,7 +1057,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
return null;
|
return null;
|
||||||
// if it has an expansion
|
// if it has an expansion
|
||||||
for (ValueSetExpansionContainsComponent exp : valueset.getExpansion().getContains()) {
|
for (ValueSetExpansionContainsComponent exp : valueset.getExpansion().getContains()) {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("findValueSetRef "+exp.toString());
|
||||||
if (system.equals(exp.getSystem()) && code.equals(exp.getCode())) {
|
if (system.equals(exp.getSystem()) && code.equals(exp.getCode())) {
|
||||||
ConceptReferenceComponent cc = new ConceptReferenceComponent();
|
ConceptReferenceComponent cc = new ConceptReferenceComponent();
|
||||||
cc.setDisplay(exp.getDisplay());
|
cc.setDisplay(exp.getDisplay());
|
||||||
|
@ -1048,7 +1096,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConceptDefinitionComponent findCodeInConcept(ConceptDefinitionComponent concept, String code, boolean caseSensitive, AlternateCodesProcessingRules altCodeRules) {
|
private ConceptDefinitionComponent findCodeInConcept(ConceptDefinitionComponent concept, String code, boolean caseSensitive, AlternateCodesProcessingRules altCodeRules) {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("findCodeInConcept: "+code.toString()+", "+concept.toString());
|
||||||
if (code.equals(concept.getCode())) {
|
if (code.equals(concept.getCode())) {
|
||||||
return concept;
|
return concept;
|
||||||
}
|
}
|
||||||
|
@ -1121,7 +1169,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (ConceptSetComponent vsi : valueset.getCompose().getInclude()) {
|
for (ConceptSetComponent vsi : valueset.getCompose().getInclude()) {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("scanForCodeInValueSet: "+code.toString());
|
||||||
if (scanForCodeInValueSetInclude(code, sys, problems, i, vsi)) {
|
if (scanForCodeInValueSetInclude(code, sys, problems, i, vsi)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1241,7 +1289,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
*/
|
*/
|
||||||
private boolean checkSystems(List<ValueSetExpansionContainsComponent> contains, String code, Set<String> systems, List<StringWithCode> problems) {
|
private boolean checkSystems(List<ValueSetExpansionContainsComponent> contains, String code, Set<String> systems, List<StringWithCode> problems) {
|
||||||
for (ValueSetExpansionContainsComponent c: contains) {
|
for (ValueSetExpansionContainsComponent c: contains) {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("checkSystems "+code.toString());
|
||||||
if (c.getCode().equals(code)) {
|
if (c.getCode().equals(code)) {
|
||||||
systems.add(c.getSystem());
|
systems.add(c.getSystem());
|
||||||
}
|
}
|
||||||
|
@ -1255,7 +1303,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
if (valueset == null) {
|
if (valueset == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("codeInValueSet: "+system+"#"+code);
|
||||||
checkCanonical(info.getIssues(), path, valueset, valueset);
|
checkCanonical(info.getIssues(), path, valueset, valueset);
|
||||||
Boolean result = false;
|
Boolean result = false;
|
||||||
VersionInfo vi = new VersionInfo(this);
|
VersionInfo vi = new VersionInfo(this);
|
||||||
|
@ -1290,7 +1338,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Boolean inComponent(String path, ConceptSetComponent vsi, int vsiIndex, String system, String version, String code, boolean only, ValidationProcessInfo info) throws FHIRException {
|
private Boolean inComponent(String path, ConceptSetComponent vsi, int vsiIndex, String system, String version, String code, boolean only, ValidationProcessInfo info) throws FHIRException {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("inComponent "+vsiIndex);
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
|
|
||||||
if (vsi.hasValueSet()) {
|
if (vsi.hasValueSet()) {
|
||||||
|
@ -1339,6 +1387,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
vs.setUrl(valueset.getUrl()+"--"+vsiIndex);
|
vs.setUrl(valueset.getUrl()+"--"+vsiIndex);
|
||||||
vs.setVersion(valueset.getVersion());
|
vs.setVersion(valueset.getVersion());
|
||||||
vs.getCompose().addInclude(vsi);
|
vs.getCompose().addInclude(vsi);
|
||||||
|
opContext.deadCheck("hit server "+vs.getVersionedUrl());
|
||||||
ValidationResult res = context.validateCode(options.withNoClient(), new Coding(system, code, null), vs);
|
ValidationResult res = context.validateCode(options.withNoClient(), new Coding(system, code, null), vs);
|
||||||
if (res.getErrorClass() == TerminologyServiceErrorClass.UNKNOWN || res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED || res.getErrorClass() == TerminologyServiceErrorClass.VALUESET_UNSUPPORTED) {
|
if (res.getErrorClass() == TerminologyServiceErrorClass.UNKNOWN || res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED || res.getErrorClass() == TerminologyServiceErrorClass.VALUESET_UNSUPPORTED) {
|
||||||
if (info != null && res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) {
|
if (info != null && res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) {
|
||||||
|
@ -1348,16 +1397,20 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
info.addIssue(makeIssue(IssueSeverity.WARNING, IssueType.UNKNOWN, path, msg, OpIssueCode.NotFound, null));
|
info.addIssue(makeIssue(IssueSeverity.WARNING, IssueType.UNKNOWN, path, msg, OpIssueCode.NotFound, null));
|
||||||
for (ConceptReferenceComponent cc : vsi.getConcept()) {
|
for (ConceptReferenceComponent cc : vsi.getConcept()) {
|
||||||
if (cc.getCode().equals(code)) {
|
if (cc.getCode().equals(code)) {
|
||||||
|
opContext.deadCheck("server true");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
info.setErr(TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED);
|
info.setErr(TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED);
|
||||||
|
opContext.deadCheck("server codesystem unsupported");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
opContext.deadCheck("server not found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (res.getErrorClass() == TerminologyServiceErrorClass.NOSERVICE) {
|
if (res.getErrorClass() == TerminologyServiceErrorClass.NOSERVICE) {
|
||||||
|
opContext.deadCheck("server no server");
|
||||||
throw new NoTerminologyServiceException();
|
throw new NoTerminologyServiceException();
|
||||||
}
|
}
|
||||||
return res.isOk();
|
return res.isOk();
|
||||||
|
@ -1538,7 +1591,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean validateCodeInConceptList(String code, CodeSystem def, List<ConceptDefinitionComponent> list, AlternateCodesProcessingRules altCodeRules) {
|
public boolean validateCodeInConceptList(String code, CodeSystem def, List<ConceptDefinitionComponent> list, AlternateCodesProcessingRules altCodeRules) {
|
||||||
opContext.deadCheck();
|
opContext.deadCheck("validateCodeInConceptList");
|
||||||
if (def.hasUserData("tx.cs.special")) {
|
if (def.hasUserData("tx.cs.special")) {
|
||||||
return ((SpecialCodeSystem) def.getUserData("tx.cs.special")).findConcept(new Coding().setCode(code)) != null;
|
return ((SpecialCodeSystem) def.getUserData("tx.cs.special")).findConcept(new Coding().setCode(code)) != null;
|
||||||
} else if (def.getCaseSensitive()) {
|
} else if (def.getCaseSensitive()) {
|
||||||
|
@ -1580,7 +1633,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
inner.put(url, vsc);
|
inner.put(url, vsc);
|
||||||
return vsc;
|
return vsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Boolean inImport(String path, String uri, String system, String version, String code, ValidationProcessInfo info) throws FHIRException {
|
private Boolean inImport(String path, String uri, String system, String version, String code, ValidationProcessInfo info) throws FHIRException {
|
||||||
ValueSetValidator vs = getVs(uri, info);
|
ValueSetValidator vs = getVs(uri, info);
|
||||||
if (vs == null) {
|
if (vs == null) {
|
||||||
|
|
|
@ -36,6 +36,10 @@ public class PackageHackerR5 {
|
||||||
r.hack("http://terminology.hl7.org/CodeSystem/v2-0360-2.3.1", "2.3.1");
|
r.hack("http://terminology.hl7.org/CodeSystem/v2-0360-2.3.1", "2.3.1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ("http://hl7.org/fhir/ValueSet/languages".equals(r.getUrl())) {
|
||||||
|
r.getResource().setExperimental(false);
|
||||||
|
}
|
||||||
|
|
||||||
if ("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor".equals(r.getUrl()) && "4.0.1".equals(r.getVersion())) {
|
if ("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor".equals(r.getUrl()) && "4.0.1".equals(r.getVersion())) {
|
||||||
StructureDefinition sd = (StructureDefinition) r.getResource();
|
StructureDefinition sd = (StructureDefinition) r.getResource();
|
||||||
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||||
|
|
|
@ -59,7 +59,8 @@ public class FhirLoggingInterceptor implements Interceptor {
|
||||||
headerMap.keySet().forEach(key -> headerMap.get(key).forEach(value -> headerList.add(key + ":" + value)));
|
headerMap.keySet().forEach(key -> headerMap.get(key).forEach(value -> headerList.add(key + ":" + value)));
|
||||||
|
|
||||||
if (logger != null) {
|
if (logger != null) {
|
||||||
logger.logResponse(Integer.toString(response.code()), headerList, bodyBytes);
|
long responseTimeInMillis = response.receivedResponseAtMillis() - response.sentRequestAtMillis();
|
||||||
|
logger.logResponse(Integer.toString(response.code()), headerList, bodyBytes, responseTimeInMillis);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reading byte[] clears body. Need to recreate.
|
// Reading byte[] clears body. Need to recreate.
|
||||||
|
|
|
@ -44,6 +44,8 @@ import org.w3c.dom.events.MutationEvent;
|
||||||
import org.xml.sax.Attributes;
|
import org.xml.sax.Attributes;
|
||||||
import org.xml.sax.Locator;
|
import org.xml.sax.Locator;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.SAXNotRecognizedException;
|
||||||
|
import org.xml.sax.SAXNotSupportedException;
|
||||||
import org.xml.sax.XMLReader;
|
import org.xml.sax.XMLReader;
|
||||||
import org.xml.sax.helpers.LocatorImpl;
|
import org.xml.sax.helpers.LocatorImpl;
|
||||||
import org.xml.sax.helpers.XMLFilterImpl;
|
import org.xml.sax.helpers.XMLFilterImpl;
|
||||||
|
@ -71,6 +73,22 @@ public class XmlLocationAnnotator extends XMLFilterImpl {
|
||||||
((EventTarget) dom).addEventListener("DOMNodeInserted", modListener, true);
|
((EventTarget) dom).addEventListener("DOMNodeInserted", modListener, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||||
|
if (!name.equals("http://javax.xml.XMLConstants/property/accessExternalDTD")) {
|
||||||
|
super.setProperty(name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||||
|
if (!name.equals("http://javax.xml.XMLConstants/property/accessExternalDTD")) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return super.getProperty(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDocumentLocator(Locator locator) {
|
public void setDocumentLocator(Locator locator) {
|
||||||
super.setDocumentLocator(locator);
|
super.setDocumentLocator(locator);
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.hl7.fhir.r5.utils.validation.IResourceValidator;
|
||||||
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier;
|
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier;
|
||||||
import org.hl7.fhir.utilities.FhirPublication;
|
import org.hl7.fhir.utilities.FhirPublication;
|
||||||
import org.hl7.fhir.utilities.ToolingClientLogger;
|
import org.hl7.fhir.utilities.ToolingClientLogger;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.npm.BasePackageCacheManager;
|
import org.hl7.fhir.utilities.npm.BasePackageCacheManager;
|
||||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
|
@ -341,6 +342,7 @@ public class BaseWorkerContextTests {
|
||||||
public void testValidateCodingWithValueSetChecker() throws IOException {
|
public void testValidateCodingWithValueSetChecker() throws IOException {
|
||||||
ValidationOptions validationOptions = new ValidationOptions(FhirPublication.R5).withGuessSystem().withVersionFlexible(false);
|
ValidationOptions validationOptions = new ValidationOptions(FhirPublication.R5).withGuessSystem().withVersionFlexible(false);
|
||||||
ValueSet valueSet = new ValueSet();
|
ValueSet valueSet = new ValueSet();
|
||||||
|
valueSet.setUrl(Utilities.makeUuidUrn());
|
||||||
Coding coding = new Coding();
|
Coding coding = new Coding();
|
||||||
|
|
||||||
Mockito.doReturn(cacheToken).when(terminologyCache).generateValidationToken(validationOptions, coding, valueSet, expParameters);
|
Mockito.doReturn(cacheToken).when(terminologyCache).generateValidationToken(validationOptions, coding, valueSet, expParameters);
|
||||||
|
|
|
@ -172,6 +172,6 @@ class ClientTest {
|
||||||
Mockito.verify(mockLogger, Mockito.times(1))
|
Mockito.verify(mockLogger, Mockito.times(1))
|
||||||
.logRequest(Mockito.anyString(), Mockito.anyString(), Mockito.anyList(), Mockito.any());
|
.logRequest(Mockito.anyString(), Mockito.anyString(), Mockito.anyList(), Mockito.any());
|
||||||
Mockito.verify(mockLogger, Mockito.times(1))
|
Mockito.verify(mockLogger, Mockito.times(1))
|
||||||
.logResponse(Mockito.anyString(), Mockito.anyList(), Mockito.any());
|
.logResponse(Mockito.anyString(), Mockito.anyList(), Mockito.any(), Mockito.anyLong());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>6.3.26-SNAPSHOT</version>
|
<version>6.3.30-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>6.3.26-SNAPSHOT</version>
|
<version>6.3.30-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ import java.util.List;
|
||||||
public interface ToolingClientLogger {
|
public interface ToolingClientLogger {
|
||||||
|
|
||||||
void logRequest(String method, String url, List<String> headers, byte[] body);
|
void logRequest(String method, String url, List<String> headers, byte[] body);
|
||||||
void logResponse(String outcome, List<String> headers, byte[] body);
|
void logResponse(String outcome, List<String> headers, byte[] body, long length);
|
||||||
String getLastId();
|
String getLastId();
|
||||||
void clearLastId();
|
void clearLastId();
|
||||||
|
|
||||||
|
|
|
@ -64,9 +64,9 @@ public class ManagedWebAccess {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum WebAccessPolicy {
|
public enum WebAccessPolicy {
|
||||||
DIRECT, // open access to the local file system, though access can be restricted only to files under the paths in AllowedPaths
|
DIRECT, // open access to the web, though access can be restricted only to domains in AllowedDomains
|
||||||
MANAGED, // no access except by the FileSystemProxyProvider
|
MANAGED, // no access except by the IWebAccessor
|
||||||
PROHIBITED, // no access at all to File() services
|
PROHIBITED, // no access at all to the web
|
||||||
}
|
}
|
||||||
|
|
||||||
private static WebAccessPolicy accessPolicy = WebAccessPolicy.DIRECT; // for legacy reasons
|
private static WebAccessPolicy accessPolicy = WebAccessPolicy.DIRECT; // for legacy reasons
|
||||||
|
|
|
@ -125,7 +125,7 @@ public abstract class I18nBase {
|
||||||
if (Objects.nonNull(theMessageArguments) && theMessageArguments.length > 0) {
|
if (Objects.nonNull(theMessageArguments) && theMessageArguments.length > 0) {
|
||||||
message = MessageFormat.format(messages.getString(theMessage).trim(), theMessageArguments);
|
message = MessageFormat.format(messages.getString(theMessage).trim(), theMessageArguments);
|
||||||
} else {
|
} else {
|
||||||
message = MessageFormat.format(messages.getString(theMessage).trim(), null);
|
message = MessageFormat.format(messages.getString(theMessage).trim(), (Object) null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return message;
|
return message;
|
||||||
|
|
|
@ -18,7 +18,9 @@ public class I18nConstants {
|
||||||
public static final String BAD_FILE_PATH_ERROR = "Bad_file_path_error";
|
public static final String BAD_FILE_PATH_ERROR = "Bad_file_path_error";
|
||||||
public static final String BASE_PROFILE__HAS_NO_TYPE = "Base_profile__has_no_type";
|
public static final String BASE_PROFILE__HAS_NO_TYPE = "Base_profile__has_no_type";
|
||||||
public static final String BASE__DERIVED_PROFILES_HAVE_DIFFERENT_TYPES____VS___ = "Base__Derived_profiles_have_different_types____vs___";
|
public static final String BASE__DERIVED_PROFILES_HAVE_DIFFERENT_TYPES____VS___ = "Base__Derived_profiles_have_different_types____vs___";
|
||||||
public static final String BINDING_ADDITIONAL = "BINDING_ADDITIONAL";
|
public static final String BINDING_ADDITIONAL_D = "BINDING_ADDITIONAL_D";
|
||||||
|
public static final String BINDING_ADDITIONAL_UC = "BINDING_ADDITIONAL_UC";
|
||||||
|
public static final String BINDING_ADDITIONAL_USAGE = "BINDING_ADDITIONAL_USAGE";
|
||||||
public static final String BINDING_MAX = "BINDING_MAX";
|
public static final String BINDING_MAX = "BINDING_MAX";
|
||||||
public static final String BUNDLE_BUNDLE_ENTRY_CANONICAL = "Bundle_BUNDLE_Entry_Canonical";
|
public static final String BUNDLE_BUNDLE_ENTRY_CANONICAL = "Bundle_BUNDLE_Entry_Canonical";
|
||||||
public static final String BUNDLE_BUNDLE_ENTRY_DOCUMENT = "Bundle_BUNDLE_Entry_Document";
|
public static final String BUNDLE_BUNDLE_ENTRY_DOCUMENT = "Bundle_BUNDLE_Entry_Document";
|
||||||
|
@ -1108,4 +1110,10 @@ public class I18nConstants {
|
||||||
public static final String SM_TARGET_TYPE_UNKNOWN = "SM_TARGET_TYPE_UNKNOWN";
|
public static final String SM_TARGET_TYPE_UNKNOWN = "SM_TARGET_TYPE_UNKNOWN";
|
||||||
public static final String XHTML_XHTML_ATTRIBUTE_XML_SPACE = "XHTML_XHTML_ATTRIBUTE_XML_SPACE";
|
public static final String XHTML_XHTML_ATTRIBUTE_XML_SPACE = "XHTML_XHTML_ATTRIBUTE_XML_SPACE";
|
||||||
public static final String VALIDATION_HL7_PUBLISHER_MULTIPLE_WGS = "VALIDATION_HL7_PUBLISHER_MULTIPLE_WGS";
|
public static final String VALIDATION_HL7_PUBLISHER_MULTIPLE_WGS = "VALIDATION_HL7_PUBLISHER_MULTIPLE_WGS";
|
||||||
|
public static final String SD_BASE_EXPERIMENTAL = "SD_BASE_EXPERIMENTAL";
|
||||||
|
public static final String SD_ED_EXPERIMENTAL_BINDING = "SD_ED_EXPERIMENTAL_BINDING";
|
||||||
|
public static final String VALIDATION_NO_EXPERIMENTAL_CONTENT = "VALIDATION_NO_EXPERIMENTAL_CONTENT";
|
||||||
|
public static final String SD_ED_ADDITIONAL_BINDING_USAGE_UNKNOWN = "SD_ED_ADDITIONAL_BINDING_USAGE_UNKNOWN";
|
||||||
|
public static final String SD_ED_ADDITIONAL_BINDING_USAGE_INVALID_ELEMENT = "SD_ED_ADDITIONAL_BINDING_USAGE_INVALID_ELEMENT";
|
||||||
|
public static final String SD_ED_ADDITIONAL_BINDING_USAGE_INVALID_TYPE = "SD_ED_ADDITIONAL_BINDING_USAGE_INVALID_TYPE";
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,6 +214,7 @@ public class RenderingI18nContext extends I18nBase {
|
||||||
public static final String DATA_REND_DATA = "DATA_REND_DATA";
|
public static final String DATA_REND_DATA = "DATA_REND_DATA";
|
||||||
public static final String DATA_REND_DETAILS = "DATA_REND_DETAILS";
|
public static final String DATA_REND_DETAILS = "DATA_REND_DETAILS";
|
||||||
public static final String DATA_REND_DETAILS_STATED = "DATA_REND_DETAILS_STATED";
|
public static final String DATA_REND_DETAILS_STATED = "DATA_REND_DETAILS_STATED";
|
||||||
|
public static final String DATA_REND_DETAILS_STATED_ND = "DATA_REND_DETAILS_STATED_ND";
|
||||||
public static final String DATA_REND_DICOM = "DATA_REND_DICOM";
|
public static final String DATA_REND_DICOM = "DATA_REND_DICOM";
|
||||||
public static final String DATA_REND_DIM = "DATA_REND_DIM";
|
public static final String DATA_REND_DIM = "DATA_REND_DIM";
|
||||||
public static final String DATA_REND_DURATION = "DATA_REND_DURATION";
|
public static final String DATA_REND_DURATION = "DATA_REND_DURATION";
|
||||||
|
|
|
@ -8,6 +8,7 @@ import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
@ -77,12 +78,13 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
||||||
|
|
||||||
private final FilesystemPackageCacheManagerLocks locks;
|
private final FilesystemPackageCacheManagerLocks locks;
|
||||||
|
|
||||||
|
private final FilesystemPackageCacheManagerLocks.LockParameters lockParameters;
|
||||||
|
|
||||||
// When running in testing mode, some packages are provided from the test case repository rather than by the normal means
|
// When running in testing mode, some packages are provided from the test case repository rather than by the normal means
|
||||||
// the PackageProvider is responsible for this. if no package provider is defined, or it declines to handle the package,
|
// the PackageProvider is responsible for this. if no package provider is defined, or it declines to handle the package,
|
||||||
// then the normal means will be used
|
// then the normal means will be used
|
||||||
public interface IPackageProvider {
|
public interface IPackageProvider {
|
||||||
boolean handlesPackage(String id, String version);
|
boolean handlesPackage(String id, String version);
|
||||||
|
|
||||||
InputStreamWithSrc provide(String id, String version) throws IOException;
|
InputStreamWithSrc provide(String id, String version) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +94,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
||||||
public static final String PACKAGE_VERSION_REGEX_OPT = "^[A-Za-z][A-Za-z0-9\\_\\-]*(\\.[A-Za-z0-9\\_\\-]+)+(\\#[A-Za-z0-9\\-\\_]+(\\.[A-Za-z0-9\\-\\_]+)*)?$";
|
public static final String PACKAGE_VERSION_REGEX_OPT = "^[A-Za-z][A-Za-z0-9\\_\\-]*(\\.[A-Za-z0-9\\_\\-]+)+(\\#[A-Za-z0-9\\-\\_]+(\\.[A-Za-z0-9\\-\\_]+)*)?$";
|
||||||
private static final Logger ourLog = LoggerFactory.getLogger(FilesystemPackageCacheManager.class);
|
private static final Logger ourLog = LoggerFactory.getLogger(FilesystemPackageCacheManager.class);
|
||||||
private static final String CACHE_VERSION = "3"; // second version - see wiki page
|
private static final String CACHE_VERSION = "3"; // second version - see wiki page
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private final File cacheFolder;
|
private final File cacheFolder;
|
||||||
|
|
||||||
|
@ -100,6 +103,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
||||||
private final Map<String, String> ciList = new HashMap<>();
|
private final Map<String, String> ciList = new HashMap<>();
|
||||||
private JsonArray buildInfo;
|
private JsonArray buildInfo;
|
||||||
private boolean suppressErrors;
|
private boolean suppressErrors;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
@Getter
|
@Getter
|
||||||
private boolean minimalMemory;
|
private boolean minimalMemory;
|
||||||
|
@ -113,9 +117,20 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
||||||
@Getter
|
@Getter
|
||||||
private final List<PackageServer> packageServers;
|
private final List<PackageServer> packageServers;
|
||||||
|
|
||||||
|
@With
|
||||||
|
@Getter
|
||||||
|
private final FilesystemPackageCacheManagerLocks.LockParameters lockParameters;
|
||||||
|
|
||||||
public Builder() throws IOException {
|
public Builder() throws IOException {
|
||||||
this.cacheFolder = getUserCacheFolder();
|
this.cacheFolder = getUserCacheFolder();
|
||||||
this.packageServers = getPackageServersFromFHIRSettings();
|
this.packageServers = getPackageServersFromFHIRSettings();
|
||||||
|
this.lockParameters = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder(File cacheFolder, List<PackageServer> packageServers, FilesystemPackageCacheManagerLocks.LockParameters lockParameters) {
|
||||||
|
this.cacheFolder = cacheFolder;
|
||||||
|
this.packageServers = packageServers;
|
||||||
|
this.lockParameters = lockParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
private File getUserCacheFolder() throws IOException {
|
private File getUserCacheFolder() throws IOException {
|
||||||
|
@ -143,17 +158,12 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
||||||
return PackageServer.getConfiguredServers();
|
return PackageServer.getConfiguredServers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Builder(File cacheFolder, List<PackageServer> packageServers) {
|
|
||||||
this.cacheFolder = cacheFolder;
|
|
||||||
this.packageServers = packageServers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder withCacheFolder(String cacheFolderPath) throws IOException {
|
public Builder withCacheFolder(String cacheFolderPath) throws IOException {
|
||||||
File cacheFolder = ManagedFileAccess.file(cacheFolderPath);
|
File cacheFolder = ManagedFileAccess.file(cacheFolderPath);
|
||||||
if (!cacheFolder.exists()) {
|
if (!cacheFolder.exists()) {
|
||||||
throw new FHIRException("The folder '" + cacheFolder + "' could not be found");
|
throw new FHIRException("The folder '" + cacheFolder + "' could not be found");
|
||||||
}
|
}
|
||||||
return new Builder(cacheFolder, this.packageServers);
|
return new Builder(cacheFolder, this.packageServers, this.lockParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder withSystemCacheFolder() throws IOException {
|
public Builder withSystemCacheFolder() throws IOException {
|
||||||
|
@ -163,32 +173,33 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
||||||
} else {
|
} else {
|
||||||
systemCacheFolder = ManagedFileAccess.file(Utilities.path("/var", "lib", ".fhir", "packages"));
|
systemCacheFolder = ManagedFileAccess.file(Utilities.path("/var", "lib", ".fhir", "packages"));
|
||||||
}
|
}
|
||||||
return new Builder(systemCacheFolder, this.packageServers);
|
return new Builder(systemCacheFolder, this.packageServers, this.lockParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder withTestingCacheFolder() throws IOException {
|
public Builder withTestingCacheFolder() throws IOException {
|
||||||
return new Builder(ManagedFileAccess.file(Utilities.path("[tmp]", ".fhir", "packages")), this.packageServers);
|
return new Builder(ManagedFileAccess.file(Utilities.path("[tmp]", ".fhir", "packages")), this.packageServers, this.lockParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FilesystemPackageCacheManager build() throws IOException {
|
public FilesystemPackageCacheManager build() throws IOException {
|
||||||
return new FilesystemPackageCacheManager(cacheFolder, packageServers);
|
final FilesystemPackageCacheManagerLocks locks;
|
||||||
|
try {
|
||||||
|
locks = FilesystemPackageCacheManagerLocks.getFilesystemPackageCacheManagerLocks(cacheFolder);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
if (e.getCause() instanceof IOException) {
|
||||||
|
throw (IOException) e.getCause();
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new FilesystemPackageCacheManager(cacheFolder, packageServers, locks, lockParameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private FilesystemPackageCacheManager(@Nonnull File cacheFolder, @Nonnull List<PackageServer> packageServers) throws IOException {
|
private FilesystemPackageCacheManager(@Nonnull File cacheFolder, @Nonnull List<PackageServer> packageServers, @Nonnull FilesystemPackageCacheManagerLocks locks, @Nullable FilesystemPackageCacheManagerLocks.LockParameters lockParameters) throws IOException {
|
||||||
super(packageServers);
|
super(packageServers);
|
||||||
this.cacheFolder = cacheFolder;
|
this.cacheFolder = cacheFolder;
|
||||||
|
this.locks = locks;
|
||||||
try {
|
this.lockParameters = lockParameters;
|
||||||
this.locks = FilesystemPackageCacheManagerLocks.getFilesystemPackageCacheManagerLocks(cacheFolder);
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
if (e.getCause() instanceof IOException) {
|
|
||||||
throw (IOException) e.getCause();
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prepareCacheFolder();
|
prepareCacheFolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,11 +229,35 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
||||||
createIniFile();
|
createIniFile();
|
||||||
}
|
}
|
||||||
deleteOldTempDirectories();
|
deleteOldTempDirectories();
|
||||||
|
cleanUpCorruptPackages();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Look for .lock files that are not actively held by a process. If found, delete the lock file, and the package
|
||||||
|
referenced.
|
||||||
|
*/
|
||||||
|
protected void cleanUpCorruptPackages() throws IOException {
|
||||||
|
for (File file : Objects.requireNonNull(cacheFolder.listFiles())) {
|
||||||
|
if (file.getName().endsWith(".lock")) {
|
||||||
|
if (locks.getCacheLock().canLockFileBeHeldByThisProcess(file)) {
|
||||||
|
String packageDirectoryName = file.getName().substring(0, file.getName().length() - 5);
|
||||||
|
log("Detected potential incomplete package installed in cache: " + packageDirectoryName + ". Attempting to delete");
|
||||||
|
|
||||||
|
File packageDirectory = ManagedFileAccess.file(Utilities.path(cacheFolder, packageDirectoryName));
|
||||||
|
if (packageDirectory.exists()) {
|
||||||
|
Utilities.clearDirectory(packageDirectory.getAbsolutePath());
|
||||||
|
packageDirectory.delete();
|
||||||
|
}
|
||||||
|
file.delete();
|
||||||
|
log("Deleted potential incomplete package: " + packageDirectoryName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean iniFileExists() throws IOException {
|
private boolean iniFileExists() throws IOException {
|
||||||
String iniPath = getPackagesIniPath();
|
String iniPath = getPackagesIniPath();
|
||||||
File iniFile = ManagedFileAccess.file(iniPath);
|
File iniFile = ManagedFileAccess.file(iniPath);
|
||||||
|
@ -421,7 +456,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
});
|
}, lockParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -465,7 +500,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return loadPackageInfo(path);
|
return loadPackageInfo(path);
|
||||||
});
|
}, lockParameters);
|
||||||
if (foundPackage != null) {
|
if (foundPackage != null) {
|
||||||
if (foundPackage.isIndexed()){
|
if (foundPackage.isIndexed()){
|
||||||
return foundPackage;
|
return foundPackage;
|
||||||
|
@ -488,7 +523,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
||||||
String path = Utilities.path(cacheFolder, foundPackageFolder);
|
String path = Utilities.path(cacheFolder, foundPackageFolder);
|
||||||
output.checkIndexed(path);
|
output.checkIndexed(path);
|
||||||
return output;
|
return output;
|
||||||
});
|
}, lockParameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -589,7 +624,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
return npmPackage;
|
return npmPackage;
|
||||||
});
|
}, lockParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void log(String s) {
|
private void log(String s) {
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
package org.hl7.fhir.utilities.npm;
|
package org.hl7.fhir.utilities.npm;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.hl7.fhir.utilities.TextFile;
|
import lombok.With;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
import java.nio.channels.FileLock;
|
import java.nio.channels.FileLock;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -27,9 +32,23 @@ public class FilesystemPackageCacheManagerLocks {
|
||||||
|
|
||||||
private final File cacheFolder;
|
private final File cacheFolder;
|
||||||
|
|
||||||
private final Long lockTimeoutTime;
|
private static final LockParameters lockParameters = new LockParameters();
|
||||||
|
|
||||||
private final TimeUnit lockTimeoutTimeUnit;
|
public static class LockParameters {
|
||||||
|
@Getter @With
|
||||||
|
private final long lockTimeoutTime;
|
||||||
|
@Getter @With
|
||||||
|
private final TimeUnit lockTimeoutTimeUnit;
|
||||||
|
|
||||||
|
public LockParameters() {
|
||||||
|
this(60L, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockParameters(long lockTimeoutTime, TimeUnit lockTimeoutTimeUnit) {
|
||||||
|
this.lockTimeoutTime = lockTimeoutTime;
|
||||||
|
this.lockTimeoutTimeUnit = lockTimeoutTimeUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is intended to be used only for testing purposes.
|
* This method is intended to be used only for testing purposes.
|
||||||
|
@ -43,21 +62,9 @@ public class FilesystemPackageCacheManagerLocks {
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public FilesystemPackageCacheManagerLocks(File cacheFolder) throws IOException {
|
public FilesystemPackageCacheManagerLocks(File cacheFolder) throws IOException {
|
||||||
this(cacheFolder, 60L, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
private FilesystemPackageCacheManagerLocks(File cacheFolder, Long lockTimeoutTime, TimeUnit lockTimeoutTimeUnit) throws IOException {
|
|
||||||
this.cacheFolder = cacheFolder;
|
this.cacheFolder = cacheFolder;
|
||||||
this.lockTimeoutTime = lockTimeoutTime;
|
|
||||||
this.lockTimeoutTimeUnit = lockTimeoutTimeUnit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is intended to be used only for testing purposes.
|
|
||||||
*/
|
|
||||||
protected FilesystemPackageCacheManagerLocks withLockTimeout(Long lockTimeoutTime, TimeUnit lockTimeoutTimeUnit) throws IOException {
|
|
||||||
return new FilesystemPackageCacheManagerLocks(cacheFolder, lockTimeoutTime, lockTimeoutTimeUnit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a single FilesystemPackageCacheManagerLocks instance for the given cacheFolder.
|
* Returns a single FilesystemPackageCacheManagerLocks instance for the given cacheFolder.
|
||||||
|
@ -102,6 +109,19 @@ public class FilesystemPackageCacheManagerLocks {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean canLockFileBeHeldByThisProcess(File lockFile) throws IOException {
|
||||||
|
return doWriteWithLock(() -> {
|
||||||
|
try (FileChannel channel = new RandomAccessFile(lockFile, "rw").getChannel()) {
|
||||||
|
FileLock fileLock = channel.tryLock(0, Long.MAX_VALUE, false);
|
||||||
|
if (fileLock != null) {
|
||||||
|
fileLock.release();
|
||||||
|
channel.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PackageLock {
|
public class PackageLock {
|
||||||
|
@ -114,15 +134,43 @@ public class FilesystemPackageCacheManagerLocks {
|
||||||
this.lock = lock;
|
this.lock = lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkForLockFileWaitForDeleteIfExists(File lockFile) throws IOException {
|
private void checkForLockFileWaitForDeleteIfExists(File lockFile, @Nonnull LockParameters lockParameters) throws IOException {
|
||||||
if (!lockFile.exists()) {
|
if (!lockFile.exists()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the file is locked by a process. If it is not, it is likely an incomplete package cache install, and
|
||||||
|
// we should throw an exception.
|
||||||
|
if (lockFile.isFile()) {
|
||||||
|
try (FileChannel channel = new RandomAccessFile(lockFile, "rw").getChannel()) {
|
||||||
|
FileLock fileLock = channel.tryLock(0, Long.MAX_VALUE, false);
|
||||||
|
if (fileLock != null) {
|
||||||
|
fileLock.release();
|
||||||
|
channel.close();
|
||||||
|
throw new IOException("Lock file exists, but is not locked by a process: " + lockFile.getName());
|
||||||
|
}
|
||||||
|
System.out.println("File is locked.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
waitForLockFileDeletion(lockFile, lockParameters);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw new IOException("Thread interrupted while waiting for lock", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Wait for the lock file to be deleted. If the lock file is not deleted within the timeout or if the thread is
|
||||||
|
interrupted, an IOException is thrown.
|
||||||
|
*/
|
||||||
|
private void waitForLockFileDeletion(File lockFile, @Nonnull LockParameters lockParameters) throws IOException, InterruptedException {
|
||||||
|
|
||||||
try (WatchService watchService = FileSystems.getDefault().newWatchService()) {
|
try (WatchService watchService = FileSystems.getDefault().newWatchService()) {
|
||||||
Path dir = lockFile.getParentFile().toPath();
|
Path dir = lockFile.getParentFile().toPath();
|
||||||
dir.register(watchService, StandardWatchEventKinds.ENTRY_DELETE);
|
dir.register(watchService, StandardWatchEventKinds.ENTRY_DELETE);
|
||||||
|
|
||||||
WatchKey key = watchService.poll(lockTimeoutTime, lockTimeoutTimeUnit);
|
WatchKey key = watchService.poll(lockParameters.lockTimeoutTime, lockParameters.lockTimeoutTimeUnit);
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
// It is possible that the lock file is deleted before the watch service is registered, so if we timeout at
|
// It is possible that the lock file is deleted before the watch service is registered, so if we timeout at
|
||||||
// this point, we should check if the lock file still exists.
|
// this point, we should check if the lock file still exists.
|
||||||
|
@ -141,24 +189,33 @@ public class FilesystemPackageCacheManagerLocks {
|
||||||
key.reset();
|
key.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
throw new IOException("Error reading package.", e);
|
|
||||||
} catch (TimeoutException e) {
|
} catch (TimeoutException e) {
|
||||||
throw new IOException("Error reading package.", e);
|
throw new IOException("Package cache timed out waiting for lock.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public <T> T doReadWithLock(FilesystemPackageCacheManager.CacheLockFunction<T> f) throws IOException {
|
/**
|
||||||
|
* Wraps the execution of a package read function with the appropriate cache, package, and .lock file locking and
|
||||||
|
* checks.
|
||||||
|
*
|
||||||
|
* @param function The function to execute
|
||||||
|
* @param lockParameters The parameters for the lock
|
||||||
|
* @return The return of the function
|
||||||
|
* @param <T> The return type of the function
|
||||||
|
* @throws IOException If an error occurs while managing locking.
|
||||||
|
*/
|
||||||
|
public <T> T doReadWithLock(FilesystemPackageCacheManager.CacheLockFunction<T> function, @Nullable LockParameters lockParameters) throws IOException {
|
||||||
|
final LockParameters resolvedLockParameters = lockParameters != null ? lockParameters : FilesystemPackageCacheManagerLocks.lockParameters;
|
||||||
|
|
||||||
cacheLock.getLock().readLock().lock();
|
cacheLock.getLock().readLock().lock();
|
||||||
lock.readLock().lock();
|
lock.readLock().lock();
|
||||||
|
|
||||||
checkForLockFileWaitForDeleteIfExists(lockFile);
|
checkForLockFileWaitForDeleteIfExists(lockFile, resolvedLockParameters);
|
||||||
|
|
||||||
T result = null;
|
T result = null;
|
||||||
try {
|
try {
|
||||||
result = f.get();
|
result = function.get();
|
||||||
} finally {
|
} finally {
|
||||||
lock.readLock().unlock();
|
lock.readLock().unlock();
|
||||||
cacheLock.getLock().readLock().unlock();
|
cacheLock.getLock().readLock().unlock();
|
||||||
|
@ -166,35 +223,55 @@ public class FilesystemPackageCacheManagerLocks {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T doWriteWithLock(FilesystemPackageCacheManager.CacheLockFunction<T> f) throws IOException {
|
/**
|
||||||
|
* Wraps the execution of a package write function with the appropriate cache, package, and .lock file locking and
|
||||||
|
* checks.
|
||||||
|
*
|
||||||
|
* @param function The function to execute
|
||||||
|
* @param lockParameters The parameters for the lock
|
||||||
|
* @return The return of the function
|
||||||
|
* @param <T> The return type of the function
|
||||||
|
* @throws IOException If an error occurs while managing locking.
|
||||||
|
*/
|
||||||
|
public <T> T doWriteWithLock(FilesystemPackageCacheManager.CacheLockFunction<T> function, @Nullable LockParameters lockParameters) throws IOException {
|
||||||
|
final LockParameters resolvedLockParameters = lockParameters != null ? lockParameters : FilesystemPackageCacheManagerLocks.lockParameters;
|
||||||
|
|
||||||
cacheLock.getLock().writeLock().lock();
|
cacheLock.getLock().writeLock().lock();
|
||||||
lock.writeLock().lock();
|
lock.writeLock().lock();
|
||||||
|
|
||||||
if (!lockFile.isFile()) {
|
/*TODO Eventually, this logic should exist in a Lockfile class so that it isn't duplicated between the main code and
|
||||||
try {
|
the test code.
|
||||||
TextFile.stringToFile("", lockFile);
|
*/
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try (FileChannel channel = new RandomAccessFile(lockFile, "rw").getChannel()) {
|
try (FileChannel channel = new RandomAccessFile(lockFile, "rw").getChannel()) {
|
||||||
FileLock fileLock = null;
|
|
||||||
while (fileLock == null) {
|
FileLock fileLock = channel.tryLock(0, Long.MAX_VALUE, false);
|
||||||
fileLock = channel.tryLock(0, Long.MAX_VALUE, true);
|
|
||||||
if (fileLock == null) {
|
if (fileLock == null) {
|
||||||
Thread.sleep(100); // Wait and retry
|
waitForLockFileDeletion(lockFile, resolvedLockParameters);
|
||||||
}
|
fileLock = channel.tryLock(0, Long.MAX_VALUE, false);
|
||||||
|
}
|
||||||
|
if (fileLock == null) {
|
||||||
|
throw new IOException("Failed to acquire lock on file: " + lockFile.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lockFile.isFile()) {
|
||||||
|
final ByteBuffer buff = ByteBuffer.wrap(String.valueOf(ProcessHandle.current().pid()).getBytes(StandardCharsets.UTF_8));
|
||||||
|
channel.write(buff);
|
||||||
}
|
}
|
||||||
T result = null;
|
T result = null;
|
||||||
try {
|
try {
|
||||||
result = f.get();
|
result = function.get();
|
||||||
} finally {
|
} finally {
|
||||||
|
|
||||||
|
lockFile.renameTo(ManagedFileAccess.file(File.createTempFile(lockFile.getName(), ".lock-renamed").getAbsolutePath()));
|
||||||
|
|
||||||
fileLock.release();
|
fileLock.release();
|
||||||
channel.close();
|
channel.close();
|
||||||
|
|
||||||
if (!lockFile.delete()) {
|
if (!lockFile.delete()) {
|
||||||
lockFile.deleteOnExit();
|
lockFile.deleteOnExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
lock.writeLock().unlock();
|
lock.writeLock().unlock();
|
||||||
cacheLock.getLock().writeLock().unlock();
|
cacheLock.getLock().writeLock().unlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.hl7.fhir.utilities.TextFile;
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
import org.hl7.fhir.utilities.VersionUtilities;
|
||||||
import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
|
import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
|
||||||
import org.hl7.fhir.utilities.json.model.JsonArray;
|
import org.hl7.fhir.utilities.json.model.JsonArray;
|
||||||
import org.hl7.fhir.utilities.json.model.JsonObject;
|
import org.hl7.fhir.utilities.json.model.JsonObject;
|
||||||
|
@ -43,7 +44,44 @@ public class PackageHacker {
|
||||||
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot2/hl7.fhir.r6.search.tgz");
|
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot2/hl7.fhir.r6.search.tgz");
|
||||||
|
|
||||||
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/us/core/v311/package.tgz", "http://hl7.org/fhir/us/core/STU3.1.1");
|
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/us/core/v311/package.tgz", "http://hl7.org/fhir/us/core/STU3.1.1");
|
||||||
new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/us/core/v700/package.tgz", "http://hl7.org/fhir/us/core/STU7");
|
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/us/core/v700/package.tgz", "http://hl7.org/fhir/us/core/STU7");
|
||||||
|
|
||||||
|
PackageHacker self = new PackageHacker();
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/hl7.terminology.r4b.tgz");
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/1.0.0/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/1.0.0/hl7.terminology.r4b.tgz");
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/2.0.0/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/2.0.0/hl7.terminology.r4b.tgz");
|
||||||
|
self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/2.1.0/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/2.1.0/hl7.terminology.r4b.tgz");
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/3.0.0/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/3.0.0/hl7.terminology.r4b.tgz");
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/3.1.0/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/3.1.0/hl7.terminology.r4b.tgz");
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/4.0.0/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/4.0.0/hl7.terminology.r4b.tgz");
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/5.0.0/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/5.0.0/hl7.terminology.r4b.tgz");
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/5.1.0/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/5.1.0/hl7.terminology.r4b.tgz");
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/5.2.0/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/5.2.0/hl7.terminology.r4b.tgz");
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/5.3.0/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/5.3.0/hl7.terminology.r4b.tgz");
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/5.4.0/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/5.4.0/hl7.terminology.r4b.tgz");
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/5.5.0/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/5.5.0/hl7.terminology.r4b.tgz");
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/6.0.0/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/6.0.0/hl7.terminology.r4b.tgz");
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/6.0.1/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/6.0.1/hl7.terminology.r4b.tgz");
|
||||||
|
// self.cloneToR4B("/Users/grahamegrieve/web/terminology.hl7.org/6.0.2/hl7.terminology.r4.tgz", "/Users/grahamegrieve/web/terminology.hl7.org/6.0.2/hl7.terminology.r4b.tgz");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cloneToR4B(String src, String dst) throws IOException {
|
||||||
|
FileInputStream fs = ManagedFileAccess.inStream(src);
|
||||||
|
NpmPackage pck = NpmPackage.fromPackage(fs);
|
||||||
|
System.out.println(nice(pck.getNpm()));
|
||||||
|
JsonObject json = pck.getNpm();
|
||||||
|
String name = json.asString("name");
|
||||||
|
json.remove("name");
|
||||||
|
json.add("name", name.replace(".r4", ".r4b"));
|
||||||
|
json.remove("fhirVersions");
|
||||||
|
json.remove("dependencies");
|
||||||
|
JsonArray fv = new JsonArray();
|
||||||
|
json.add("fhirVersions", fv);
|
||||||
|
fv.add("4.3.0");
|
||||||
|
JsonObject dep = new JsonObject();
|
||||||
|
json.add("dependencies", dep);
|
||||||
|
dep.add(VersionUtilities.packageForVersion("4.3.0"), "4.3.0");
|
||||||
|
pck.save(new FileOutputStream(dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
// private void massEdit(File dir) throws IOException {
|
// private void massEdit(File dir) throws IOException {
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class CacheVerificationLogger implements ToolingClientLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void logResponse(String outcome, List<String> headers, byte[] body) {
|
public void logResponse(String outcome, List<String> headers, byte[] body, long start) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
package org.hl7.fhir.utilities.xml;
|
package org.hl7.fhir.utilities.xml;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2011+, HL7, Inc.
|
Copyright (c) 2011+, HL7, Inc.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
@ -28,80 +28,85 @@ package org.hl7.fhir.utilities.xml;
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.hl7.fhir.utilities.ElementDecoration;
|
import org.hl7.fhir.utilities.ElementDecoration;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generalize
|
* Generalize
|
||||||
* @author dennisn
|
* @author dennisn
|
||||||
*/
|
*/
|
||||||
public interface IXMLWriter {
|
public interface IXMLWriter {
|
||||||
|
|
||||||
public abstract void start() throws IOException;
|
public abstract void start() throws IOException;
|
||||||
public abstract void end() throws IOException;
|
public abstract void end() throws IOException;
|
||||||
|
|
||||||
public abstract void attribute(String namespace, String name, String value, boolean onlyIfNotEmpty) throws IOException;
|
public abstract void attribute(String namespace, String name, String value, boolean onlyIfNotEmpty) throws IOException;
|
||||||
public abstract void attribute(String namespace, String name, String value) throws IOException;
|
public abstract void attribute(String namespace, String name, String value) throws IOException;
|
||||||
public abstract void attribute(String name, String value, boolean onlyIfNotEmpty) throws IOException;
|
public abstract void attribute(String name, String value, boolean onlyIfNotEmpty) throws IOException;
|
||||||
public abstract void attribute(String name, String value) throws IOException;
|
public abstract void attribute(String name, String value) throws IOException;
|
||||||
public abstract void attributeNoLines(String name, String value) throws IOException;
|
public abstract void attributeNoLines(String name, String value) throws IOException;
|
||||||
|
|
||||||
public abstract boolean namespaceDefined(String namespace);
|
public abstract boolean namespaceDefined(String namespace);
|
||||||
public abstract boolean abbreviationDefined(String abbreviation);
|
public abstract boolean abbreviationDefined(String abbreviation);
|
||||||
public abstract String getDefaultNamespace();
|
public abstract String getDefaultNamespace();
|
||||||
public abstract void namespace(String namespace) throws IOException;
|
public abstract void namespace(String namespace) throws IOException;
|
||||||
public abstract void setDefaultNamespace(String namespace) throws IOException;
|
public abstract void setDefaultNamespace(String namespace) throws IOException;
|
||||||
public abstract void namespace(String namespace, String abbreviation) throws IOException;
|
public abstract void namespace(String namespace, String abbreviation) throws IOException;
|
||||||
|
|
||||||
public abstract void comment(String comment, boolean doPretty) throws IOException;
|
public abstract void comment(String comment, boolean doPretty) throws IOException;
|
||||||
public abstract void decorate(ElementDecoration decoration) throws IOException;
|
public abstract void decorate(ElementDecoration decoration) throws IOException;
|
||||||
public abstract void setSchemaLocation(String ns, String loc) throws IOException;
|
public abstract void setSchemaLocation(String ns, String loc) throws IOException;
|
||||||
|
|
||||||
public abstract void enter(String name) throws IOException;
|
public abstract void enter(String name) throws IOException;
|
||||||
public abstract void enter(String namespace, String name) throws IOException;
|
public abstract void enter(String namespace, String name) throws IOException;
|
||||||
public abstract void enter(String namespace, String name, String comment) throws IOException;
|
public abstract void enter(String namespace, String name, String comment) throws IOException;
|
||||||
|
|
||||||
public abstract void exit() throws IOException;
|
public abstract void exit() throws IOException;
|
||||||
public abstract void exit(String name) throws IOException;
|
public abstract void exit(String name) throws IOException;
|
||||||
public abstract void exit(String namespace, String name) throws IOException;
|
public abstract void exit(String namespace, String name) throws IOException;
|
||||||
public abstract void exitToLevel(int count) throws IOException;
|
public abstract void exitToLevel(int count) throws IOException;
|
||||||
|
|
||||||
|
|
||||||
public abstract void element(String namespace, String name, String content, boolean onlyIfNotEmpty) throws IOException;
|
public abstract void element(String namespace, String name, String content, boolean onlyIfNotEmpty) throws IOException;
|
||||||
public abstract void element(String namespace, String name, String content, String comment) throws IOException;
|
public abstract void element(String namespace, String name, String content, String comment) throws IOException;
|
||||||
public abstract void element(String namespace, String name, String content) throws IOException;
|
public abstract void element(String namespace, String name, String content) throws IOException;
|
||||||
public abstract void element(String name, String content, boolean onlyIfNotEmpty) throws IOException;
|
public abstract void element(String name, String content, boolean onlyIfNotEmpty) throws IOException;
|
||||||
public abstract void element(String name, String content) throws IOException;
|
public abstract void element(String name, String content) throws IOException;
|
||||||
public abstract void element(String name) throws IOException;
|
public abstract void element(String name) throws IOException;
|
||||||
|
|
||||||
public abstract void text(String content) throws IOException;
|
public abstract void text(String content) throws IOException;
|
||||||
public abstract void text(String content, boolean dontEscape) throws IOException;
|
public abstract void text(String content, boolean dontEscape) throws IOException;
|
||||||
|
|
||||||
public abstract void cData(String text) throws IOException;
|
public abstract void cData(String text) throws IOException;
|
||||||
|
|
||||||
public abstract void writeBytes(byte[] bytes) throws IOException;
|
public abstract void writeBytes(byte[] bytes) throws IOException;
|
||||||
|
|
||||||
public abstract boolean isPretty() throws IOException;
|
public abstract boolean isPretty() throws IOException;
|
||||||
public abstract void setPretty(boolean pretty) throws IOException;
|
public abstract void setPretty(boolean pretty) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start comment inserts a <!-- in the stream, but allows the user to
|
* Start comment inserts a <!-- in the stream, but allows the user to
|
||||||
* go on creating xml content as usual, with proper formatting applied etc.
|
* go on creating xml content as usual, with proper formatting applied etc.
|
||||||
* Any comments inserted inside a comment will be terminated with -- > instead of -->
|
* Any comments inserted inside a comment will be terminated with -- > instead of -->
|
||||||
* so the comment doesn't close prematurely.
|
* so the comment doesn't close prematurely.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public abstract void startCommentBlock() throws IOException;
|
public abstract void startCommentBlock() throws IOException;
|
||||||
public abstract void endCommentBlock() throws IOException;
|
public abstract void endCommentBlock() throws IOException;
|
||||||
public abstract void escapedText(String content) throws IOException;
|
public abstract void escapedText(String content) throws IOException;
|
||||||
|
|
||||||
// this is only implemented by an implementation that is producing an xhtml representation, and is able to render elements as hyperlinks
|
// this is only implemented by an implementation that is producing an xhtml representation, and is able to render elements as hyperlinks
|
||||||
public abstract void link(String href);
|
public abstract void link(String href);
|
||||||
public abstract void anchor(String name);
|
public abstract void anchor(String name);
|
||||||
public abstract void externalLink(String ref) throws IOException;
|
public abstract void externalLink(String ref) throws IOException;
|
||||||
|
|
||||||
|
// this is only implemented by an implementation that is producing an xhtml representation and handles ellipsing elements
|
||||||
|
public abstract boolean canElide();
|
||||||
|
public abstract void elide() throws IOException;
|
||||||
|
public abstract void attributeElide();
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,9 @@ Attempt_to_a_slice_an_element_that_does_not_repeat__from__in_ = Attempt to a sli
|
||||||
Attempt_to_replace_element_name_for_a_nonchoice_type=Attempt to replace element name for a non-choice type
|
Attempt_to_replace_element_name_for_a_nonchoice_type=Attempt to replace element name for a non-choice type
|
||||||
Attempt_to_use_Terminology_server_when_no_Terminology_server_is_available = Attempt to use Terminology server when no Terminology server is available
|
Attempt_to_use_Terminology_server_when_no_Terminology_server_is_available = Attempt to use Terminology server when no Terminology server is available
|
||||||
Attempt_to_use_a_snapshot_on_profile__as__before_it_is_generated = Attempt to use a snapshot on profile ''{0}'' as {1} before it is generated
|
Attempt_to_use_a_snapshot_on_profile__as__before_it_is_generated = Attempt to use a snapshot on profile ''{0}'' as {1} before it is generated
|
||||||
BINDING_ADDITIONAL = {0} specified in an additional binding
|
BINDING_ADDITIONAL_D = {0} specified in an additional binding
|
||||||
|
BINDING_ADDITIONAL_UC = {0} specified in an additional binding which applies because {1}
|
||||||
|
BINDING_ADDITIONAL_USAGE = {0} = {1}
|
||||||
BINDING_MAX = {0} specified in the max binding
|
BINDING_MAX = {0} specified in the max binding
|
||||||
BUNDLE_BUNDLE_ENTRY_FOUND_MULTIPLE = Found {0} matches for ''{1}'' in the bundle ({2})
|
BUNDLE_BUNDLE_ENTRY_FOUND_MULTIPLE = Found {0} matches for ''{1}'' in the bundle ({2})
|
||||||
BUNDLE_BUNDLE_ENTRY_FOUND_MULTIPLE_FRAGMENT = Found {0} matches for fragment {2} in resource ''{1}'' in the bundle ({3})
|
BUNDLE_BUNDLE_ENTRY_FOUND_MULTIPLE_FRAGMENT = Found {0} matches for fragment {2} in resource ''{1}'' in the bundle ({3})
|
||||||
|
@ -1029,7 +1031,7 @@ VALUESET_SUPPLEMENT_MISSING_one = Required supplement not found: {1}
|
||||||
VALUESET_SUPPLEMENT_MISSING_other = Required supplements not found: {1}
|
VALUESET_SUPPLEMENT_MISSING_other = Required supplements not found: {1}
|
||||||
VALUESET_TOO_COSTLY = The value set ''{0}'' expansion has too many codes to display ({1})
|
VALUESET_TOO_COSTLY = The value set ''{0}'' expansion has too many codes to display ({1})
|
||||||
VALUESET_TOO_COSTLY_COUNT = The value set ''{0}'' expansion has {2} codes, which is too many to display ({1})
|
VALUESET_TOO_COSTLY_COUNT = The value set ''{0}'' expansion has {2} codes, which is too many to display ({1})
|
||||||
VALUESET_TOO_COSTLY_TIME = The value set ''{0}'' expansion took too long to process (>{1}sec)
|
VALUESET_TOO_COSTLY_TIME = The value set ''{0}'' {2} took too long to process (>{1}sec)
|
||||||
VALUESET_UNC_SYSTEM_WARNING = Unknown System ''{0}'' specified, so Concepts and Filters can''t be checked (Details: {1})
|
VALUESET_UNC_SYSTEM_WARNING = Unknown System ''{0}'' specified, so Concepts and Filters can''t be checked (Details: {1})
|
||||||
VALUESET_UNC_SYSTEM_WARNING_VER = Unknown System/Version ''{0}'' specified, so Concepts and Filters can''t be checked (Details: {1})
|
VALUESET_UNC_SYSTEM_WARNING_VER = Unknown System/Version ''{0}'' specified, so Concepts and Filters can''t be checked (Details: {1})
|
||||||
VALUESET_UNKNOWN_FILTER_PROPERTY = The property ''{0}'' is not known for the system ''{1}'', so may not be understood by the terminology ecosystem. Known properties for this system: {2}
|
VALUESET_UNKNOWN_FILTER_PROPERTY = The property ''{0}'' is not known for the system ''{1}'', so may not be understood by the terminology ecosystem. Known properties for this system: {2}
|
||||||
|
@ -1138,6 +1140,12 @@ TYPE_SPECIFIC_CHECKS_DT_XHTML_LITERAL_HREF = Hyperlink scheme ''{3}'' in ''{0}''
|
||||||
SM_TARGET_TYPE_UNKNOWN = The type of the target variable is not known: {0}
|
SM_TARGET_TYPE_UNKNOWN = The type of the target variable is not known: {0}
|
||||||
XHTML_XHTML_ATTRIBUTE_XML_SPACE = The attribute 'xml:space' is legal but has a fixed value of 'preserve'. It''s use is discouraged
|
XHTML_XHTML_ATTRIBUTE_XML_SPACE = The attribute 'xml:space' is legal but has a fixed value of 'preserve'. It''s use is discouraged
|
||||||
VALIDATION_HL7_PUBLISHER_MULTIPLE_WGS = This resource has more than workgroup extension (http://hl7.org/fhir/StructureDefinition/structuredefinition-wg)
|
VALIDATION_HL7_PUBLISHER_MULTIPLE_WGS = This resource has more than workgroup extension (http://hl7.org/fhir/StructureDefinition/structuredefinition-wg)
|
||||||
NO_VALID_DISPLAY_FOUND_NONE_FOR_LANG = Wrong Display Name ''{0}'' for {1}#{2}. There are no valid display names found for language(s) ''{3}''. Default display is ''{4}''
|
NO_VALID_DISPLAY_FOUND_NONE_FOR_LANG_OK = There are no valid display names found for the code {1}#{2} for language(s) ''{3}''. The display is ''{4}'' the default language display
|
||||||
|
NO_VALID_DISPLAY_FOUND_NONE_FOR_LANG_ERR = Wrong Display Name ''{0}'' for {1}#{2}. There are no valid display names found for language(s) ''{3}''. Default display is ''{4}''
|
||||||
NO_VALID_DISPLAY_AT_ALL = Cannot validate display Name ''{0}'' for {1}#{2}: No displays are known
|
NO_VALID_DISPLAY_AT_ALL = Cannot validate display Name ''{0}'' for {1}#{2}: No displays are known
|
||||||
|
SD_BASE_EXPERIMENTAL = The definition builds on ''{0}'' which is experimental, but this definition is not labeled as experimental
|
||||||
|
SD_ED_EXPERIMENTAL_BINDING = The definition for the element ''{0}'' binds to the value set ''{1}'' which is experimental, but this structure is not labeled as experimental
|
||||||
|
VALIDATION_NO_EXPERIMENTAL_CONTENT = Experimental content is not allowed in this context
|
||||||
|
SD_ED_ADDITIONAL_BINDING_USAGE_UNKNOWN = The Usage Context {0}#{1} is not recognised and may not be correct
|
||||||
|
SD_ED_ADDITIONAL_BINDING_USAGE_INVALID_ELEMENT = The Usage Context {0}#{1} is a reference to an element that does not exist
|
||||||
|
SD_ED_ADDITIONAL_BINDING_USAGE_INVALID_TYPE = The Usage Context value must be of type {1} not {0}
|
||||||
|
|
|
@ -207,7 +207,8 @@ DATA_REND_COND = Condition
|
||||||
DATA_REND_COUNT = Count {0}
|
DATA_REND_COUNT = Count {0}
|
||||||
DATA_REND_DATA = Data: {0}
|
DATA_REND_DATA = Data: {0}
|
||||||
DATA_REND_DETAILS = (Details: {0} code
|
DATA_REND_DETAILS = (Details: {0} code
|
||||||
DATA_REND_DETAILS_STATED = (Details: {0} code {1} {2} {3} '', stated as '' {4} {5}
|
DATA_REND_DETAILS_STATED = (Details: {0} code {1} = ''{2}'')
|
||||||
|
DATA_REND_DETAILS_STATED_ND = (Details: {0} code {1})
|
||||||
DATA_REND_DICOM = DICOM
|
DATA_REND_DICOM = DICOM
|
||||||
DATA_REND_DIM = Dimensions: {0}
|
DATA_REND_DIM = Dimensions: {0}
|
||||||
DATA_REND_DURATION = Duration {0}
|
DATA_REND_DURATION = Duration {0}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.hl7.fhir.utilities.npm;
|
package org.hl7.fhir.utilities.npm;
|
||||||
|
|
||||||
import org.hl7.fhir.utilities.TextFile;
|
|
||||||
import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
|
import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@ -12,10 +12,12 @@ import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
public class FilesystemPackageManagerLockTests {
|
public class FilesystemPackageManagerLockTests {
|
||||||
|
@ -49,13 +51,13 @@ public class FilesystemPackageManagerLockTests {
|
||||||
packageLock.doWriteWithLock(() -> {
|
packageLock.doWriteWithLock(() -> {
|
||||||
assertThat(packageLock.getLockFile()).exists();
|
assertThat(packageLock.getLockFile()).exists();
|
||||||
return null;
|
return null;
|
||||||
});
|
}, null);
|
||||||
assertThat(packageLock.getLockFile()).doesNotExist();
|
assertThat(packageLock.getLockFile()).doesNotExist();
|
||||||
|
|
||||||
packageLock.doReadWithLock(() -> {
|
packageLock.doReadWithLock(() -> {
|
||||||
assertThat(packageLock.getLockFile()).doesNotExist();
|
assertThat(packageLock.getLockFile()).doesNotExist();
|
||||||
return null;
|
return null;
|
||||||
});
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test void testNoPackageWriteOrReadWhileWholeCacheIsLocked() throws IOException, InterruptedException {
|
@Test void testNoPackageWriteOrReadWhileWholeCacheIsLocked() throws IOException, InterruptedException {
|
||||||
|
@ -87,7 +89,7 @@ public class FilesystemPackageManagerLockTests {
|
||||||
packageLock.doWriteWithLock(() -> {
|
packageLock.doWriteWithLock(() -> {
|
||||||
assertThat(cacheLockFinished.get()).isTrue();
|
assertThat(cacheLockFinished.get()).isTrue();
|
||||||
return null;
|
return null;
|
||||||
});
|
}, null);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@ -97,7 +99,7 @@ public class FilesystemPackageManagerLockTests {
|
||||||
packageLock.doReadWithLock(() -> {
|
packageLock.doReadWithLock(() -> {
|
||||||
assertThat(cacheLockFinished.get()).isTrue();
|
assertThat(cacheLockFinished.get()).isTrue();
|
||||||
return null;
|
return null;
|
||||||
});
|
}, null);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@ -116,6 +118,23 @@ public class FilesystemPackageManagerLockTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test void testWhenLockIsntHeld_canLockFileBeHeldByThisProcessIsTrue() throws IOException {
|
||||||
|
File lockFile = getPackageLockFile();
|
||||||
|
lockFile.createNewFile();
|
||||||
|
Assertions.assertTrue(filesystemPackageCacheLockManager.getCacheLock().canLockFileBeHeldByThisProcess(lockFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test void testWhenLockIsHelp_canLockFileBeHeldByThisProcessIsFalse() throws InterruptedException, TimeoutException, IOException {
|
||||||
|
File lockFile = getPackageLockFile();
|
||||||
|
Thread lockThread = LockfileTestProcessUtility.lockWaitAndDeleteInNewProcess(cachePath, DUMMY_PACKAGE + ".lock", 2);
|
||||||
|
|
||||||
|
LockfileTestUtility.waitForLockfileCreation(cacheDirectory.getAbsolutePath(), DUMMY_PACKAGE + ".lock");
|
||||||
|
|
||||||
|
Assertions.assertFalse(filesystemPackageCacheLockManager.getCacheLock().canLockFileBeHeldByThisProcess(lockFile));
|
||||||
|
|
||||||
|
lockThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
@Test void testSinglePackageWriteMultiPackageRead() throws IOException {
|
@Test void testSinglePackageWriteMultiPackageRead() throws IOException {
|
||||||
final FilesystemPackageCacheManagerLocks.PackageLock packageLock = filesystemPackageCacheLockManager.getPackageLock(DUMMY_PACKAGE);
|
final FilesystemPackageCacheManagerLocks.PackageLock packageLock = filesystemPackageCacheLockManager.getPackageLock(DUMMY_PACKAGE);
|
||||||
AtomicInteger writeCounter = new AtomicInteger(0);
|
AtomicInteger writeCounter = new AtomicInteger(0);
|
||||||
|
@ -133,7 +152,7 @@ public class FilesystemPackageManagerLockTests {
|
||||||
assertThat(writeCount).isEqualTo(1);
|
assertThat(writeCount).isEqualTo(1);
|
||||||
writeCounter.decrementAndGet();
|
writeCounter.decrementAndGet();
|
||||||
return null;
|
return null;
|
||||||
});
|
}, null);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@ -156,7 +175,7 @@ public class FilesystemPackageManagerLockTests {
|
||||||
}
|
}
|
||||||
readCounter.decrementAndGet();
|
readCounter.decrementAndGet();
|
||||||
return null;
|
return null;
|
||||||
});
|
}, null);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@ -179,49 +198,47 @@ public class FilesystemPackageManagerLockTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadWhenLockedByFileTimesOut() throws IOException {
|
public void testReadWhenLockedByFileTimesOut() throws InterruptedException, TimeoutException, IOException {
|
||||||
FilesystemPackageCacheManagerLocks shorterTimeoutManager = filesystemPackageCacheLockManager.withLockTimeout(3L, TimeUnit.SECONDS);
|
FilesystemPackageCacheManagerLocks shorterTimeoutManager = filesystemPackageCacheLockManager;
|
||||||
final FilesystemPackageCacheManagerLocks.PackageLock packageLock = shorterTimeoutManager.getPackageLock(DUMMY_PACKAGE);
|
final FilesystemPackageCacheManagerLocks.PackageLock packageLock = shorterTimeoutManager.getPackageLock(DUMMY_PACKAGE);
|
||||||
File lockFile = createPackageLockFile();
|
File lockFile = getPackageLockFile();
|
||||||
|
Thread lockThread = LockfileTestProcessUtility.lockWaitAndDeleteInNewProcess(cachePath, lockFile.getName(), 5);
|
||||||
|
LockfileTestUtility.waitForLockfileCreation(cachePath,lockFile.getName());
|
||||||
|
|
||||||
Exception exception = assertThrows(IOException.class, () -> {
|
Exception exception = assertThrows(IOException.class, () -> {
|
||||||
packageLock.doReadWithLock(() -> {
|
packageLock.doReadWithLock(() -> {
|
||||||
assertThat(lockFile).exists();
|
assertThat(lockFile).exists();
|
||||||
return null;
|
return null;
|
||||||
});
|
}, new FilesystemPackageCacheManagerLocks.LockParameters(3L, TimeUnit.SECONDS));
|
||||||
});
|
});
|
||||||
|
|
||||||
assertThat(exception.getMessage()).contains("Error reading package");
|
assertThat(exception.getMessage()).contains("Package cache timed out waiting for lock");
|
||||||
assertThat(exception.getCause().getMessage()).contains("Timeout waiting for lock file deletion: " + lockFile.getName());
|
assertThat(exception.getCause().getMessage()).contains("Timeout waiting for lock file deletion: " + lockFile.getName());
|
||||||
|
|
||||||
|
lockThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReadWhenLockFileIsDeleted() throws IOException {
|
|
||||||
FilesystemPackageCacheManagerLocks shorterTimeoutManager = filesystemPackageCacheLockManager.withLockTimeout(5L, TimeUnit.SECONDS);
|
|
||||||
final FilesystemPackageCacheManagerLocks.PackageLock packageLock = shorterTimeoutManager.getPackageLock(DUMMY_PACKAGE);
|
|
||||||
File lockFile = createPackageLockFile();
|
|
||||||
|
|
||||||
Thread t = new Thread(() -> {
|
@Test
|
||||||
try {
|
public void testReadWhenLockFileIsDeleted() throws InterruptedException, TimeoutException, IOException {
|
||||||
Thread.sleep(2000);
|
|
||||||
} catch (InterruptedException e) {
|
final FilesystemPackageCacheManagerLocks.PackageLock packageLock = filesystemPackageCacheLockManager.getPackageLock(DUMMY_PACKAGE);
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
final File lockFile = getPackageLockFile();
|
||||||
lockFile.delete();
|
|
||||||
});
|
Thread lockThread = LockfileTestProcessUtility.lockWaitAndDeleteInNewProcess(cachePath, lockFile.getName(), 5);
|
||||||
t.start();
|
LockfileTestUtility.waitForLockfileCreation(cachePath,lockFile.getName());
|
||||||
|
|
||||||
packageLock.doReadWithLock(() -> {
|
packageLock.doReadWithLock(() -> {
|
||||||
assertThat(lockFile).doesNotExist();
|
assertThat(lockFile).doesNotExist();
|
||||||
return null;
|
return null;
|
||||||
});
|
}, new FilesystemPackageCacheManagerLocks.LockParameters(10L, TimeUnit.SECONDS));
|
||||||
|
|
||||||
|
lockThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
private File createPackageLockFile() throws IOException {
|
private File getPackageLockFile() {
|
||||||
File lockFile = Path.of(cachePath, DUMMY_PACKAGE + ".lock").toFile();
|
return Path.of(cachePath, DUMMY_PACKAGE + ".lock").toFile();
|
||||||
TextFile.stringToFile("", lockFile);
|
|
||||||
return lockFile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.hl7.fhir.utilities.npm;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
@ -13,6 +14,8 @@ import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@ -20,6 +23,7 @@ import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import org.hl7.fhir.utilities.IniFile;
|
import org.hl7.fhir.utilities.IniFile;
|
||||||
import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
|
import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.condition.DisabledOnOs;
|
import org.junit.jupiter.api.condition.DisabledOnOs;
|
||||||
import org.junit.jupiter.api.condition.EnabledOnOs;
|
import org.junit.jupiter.api.condition.EnabledOnOs;
|
||||||
|
@ -113,6 +117,97 @@ public class FilesystemPackageManagerTests {
|
||||||
assertEquals( System.getenv("ProgramData") + "\\.fhir\\packages", folder.getAbsolutePath());
|
assertEquals( System.getenv("ProgramData") + "\\.fhir\\packages", folder.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCorruptPackageCleanup() throws IOException {
|
||||||
|
File cacheDirectory = ManagedFileAccess.fromPath(Files.createTempDirectory("fpcm-multithreadingTest"));
|
||||||
|
|
||||||
|
File dummyPackage = createDummyPackage(cacheDirectory, "example.fhir.uv.myig", "1.2.3");
|
||||||
|
File dummyLockFile = createDummyLockFile(cacheDirectory, "example.fhir.uv.myig" , "1.2.3");
|
||||||
|
|
||||||
|
assertThat(dummyPackage).isDirectory();
|
||||||
|
assertThat(dummyPackage).exists();
|
||||||
|
assertThat(dummyLockFile).exists();
|
||||||
|
|
||||||
|
FilesystemPackageCacheManager filesystemPackageCacheManager = new FilesystemPackageCacheManager.Builder().withCacheFolder(cacheDirectory.getAbsolutePath()).build();
|
||||||
|
|
||||||
|
assertThat(dummyPackage).doesNotExist();
|
||||||
|
assertThat(dummyLockFile).doesNotExist();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLockedPackageIsntCleanedUp() throws IOException, InterruptedException, TimeoutException {
|
||||||
|
File cacheDirectory = ManagedFileAccess.fromPath(Files.createTempDirectory("fpcm-multithreadingTest"));
|
||||||
|
|
||||||
|
File dummyPackage = createDummyPackage(cacheDirectory, "example.fhir.uv.myig", "1.2.3");
|
||||||
|
|
||||||
|
Thread lockThread = LockfileTestProcessUtility.lockWaitAndDeleteInNewProcess(cacheDirectory.getAbsolutePath(), "example.fhir.uv.myig#1.2.3.lock", 2);
|
||||||
|
|
||||||
|
LockfileTestUtility.waitForLockfileCreation(cacheDirectory.getAbsolutePath(), "example.fhir.uv.myig#1.2.3.lock");
|
||||||
|
File dummyLockFile = ManagedFileAccess.file(cacheDirectory.getAbsolutePath(), "example.fhir.uv.myig#1.2.3.lock");
|
||||||
|
|
||||||
|
assertThat(dummyPackage).isDirectory();
|
||||||
|
assertThat(dummyPackage).exists();
|
||||||
|
assertThat(dummyLockFile).exists();
|
||||||
|
|
||||||
|
FilesystemPackageCacheManager filesystemPackageCacheManager = new FilesystemPackageCacheManager.Builder().withCacheFolder(cacheDirectory.getAbsolutePath()).build();
|
||||||
|
|
||||||
|
assertThat(dummyPackage).exists();
|
||||||
|
assertThat(dummyLockFile).exists();
|
||||||
|
|
||||||
|
lockThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTimeoutForLockedPackageRead() throws IOException, InterruptedException, TimeoutException {
|
||||||
|
String pcmPath = ManagedFileAccess.fromPath(Files.createTempDirectory("fpcm-multithreadingTest")).getAbsolutePath();
|
||||||
|
|
||||||
|
final FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager.Builder()
|
||||||
|
.withCacheFolder(pcmPath)
|
||||||
|
.withLockParameters(new FilesystemPackageCacheManagerLocks.LockParameters(5,TimeUnit.SECONDS))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Assertions.assertTrue(pcm.listPackages().isEmpty());
|
||||||
|
|
||||||
|
Thread lockThread = LockfileTestProcessUtility.lockWaitAndDeleteInNewProcess(pcmPath, "example.fhir.uv.myig#1.2.3.lock", 10);
|
||||||
|
File directory = ManagedFileAccess.file(pcmPath, "example.fhir.uv.myig#1.2.3" );
|
||||||
|
directory.mkdir();
|
||||||
|
|
||||||
|
LockfileTestUtility.waitForLockfileCreation(pcmPath, "example.fhir.uv.myig#1.2.3.lock");
|
||||||
|
|
||||||
|
IOException exception = assertThrows(IOException.class, () -> pcm.loadPackageFromCacheOnly("example.fhir.uv.myig", "1.2.3"));
|
||||||
|
|
||||||
|
assertThat(exception.getMessage()).contains("Package cache timed out waiting for lock");
|
||||||
|
assertThat(exception.getCause().getMessage()).contains("Timeout waiting for lock file deletion");
|
||||||
|
lockThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadFromCacheOnlyWaitsForLockDelete() throws IOException, InterruptedException, TimeoutException {
|
||||||
|
String pcmPath = ManagedFileAccess.fromPath(Files.createTempDirectory("fpcm-multithreadingTest")).getAbsolutePath();
|
||||||
|
|
||||||
|
final FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager.Builder().withCacheFolder(pcmPath).build();
|
||||||
|
|
||||||
|
Assertions.assertTrue(pcm.listPackages().isEmpty());
|
||||||
|
|
||||||
|
pcm.addPackageToCache("example.fhir.uv.myig", "1.2.3", this.getClass().getResourceAsStream("/npm/dummy-package.tgz"), "https://packages.fhir.org/example.fhir.uv.myig/1.2.3");
|
||||||
|
|
||||||
|
String packageAndVersion = "example.fhir.uv.myig#1.2.3";
|
||||||
|
|
||||||
|
//Now sneak in a new lock file and directory:
|
||||||
|
|
||||||
|
File directory = ManagedFileAccess.file(pcmPath, packageAndVersion);
|
||||||
|
directory.mkdir();
|
||||||
|
|
||||||
|
Thread lockThread = LockfileTestProcessUtility.lockWaitAndDeleteInNewProcess(pcmPath, "example.fhir.uv.myig#1.2.3.lock", 5);
|
||||||
|
LockfileTestUtility.waitForLockfileCreation(pcmPath, "example.fhir.uv.myig#1.2.3.lock");
|
||||||
|
|
||||||
|
NpmPackage npmPackage = pcm.loadPackageFromCacheOnly("example.fhir.uv.myig", "1.2.3");
|
||||||
|
|
||||||
|
assertThat(npmPackage.id()).isEqualTo("example.fhir.uv.myig");
|
||||||
|
|
||||||
|
lockThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
We repeat the same tests multiple times here, in order to catch very rare edge cases.
|
We repeat the same tests multiple times here, in order to catch very rare edge cases.
|
||||||
*/
|
*/
|
||||||
|
@ -126,16 +221,16 @@ public class FilesystemPackageManagerTests {
|
||||||
return params.stream();
|
return params.stream();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createDummyTemp(File cacheDirectory, String lowerCase) throws IOException {
|
private File createDummyTemp(File cacheDirectory, String lowerCase) throws IOException {
|
||||||
createDummyPackage(cacheDirectory, lowerCase);
|
return createDummyPackage(cacheDirectory, lowerCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createDummyPackage(File cacheDirectory, String packageName, String packageVersion) throws IOException {
|
private File createDummyPackage(File cacheDirectory, String packageName, String packageVersion) throws IOException {
|
||||||
String directoryName = packageName + "#" + packageVersion;
|
String directoryName = packageName + "#" + packageVersion;
|
||||||
createDummyPackage(cacheDirectory, directoryName);
|
return createDummyPackage(cacheDirectory, directoryName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createDummyPackage(File cacheDirectory, String directoryName) throws IOException {
|
private static File createDummyPackage(File cacheDirectory, String directoryName) throws IOException {
|
||||||
File packageDirectory = ManagedFileAccess.file(cacheDirectory.getAbsolutePath(), directoryName);
|
File packageDirectory = ManagedFileAccess.file(cacheDirectory.getAbsolutePath(), directoryName);
|
||||||
packageDirectory.mkdirs();
|
packageDirectory.mkdirs();
|
||||||
|
|
||||||
|
@ -144,6 +239,16 @@ public class FilesystemPackageManagerTests {
|
||||||
wr.write("Ain't nobody here but us chickens");
|
wr.write("Ain't nobody here but us chickens");
|
||||||
wr.flush();
|
wr.flush();
|
||||||
wr.close();
|
wr.close();
|
||||||
|
return packageDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
private File createDummyLockFile(File cacheDirectory, String packageName, String packageVersion) throws IOException {
|
||||||
|
final File dummyLockFile = ManagedFileAccess.file(cacheDirectory.getAbsolutePath(), packageName + "#" + packageVersion + ".lock");
|
||||||
|
final FileWriter wr = new FileWriter(dummyLockFile);
|
||||||
|
wr.write("Ain't nobody here but us chickens");
|
||||||
|
wr.flush();
|
||||||
|
wr.close();
|
||||||
|
return dummyLockFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatDummyTempExists(File cacheDirectory, String dummyTempPackage) throws IOException {
|
private void assertThatDummyTempExists(File cacheDirectory, String dummyTempPackage) throws IOException {
|
||||||
|
@ -241,13 +346,13 @@ public class FilesystemPackageManagerTests {
|
||||||
@MethodSource("packageCacheMultiThreadTestParams")
|
@MethodSource("packageCacheMultiThreadTestParams")
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
public void packageCacheMultiThreadTest(final int threadTotal, final int packageCacheManagerTotal) throws IOException {
|
public void packageCacheMultiThreadTest(final int threadTotal, final int packageCacheManagerTotal) throws IOException {
|
||||||
|
|
||||||
String pcmPath = ManagedFileAccess.fromPath(Files.createTempDirectory("fpcm-multithreadingTest")).getAbsolutePath();
|
String pcmPath = ManagedFileAccess.fromPath(Files.createTempDirectory("fpcm-multithreadingTest")).getAbsolutePath();
|
||||||
|
System.out.println("Using temp pcm path: " + pcmPath);
|
||||||
FilesystemPackageCacheManager[] packageCacheManagers = new FilesystemPackageCacheManager[packageCacheManagerTotal];
|
FilesystemPackageCacheManager[] packageCacheManagers = new FilesystemPackageCacheManager[packageCacheManagerTotal];
|
||||||
Random rand = new Random();
|
Random rand = new Random();
|
||||||
|
|
||||||
final AtomicInteger totalSuccessful = new AtomicInteger();
|
final AtomicInteger totalSuccessful = new AtomicInteger();
|
||||||
final ConcurrentHashMap successfulThreads = new ConcurrentHashMap();
|
final ConcurrentHashMap<Long, Integer> successfulThreads = new ConcurrentHashMap<>();
|
||||||
List<Thread> threads = new ArrayList<>();
|
List<Thread> threads = new ArrayList<>();
|
||||||
for (int i = 0; i < threadTotal; i++) {
|
for (int i = 0; i < threadTotal; i++) {
|
||||||
final int index = i;
|
final int index = i;
|
||||||
|
@ -256,22 +361,27 @@ public class FilesystemPackageManagerTests {
|
||||||
System.out.println("Thread #" + index + ": " + Thread.currentThread().getId() + " started");
|
System.out.println("Thread #" + index + ": " + Thread.currentThread().getId() + " started");
|
||||||
final int randomPCM = rand.nextInt(packageCacheManagerTotal);
|
final int randomPCM = rand.nextInt(packageCacheManagerTotal);
|
||||||
final int randomOperation = rand.nextInt(4);
|
final int randomOperation = rand.nextInt(4);
|
||||||
|
final String operationName;
|
||||||
if (packageCacheManagers[randomPCM] == null) {
|
if (packageCacheManagers[randomPCM] == null) {
|
||||||
packageCacheManagers[randomPCM] = new FilesystemPackageCacheManager.Builder().withCacheFolder(pcmPath).build();
|
packageCacheManagers[randomPCM] = new FilesystemPackageCacheManager.Builder().withCacheFolder(pcmPath).build();
|
||||||
}
|
}
|
||||||
FilesystemPackageCacheManager pcm = packageCacheManagers[randomPCM];
|
FilesystemPackageCacheManager pcm = packageCacheManagers[randomPCM];
|
||||||
if (randomOperation == 0) {
|
if (randomOperation == 0) {
|
||||||
|
operationName = "addPackageToCache";
|
||||||
pcm.addPackageToCache("example.fhir.uv.myig", "1.2.3", this.getClass().getResourceAsStream("/npm/dummy-package.tgz"), "https://packages.fhir.org/example.fhir.uv.myig/1.2.3");
|
pcm.addPackageToCache("example.fhir.uv.myig", "1.2.3", this.getClass().getResourceAsStream("/npm/dummy-package.tgz"), "https://packages.fhir.org/example.fhir.uv.myig/1.2.3");
|
||||||
} else if (randomOperation == 1) {
|
} else if (randomOperation == 1) {
|
||||||
|
operationName = "clear";
|
||||||
pcm.clear();
|
pcm.clear();
|
||||||
} else if (randomOperation == 2) {
|
} else if (randomOperation == 2) {
|
||||||
|
operationName = "loadPackageFromCacheOnly";
|
||||||
pcm.loadPackageFromCacheOnly("example.fhir.uv.myig", "1.2.3");
|
pcm.loadPackageFromCacheOnly("example.fhir.uv.myig", "1.2.3");
|
||||||
} else {
|
} else {
|
||||||
|
operationName = "removePackage";
|
||||||
pcm.removePackage("example.fhir.uv.myig", "1.2.3");
|
pcm.removePackage("example.fhir.uv.myig", "1.2.3");
|
||||||
}
|
}
|
||||||
totalSuccessful.incrementAndGet();
|
totalSuccessful.incrementAndGet();
|
||||||
successfulThreads.put(Thread.currentThread().getId(), index);
|
successfulThreads.put(Thread.currentThread().getId(), index);
|
||||||
System.out.println("Thread #" + index + ": " + Thread.currentThread().getId() + " completed");
|
System.out.println("Thread #" + index + ": " + Thread.currentThread().getId() + " completed. Ran: " + operationName);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.err.println("Thread #" + index + ": " + Thread.currentThread().getId() + " failed");
|
System.err.println("Thread #" + index + ": " + Thread.currentThread().getId() + " failed");
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
package org.hl7.fhir.utilities.npm;
|
||||||
|
|
||||||
|
import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.channels.FileLock;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FilesystemPackageCacheManagerLocks relies on the existence of .lock files to prevent access to packages being written
|
||||||
|
* by processes outside the current JVM. Testing this functionality means creating a process outside the JUnit test JVM,
|
||||||
|
* which is achieved by running a separate Java process.
|
||||||
|
* <p/>
|
||||||
|
* Intended usage:
|
||||||
|
* <p/>
|
||||||
|
* The helper method {@link #lockWaitAndDeleteInNewProcess(String, String, int)} is the intended starting point for
|
||||||
|
* using this class.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This class deliberately avoids using any dependencies outside java.*, which avoids having to construct a classpath
|
||||||
|
* for the separate process.
|
||||||
|
*/
|
||||||
|
public class LockfileTestProcessUtility {
|
||||||
|
/**
|
||||||
|
* Main method to allow running this class.
|
||||||
|
* <p/
|
||||||
|
* It is not recommended to call this method directly. Instead, use the provided {@link #lockWaitAndDeleteInNewProcess(String, String, int)} method.
|
||||||
|
*
|
||||||
|
* @param args The arguments to the main method. The first argument is the path to create the lockfile in, the second
|
||||||
|
* argument is the name of the lockfile, and the third argument is the number of seconds to wait before
|
||||||
|
* deleting the lockfile.
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
String path = args[0];
|
||||||
|
String lockFileName = args[1];
|
||||||
|
int seconds = Integer.parseInt(args[2]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
lockWaitAndDelete(path, lockFileName, seconds);
|
||||||
|
} catch (InterruptedException | IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static helper method that starts a new process, creates a lock file in the path and waits for a specified number of
|
||||||
|
* seconds before deleting it.
|
||||||
|
* <p/>
|
||||||
|
* This method calls the {@link #main(String[])} method in a new process.
|
||||||
|
*
|
||||||
|
* @param path The path to create the lockfile in
|
||||||
|
* @param lockFileName The name of the lockfile
|
||||||
|
* @param seconds The number of seconds to wait before deleting the lockfile
|
||||||
|
* @return The thread wrapping the process execution. This can be used to wait for the process to complete, so that
|
||||||
|
* System.out and System.err can be processed before tests return results.
|
||||||
|
*/
|
||||||
|
public static Thread lockWaitAndDeleteInNewProcess(String path, String lockFileName, int seconds) {
|
||||||
|
Thread t = new Thread(() -> {
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder("java", "-cp", "target/test-classes", LockfileTestProcessUtility.class.getName(), path, lockFileName, Integer.toString(seconds));
|
||||||
|
try {
|
||||||
|
Process process = processBuilder.start();
|
||||||
|
process.getErrorStream().transferTo(System.err);
|
||||||
|
process.getInputStream().transferTo(System.out);
|
||||||
|
process.waitFor();
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
t.start();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The actual logic to create a .lock file.
|
||||||
|
* <p/>
|
||||||
|
* This should match the logic in FilesystemPackageCacheManagerLocks
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @param path The path to create the lockfile in
|
||||||
|
* @param lockFileName The name of the lockfile
|
||||||
|
* @param seconds The number of seconds to wait before deleting the lockfile
|
||||||
|
* @throws InterruptedException If the thread is interrupted while waiting
|
||||||
|
* @throws IOException If there is an error accessing the file system
|
||||||
|
*/
|
||||||
|
/* TODO Eventually, this logic should exist in a Lockfile class so that it isn't duplicated between the main code and
|
||||||
|
the test code.
|
||||||
|
*/
|
||||||
|
private static void lockWaitAndDelete(String path, String lockFileName, int seconds) throws InterruptedException, IOException {
|
||||||
|
|
||||||
|
File lockFile = Paths.get(path,lockFileName).toFile();
|
||||||
|
|
||||||
|
try (FileChannel channel = new RandomAccessFile(lockFile.getAbsolutePath(), "rw").getChannel()) {
|
||||||
|
FileLock fileLock = channel.tryLock(0, Long.MAX_VALUE, false);
|
||||||
|
if (fileLock != null) {
|
||||||
|
final ByteBuffer buff = ByteBuffer.wrap("Hello world".getBytes(StandardCharsets.UTF_8));
|
||||||
|
channel.write(buff);
|
||||||
|
System.out.println("File "+lockFileName+" is locked. Waiting for " + seconds + " seconds to release. ");
|
||||||
|
Thread.sleep(seconds * 1000L);
|
||||||
|
|
||||||
|
lockFile.renameTo(ManagedFileAccess.file(File.createTempFile(lockFile.getName(), ".lock-renamed").getAbsolutePath()));
|
||||||
|
|
||||||
|
fileLock.release();
|
||||||
|
channel.close();
|
||||||
|
System.out.println(System.currentTimeMillis());
|
||||||
|
System.out.println("File "+lockFileName+" is released.");
|
||||||
|
|
||||||
|
lockFile.delete();
|
||||||
|
}}finally {
|
||||||
|
if (lockFile.exists()) {
|
||||||
|
lockFile.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package org.hl7.fhir.utilities.npm;
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
|
||||||
|
import org.apache.commons.io.monitor.FileAlterationMonitor;
|
||||||
|
import org.apache.commons.io.monitor.FileAlterationObserver;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
import java.nio.file.*;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
|
||||||
|
public class LockfileTestUtility {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for the lock file to be created in the given path.
|
||||||
|
* <p/>
|
||||||
|
* Normally, within the same JVM, you could use a CountdownLatch for the same purpose, but since this the lock file is
|
||||||
|
* being created in a separate process, we need to use a mechanism that doesn't rely on shared threads.
|
||||||
|
*
|
||||||
|
* @param path The path containing the lock file
|
||||||
|
* @param lockFileName The name of the lock file
|
||||||
|
* @throws InterruptedException If the thread is interrupted while waiting
|
||||||
|
* @throws TimeoutException If the lock file is not created within 10 seconds
|
||||||
|
*/
|
||||||
|
public static void waitForLockfileCreation(String path, String lockFileName) throws InterruptedException, TimeoutException {
|
||||||
|
|
||||||
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
FileAlterationMonitor monitor = new FileAlterationMonitor(100);
|
||||||
|
FileAlterationObserver observer = new FileAlterationObserver(path);
|
||||||
|
|
||||||
|
observer.addListener(new FileAlterationListenerAdaptor(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart(FileAlterationObserver observer) {
|
||||||
|
if (Files.exists(Paths.get(path, lockFileName))) {
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFileCreate(File file) {
|
||||||
|
System.out.println("File created: " + file.getName());
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
monitor.addObserver(observer);
|
||||||
|
|
||||||
|
try {
|
||||||
|
monitor.start();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
boolean success = latch.await(10, TimeUnit.SECONDS);
|
||||||
|
try {
|
||||||
|
monitor.stop();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
throw new TimeoutException("Timed out waiting for lock file creation: " + lockFileName);
|
||||||
|
}
|
||||||
|
// TODO This is a workaround for an edge condition that shows up with testing, where the lock is not reflected in
|
||||||
|
// the file system immediately. It is unlikely to appear in production environments. Should it occur, it will
|
||||||
|
// result in a lock file being erroneously reported as not having an owning process, and will cause a package to
|
||||||
|
// fail to be loaded from that cache until the lock is cleaned up by cache initialization.
|
||||||
|
Thread.sleep(100);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>6.3.26-SNAPSHOT</version>
|
<version>6.3.30-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>6.3.26-SNAPSHOT</version>
|
<version>6.3.30-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -1192,6 +1192,34 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected int countFragmentMatches(Element element, String fragment, NodeStack stack) {
|
||||||
|
int count = countFragmentMatches(element, fragment);
|
||||||
|
if (count == 0 && element.isResource() && element.hasParentForValidator()) {
|
||||||
|
Element bnd = getElementBundle(element);
|
||||||
|
if (bnd != null) {
|
||||||
|
// in this case, we look into the parent - if there is one - and if it's a bundle, we look at the entries (but not in them)
|
||||||
|
for (Element be : bnd.getChildrenByName("entry")) {
|
||||||
|
String id = be.getIdBase();
|
||||||
|
if (fragment.equals(id)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Element getElementBundle(Element element) {
|
||||||
|
Element p = element.getParentForValidator();
|
||||||
|
if (p != null) {
|
||||||
|
Element b = p.getParentForValidator();
|
||||||
|
if (b != null && b.fhirType().equals("Bundle")) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
protected int countFragmentMatches(Element element, String fragment) {
|
protected int countFragmentMatches(Element element, String fragment) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
if (fragment.equals(element.getIdBase())) {
|
if (fragment.equals(element.getIdBase())) {
|
||||||
|
|
|
@ -227,6 +227,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
||||||
@Getter @Setter private boolean checkIPSCodes;
|
@Getter @Setter private boolean checkIPSCodes;
|
||||||
@Getter @Setter private BestPracticeWarningLevel bestPracticeLevel;
|
@Getter @Setter private BestPracticeWarningLevel bestPracticeLevel;
|
||||||
@Getter @Setter private boolean unknownCodeSystemsCauseErrors;
|
@Getter @Setter private boolean unknownCodeSystemsCauseErrors;
|
||||||
|
@Getter @Setter private boolean noExperimentalContent;
|
||||||
@Getter @Setter private Locale locale;
|
@Getter @Setter private Locale locale;
|
||||||
@Getter @Setter private List<ImplementationGuide> igs = new ArrayList<>();
|
@Getter @Setter private List<ImplementationGuide> igs = new ArrayList<>();
|
||||||
@Getter @Setter private List<String> extensionDomains = new ArrayList<>();
|
@Getter @Setter private List<String> extensionDomains = new ArrayList<>();
|
||||||
|
@ -909,6 +910,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
||||||
validator.setPolicyAdvisor(policyAdvisor);
|
validator.setPolicyAdvisor(policyAdvisor);
|
||||||
}
|
}
|
||||||
validator.setUnknownCodeSystemsCauseErrors(unknownCodeSystemsCauseErrors);
|
validator.setUnknownCodeSystemsCauseErrors(unknownCodeSystemsCauseErrors);
|
||||||
|
validator.setNoExperimentalContent(noExperimentalContent);
|
||||||
return validator;
|
return validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ public class CliContext {
|
||||||
private boolean showTimes = false;
|
private boolean showTimes = false;
|
||||||
|
|
||||||
@JsonProperty("locale")
|
@JsonProperty("locale")
|
||||||
private String locale = Locale.ENGLISH.getDisplayLanguage();
|
private String locale = Locale.ENGLISH.toLanguageTag();
|
||||||
|
|
||||||
@JsonProperty("locations")
|
@JsonProperty("locations")
|
||||||
private Map<String, String> locations = new HashMap<String, String>();
|
private Map<String, String> locations = new HashMap<String, String>();
|
||||||
|
@ -165,6 +165,9 @@ public class CliContext {
|
||||||
|
|
||||||
@JsonProperty("unknownCodeSystemsCauseErrors")
|
@JsonProperty("unknownCodeSystemsCauseErrors")
|
||||||
private boolean unknownCodeSystemsCauseErrors;
|
private boolean unknownCodeSystemsCauseErrors;
|
||||||
|
|
||||||
|
@JsonProperty("noExperimentalContent")
|
||||||
|
private boolean noExperimentalContent;
|
||||||
|
|
||||||
@JsonProperty("baseEngine")
|
@JsonProperty("baseEngine")
|
||||||
public String getBaseEngine() {
|
public String getBaseEngine() {
|
||||||
|
@ -836,6 +839,7 @@ public class CliContext {
|
||||||
Objects.equals(bestPracticeLevel, that.bestPracticeLevel) &&
|
Objects.equals(bestPracticeLevel, that.bestPracticeLevel) &&
|
||||||
Objects.equals(watchScanDelay, that.watchScanDelay) &&
|
Objects.equals(watchScanDelay, that.watchScanDelay) &&
|
||||||
Objects.equals(unknownCodeSystemsCauseErrors, that.unknownCodeSystemsCauseErrors) &&
|
Objects.equals(unknownCodeSystemsCauseErrors, that.unknownCodeSystemsCauseErrors) &&
|
||||||
|
Objects.equals(noExperimentalContent, that.noExperimentalContent) &&
|
||||||
Objects.equals(watchSettleTime, that.watchSettleTime) ;
|
Objects.equals(watchSettleTime, that.watchSettleTime) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -844,7 +848,7 @@ public class CliContext {
|
||||||
return Objects.hash(baseEngine, doNative, extensions, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, noInternalCaching,
|
return Objects.hash(baseEngine, doNative, extensions, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, noInternalCaching,
|
||||||
noExtensibleBindingMessages, noInvariants, displayWarnings, wantInvariantsInMessages, map, output, outputSuffix, htmlOutput, txServer, sv, txLog, txCache, mapLog, lang, srcLang, tgtLang, fhirpath, snomedCT,
|
noExtensibleBindingMessages, noInvariants, displayWarnings, wantInvariantsInMessages, map, output, outputSuffix, htmlOutput, txServer, sv, txLog, txCache, mapLog, lang, srcLang, tgtLang, fhirpath, snomedCT,
|
||||||
targetVer, igs, questionnaireMode, level, profiles, sources, inputs, mode, locale, locations, crumbTrails, forPublication, showTimes, allowExampleUrls, outputStyle, jurisdiction, noUnicodeBiDiControlChars,
|
targetVer, igs, questionnaireMode, level, profiles, sources, inputs, mode, locale, locations, crumbTrails, forPublication, showTimes, allowExampleUrls, outputStyle, jurisdiction, noUnicodeBiDiControlChars,
|
||||||
watchMode, watchScanDelay, watchSettleTime, bestPracticeLevel, unknownCodeSystemsCauseErrors, htmlInMarkdownCheck, allowDoubleQuotesInFHIRPath, checkIPSCodes);
|
watchMode, watchScanDelay, watchSettleTime, bestPracticeLevel, unknownCodeSystemsCauseErrors, noExperimentalContent, htmlInMarkdownCheck, allowDoubleQuotesInFHIRPath, checkIPSCodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -904,6 +908,7 @@ public class CliContext {
|
||||||
", watchSettleTime=" + watchSettleTime +
|
", watchSettleTime=" + watchSettleTime +
|
||||||
", watchScanDelay=" + watchScanDelay +
|
", watchScanDelay=" + watchScanDelay +
|
||||||
", unknownCodeSystemsCauseErrors=" + unknownCodeSystemsCauseErrors +
|
", unknownCodeSystemsCauseErrors=" + unknownCodeSystemsCauseErrors +
|
||||||
|
", noExperimentalContent=" + noExperimentalContent +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -973,5 +978,16 @@ public class CliContext {
|
||||||
this.unknownCodeSystemsCauseErrors = unknownCodeSystemsCauseErrors;
|
this.unknownCodeSystemsCauseErrors = unknownCodeSystemsCauseErrors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonProperty("noExperimentalContent")
|
||||||
|
public boolean isNoExperimentalContent() {
|
||||||
|
return noExperimentalContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonProperty("noExperimentalContent")
|
||||||
|
public void setNoExperimentalContent(boolean noExperimentalContent) {
|
||||||
|
this.noExperimentalContent = noExperimentalContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -529,14 +529,18 @@ public class ValidationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
protected ValidationEngine buildValidationEngine( CliContext cliContext, String definitions, TimeTracker timeTracker) throws IOException, URISyntaxException {
|
protected ValidationEngine buildValidationEngine(CliContext cliContext, String definitions, TimeTracker timeTracker) throws IOException, URISyntaxException {
|
||||||
System.out.print(" Load FHIR v" + cliContext.getSv() + " from " + definitions);
|
System.out.print(" Load FHIR v" + cliContext.getSv() + " from " + definitions);
|
||||||
ValidationEngine validationEngine = getValidationEngineBuilder().withTHO(false).withVersion(cliContext.getSv()).withTimeTracker(timeTracker).withUserAgent(Common.getValidatorUserAgent()).fromSource(definitions);
|
ValidationEngine validationEngine = getValidationEngineBuilder().withTHO(false).withVersion(cliContext.getSv()).withTimeTracker(timeTracker).withUserAgent(Common.getValidatorUserAgent()).fromSource(definitions);
|
||||||
|
|
||||||
System.out.println(" - " + validationEngine.getContext().countAllCaches() + " resources (" + timeTracker.milestone() + ")");
|
System.out.println(" - " + validationEngine.getContext().countAllCaches() + " resources (" + timeTracker.milestone() + ")");
|
||||||
|
|
||||||
loadIgsAndExtensions(validationEngine, cliContext, timeTracker);
|
loadIgsAndExtensions(validationEngine, cliContext, timeTracker);
|
||||||
if (validationEngine.getContext().getTxCache() == null) {
|
if (cliContext.getTxCache() != null) {
|
||||||
|
TerminologyCache cache = new TerminologyCache(new Object(), cliContext.getTxCache());
|
||||||
|
validationEngine.getContext().initTxCache(cache);
|
||||||
|
}
|
||||||
|
if (validationEngine.getContext().getTxCache() == null || validationEngine.getContext().getTxCache().getFolder() == null) {
|
||||||
System.out.println(" No Terminology Cache");
|
System.out.println(" No Terminology Cache");
|
||||||
} else {
|
} else {
|
||||||
System.out.println(" Terminology Cache at "+validationEngine.getContext().getTxCache().getFolder());
|
System.out.println(" Terminology Cache at "+validationEngine.getContext().getTxCache().getFolder());
|
||||||
|
@ -582,6 +586,7 @@ public class ValidationService {
|
||||||
validationEngine.getBundleValidationRules().addAll(cliContext.getBundleValidationRules());
|
validationEngine.getBundleValidationRules().addAll(cliContext.getBundleValidationRules());
|
||||||
validationEngine.setJurisdiction(CodeSystemUtilities.readCoding(cliContext.getJurisdiction()));
|
validationEngine.setJurisdiction(CodeSystemUtilities.readCoding(cliContext.getJurisdiction()));
|
||||||
validationEngine.setUnknownCodeSystemsCauseErrors(cliContext.isUnknownCodeSystemsCauseErrors());
|
validationEngine.setUnknownCodeSystemsCauseErrors(cliContext.isUnknownCodeSystemsCauseErrors());
|
||||||
|
validationEngine.setNoExperimentalContent(cliContext.isNoExperimentalContent());
|
||||||
TerminologyCache.setNoCaching(cliContext.isNoInternalCaching());
|
TerminologyCache.setNoCaching(cliContext.isNoInternalCaching());
|
||||||
validationEngine.prepare(); // generate any missing snapshots
|
validationEngine.prepare(); // generate any missing snapshots
|
||||||
System.out.println(" go (" + timeTracker.milestone() + ")");
|
System.out.println(" go (" + timeTracker.milestone() + ")");
|
||||||
|
|
|
@ -94,7 +94,8 @@ public class Params {
|
||||||
public static final String DISABLE_DEFAULT_RESOURCE_FETCHER = "-disable-default-resource-fetcher";
|
public static final String DISABLE_DEFAULT_RESOURCE_FETCHER = "-disable-default-resource-fetcher";
|
||||||
public static final String CHECK_IPS_CODES = "-check-ips-codes";
|
public static final String CHECK_IPS_CODES = "-check-ips-codes";
|
||||||
public static final String BEST_PRACTICE = "-best-practice";
|
public static final String BEST_PRACTICE = "-best-practice";
|
||||||
public static final String UNKNOWN_CODESYSTEMS_CAUSE_ERROR = "-unknown-codesystems-cause-errors";
|
public static final String UNKNOWN_CODESYSTEMS_CAUSE_ERROR = "-unknown-codesystems-cause-errors";
|
||||||
|
public static final String NO_EXPERIMENTAL_CONTENT = "-no-experimental-content";
|
||||||
|
|
||||||
public static final String RUN_TESTS = "-run-tests";
|
public static final String RUN_TESTS = "-run-tests";
|
||||||
|
|
||||||
|
@ -321,6 +322,8 @@ public class Params {
|
||||||
cliContext.setForPublication(true);
|
cliContext.setForPublication(true);
|
||||||
} else if (args[i].equals(UNKNOWN_CODESYSTEMS_CAUSE_ERROR)) {
|
} else if (args[i].equals(UNKNOWN_CODESYSTEMS_CAUSE_ERROR)) {
|
||||||
cliContext.setUnknownCodeSystemsCauseErrors(true);
|
cliContext.setUnknownCodeSystemsCauseErrors(true);
|
||||||
|
} else if (args[i].equals(NO_EXPERIMENTAL_CONTENT)) {
|
||||||
|
cliContext.setNoExperimentalContent(true);
|
||||||
} else if (args[i].equals(VERBOSE)) {
|
} else if (args[i].equals(VERBOSE)) {
|
||||||
cliContext.setCrumbTrails(true);
|
cliContext.setCrumbTrails(true);
|
||||||
} else if (args[i].equals(ALLOW_EXAMPLE_URLS)) {
|
} else if (args[i].equals(ALLOW_EXAMPLE_URLS)) {
|
||||||
|
|
|
@ -217,6 +217,7 @@ import org.hl7.fhir.validation.instance.type.ValueSetValidator;
|
||||||
import org.hl7.fhir.validation.instance.utils.*;
|
import org.hl7.fhir.validation.instance.utils.*;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thinking of using this in a java program? Don't!
|
* Thinking of using this in a java program? Don't!
|
||||||
* You should use one of the wrappers instead. Either in HAPI, or use ValidationEngine
|
* You should use one of the wrappers instead. Either in HAPI, or use ValidationEngine
|
||||||
|
@ -599,6 +600,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
private IDigitalSignatureServices signatureServices;
|
private IDigitalSignatureServices signatureServices;
|
||||||
private ContextUtilities cu;
|
private ContextUtilities cu;
|
||||||
private boolean unknownCodeSystemsCauseErrors;
|
private boolean unknownCodeSystemsCauseErrors;
|
||||||
|
private boolean noExperimentalContent;
|
||||||
|
|
||||||
public InstanceValidator(@Nonnull IWorkerContext theContext, @Nonnull IEvaluationContext hostServices, @Nonnull XVerExtensionManager xverManager) {
|
public InstanceValidator(@Nonnull IWorkerContext theContext, @Nonnull IEvaluationContext hostServices, @Nonnull XVerExtensionManager xverManager) {
|
||||||
super(theContext, xverManager, false);
|
super(theContext, xverManager, false);
|
||||||
|
@ -1355,19 +1357,20 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
BindingStrength strength = binding.getStrength();
|
BindingStrength strength = binding.getStrength();
|
||||||
Extension maxVS = binding.getExtensionByUrl(ToolingExtensions.EXT_MAX_VALUESET);
|
Extension maxVS = binding.getExtensionByUrl(ToolingExtensions.EXT_MAX_VALUESET);
|
||||||
|
|
||||||
checkDisp = validateBindingCodeableConcept(errors, path, element, profile, stack, bh, checkDisp, checked, cc, vsRef, valueset, strength, maxVS, true);
|
checkDisp = validateBindingCodeableConcept(errors, path, element, profile, stack, bh, checkDisp, checked, cc, vsRef, valueset, strength, maxVS, true, null);
|
||||||
// } else if (binding.hasValueSet()) {
|
// } else if (binding.hasValueSet()) {
|
||||||
// hint(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_CANTCHECK);
|
// hint(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_CANTCHECK);
|
||||||
} else if (!noBindingMsgSuppressed) {
|
} else if (!noBindingMsgSuppressed) {
|
||||||
hint(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_NOSOURCE, path);
|
hint(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_NOSOURCE, path);
|
||||||
}
|
}
|
||||||
for (ElementDefinitionBindingAdditionalComponent ab : binding.getAdditional()) {
|
for (ElementDefinitionBindingAdditionalComponent ab : binding.getAdditional()) {
|
||||||
if (isTestableBinding(ab) && isInScope(ab)) {
|
StringBuilder b = new StringBuilder();
|
||||||
|
if (isTestableBinding(ab) && isInScope(ab, profile, getResource(stack), b)) {
|
||||||
String vsRef = ab.getValueSet();
|
String vsRef = ab.getValueSet();
|
||||||
ValueSet valueset = resolveBindingReference(profile, vsRef, profile.getUrl(), profile);
|
ValueSet valueset = resolveBindingReference(profile, vsRef, profile.getUrl(), profile);
|
||||||
BindingStrength strength = convertPurposeToStrength(ab.getPurpose());
|
BindingStrength strength = convertPurposeToStrength(ab.getPurpose());
|
||||||
|
|
||||||
checkDisp = validateBindingCodeableConcept(errors, path, element, profile, stack, bh, checkDisp, checked, cc, vsRef, valueset, strength, null, false) && checkDisp;
|
checkDisp = validateBindingCodeableConcept(errors, path, element, profile, stack, bh, checkDisp, checked, cc, vsRef, valueset, strength, null, false, b.toString()) && checkDisp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (CheckCodeOnServerException e) {
|
} catch (CheckCodeOnServerException e) {
|
||||||
|
@ -1393,25 +1396,186 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
return checkDisp;
|
return checkDisp;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInScope(ElementDefinitionBindingAdditionalComponent ab) {
|
private boolean isInScope(ElementDefinitionBindingAdditionalComponent ab, StructureDefinition profile, Element resource, StringBuilder b) {
|
||||||
|
if (ab.getUsage().isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
boolean ok = true;
|
||||||
for (UsageContext usage : ab.getUsage()) {
|
for (UsageContext usage : ab.getUsage()) {
|
||||||
if (isInScope(usage)) {
|
if (!isInScope(usage, profile, resource, b)) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isInScope(UsageContext usage, StructureDefinition profile, Element resource, StringBuilder b) {
|
||||||
|
if (isKnownUsage(usage)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (usage.getCode().hasSystem() && (usage.getCode().getSystem().equals(profile.getUrl()) || usage.getCode().getSystem().equals(profile.getVersionedUrl()))) {
|
||||||
|
// if it's not a defined usage from external sources, it might match something in the data content
|
||||||
|
List<Element> items = findDataValue(resource, usage.getCode().getCode());
|
||||||
|
if (matchesUsage(items, usage.getValue())) {
|
||||||
|
b.append(context.formatMessage(I18nConstants.BINDING_ADDITIONAL_USAGE, displayCoding(usage.getCode()), display(usage.getValue())));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ab.getUsage().isEmpty();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInScope(UsageContext usage) {
|
private String displayCoding(Coding value) {
|
||||||
if (isKnownUsage(usage)) {
|
return value.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String displayCodeableConcept(CodeableConcept value) {
|
||||||
|
for (Coding c : value.getCoding()) {
|
||||||
|
String s = displayCoding(c);
|
||||||
|
if (s != null) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String display(DataType value) {
|
||||||
|
switch (value.fhirType()) {
|
||||||
|
case "Coding" : return displayCoding((Coding) value);
|
||||||
|
case "CodeableConcept" : return displayCodeableConcept((CodeableConcept) value);
|
||||||
|
}
|
||||||
|
return value.fhirType();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean matchesUsage(List<Element> items, DataType value) {
|
||||||
|
for (Element item : items) {
|
||||||
|
if (matchesUsage(item, value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private String display(List<Element> items) {
|
||||||
|
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
|
||||||
|
for (Element item : items) {
|
||||||
|
display(b, item);
|
||||||
|
}
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void display(CommaSeparatedStringBuilder b, Element item) {
|
||||||
|
if (item.isPrimitive()) {
|
||||||
|
b.append(item.primitiveValue());
|
||||||
|
} else if (item.fhirType().equals("CodeableConcept")) {
|
||||||
|
for (Element c : item.getChildren("coding")) {
|
||||||
|
b.append(c.getNamedChildValue("code"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
b.append(item.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean matchesUsage(Element item, DataType value) {
|
||||||
|
switch (value.fhirType()) {
|
||||||
|
case "CodeableConcept": return matchesUsageCodeableConcept(item, (CodeableConcept) value);
|
||||||
|
case "Quantity": return false;
|
||||||
|
case "Range": return false;
|
||||||
|
case "Reference": return false;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean matchesUsageCodeableConcept(Element item, CodeableConcept value) {
|
||||||
|
switch (item.fhirType()) {
|
||||||
|
case "CodeableConcept": return matchesUsageCodeableConceptCodeableConcept(item, value);
|
||||||
|
case "Coding": return matchesUsageCodeableConceptCoding(item, value);
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean matchesUsageCodeableConceptCoding(Element item, CodeableConcept value) {
|
||||||
|
String system = item.getNamedChildValue("system");
|
||||||
|
String version = item.getNamedChildValue("version");
|
||||||
|
String code = item.getNamedChildValue("code");
|
||||||
|
for (Coding c : value.getCoding()) {
|
||||||
|
if (system == null || !system.equals(c.getSystem())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (code == null || !code.equals(c.getCode())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c.hasVersion()) {
|
||||||
|
if (version == null || !version.equals(c.getVersion())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean matchesUsageCodeableConceptCodeableConcept(Element item, CodeableConcept value) {
|
||||||
|
for (Element code : item.getChildren("coding")) {
|
||||||
|
if (matchesUsageCodeableConceptCoding(code, value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Element> findDataValue(Element resource, String code) {
|
||||||
|
List<Element> items = new ArrayList<Element>();
|
||||||
|
if (resource != null) {
|
||||||
|
findDataValues(items, resource, code);
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findDataValues(List<Element> items, Element element, String path) {
|
||||||
|
if (element.getPath() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pathMatches(element.getPath(), path)) {
|
||||||
|
items.add(element);
|
||||||
|
} else if (element.hasChildren() && path.startsWith(element.getPath())) {
|
||||||
|
for (Element child : element.getChildren()) {
|
||||||
|
findDataValues(items, child, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean pathMatches(String actualPath, String pathSpec) {
|
||||||
|
String[] ap = actualPath.split("\\.");
|
||||||
|
String[] ps = pathSpec.split("\\.");
|
||||||
|
if (ap.length != ps.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < ap.length; i++) {
|
||||||
|
if (!pathSegmentMatches(ap[i], ps[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean pathSegmentMatches(String ap, String ps) {
|
||||||
|
if (ps.contains("[")) {
|
||||||
|
return ap.equals(ps);
|
||||||
|
} else {
|
||||||
|
if (ap.contains("[")) {
|
||||||
|
ap = ap.substring(0, ap.indexOf("["));
|
||||||
|
}
|
||||||
|
return ap.equals(ps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private BindingStrength convertPurposeToStrength(AdditionalBindingPurposeVS purpose) {
|
private BindingStrength convertPurposeToStrength(AdditionalBindingPurposeVS purpose) {
|
||||||
switch (purpose) {
|
switch (purpose) {
|
||||||
case MAXIMUM: return BindingStrength.REQUIRED;
|
case MAXIMUM: return BindingStrength.REQUIRED;
|
||||||
|
case EXTENSIBLE: return BindingStrength.EXTENSIBLE;
|
||||||
case PREFERRED: return BindingStrength.PREFERRED;
|
case PREFERRED: return BindingStrength.PREFERRED;
|
||||||
case REQUIRED: return BindingStrength.REQUIRED;
|
case REQUIRED: return BindingStrength.REQUIRED;
|
||||||
default: return null;
|
default: return null;
|
||||||
|
@ -1423,7 +1587,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean validateBindingCodeableConcept(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, NodeStack stack, BooleanHolder bh, boolean checkDisp, BooleanHolder checked,
|
private boolean validateBindingCodeableConcept(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, NodeStack stack, BooleanHolder bh, boolean checkDisp, BooleanHolder checked,
|
||||||
CodeableConcept cc, String vsRef, ValueSet valueset, BindingStrength strength, Extension maxVS, boolean base) throws CheckCodeOnServerException {
|
CodeableConcept cc, String vsRef, ValueSet valueset, BindingStrength strength, Extension maxVS, boolean base, String usageNote) throws CheckCodeOnServerException {
|
||||||
if (valueset == null) {
|
if (valueset == null) {
|
||||||
CodeSystem cs = context.fetchCodeSystem(vsRef);
|
CodeSystem cs = context.fetchCodeSystem(vsRef);
|
||||||
if (rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, cs == null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND_CS, describeReference(vsRef))) {
|
if (rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, cs == null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND_CS, describeReference(vsRef))) {
|
||||||
|
@ -1435,12 +1599,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
BindingContext bc = base ? BindingContext.BASE : BindingContext.ADDITIONAL;
|
BindingContext bc = base ? BindingContext.BASE : BindingContext.ADDITIONAL;
|
||||||
if (!cc.hasCoding()) {
|
if (!cc.hasCoding()) {
|
||||||
if (strength == BindingStrength.REQUIRED)
|
if (strength == BindingStrength.REQUIRED)
|
||||||
bh.see(rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CODE_VALUESET, describeReference(vsRef, valueset, bc)));
|
bh.see(rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CODE_VALUESET, describeReference(vsRef, valueset, bc, usageNote)));
|
||||||
else if (strength == BindingStrength.EXTENSIBLE) {
|
else if (strength == BindingStrength.EXTENSIBLE) {
|
||||||
if (maxVS != null)
|
if (maxVS != null)
|
||||||
bh.see(rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CODE_VALUESETMAX, describeReference(ToolingExtensions.readStringFromExtension(maxVS)), valueset.getVersionedUrl()));
|
bh.see(rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CODE_VALUESETMAX, describeReference(ToolingExtensions.readStringFromExtension(maxVS)), valueset.getVersionedUrl()));
|
||||||
else if (!noExtensibleWarnings) {
|
else if (!noExtensibleWarnings) {
|
||||||
warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CODE_VALUESET_EXT, describeReference(vsRef, valueset, bc));
|
warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CODE_VALUESET_EXT, describeReference(vsRef, valueset, bc, usageNote));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1490,17 +1654,17 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
} else if (vr.getErrorClass() != null && vr.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) {
|
} else if (vr.getErrorClass() != null && vr.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) {
|
||||||
// we've already handled the warnings / errors about this, and set the status correctly. We don't need to do anything more?
|
// we've already handled the warnings / errors about this, and set the status correctly. We don't need to do anything more?
|
||||||
} else {
|
} else if (vr.getErrorClass() != TerminologyServiceErrorClass.SERVER_ERROR) { // (should have?) already handled server error
|
||||||
if (strength == BindingStrength.REQUIRED) {
|
if (strength == BindingStrength.REQUIRED) {
|
||||||
bh.see(txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_1_CC, describeReference(vsRef, valueset, bc), ccSummary(cc)));
|
bh.see(txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_1_CC, describeReference(vsRef, valueset, bc, usageNote), ccSummary(cc)));
|
||||||
} else if (strength == BindingStrength.EXTENSIBLE) {
|
} else if (strength == BindingStrength.EXTENSIBLE) {
|
||||||
if (maxVS != null)
|
if (maxVS != null)
|
||||||
bh.see(checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringFromExtension(maxVS), cc, stack));
|
bh.see(checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringFromExtension(maxVS), cc, stack));
|
||||||
if (!noExtensibleWarnings)
|
if (!noExtensibleWarnings)
|
||||||
txWarningForLaterRemoval(element, errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_2_CC, describeReference(vsRef, valueset, bc), ccSummary(cc));
|
txWarningForLaterRemoval(element, errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_2_CC, describeReference(vsRef, valueset, bc, usageNote), ccSummary(cc));
|
||||||
} else if (strength == BindingStrength.PREFERRED) {
|
} else if (strength == BindingStrength.PREFERRED) {
|
||||||
if (baseOnly) {
|
if (baseOnly) {
|
||||||
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_3_CC, describeReference(vsRef, valueset, bc), ccSummary(cc));
|
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_3_CC, describeReference(vsRef, valueset, bc, usageNote), ccSummary(cc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1647,7 +1811,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
BindingStrength strength = binding.getStrength();
|
BindingStrength strength = binding.getStrength();
|
||||||
Extension vsMax = binding.getExtensionByUrl(ToolingExtensions.EXT_MAX_VALUESET);
|
Extension vsMax = binding.getExtensionByUrl(ToolingExtensions.EXT_MAX_VALUESET);
|
||||||
|
|
||||||
validateBindingCodeableConcept(errors, path, element, profile, stack, ok, false, new BooleanHolder(), cc, vsRef, valueset, strength, vsMax, true);
|
validateBindingCodeableConcept(errors, path, element, profile, stack, ok, false, new BooleanHolder(), cc, vsRef, valueset, strength, vsMax, true, null);
|
||||||
|
|
||||||
// special case: if the logical model has both CodeableConcept and Coding mappings, we'll also check the first coding.
|
// special case: if the logical model has both CodeableConcept and Coding mappings, we'll also check the first coding.
|
||||||
if (getMapping("http://hl7.org/fhir/terminology-pattern", logical, logical.getSnapshot().getElementFirstRep()).contains("Coding")) {
|
if (getMapping("http://hl7.org/fhir/terminology-pattern", logical, logical.getSnapshot().getElementFirstRep()).contains("Coding")) {
|
||||||
|
@ -1659,11 +1823,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
hint(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_NOSOURCE, path);
|
hint(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_NOSOURCE, path);
|
||||||
}
|
}
|
||||||
for (ElementDefinitionBindingAdditionalComponent ab : binding.getAdditional()) {
|
for (ElementDefinitionBindingAdditionalComponent ab : binding.getAdditional()) {
|
||||||
if (isTestableBinding(ab) && isInScope(ab)) {
|
StringBuilder b = new StringBuilder();
|
||||||
|
if (isTestableBinding(ab) && isInScope(ab, profile, getResource(stack), b)) {
|
||||||
String vsRef = ab.getValueSet();
|
String vsRef = ab.getValueSet();
|
||||||
ValueSet valueset = resolveBindingReference(profile, vsRef, profile.getUrl(), profile);
|
ValueSet valueset = resolveBindingReference(profile, vsRef, profile.getUrl(), profile);
|
||||||
BindingStrength strength = convertPurposeToStrength(ab.getPurpose());
|
BindingStrength strength = convertPurposeToStrength(ab.getPurpose());
|
||||||
validateBindingCodeableConcept(errors, path, element, profile, stack, ok, false, new BooleanHolder(), cc, vsRef, valueset, strength, null, false);
|
validateBindingCodeableConcept(errors, path, element, profile, stack, ok, false, new BooleanHolder(), cc, vsRef, valueset, strength, null, false, b.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1697,18 +1862,19 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
BindingStrength strength = binding.getStrength();
|
BindingStrength strength = binding.getStrength();
|
||||||
Extension vsMax = binding.getExtensionByUrl(ToolingExtensions.EXT_MAX_VALUESET);
|
Extension vsMax = binding.getExtensionByUrl(ToolingExtensions.EXT_MAX_VALUESET);
|
||||||
|
|
||||||
ok = validateBindingTerminologyCoding(errors, path, element, profile, stack, ok, c, code, system, display, vsRef, valueset, strength, vsMax, true);
|
ok = validateBindingTerminologyCoding(errors, path, element, profile, stack, ok, c, code, system, display, vsRef, valueset, strength, vsMax, true, null);
|
||||||
} else if (binding.hasValueSet()) {
|
} else if (binding.hasValueSet()) {
|
||||||
hint(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_CANTCHECK);
|
hint(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_CANTCHECK);
|
||||||
} else if (!inCodeableConcept && !noBindingMsgSuppressed) {
|
} else if (!inCodeableConcept && !noBindingMsgSuppressed) {
|
||||||
hint(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_NOSOURCE, path);
|
hint(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_NOSOURCE, path);
|
||||||
}
|
}
|
||||||
for (ElementDefinitionBindingAdditionalComponent ab : binding.getAdditional()) {
|
for (ElementDefinitionBindingAdditionalComponent ab : binding.getAdditional()) {
|
||||||
if (isTestableBinding(ab) && isInScope(ab)) {
|
StringBuilder b = new StringBuilder();
|
||||||
|
if (isTestableBinding(ab) && isInScope(ab, profile, getResource(stack), b)) {
|
||||||
String vsRef = ab.getValueSet();
|
String vsRef = ab.getValueSet();
|
||||||
ValueSet valueset = resolveBindingReference(profile, vsRef, profile.getUrl(), profile);
|
ValueSet valueset = resolveBindingReference(profile, vsRef, profile.getUrl(), profile);
|
||||||
BindingStrength strength = convertPurposeToStrength(ab.getPurpose());
|
BindingStrength strength = convertPurposeToStrength(ab.getPurpose());
|
||||||
ok = validateBindingTerminologyCoding(errors, path, element, profile, stack, ok, c, code, system, display, vsRef, valueset, strength, null, true) && ok;
|
ok = validateBindingTerminologyCoding(errors, path, element, profile, stack, ok, c, code, system, display, vsRef, valueset, strength, null, true, b.toString()) && ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1727,7 +1893,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
|
|
||||||
private boolean validateBindingTerminologyCoding(List<ValidationMessage> errors, String path, Element element,
|
private boolean validateBindingTerminologyCoding(List<ValidationMessage> errors, String path, Element element,
|
||||||
StructureDefinition profile, NodeStack stack, boolean ok, Coding c, String code, String system, String display,
|
StructureDefinition profile, NodeStack stack, boolean ok, Coding c, String code, String system, String display,
|
||||||
String vsRef, ValueSet valueset, BindingStrength strength, Extension vsMax, boolean base) {
|
String vsRef, ValueSet valueset, BindingStrength strength, Extension vsMax, boolean base, String usageNote) {
|
||||||
if (valueset == null) {
|
if (valueset == null) {
|
||||||
CodeSystem cs = context.fetchCodeSystem(vsRef);
|
CodeSystem cs = context.fetchCodeSystem(vsRef);
|
||||||
if (rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, cs == null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND_CS, describeReference(vsRef))) {
|
if (rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, cs == null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND_CS, describeReference(vsRef))) {
|
||||||
|
@ -1753,27 +1919,27 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_NOSERVER, system+"#"+code);
|
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_NOSERVER, system+"#"+code);
|
||||||
else if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) {
|
else if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) {
|
||||||
if (strength == BindingStrength.REQUIRED)
|
if (strength == BindingStrength.REQUIRED)
|
||||||
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_4a, describeReference(vsRef, valueset, bc), vr.getMessage(), system+"#"+code);
|
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_4a, describeReference(vsRef, valueset, bc, usageNote), vr.getMessage(), system+"#"+code);
|
||||||
else if (strength == BindingStrength.EXTENSIBLE) {
|
else if (strength == BindingStrength.EXTENSIBLE) {
|
||||||
if (vsMax != null)
|
if (vsMax != null)
|
||||||
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringFromExtension(vsMax), c, stack);
|
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringFromExtension(vsMax), c, stack);
|
||||||
else if (!noExtensibleWarnings)
|
else if (!noExtensibleWarnings)
|
||||||
txWarningForLaterRemoval(element, errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_5, describeReference(vsRef, valueset, bc));
|
txWarningForLaterRemoval(element, errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_5, describeReference(vsRef, valueset, bc, usageNote));
|
||||||
} else if (strength == BindingStrength.PREFERRED) {
|
} else if (strength == BindingStrength.PREFERRED) {
|
||||||
if (baseOnly) {
|
if (baseOnly) {
|
||||||
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_6, describeReference(vsRef, valueset, bc));
|
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_6, describeReference(vsRef, valueset, bc, usageNote));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (strength == BindingStrength.REQUIRED)
|
} else if (strength == BindingStrength.REQUIRED)
|
||||||
ok= txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_4, describeReference(vsRef, valueset, bc), (vr.getMessage() != null ? " (error message = " + vr.getMessage() + ")" : ""), system+"#"+code) && ok;
|
ok= txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_4, describeReference(vsRef, valueset, bc, usageNote), (vr.getMessage() != null ? " (error message = " + vr.getMessage() + ")" : ""), system+"#"+code) && ok;
|
||||||
else if (strength == BindingStrength.EXTENSIBLE) {
|
else if (strength == BindingStrength.EXTENSIBLE) {
|
||||||
if (vsMax != null)
|
if (vsMax != null)
|
||||||
ok = checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringFromExtension(vsMax), c, stack) && ok;
|
ok = checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringFromExtension(vsMax), c, stack) && ok;
|
||||||
else
|
else
|
||||||
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_5, describeReference(vsRef, valueset, bc), (vr.getMessage() != null ? " (error message = " + vr.getMessage() + ")" : ""), system+"#"+code);
|
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_5, describeReference(vsRef, valueset, bc, usageNote), (vr.getMessage() != null ? " (error message = " + vr.getMessage() + ")" : ""), system+"#"+code);
|
||||||
} else if (strength == BindingStrength.PREFERRED) {
|
} else if (strength == BindingStrength.PREFERRED) {
|
||||||
if (baseOnly) {
|
if (baseOnly) {
|
||||||
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_6, describeReference(vsRef, valueset, bc), (vr.getMessage() != null ? " (error message = " + vr.getMessage() + ")" : ""), system+"#"+code);
|
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_6, describeReference(vsRef, valueset, bc, usageNote), (vr.getMessage() != null ? " (error message = " + vr.getMessage() + ")" : ""), system+"#"+code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (vr != null && vr.getMessage() != null){
|
} else if (vr != null && vr.getMessage() != null){
|
||||||
|
@ -1895,9 +2061,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
timeTracker.tx(t, "vc "+cc.toString());
|
timeTracker.tx(t, "vc "+cc.toString());
|
||||||
if (!vr.isOk()) {
|
if (!vr.isOk()) {
|
||||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||||
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_7, describeReference(maxVSUrl, valueset, BindingContext.MAXVS), vr.getMessage());
|
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_7, describeReference(maxVSUrl, valueset, BindingContext.MAXVS, null), vr.getMessage());
|
||||||
else
|
else
|
||||||
ok = txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_8, describeReference(maxVSUrl, valueset, BindingContext.MAXVS), ccSummary(cc)) && ok;
|
ok = txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_8, describeReference(maxVSUrl, valueset, BindingContext.MAXVS, null), ccSummary(cc)) && ok;
|
||||||
}
|
}
|
||||||
} catch (CheckCodeOnServerException e) {
|
} catch (CheckCodeOnServerException e) {
|
||||||
if (STACK_TRACE) e.getCause().printStackTrace();
|
if (STACK_TRACE) e.getCause().printStackTrace();
|
||||||
|
@ -1935,9 +2101,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
timeTracker.tx(t, "vc "+c.getSystem()+"#"+c.getCode()+" '"+c.getDisplay()+"'");
|
timeTracker.tx(t, "vc "+c.getSystem()+"#"+c.getCode()+" '"+c.getDisplay()+"'");
|
||||||
if (!vr.isOk()) {
|
if (!vr.isOk()) {
|
||||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||||
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_9, describeReference(maxVSUrl, valueset, BindingContext.MAXVS), vr.getMessage(), c.getSystem()+"#"+c.getCode());
|
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_9, describeReference(maxVSUrl, valueset, BindingContext.MAXVS, null), vr.getMessage(), c.getSystem()+"#"+c.getCode());
|
||||||
else
|
else
|
||||||
ok = txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_10, describeReference(maxVSUrl, valueset, BindingContext.MAXVS), c.getSystem(), c.getCode()) && ok;
|
ok = txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_10, describeReference(maxVSUrl, valueset, BindingContext.MAXVS, null), c.getSystem(), c.getCode()) && ok;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (STACK_TRACE) e.printStackTrace();
|
if (STACK_TRACE) e.printStackTrace();
|
||||||
|
@ -1965,9 +2131,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
timeTracker.tx(t, "vc "+value);
|
timeTracker.tx(t, "vc "+value);
|
||||||
if (!vr.isOk()) {
|
if (!vr.isOk()) {
|
||||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||||
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_9, describeReference(maxVSUrl, valueset, BindingContext.BASE), vr.getMessage(), value);
|
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_9, describeReference(maxVSUrl, valueset, BindingContext.BASE, null), vr.getMessage(), value);
|
||||||
else {
|
else {
|
||||||
ok = txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_11, describeReference(maxVSUrl, valueset, BindingContext.BASE), vr.getMessage()) && ok;
|
ok = txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_11, describeReference(maxVSUrl, valueset, BindingContext.BASE, null), vr.getMessage()) && ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -2028,7 +2194,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
BindingStrength strength = binding.getStrength();
|
BindingStrength strength = binding.getStrength();
|
||||||
Extension vsMax = binding.getExtensionByUrl(ToolingExtensions.EXT_MAX_VALUESET);
|
Extension vsMax = binding.getExtensionByUrl(ToolingExtensions.EXT_MAX_VALUESET);
|
||||||
|
|
||||||
ok = validateBindingCodedElement(errors, path, element, profile, stack, theCode, theSystem, ok, checked, c, vsRef, valueset, strength, vsMax, true);
|
ok = validateBindingCodedElement(errors, path, element, profile, stack, theCode, theSystem, ok, checked, c, vsRef, valueset, strength, vsMax, true, null);
|
||||||
// } else if (binding.hasValueSet()) {
|
// } else if (binding.hasValueSet()) {
|
||||||
// hint(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_CANTCHECK);
|
// hint(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_CANTCHECK);
|
||||||
|
|
||||||
|
@ -2037,12 +2203,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ElementDefinitionBindingAdditionalComponent ab : binding.getAdditional()) {
|
for (ElementDefinitionBindingAdditionalComponent ab : binding.getAdditional()) {
|
||||||
if (isTestableBinding(ab) && isInScope(ab)) {
|
StringBuilder b = new StringBuilder();
|
||||||
|
if (isTestableBinding(ab) && isInScope(ab, profile, getResource(stack), b)) {
|
||||||
String vsRef = ab.getValueSet();
|
String vsRef = ab.getValueSet();
|
||||||
ValueSet valueset = resolveBindingReference(profile, vsRef, profile.getUrl(), profile);
|
ValueSet valueset = resolveBindingReference(profile, vsRef, profile.getUrl(), profile);
|
||||||
BindingStrength strength = convertPurposeToStrength(ab.getPurpose());
|
BindingStrength strength = convertPurposeToStrength(ab.getPurpose());
|
||||||
|
|
||||||
ok = validateBindingCodedElement(errors, path, element, profile, stack, theCode, theSystem, ok, checked, c, vsRef, valueset, strength, null, false) && ok;
|
ok = validateBindingCodedElement(errors, path, element, profile, stack, theCode, theSystem, ok, checked, c, vsRef, valueset, strength, null, false, b.toString()) && ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -2067,9 +2234,19 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Element getResource(NodeStack stack) {
|
||||||
|
if (stack.getElement().isResource()) {
|
||||||
|
return stack.getElement();
|
||||||
|
}
|
||||||
|
if (stack.getParent() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getResource(stack.getParent());
|
||||||
|
}
|
||||||
|
|
||||||
private boolean validateBindingCodedElement(List<ValidationMessage> errors, String path, Element element,
|
private boolean validateBindingCodedElement(List<ValidationMessage> errors, String path, Element element,
|
||||||
StructureDefinition profile, NodeStack stack, String theCode, String theSystem, boolean ok, BooleanHolder checked,
|
StructureDefinition profile, NodeStack stack, String theCode, String theSystem, boolean ok, BooleanHolder checked,
|
||||||
Coding c, String vsRef, ValueSet valueset, BindingStrength strength, Extension vsMax, boolean base) {
|
Coding c, String vsRef, ValueSet valueset, BindingStrength strength, Extension vsMax, boolean base, String usageNote) {
|
||||||
if (valueset == null) {
|
if (valueset == null) {
|
||||||
CodeSystem cs = context.fetchCodeSystem(vsRef);
|
CodeSystem cs = context.fetchCodeSystem(vsRef);
|
||||||
if (rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, cs == null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND_CS, describeReference(vsRef))) {
|
if (rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, cs == null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND_CS, describeReference(vsRef))) {
|
||||||
|
@ -2097,28 +2274,28 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_NOSERVER, theSystem+"#"+theCode);
|
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_NOSERVER, theSystem+"#"+theCode);
|
||||||
else if (vr.getErrorClass() != null && !vr.getErrorClass().isInfrastructure()) {
|
else if (vr.getErrorClass() != null && !vr.getErrorClass().isInfrastructure()) {
|
||||||
if (strength == BindingStrength.REQUIRED)
|
if (strength == BindingStrength.REQUIRED)
|
||||||
ok = txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_4a, describeReference(vsRef, valueset, bc), vr.getMessage(), theSystem+"#"+theCode) && ok;
|
ok = txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_4a, describeReference(vsRef, valueset, bc, usageNote), vr.getMessage(), theSystem+"#"+theCode) && ok;
|
||||||
else if (strength == BindingStrength.EXTENSIBLE) {
|
else if (strength == BindingStrength.EXTENSIBLE) {
|
||||||
if (vsMax != null)
|
if (vsMax != null)
|
||||||
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringFromExtension(vsMax), c, stack);
|
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringFromExtension(vsMax), c, stack);
|
||||||
else if (!noExtensibleWarnings)
|
else if (!noExtensibleWarnings)
|
||||||
txWarningForLaterRemoval(element, errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_5, describeReference(vsRef, valueset, bc), theSystem+"#"+theCode);
|
txWarningForLaterRemoval(element, errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_5, describeReference(vsRef, valueset, bc, usageNote), theSystem+"#"+theCode);
|
||||||
} else if (strength == BindingStrength.PREFERRED) {
|
} else if (strength == BindingStrength.PREFERRED) {
|
||||||
if (baseOnly) {
|
if (baseOnly) {
|
||||||
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_6, describeReference(vsRef, valueset, bc), theSystem+"#"+theCode);
|
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_6, describeReference(vsRef, valueset, bc, usageNote), theSystem+"#"+theCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (strength == BindingStrength.REQUIRED)
|
} else if (strength == BindingStrength.REQUIRED)
|
||||||
ok = txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_12, describeReference(vsRef, valueset, bc), getErrorMessage(vr.getMessage()), theSystem+"#"+theCode) && ok;
|
ok = txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_12, describeReference(vsRef, valueset, bc, usageNote), getErrorMessage(vr.getMessage()), theSystem+"#"+theCode) && ok;
|
||||||
else if (strength == BindingStrength.EXTENSIBLE) {
|
else if (strength == BindingStrength.EXTENSIBLE) {
|
||||||
if (vsMax != null)
|
if (vsMax != null)
|
||||||
ok = checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringFromExtension(vsMax), c, stack) && ok;
|
ok = checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringFromExtension(vsMax), c, stack) && ok;
|
||||||
else if (!noExtensibleWarnings) {
|
else if (!noExtensibleWarnings) {
|
||||||
txWarningForLaterRemoval(element, errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_13, describeReference(vsRef, valueset, bc), getErrorMessage(vr.getMessage()), c.getSystem()+"#"+c.getCode());
|
txWarningForLaterRemoval(element, errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_13, describeReference(vsRef, valueset, bc, usageNote), getErrorMessage(vr.getMessage()), c.getSystem()+"#"+c.getCode());
|
||||||
}
|
}
|
||||||
} else if (strength == BindingStrength.PREFERRED) {
|
} else if (strength == BindingStrength.PREFERRED) {
|
||||||
if (baseOnly) {
|
if (baseOnly) {
|
||||||
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_14, describeReference(vsRef, valueset, bc), getErrorMessage(vr.getMessage()), theSystem+"#"+theCode);
|
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_14, describeReference(vsRef, valueset, bc, usageNote), getErrorMessage(vr.getMessage()), theSystem+"#"+theCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (vr != null && vr.getMessage() != null) {
|
} else if (vr != null && vr.getMessage() != null) {
|
||||||
|
@ -3016,7 +3193,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
// check that no illegal elements and attributes have been used
|
// check that no illegal elements and attributes have been used
|
||||||
ok = checkInnerNames(errors, e, path, xhtml.getChildNodes(), false) && ok;
|
ok = checkInnerNames(errors, e, path, xhtml.getChildNodes(), false) && ok;
|
||||||
ok = checkUrls(errors, e, path, xhtml.getChildNodes()) && ok;
|
ok = checkUrls(errors, e, path, xhtml.getChildNodes()) && ok;
|
||||||
ok = checkIdRefs(errors, e, path, xhtml, resource) && ok;
|
ok = checkIdRefs(errors, e, path, xhtml, resource, node) && ok;
|
||||||
if (true) {
|
if (true) {
|
||||||
ok = checkReferences(valContext, errors, e, path, "div", xhtml, resource) && ok;
|
ok = checkReferences(valContext, errors, e, path, "div", xhtml, resource) && ok;
|
||||||
}
|
}
|
||||||
|
@ -3465,11 +3642,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkIdRefs(List<ValidationMessage> errors, Element e, String path, XhtmlNode node, Element resource) {
|
private boolean checkIdRefs(List<ValidationMessage> errors, Element e, String path, XhtmlNode node, Element resource, NodeStack stack) {
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
if (node.getNodeType() == NodeType.Element && node.getAttribute("idref") != null) {
|
if (node.getNodeType() == NodeType.Element && node.getAttribute("idref") != null) {
|
||||||
String idref = node.getAttribute("idref");
|
String idref = node.getAttribute("idref");
|
||||||
int count = countFragmentMatches(resource, idref);
|
int count = countFragmentMatches(resource, idref, stack);
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
ok = warning(errors, "2023-12-01", IssueType.INVALID, e.line(), e.col(), path, idref == null, I18nConstants.XHTML_IDREF_NOT_FOUND, idref) && ok;
|
ok = warning(errors, "2023-12-01", IssueType.INVALID, e.line(), e.col(), path, idref == null, I18nConstants.XHTML_IDREF_NOT_FOUND, idref) && ok;
|
||||||
} else if (count > 1) {
|
} else if (count > 1) {
|
||||||
|
@ -3478,7 +3655,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
if (node.hasChildren()) {
|
if (node.hasChildren()) {
|
||||||
for (XhtmlNode child : node.getChildNodes()) {
|
for (XhtmlNode child : node.getChildNodes()) {
|
||||||
checkIdRefs(errors, e, path, child, resource);
|
checkIdRefs(errors, e, path, child, resource, stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
|
@ -3562,15 +3739,15 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
} else if (vr.getErrorClass() != null && vr.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) {
|
} else if (vr.getErrorClass() != null && vr.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) {
|
||||||
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
|
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
|
||||||
} else if (binding.getStrength() == BindingStrength.REQUIRED) {
|
} else if (binding.getStrength() == BindingStrength.REQUIRED) {
|
||||||
ok = txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_16, value, describeReference(binding.getValueSet(), vs, BindingContext.BASE), getErrorMessage(vr.getMessage())) && ok;
|
ok = txRule(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_16, value, describeReference(binding.getValueSet(), vs, BindingContext.BASE, null), getErrorMessage(vr.getMessage())) && ok;
|
||||||
} else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
} else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
||||||
if (binding.hasExtension(ToolingExtensions.EXT_MAX_VALUESET))
|
if (binding.hasExtension(ToolingExtensions.EXT_MAX_VALUESET))
|
||||||
ok = checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, ToolingExtensions.EXT_MAX_VALUESET), value, stack) && ok;
|
ok = checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, ToolingExtensions.EXT_MAX_VALUESET), value, stack) && ok;
|
||||||
else if (!noExtensibleWarnings && !isOkExtension(value, vs))
|
else if (!noExtensibleWarnings && !isOkExtension(value, vs))
|
||||||
txWarningForLaterRemoval(element, errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_17, value, describeReference(binding.getValueSet(), vs, BindingContext.BASE), getErrorMessage(vr.getMessage()));
|
txWarningForLaterRemoval(element, errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_17, value, describeReference(binding.getValueSet(), vs, BindingContext.BASE, null), getErrorMessage(vr.getMessage()));
|
||||||
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
|
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
|
||||||
if (baseOnly) {
|
if (baseOnly) {
|
||||||
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_18, value, describeReference(binding.getValueSet(), vs, BindingContext.BASE), getErrorMessage(vr.getMessage()));
|
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_18, value, describeReference(binding.getValueSet(), vs, BindingContext.BASE, null), getErrorMessage(vr.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (vr != null && vr.getMessage() != null){
|
} else if (vr != null && vr.getMessage() != null){
|
||||||
|
@ -4278,7 +4455,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String describeReference(String reference, CanonicalResource target, BindingContext ctxt) {
|
private String describeReference(String reference, CanonicalResource target, BindingContext ctxt, String usageNote) {
|
||||||
if (reference == null && target == null)
|
if (reference == null && target == null)
|
||||||
return "null";
|
return "null";
|
||||||
String res = null;
|
String res = null;
|
||||||
|
@ -4296,7 +4473,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (ctxt) {
|
switch (ctxt) {
|
||||||
case ADDITIONAL: return context.formatMessage(I18nConstants.BINDING_ADDITIONAL, res);
|
case ADDITIONAL: return context.formatMessage(Utilities.noString(usageNote) ? I18nConstants.BINDING_ADDITIONAL_D : I18nConstants.BINDING_ADDITIONAL_UC, res, usageNote);
|
||||||
case MAXVS: return context.formatMessage(I18nConstants.BINDING_MAX, res);
|
case MAXVS: return context.formatMessage(I18nConstants.BINDING_MAX, res);
|
||||||
default: return res;
|
default: return res;
|
||||||
}
|
}
|
||||||
|
@ -5718,6 +5895,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
hint(errors, "2023-08-14", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), statusCodesDeeplyConsistent(status, standardsStatus), I18nConstants.VALIDATION_VAL_STATUS_INCONSISTENT_HINT, status, standardsStatus);
|
hint(errors, "2023-08-14", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), statusCodesDeeplyConsistent(status, standardsStatus), I18nConstants.VALIDATION_VAL_STATUS_INCONSISTENT_HINT, status, standardsStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (noExperimentalContent) {
|
||||||
|
String exp = element.getNamedChildValue("experimental");
|
||||||
|
ok = rule(errors, "2024-09-17", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), !"true".equals(exp), I18nConstants.VALIDATION_NO_EXPERIMENTAL_CONTENT) && ok;
|
||||||
|
}
|
||||||
|
|
||||||
if (isHL7Core(element) && !isExample()) {
|
if (isHL7Core(element) && !isExample()) {
|
||||||
ok = checkPublisherConsistency(valContext, errors, element, stack, contained) && ok;
|
ok = checkPublisherConsistency(valContext, errors, element, stack, contained) && ok;
|
||||||
|
@ -5886,20 +6067,22 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
Element div = text.getNamedChild("div", false);
|
Element div = text.getNamedChild("div", false);
|
||||||
if (lang != null && div != null) {
|
if (lang != null && div != null) {
|
||||||
XhtmlNode xhtml = div.getXhtml();
|
XhtmlNode xhtml = div.getXhtml();
|
||||||
String l = xhtml.getAttribute("lang");
|
if (xhtml != null) {
|
||||||
String xl = xhtml.getAttribute("xml:lang");
|
String l = xhtml.getAttribute("lang");
|
||||||
if (l == null && xl == null) {
|
String xl = xhtml.getAttribute("xml:lang");
|
||||||
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_MISSING1);
|
if (l == null && xl == null) {
|
||||||
} else {
|
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_MISSING1);
|
||||||
if (l == null) {
|
} else {
|
||||||
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_MISSING2);
|
if (l == null) {
|
||||||
} else if (!l.equals(lang)) {
|
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_MISSING2);
|
||||||
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_DIFFERENT1, lang, l);
|
} else if (!l.equals(lang)) {
|
||||||
}
|
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_DIFFERENT1, lang, l);
|
||||||
if (xl == null) {
|
}
|
||||||
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_MISSING3);
|
if (xl == null) {
|
||||||
} else if (!xl.equals(lang)) {
|
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_MISSING3);
|
||||||
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_DIFFERENT2, lang, xl);
|
} else if (!xl.equals(lang)) {
|
||||||
|
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_DIFFERENT2, lang, xl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7434,6 +7617,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public long timeNoTX() {
|
||||||
|
return (timeTracker.getOverall() - timeTracker.getTxTime()) / 1000000;
|
||||||
|
}
|
||||||
public String reportTimes() {
|
public String reportTimes() {
|
||||||
String s = String.format("Times (ms): overall = %d:4, tx = %d, sd = %d, load = %d, fpe = %d, spec = %d", timeTracker.getOverall() / 1000000, timeTracker.getTxTime() / 1000000, timeTracker.getSdTime() / 1000000, timeTracker.getLoadTime() / 1000000, timeTracker.getFpeTime() / 1000000, timeTracker.getSpecTime() / 1000000);
|
String s = String.format("Times (ms): overall = %d:4, tx = %d, sd = %d, load = %d, fpe = %d, spec = %d", timeTracker.getOverall() / 1000000, timeTracker.getTxTime() / 1000000, timeTracker.getSdTime() / 1000000, timeTracker.getLoadTime() / 1000000, timeTracker.getFpeTime() / 1000000, timeTracker.getSpecTime() / 1000000);
|
||||||
timeTracker.reset();
|
timeTracker.reset();
|
||||||
|
@ -7839,6 +8025,18 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
public void setUnknownCodeSystemsCauseErrors(boolean unknownCodeSystemsCauseErrors) {
|
public void setUnknownCodeSystemsCauseErrors(boolean unknownCodeSystemsCauseErrors) {
|
||||||
this.unknownCodeSystemsCauseErrors = unknownCodeSystemsCauseErrors;
|
this.unknownCodeSystemsCauseErrors = unknownCodeSystemsCauseErrors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isNoExperimentalContent() {
|
||||||
|
return noExperimentalContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNoExperimentalContent(boolean noExperimentalContent) {
|
||||||
|
this.noExperimentalContent = noExperimentalContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetTimes() {
|
||||||
|
timeTracker.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
||||||
List<ElementDefinition> snapshot = sd.getSnapshot().getElement();
|
List<ElementDefinition> snapshot = sd.getSnapshot().getElement();
|
||||||
sd.setSnapshot(null);
|
sd.setSnapshot(null);
|
||||||
typeName = sd.getTypeName();
|
typeName = sd.getTypeName();
|
||||||
|
boolean experimental = "true".equals(src.getNamedChildValue("experimental", false));
|
||||||
StructureDefinition base = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
StructureDefinition base = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||||
if (warning(errors, NO_RULE_DATE, IssueType.NOTFOUND, stack.getLiteralPath(), base != null, I18nConstants.UNABLE_TO_FIND_BASE__FOR_, sd.getBaseDefinition(), "StructureDefinition, so can't check the differential")) {
|
if (warning(errors, NO_RULE_DATE, IssueType.NOTFOUND, stack.getLiteralPath(), base != null, I18nConstants.UNABLE_TO_FIND_BASE__FOR_, sd.getBaseDefinition(), "StructureDefinition, so can't check the differential")) {
|
||||||
if (rule(errors, NO_RULE_DATE, IssueType.NOTFOUND, stack.getLiteralPath(), sd.hasDerivation(), I18nConstants.SD_MUST_HAVE_DERIVATION, sd.getUrl())) {
|
if (rule(errors, NO_RULE_DATE, IssueType.NOTFOUND, stack.getLiteralPath(), sd.hasDerivation(), I18nConstants.SD_MUST_HAVE_DERIVATION, sd.getUrl())) {
|
||||||
|
@ -129,6 +130,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
||||||
ok = rule(errors, "2022-11-02", IssueType.NOTFOUND, stack.getLiteralPath(), base.getKindElement().primitiveValue().equals(src.getChildValue("kind")),
|
ok = rule(errors, "2022-11-02", IssueType.NOTFOUND, stack.getLiteralPath(), base.getKindElement().primitiveValue().equals(src.getChildValue("kind")),
|
||||||
I18nConstants.SD_DERIVATION_KIND_MISMATCH, base.getKindElement().primitiveValue(), src.getChildValue("kind")) && ok;
|
I18nConstants.SD_DERIVATION_KIND_MISMATCH, base.getKindElement().primitiveValue(), src.getChildValue("kind")) && ok;
|
||||||
}
|
}
|
||||||
|
warning(errors, "2024-09-17", IssueType.BUSINESSRULE, stack.getLiteralPath(), !base.getExperimental() || experimental, I18nConstants.SD_BASE_EXPERIMENTAL, sd.getBaseDefinition());
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Element> differentials = src.getChildrenByName("differential");
|
List<Element> differentials = src.getChildrenByName("differential");
|
||||||
|
@ -136,10 +138,10 @@ public class StructureDefinitionValidator extends BaseValidator {
|
||||||
boolean logical = "logical".equals(src.getNamedChildValue("kind", false));
|
boolean logical = "logical".equals(src.getNamedChildValue("kind", false));
|
||||||
boolean constraint = "constraint".equals(src.getNamedChildValue("derivation", false));
|
boolean constraint = "constraint".equals(src.getNamedChildValue("derivation", false));
|
||||||
for (Element differential : differentials) {
|
for (Element differential : differentials) {
|
||||||
ok = validateElementList(errors, differential, stack.push(differential, -1, null, null), false, snapshots.size() > 0, sd, typeName, logical, constraint, src.getNamedChildValue("type", false), src.getNamedChildValue("url", false), src.getNamedChildValue("type", false), base) && ok;
|
ok = validateElementList(errors, differential, stack.push(differential, -1, null, null), false, snapshots.size() > 0, sd, typeName, logical, constraint, src.getNamedChildValue("type", false), src.getNamedChildValue("url", false), src.getNamedChildValue("type", false), base, experimental) && ok;
|
||||||
}
|
}
|
||||||
for (Element snapshotE : snapshots) {
|
for (Element snapshotE : snapshots) {
|
||||||
ok = validateElementList(errors, snapshotE, stack.push(snapshotE, -1, null, null), true, true, sd, typeName, logical, constraint, src.getNamedChildValue("type", false), src.getNamedChildValue("url", false), src.getNamedChildValue("type", false), base) && ok;
|
ok = validateElementList(errors, snapshotE, stack.push(snapshotE, -1, null, null), true, true, sd, typeName, logical, constraint, src.getNamedChildValue("type", false), src.getNamedChildValue("url", false), src.getNamedChildValue("type", false), base, experimental) && ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// obligation profile support
|
// obligation profile support
|
||||||
|
@ -189,6 +191,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
//e.printStackTrace();
|
||||||
rule(errors, NO_RULE_DATE, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.ERROR_GENERATING_SNAPSHOT, e.getMessage());
|
rule(errors, NO_RULE_DATE, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.ERROR_GENERATING_SNAPSHOT, e.getMessage());
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
@ -409,19 +412,19 @@ public class StructureDefinitionValidator extends BaseValidator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean validateElementList(List<ValidationMessage> errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical, boolean constraint, String rootPath, String profileUrl, String profileType, StructureDefinition base) {
|
private boolean validateElementList(List<ValidationMessage> errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical, boolean constraint, String rootPath, String profileUrl, String profileType, StructureDefinition base, boolean experimental) {
|
||||||
Map<String, String> invariantMap = new HashMap<>();
|
Map<String, String> invariantMap = new HashMap<>();
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
List<Element> elements = elementList.getChildrenByName("element");
|
List<Element> elements = elementList.getChildrenByName("element");
|
||||||
int cc = 0;
|
int cc = 0;
|
||||||
for (Element element : elements) {
|
for (Element element : elements) {
|
||||||
ok = validateElementDefinition(errors, elements, element, stack.push(element, cc, null, null), snapshot, hasSnapshot, sd, typeName, logical, constraint, invariantMap, rootPath, profileUrl, profileType, base) && ok;
|
ok = validateElementDefinition(errors, elements, element, stack.push(element, cc, null, null), snapshot, hasSnapshot, sd, typeName, logical, constraint, invariantMap, rootPath, profileUrl, profileType, base, experimental) && ok;
|
||||||
cc++;
|
cc++;
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean validateElementDefinition(List<ValidationMessage> errors, List<Element> elements, Element element, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical, boolean constraint, Map<String, String> invariantMap, String rootPath, String profileUrl, String profileType, StructureDefinition base) {
|
private boolean validateElementDefinition(List<ValidationMessage> errors, List<Element> elements, Element element, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical, boolean constraint, Map<String, String> invariantMap, String rootPath, String profileUrl, String profileType, StructureDefinition base, boolean experimental) {
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
boolean typeMustSupport = false;
|
boolean typeMustSupport = false;
|
||||||
String path = element.getNamedChildValue("path", false);
|
String path = element.getNamedChildValue("path", false);
|
||||||
|
@ -522,7 +525,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
||||||
ok = rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), characteristics.contains("can-bind") , I18nConstants.SD_ILLEGAL_CHARACTERISTICS, "Binding", typeCodes) && ok;
|
ok = rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), characteristics.contains("can-bind") , I18nConstants.SD_ILLEGAL_CHARACTERISTICS, "Binding", typeCodes) && ok;
|
||||||
}
|
}
|
||||||
Element binding = element.getNamedChild("binding", false);
|
Element binding = element.getNamedChild("binding", false);
|
||||||
ok = validateBinding(errors, binding, stack.push(binding, -1, null, null), typeCodes, snapshot, path) && ok;
|
ok = validateBinding(errors, binding, stack.push(binding, -1, null, null), typeCodes, snapshot, path, experimental, sd) && ok;
|
||||||
} else {
|
} else {
|
||||||
// this is a good idea but there's plenty of cases where the rule isn't met; maybe one day it's worth investing the time to exclude these cases and bring this rule back
|
// this is a good idea but there's plenty of cases where the rule isn't met; maybe one day it's worth investing the time to exclude these cases and bring this rule back
|
||||||
// String bt = boundType(typeCodes);
|
// String bt = boundType(typeCodes);
|
||||||
|
@ -986,7 +989,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean validateBinding(List<ValidationMessage> errors, Element binding, NodeStack stack, Set<String> typeCodes, boolean snapshot, String path) {
|
private boolean validateBinding(List<ValidationMessage> errors, Element binding, NodeStack stack, Set<String> typeCodes, boolean snapshot, String path, boolean experimental, StructureDefinition profile) {
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
if (bindableType(typeCodes) == null) {
|
if (bindableType(typeCodes) == null) {
|
||||||
ok = rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), !snapshot, I18nConstants.SD_ED_BIND_NO_BINDABLE, path, typeCodes.toString()) && ok;
|
ok = rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), !snapshot, I18nConstants.SD_ED_BIND_NO_BINDABLE, path, typeCodes.toString()) && ok;
|
||||||
|
@ -1006,14 +1009,132 @@ public class StructureDefinitionValidator extends BaseValidator {
|
||||||
|
|
||||||
if (warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs != null || serverSupportsValueSet(ref), I18nConstants.SD_ED_BIND_UNKNOWN_VS, path, ref)) {
|
if (warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs != null || serverSupportsValueSet(ref), I18nConstants.SD_ED_BIND_UNKNOWN_VS, path, ref)) {
|
||||||
if (vs != null) {
|
if (vs != null) {
|
||||||
ok = rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs instanceof ValueSet, I18nConstants.SD_ED_BIND_NOT_VS, path, ref, vs.fhirType()) && ok;
|
if (rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs instanceof ValueSet, I18nConstants.SD_ED_BIND_NOT_VS, path, ref, vs.fhirType())) {
|
||||||
|
ValueSet vsr = (ValueSet) vs;
|
||||||
|
warning(errors, "2024-09-17", IssueType.BUSINESSRULE, stack.getLiteralPath(), !vsr.getExperimental() || experimental, I18nConstants.SD_ED_EXPERIMENTAL_BINDING, path, ref);
|
||||||
|
} else {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (binding.hasChildren("additional")) {
|
||||||
|
int i = 0;
|
||||||
|
for (Element ab : binding.getChildren("additional")) {
|
||||||
|
ok = validateAdditionalBinding(errors, ab, stack.push(ab, i, null, null), snapshot, path, experimental) && ok;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (binding.hasExtension(ToolingExtensions.EXT_BINDING_ADDITIONAL)) {
|
||||||
|
int i = 0;
|
||||||
|
for (Element ab : binding.getChildren("extension")) {
|
||||||
|
String url = ab.getNamedChildValue("url");
|
||||||
|
if (ToolingExtensions.EXT_BINDING_ADDITIONAL.equals(url)) {
|
||||||
|
ok = validateAdditionalBindingExtension(errors, ab, stack.push(ab, i, null, null), snapshot, path, experimental, profile) && ok;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean validateAdditionalBinding(List<ValidationMessage> errors, Element binding, NodeStack stack, boolean snapshot, String path, boolean experimental) {
|
||||||
|
boolean ok = true;
|
||||||
|
|
||||||
|
if (binding.hasChild("valueSet", false)) {
|
||||||
|
Element valueSet = binding.getNamedChild("valueSet", false);
|
||||||
|
String ref = valueSet.hasPrimitiveValue() ? valueSet.primitiveValue() : valueSet.getNamedChildValue("reference", false);
|
||||||
|
if (warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), !snapshot || ref != null, I18nConstants.SD_ED_SHOULD_BIND_WITH_VS, path)) {
|
||||||
|
Resource vs = context.fetchResource(Resource.class, ref);
|
||||||
|
|
||||||
|
// just because we can't resolve it directly doesn't mean that terminology server can't. Check with it
|
||||||
|
|
||||||
|
if (warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs != null || serverSupportsValueSet(ref), I18nConstants.SD_ED_BIND_UNKNOWN_VS, path, ref)) {
|
||||||
|
if (vs != null) {
|
||||||
|
if (rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs instanceof ValueSet, I18nConstants.SD_ED_BIND_NOT_VS, path, ref, vs.fhirType())) {
|
||||||
|
ValueSet vsr = (ValueSet) vs;
|
||||||
|
warning(errors, "2024-09-17", IssueType.BUSINESSRULE, stack.getLiteralPath(), !vsr.getExperimental() || experimental, I18nConstants.SD_ED_EXPERIMENTAL_BINDING, path, ref);
|
||||||
|
} else {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (binding.hasChildren("usage")) {
|
||||||
|
for (Element usage : binding.getChildren("usage")) {
|
||||||
|
warning(errors, "2024-09-20", IssueType.BUSINESSRULE, stack.getLiteralPath(), false, "test");
|
||||||
|
}
|
||||||
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean validateAdditionalBindingExtension(List<ValidationMessage> errors, Element binding, NodeStack stack, boolean snapshot, String path, boolean experimental, StructureDefinition profile) {
|
||||||
|
boolean ok = true;
|
||||||
|
|
||||||
|
if (binding.hasExtension("valueSet")) {
|
||||||
|
Element valueSet = binding.getExtension("valueSet");
|
||||||
|
Element vv = valueSet.getNamedChild("value");
|
||||||
|
String ref = vv.hasPrimitiveValue() ? vv.primitiveValue() : vv.getNamedChildValue("reference", false);
|
||||||
|
if (warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), !snapshot || ref != null, I18nConstants.SD_ED_SHOULD_BIND_WITH_VS, path)) {
|
||||||
|
Resource vs = context.fetchResource(Resource.class, ref);
|
||||||
|
|
||||||
|
// just because we can't resolve it directly doesn't mean that terminology server can't. Check with it
|
||||||
|
|
||||||
|
if (warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs != null || serverSupportsValueSet(ref), I18nConstants.SD_ED_BIND_UNKNOWN_VS, path, ref)) {
|
||||||
|
if (vs != null) {
|
||||||
|
if (rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs instanceof ValueSet, I18nConstants.SD_ED_BIND_NOT_VS, path, ref, vs.fhirType())) {
|
||||||
|
ValueSet vsr = (ValueSet) vs;
|
||||||
|
warning(errors, "2024-09-17", IssueType.BUSINESSRULE, stack.getLiteralPath(), !vsr.getExperimental() || experimental, I18nConstants.SD_ED_EXPERIMENTAL_BINDING, path, ref);
|
||||||
|
} else {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (binding.hasExtension("usage")) {
|
||||||
|
int i = 0;
|
||||||
|
for (Element usage : binding.getChildren("extension")) {
|
||||||
|
String url = usage.getNamedChildValue("url");
|
||||||
|
if ("usage".equals(url)) {
|
||||||
|
Element uv = usage.getNamedChild("value");
|
||||||
|
ok = validateAdditionalBindingUsage(errors, uv, stack.push(uv, -1, null, null), path, profile) && ok;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean validateAdditionalBindingUsage(List<ValidationMessage> errors, Element usage, NodeStack stack, String path, StructureDefinition profile) {
|
||||||
|
boolean ok = true;
|
||||||
|
Element cc = usage.getNamedChild("code");
|
||||||
|
if (cc != null) {
|
||||||
|
String system = cc.getNamedChildValue("system");
|
||||||
|
String code = cc.getNamedChildValue("code");
|
||||||
|
if (system != null && system.equals(profile.getUrl())) {
|
||||||
|
ElementDefinition ed = profile.getDifferential().getElementByPath(code);
|
||||||
|
if (ed == null) {
|
||||||
|
ed = profile.getSnapshot().getElementByPath(code);
|
||||||
|
}
|
||||||
|
if (ed == null) {
|
||||||
|
ok = false;
|
||||||
|
rule(errors, "2024-09-17", IssueType.BUSINESSRULE, stack.getLiteralPath(), false, I18nConstants.SD_ED_ADDITIONAL_BINDING_USAGE_INVALID_ELEMENT, system, code);
|
||||||
|
} else {
|
||||||
|
if (usage.hasChild("value")) {
|
||||||
|
String t = usage.getNamedChild("value").fhirType();
|
||||||
|
ok = rule(errors, "2024-09-20", IssueType.BUSINESSRULE, stack.getLiteralPath(), "CodeableConcept".equals(t), I18nConstants.SD_ED_ADDITIONAL_BINDING_USAGE_INVALID_TYPE, t, "CodeableConcept") && ok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warning(errors, "2024-09-17", IssueType.BUSINESSRULE, stack.getLiteralPath(), false, I18nConstants.SD_ED_ADDITIONAL_BINDING_USAGE_UNKNOWN, system, code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
private Set<String> getListofBindableTypes(Set<String> types) {
|
private Set<String> getListofBindableTypes(Set<String> types) {
|
||||||
Set<String> res = new HashSet<>();
|
Set<String> res = new HashSet<>();
|
||||||
for (String s : types) {
|
for (String s : types) {
|
||||||
|
|
|
@ -362,6 +362,9 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
|
||||||
if (content.has("security-checks")) {
|
if (content.has("security-checks")) {
|
||||||
val.setSecurityChecks(content.get("security-checks").getAsBoolean());
|
val.setSecurityChecks(content.get("security-checks").getAsBoolean());
|
||||||
}
|
}
|
||||||
|
if (content.has("no-experimental-content")) {
|
||||||
|
val.setNoExperimentalContent(content.get("no-experimental-content").getAsBoolean());
|
||||||
|
}
|
||||||
if (content.has("noHtmlInMarkdown")) {
|
if (content.has("noHtmlInMarkdown")) {
|
||||||
val.setHtmlInMarkdownCheck(HtmlInMarkdownCheck.ERROR);
|
val.setHtmlInMarkdownCheck(HtmlInMarkdownCheck.ERROR);
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,4 @@
|
||||||
[servers]
|
[servers]
|
||||||
tx-dev.fhir.org.r2 = http://tx-dev.fhir.org/r2
|
tx-dev.fhir.org.r2 = http://tx-dev.fhir.org/r2
|
||||||
|
local.fhir.org.r2 = http://local.fhir.org/r2
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,4 @@
|
||||||
[servers]
|
[servers]
|
||||||
tx-dev.fhir.org.r3 = http://tx-dev.fhir.org/r3
|
tx-dev.fhir.org.r3 = http://tx-dev.fhir.org/r3
|
||||||
|
local.fhir.org.r3 = http://local.fhir.org/r3
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -521,7 +521,6 @@ v: {
|
||||||
"system" : "http://unitsofmeasure.org",
|
"system" : "http://unitsofmeasure.org",
|
||||||
"version" : "2.0.1",
|
"version" : "2.0.1",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -549,7 +548,6 @@ v: {
|
||||||
"code" : "image/jpg",
|
"code" : "image/jpg",
|
||||||
"system" : "urn:ietf:bcp:13",
|
"system" : "urn:ietf:bcp:13",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -577,7 +575,6 @@ v: {
|
||||||
"code" : "image/jpg",
|
"code" : "image/jpg",
|
||||||
"system" : "urn:ietf:bcp:13",
|
"system" : "urn:ietf:bcp:13",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -605,7 +602,6 @@ v: {
|
||||||
"code" : "application/pdf",
|
"code" : "application/pdf",
|
||||||
"system" : "urn:ietf:bcp:13",
|
"system" : "urn:ietf:bcp:13",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -633,7 +629,6 @@ v: {
|
||||||
"code" : "application/pdf",
|
"code" : "application/pdf",
|
||||||
"system" : "urn:ietf:bcp:13",
|
"system" : "urn:ietf:bcp:13",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -654,7 +649,6 @@ v: {
|
||||||
"code" : "de-CH",
|
"code" : "de-CH",
|
||||||
"system" : "urn:ietf:bcp:47",
|
"system" : "urn:ietf:bcp:47",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -720,3 +714,29 @@ v: {
|
||||||
|
|
||||||
}
|
}
|
||||||
-------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"coding" : [{
|
||||||
|
"system" : "urn:iso:std:iso:3166",
|
||||||
|
"code" : "US",
|
||||||
|
"display" : "United States of America"
|
||||||
|
}]
|
||||||
|
}, "url": "http://hl7.org/fhir/ValueSet/jurisdiction", "version": "3.0.2", "langs":"en-US", "useServer":"true", "useClient":"true", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "United States of America",
|
||||||
|
"code" : "US",
|
||||||
|
"system" : "urn:iso:std:iso:3166",
|
||||||
|
"version" : "2018",
|
||||||
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
[servers]
|
[servers]
|
||||||
tx-dev.fhir.org.r3 = http://tx-dev.fhir.org/r3
|
tx-dev.fhir.org.r3 = http://tx-dev.fhir.org/r3
|
||||||
|
local.fhir.org.r3 = http://local.fhir.org/r3
|
||||||
|
|
||||||
|
|
|
@ -1108,7 +1108,6 @@ v: {
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1132,7 +1131,6 @@ v: {
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1159,7 +1157,6 @@ v: {
|
||||||
"error" : "Wrong Display Name 'Laboratory test finding (finding)' for http://snomed.info/sct#118246004. Valid display is one of 4 choices: 'Laboratory test finding', 'Laboratory test observations', 'Laboratory test result' or 'Laboratory test finding (navigational concept)' (for the language(s) 'en-US')",
|
"error" : "Wrong Display Name 'Laboratory test finding (finding)' for http://snomed.info/sct#118246004. Valid display is one of 4 choices: 'Laboratory test finding', 'Laboratory test observations', 'Laboratory test result' or 'Laboratory test finding (navigational concept)' (for the language(s) 'en-US')",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1203,7 +1200,6 @@ v: {
|
||||||
"error" : "Wrong Display Name 'Chemistry' for http://snomed.info/sct#275711006. Valid display is one of 2 choices: 'Serum chemistry test' or 'Serum chemistry test (procedure)' (for the language(s) 'en-US')",
|
"error" : "Wrong Display Name 'Chemistry' for http://snomed.info/sct#275711006. Valid display is one of 2 choices: 'Serum chemistry test' or 'Serum chemistry test (procedure)' (for the language(s) 'en-US')",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1244,7 +1240,6 @@ v: {
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1268,7 +1263,6 @@ v: {
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1292,7 +1286,6 @@ v: {
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1316,7 +1309,6 @@ v: {
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1340,7 +1332,6 @@ v: {
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1364,7 +1355,6 @@ v: {
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1388,7 +1378,6 @@ v: {
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1413,7 +1402,6 @@ v: {
|
||||||
"error" : "Unknown code '823681000000100' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '823681000000100' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1455,7 +1443,6 @@ v: {
|
||||||
"error" : "Unknown code '886921000000105' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '886921000000105' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1497,7 +1484,6 @@ v: {
|
||||||
"error" : "Unknown code '1077881000000105' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '1077881000000105' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1539,7 +1525,6 @@ v: {
|
||||||
"error" : "Unknown code '887181000000106' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '887181000000106' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1581,7 +1566,6 @@ v: {
|
||||||
"error" : "Unknown code '887161000000102' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '887161000000102' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1623,7 +1607,6 @@ v: {
|
||||||
"error" : "Unknown code '1052891000000108' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '1052891000000108' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1665,7 +1648,6 @@ v: {
|
||||||
"error" : "Unknown code '715851000000102' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '715851000000102' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1707,7 +1689,6 @@ v: {
|
||||||
"error" : "Unknown code '717121000000105' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '717121000000105' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1749,7 +1730,6 @@ v: {
|
||||||
"error" : "Unknown code '933361000000108' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '933361000000108' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1791,7 +1771,6 @@ v: {
|
||||||
"error" : "Unknown code '887171000000109' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '887171000000109' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1833,7 +1812,6 @@ v: {
|
||||||
"error" : "Unknown code '887201000000105' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '887201000000105' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1875,7 +1853,6 @@ v: {
|
||||||
"error" : "Unknown code '1052951000000105' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '1052951000000105' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1917,7 +1894,6 @@ v: {
|
||||||
"error" : "Unknown code '886731000000109' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '886731000000109' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -1959,7 +1935,6 @@ v: {
|
||||||
"error" : "Unknown code '887231000000104' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '887231000000104' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -2001,7 +1976,6 @@ v: {
|
||||||
"error" : "Unknown code '9290701000001101' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '9290701000001101' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -2042,7 +2016,6 @@ v: {
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2066,7 +2039,6 @@ v: {
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2089,7 +2061,6 @@ v: {
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2113,7 +2084,6 @@ v: {
|
||||||
"error" : "Unknown code '11181000146103' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
"error" : "Unknown code '11181000146103' in the CodeSystem 'http://snomed.info/sct' version 'http://snomed.info/sct/900000000000207008/version/20240201'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r3",
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -2137,3 +2107,61 @@ v: {
|
||||||
|
|
||||||
}
|
}
|
||||||
-------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"coding" : [{
|
||||||
|
"system" : "http://snomed.info/sct",
|
||||||
|
"code" : "17621005",
|
||||||
|
"display" : "Normal (qualifier value)"
|
||||||
|
}]
|
||||||
|
}, "url": "http://hl7.org/fhir/ValueSet/security-labels", "version": "3.0.2", "langs":"en-US", "useServer":"true", "useClient":"true", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"version" : "http://snomed.info/sct/900000000000207008/version/20240201",
|
||||||
|
"severity" : "error",
|
||||||
|
"error" : "No valid coding was found for the value set 'http://hl7.org/fhir/ValueSet/security-labels|3.0.2'; The provided code 'http://snomed.info/sct#17621005 ('Normal (qualifier value)')' was not found in the value set 'http://hl7.org/fhir/ValueSet/security-labels|3.0.2'",
|
||||||
|
"class" : "UNKNOWN",
|
||||||
|
"server" : "http://tx-dev.fhir.org/r3",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome",
|
||||||
|
"issue" : [{
|
||||||
|
"extension" : [{
|
||||||
|
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
|
||||||
|
"valueUrl" : "http://tx-dev.fhir.org/r3"
|
||||||
|
}],
|
||||||
|
"severity" : "information",
|
||||||
|
"code" : "code-invalid",
|
||||||
|
"details" : {
|
||||||
|
"coding" : [{
|
||||||
|
"system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type",
|
||||||
|
"code" : "this-code-not-in-vs"
|
||||||
|
}],
|
||||||
|
"text" : "The provided code 'http://snomed.info/sct#17621005 ('Normal (qualifier value)')' was not found in the value set 'http://hl7.org/fhir/ValueSet/security-labels|3.0.2'"
|
||||||
|
},
|
||||||
|
"location" : ["CodeableConcept.coding[0].code"],
|
||||||
|
"expression" : ["CodeableConcept.coding[0].code"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"extension" : [{
|
||||||
|
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
|
||||||
|
"valueUrl" : "http://tx-dev.fhir.org/r3"
|
||||||
|
}],
|
||||||
|
"severity" : "error",
|
||||||
|
"code" : "code-invalid",
|
||||||
|
"details" : {
|
||||||
|
"coding" : [{
|
||||||
|
"system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type",
|
||||||
|
"code" : "not-in-vs"
|
||||||
|
}],
|
||||||
|
"text" : "No valid coding was found for the value set 'http://hl7.org/fhir/ValueSet/security-labels|3.0.2'"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -39,10 +39,68 @@ v: {
|
||||||
"system" : "http://www.ada.org/snodent",
|
"system" : "http://www.ada.org/snodent",
|
||||||
"version" : "2.1.0",
|
"version" : "2.1.0",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
-------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"coding" : [{
|
||||||
|
"system" : "http://www.ada.org/snodent",
|
||||||
|
"code" : "210965D",
|
||||||
|
"display" : "Anterior part of lower alveolar ridge"
|
||||||
|
}],
|
||||||
|
"text" : "Anterior part of lower alveolar ridge"
|
||||||
|
}, "url": "http://hl7.org/fhir/us/dental-data-exchange/ValueSet/dental-anatomy", "version": "1.0.0", "langs":"en-US", "useServer":"true", "useClient":"true", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"version" : "2.1.0",
|
||||||
|
"severity" : "error",
|
||||||
|
"error" : "No valid coding was found for the value set 'http://hl7.org/fhir/us/dental-data-exchange/ValueSet/dental-anatomy|1.0.0'; The provided code 'http://www.ada.org/snodent#210965D ('Anterior part of lower alveolar ridge')' was not found in the value set 'http://hl7.org/fhir/us/dental-data-exchange/ValueSet/dental-anatomy|1.0.0'",
|
||||||
|
"class" : "UNKNOWN",
|
||||||
|
"server" : "http://local.fhir.org/r4",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome",
|
||||||
|
"issue" : [{
|
||||||
|
"extension" : [{
|
||||||
|
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
|
||||||
|
"valueUrl" : "http://local.fhir.org/r4"
|
||||||
|
}],
|
||||||
|
"severity" : "information",
|
||||||
|
"code" : "code-invalid",
|
||||||
|
"details" : {
|
||||||
|
"coding" : [{
|
||||||
|
"system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type",
|
||||||
|
"code" : "this-code-not-in-vs"
|
||||||
|
}],
|
||||||
|
"text" : "The provided code 'http://www.ada.org/snodent#210965D ('Anterior part of lower alveolar ridge')' was not found in the value set 'http://hl7.org/fhir/us/dental-data-exchange/ValueSet/dental-anatomy|1.0.0'"
|
||||||
|
},
|
||||||
|
"location" : ["CodeableConcept.coding[0].code"],
|
||||||
|
"expression" : ["CodeableConcept.coding[0].code"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"extension" : [{
|
||||||
|
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
|
||||||
|
"valueUrl" : "http://local.fhir.org/r4"
|
||||||
|
}],
|
||||||
|
"severity" : "error",
|
||||||
|
"code" : "code-invalid",
|
||||||
|
"details" : {
|
||||||
|
"coding" : [{
|
||||||
|
"system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type",
|
||||||
|
"code" : "not-in-vs"
|
||||||
|
}],
|
||||||
|
"text" : "No valid coding was found for the value set 'http://hl7.org/fhir/us/dental-data-exchange/ValueSet/dental-anatomy|1.0.0'"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -8422,7 +8422,6 @@ v: {
|
||||||
"error" : "Wrong Display Name 'O2 % BldC Oximetry' for http://loinc.org#59408-5. Valid display is 'Oxygen saturation in Arterial blood by Pulse oximetry' (en-US) (for the language(s) 'en-US')",
|
"error" : "Wrong Display Name 'O2 % BldC Oximetry' for http://loinc.org#59408-5. Valid display is 'Oxygen saturation in Arterial blood by Pulse oximetry' (en-US) (for the language(s) 'en-US')",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -8463,7 +8462,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -8489,7 +8487,6 @@ v: {
|
||||||
"error" : "The provided code 'http://loinc.org#59408-5' was not found in the value set 'http://hl7.org/fhir/ValueSet/observation-vitalsignresult--0|4.0.1'",
|
"error" : "The provided code 'http://loinc.org#59408-5' was not found in the value set 'http://hl7.org/fhir/ValueSet/observation-vitalsignresult--0|4.0.1'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -8529,7 +8526,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -8553,7 +8549,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -8579,7 +8574,6 @@ v: {
|
||||||
"error" : "The provided code 'http://loinc.org#3150-0' was not found in the value set 'http://hl7.org/fhir/ValueSet/observation-vitalsignresult--0|4.0.1'",
|
"error" : "The provided code 'http://loinc.org#3150-0' was not found in the value set 'http://hl7.org/fhir/ValueSet/observation-vitalsignresult--0|4.0.1'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -8623,7 +8617,6 @@ v: {
|
||||||
"error" : "Wrong Display Name 'Flow Rate' for http://loinc.org#3151-8. Valid display is 'Inhaled oxygen flow rate' (en-US) (for the language(s) 'en-US')",
|
"error" : "Wrong Display Name 'Flow Rate' for http://loinc.org#3151-8. Valid display is 'Inhaled oxygen flow rate' (en-US) (for the language(s) 'en-US')",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -8666,7 +8659,6 @@ v: {
|
||||||
"error" : "The provided code 'http://loinc.org#3151-8' was not found in the value set 'http://hl7.org/fhir/ValueSet/observation-vitalsignresult--0|4.0.1'",
|
"error" : "The provided code 'http://loinc.org#3151-8' was not found in the value set 'http://hl7.org/fhir/ValueSet/observation-vitalsignresult--0|4.0.1'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -8706,7 +8698,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -8732,7 +8723,6 @@ v: {
|
||||||
"error" : "The provided code 'http://loinc.org#2708-6' was not found in the value set 'http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs--0|4.0.0'",
|
"error" : "The provided code 'http://loinc.org#2708-6' was not found in the value set 'http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs--0|4.0.0'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -8772,7 +8762,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -8795,7 +8784,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -8818,7 +8806,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -8844,7 +8831,6 @@ v: {
|
||||||
"error" : "The provided code 'http://loinc.org#100066-0' was not found in the value set 'http://hl7.org/fhir/test/StructureDefinition/additional-bindings-vs1--0|1.0.0'",
|
"error" : "The provided code 'http://loinc.org#100066-0' was not found in the value set 'http://hl7.org/fhir/test/StructureDefinition/additional-bindings-vs1--0|1.0.0'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -8884,7 +8870,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -8907,7 +8892,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -8930,7 +8914,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -8954,7 +8937,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -8978,7 +8960,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9002,7 +8983,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9026,7 +9006,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9049,7 +9028,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9073,7 +9051,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9096,7 +9073,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9120,7 +9096,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9143,7 +9118,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9167,7 +9141,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9190,7 +9163,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9214,7 +9186,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9237,7 +9208,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9261,7 +9231,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9284,7 +9253,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9308,7 +9276,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9332,7 +9299,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9359,7 +9325,6 @@ v: {
|
||||||
"error" : "Wrong Display Name 'Patient Authorization Signature' for http://loinc.org#59284-0. Valid display is 'Consent Document' (en-US) (for the language(s) 'en-US')",
|
"error" : "Wrong Display Name 'Patient Authorization Signature' for http://loinc.org#59284-0. Valid display is 'Consent Document' (en-US) (for the language(s) 'en-US')",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -9399,7 +9364,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9423,7 +9387,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9446,7 +9409,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9470,7 +9432,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9494,7 +9455,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9518,7 +9478,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9545,7 +9504,6 @@ v: {
|
||||||
"error" : "Wrong Display Name 'NDC labeler code request' for http://loinc.org#51726-8. Valid display is 'FDA product label NDC labeler code request' (en-US) (for the language(s) 'en-US')",
|
"error" : "Wrong Display Name 'NDC labeler code request' for http://loinc.org#51726-8. Valid display is 'FDA product label NDC labeler code request' (en-US) (for the language(s) 'en-US')",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -9586,7 +9544,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9611,7 +9568,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9634,7 +9590,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9662,7 +9617,6 @@ v: {
|
||||||
"error" : "Wrong Display Name 'Allergies and adverse reactions' for http://loinc.org#48765-2. Valid display is 'Allergies and adverse reactions Document' (en-US) (for the language(s) 'en-US')",
|
"error" : "Wrong Display Name 'Allergies and adverse reactions' for http://loinc.org#48765-2. Valid display is 'Allergies and adverse reactions Document' (en-US) (for the language(s) 'en-US')",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -9703,7 +9657,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9726,7 +9679,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9749,7 +9701,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9773,7 +9724,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9796,7 +9746,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9821,7 +9770,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9845,7 +9793,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9868,7 +9815,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9892,7 +9838,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9915,7 +9860,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9939,7 +9883,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9962,7 +9905,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -9986,7 +9928,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10010,7 +9951,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10033,7 +9973,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10057,7 +9996,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10080,7 +10018,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10103,7 +10040,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10128,7 +10064,6 @@ v: {
|
||||||
"error" : "Unknown code '<27>g<EFBFBD><67>' in the CodeSystem 'http://loinc.org' version '2.77'",
|
"error" : "Unknown code '<27>g<EFBFBD><67>' in the CodeSystem 'http://loinc.org' version '2.77'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -10169,7 +10104,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10196,7 +10130,6 @@ v: {
|
||||||
"error" : "Wrong Display Name '<27><><EFBFBD><EFBFBD>' for http://loinc.org#18684-1. Valid display is 'First Blood pressure Set' (en-US) (for the language(s) 'en-US')",
|
"error" : "Wrong Display Name '<27><><EFBFBD><EFBFBD>' for http://loinc.org#18684-1. Valid display is 'First Blood pressure Set' (en-US) (for the language(s) 'en-US')",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -10240,7 +10173,6 @@ v: {
|
||||||
"error" : "Wrong Display Name '<27><><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>' for http://loinc.org#8480-6. Valid display is 'Systolic blood pressure' (en-US) (for the language(s) 'en-US')",
|
"error" : "Wrong Display Name '<27><><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>' for http://loinc.org#8480-6. Valid display is 'Systolic blood pressure' (en-US) (for the language(s) 'en-US')",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -10284,7 +10216,6 @@ v: {
|
||||||
"error" : "Wrong Display Name '<27>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>' for http://loinc.org#8462-4. Valid display is 'Diastolic blood pressure' (en-US) (for the language(s) 'en-US')",
|
"error" : "Wrong Display Name '<27>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>' for http://loinc.org#8462-4. Valid display is 'Diastolic blood pressure' (en-US) (for the language(s) 'en-US')",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -10325,7 +10256,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10349,7 +10279,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10373,7 +10302,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10397,7 +10325,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10422,7 +10349,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10447,7 +10373,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10471,7 +10396,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10495,7 +10419,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10518,7 +10441,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10541,7 +10463,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10564,7 +10485,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10587,7 +10507,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10610,7 +10529,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10633,7 +10551,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10656,7 +10573,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10679,7 +10595,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10702,7 +10617,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10737,7 +10651,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10772,7 +10685,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10807,7 +10719,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10831,7 +10742,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10854,7 +10764,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10877,7 +10786,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10901,7 +10809,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10927,7 +10834,6 @@ v: {
|
||||||
"error" : "The provided code 'http://loinc.org#76534-7' was not found in the value set 'http://hl7.org/fhir/ValueSet/observation-vitalsignresult--0|4.0.1'",
|
"error" : "The provided code 'http://loinc.org#76534-7' was not found in the value set 'http://hl7.org/fhir/ValueSet/observation-vitalsignresult--0|4.0.1'",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -10967,7 +10873,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -10991,7 +10896,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -11015,7 +10919,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -11039,7 +10942,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -11063,7 +10965,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -11087,7 +10988,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -11111,7 +11011,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -11135,7 +11034,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -11158,7 +11056,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -11181,7 +11078,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -11205,7 +11101,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -11229,7 +11124,6 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -11252,6 +11146,82 @@ v: {
|
||||||
"system" : "http://loinc.org",
|
"system" : "http://loinc.org",
|
||||||
"version" : "2.77",
|
"version" : "2.77",
|
||||||
"server" : "http://tx-dev.fhir.org/r4",
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"coding" : [{
|
||||||
|
"system" : "http://loinc.org",
|
||||||
|
"code" : "59408-5",
|
||||||
|
"display" : "O2 % BldC Oximetry"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system" : "http://loinc.org",
|
||||||
|
"code" : "2708-6",
|
||||||
|
"display" : "Oxygen saturation in Arterial blood"
|
||||||
|
}]
|
||||||
|
}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs", "version": "4.0.0", "langs":"en-US", "useServer":"true", "useClient":"true", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "Oxygen saturation in Arterial blood",
|
||||||
|
"code" : "2708-6",
|
||||||
|
"system" : "http://loinc.org",
|
||||||
|
"version" : "2.78",
|
||||||
|
"severity" : "error",
|
||||||
|
"error" : "Wrong Display Name 'O2 % BldC Oximetry' for http://loinc.org#59408-5. Valid display is one of 3 choices: 'Oxygen saturation in Arterial blood by Pulse oximetry' (en-US), 'Oxygen saturation in Arterial blood by Pulse oximetry' (en-US) or 'SaO2 % BldA PulseOx' (en-US) (for the language(s) 'en-US')",
|
||||||
|
"class" : "UNKNOWN",
|
||||||
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome",
|
||||||
|
"issue" : [{
|
||||||
|
"extension" : [{
|
||||||
|
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
|
||||||
|
"valueUrl" : "http://tx-dev.fhir.org/r4"
|
||||||
|
}],
|
||||||
|
"severity" : "error",
|
||||||
|
"code" : "invalid",
|
||||||
|
"details" : {
|
||||||
|
"coding" : [{
|
||||||
|
"system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type",
|
||||||
|
"code" : "invalid-display"
|
||||||
|
}],
|
||||||
|
"text" : "Wrong Display Name 'O2 % BldC Oximetry' for http://loinc.org#59408-5. Valid display is one of 3 choices: 'Oxygen saturation in Arterial blood by Pulse oximetry' (en-US), 'Oxygen saturation in Arterial blood by Pulse oximetry' (en-US) or 'SaO2 % BldA PulseOx' (en-US) (for the language(s) 'en-US')"
|
||||||
|
},
|
||||||
|
"location" : ["CodeableConcept.coding[0].display"],
|
||||||
|
"expression" : ["CodeableConcept.coding[0].display"]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"coding" : [{
|
||||||
|
"system" : "http://loinc.org",
|
||||||
|
"code" : "3150-0",
|
||||||
|
"display" : "Inhaled Oxygen Concentration"
|
||||||
|
}]
|
||||||
|
}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs", "version": "4.0.0", "langs":"en-US", "useServer":"true", "useClient":"true", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "Inhaled oxygen concentration",
|
||||||
|
"code" : "3150-0",
|
||||||
|
"system" : "http://loinc.org",
|
||||||
|
"version" : "2.78",
|
||||||
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
"unknown-systems" : "",
|
"unknown-systems" : "",
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
|
@ -11259,3 +11229,49 @@ v: {
|
||||||
|
|
||||||
}
|
}
|
||||||
-------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"coding" : [{
|
||||||
|
"system" : "http://loinc.org",
|
||||||
|
"code" : "3151-8",
|
||||||
|
"display" : "Flow Rate"
|
||||||
|
}]
|
||||||
|
}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs", "version": "4.0.0", "langs":"en-US", "useServer":"true", "useClient":"true", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "Inhaled oxygen flow rate",
|
||||||
|
"code" : "3151-8",
|
||||||
|
"system" : "http://loinc.org",
|
||||||
|
"version" : "2.78",
|
||||||
|
"severity" : "error",
|
||||||
|
"error" : "Wrong Display Name 'Flow Rate' for http://loinc.org#3151-8. Valid display is one of 4 choices: 'Inhaled oxygen flow rate' (en-US), 'Inhaled oxygen flow rate' (en-US), 'Inhaled O2 flow rate' (en-US) or 'Inhaled oxygen' (en-US) (for the language(s) 'en-US')",
|
||||||
|
"class" : "UNKNOWN",
|
||||||
|
"server" : "http://tx-dev.fhir.org/r4",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome",
|
||||||
|
"issue" : [{
|
||||||
|
"extension" : [{
|
||||||
|
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
|
||||||
|
"valueUrl" : "http://tx-dev.fhir.org/r4"
|
||||||
|
}],
|
||||||
|
"severity" : "error",
|
||||||
|
"code" : "invalid",
|
||||||
|
"details" : {
|
||||||
|
"coding" : [{
|
||||||
|
"system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type",
|
||||||
|
"code" : "invalid-display"
|
||||||
|
}],
|
||||||
|
"text" : "Wrong Display Name 'Flow Rate' for http://loinc.org#3151-8. Valid display is one of 4 choices: 'Inhaled oxygen flow rate' (en-US), 'Inhaled oxygen flow rate' (en-US), 'Inhaled O2 flow rate' (en-US) or 'Inhaled oxygen' (en-US) (for the language(s) 'en-US')"
|
||||||
|
},
|
||||||
|
"location" : ["CodeableConcept.coding[0].display"],
|
||||||
|
"expression" : ["CodeableConcept.coding[0].display"]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue