Merge pull request #1336 from hapifhir/gg-202307-rendering

Gg 202307 rendering
This commit is contained in:
Grahame Grieve 2023-07-07 14:36:01 +10:00 committed by GitHub
commit 99ff8b5ae1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 16616 additions and 15813 deletions

View File

@ -47,6 +47,7 @@ public class VersionConvertorConstants {
public static final String EXT_NAMINGSYSTEM_TITLE = "http://hl7.org/fhir/5.0/StructureDefinition/extension-NamingSystem.title";
public static final String EXT_NAMINGSYSTEM_URL = "http://hl7.org/fhir/5.0/StructureDefinition/extension-NamingSystem.url";
public static final String EXT_NAMINGSYSTEM_VERSION = "http://hl7.org/fhir/5.0/StructureDefinition/extension-NamingSystem.version";
public static final String EXT_OPDEF_ORIGINAL_TYPE = "http://hl7.org/fhir/4.0/StructureDefinition/extension-OperationDefinition.parameter.type";
public static String refToVS(String url) {
if (url == null)

View File

@ -0,0 +1,72 @@
package org.hl7.fhir.convertors.conv40_50.datatypes40_50;
import org.hl7.fhir.convertors.VersionConvertorConstants;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.Extension;
import org.hl7.fhir.r5.model.Enumeration;
import org.hl7.fhir.r5.model.Enumerations.FHIRTypes;
import org.hl7.fhir.utilities.Utilities;
public class Utilities40_50 {
public static void convertType(org.hl7.fhir.r4.model.CodeType src, org.hl7.fhir.r5.model.Enumeration<FHIRTypes> tgt) {
if (Utilities.existsInList(src.primitiveValue(), "Media")) {
setType(tgt, src.primitiveValue(), "DocumentReference");
} else if (Utilities.existsInList(src.primitiveValue(), "DeviceUseStatement")) {
setType(tgt, src.primitiveValue(), "DeviceUsage");
} else if (Utilities.existsInList(src.primitiveValue(), "DocumentManifest")) {
setType(tgt, src.primitiveValue(), "List");
} else if (Utilities.existsInList(src.primitiveValue(), "MedicinalProduct")) {
setType(tgt, src.primitiveValue(), "MedicinalProductDefinition");
} else if (Utilities.existsInList(src.primitiveValue(), "MedicinalProductAuthorization")) {
setType(tgt, src.primitiveValue(), "RegulatedAuthorization");
} else if (Utilities.existsInList(src.primitiveValue(), "RequestGroup")) {
setType(tgt, src.primitiveValue(), "RequestOrchestration");
} else if (Utilities.existsInList(src.primitiveValue(), "MedicinalProductIngredient")) {
setType(tgt, src.primitiveValue(), "Ingredient");
} else if (Utilities.existsInList(src.primitiveValue(), "MedicinalProductManufactured")) {
setType(tgt, src.primitiveValue(), "ManufacturedItemDefinition");
} else if (Utilities.existsInList(src.primitiveValue(), "MedicinalProductPackaged")) {
setType(tgt, src.primitiveValue(), "PackagedProductDefinition");
} else if (Utilities.existsInList(src.primitiveValue(), "MedicinalProductPharmaceutical")) {
setType(tgt, src.primitiveValue(), "AdministrableProductDefinition");
} else if (Utilities.existsInList(src.primitiveValue(), "SubstanceSpecification")) {
setType(tgt, src.primitiveValue(), "SubstanceDefinition");
} else if (Utilities.existsInList(src.primitiveValue(), "MedicinalProductContraindication", "MedicinalProductIndication", "MedicinalProductInteraction", "MedicinalProductUndesirableEffect", "ClinicalUseDefinition")) {
setType(tgt, src.primitiveValue(), "SubstanceDefinition");
} else if (Utilities.existsInList(src.primitiveValue(), "EffectEvidenceSynthesis", "CatalogEntry", "ResearchDefinition", "ResearchElementDefinition", "RiskEvidenceSynthesis",
"Contributor", "ProdCharacteristic", "SubstanceAmount")) {
setType(tgt, src.primitiveValue(), "Basic");
} else {
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRTypes.fromCode(src.primitiveValue()));
}
}
private static void setType(org.hl7.fhir.r5.model.Enumeration<FHIRTypes> tgt, String original, String value) {
tgt.setValueAsString(value);
tgt.addExtension(new Extension().setUrl(VersionConvertorConstants.EXT_OPDEF_ORIGINAL_TYPE).setValue(new CodeType(original)));
}
public static void convertType(org.hl7.fhir.r5.model.Enumeration<FHIRTypes> src, org.hl7.fhir.r4.model.CodeType tgt) {
if (src.hasExtension(VersionConvertorConstants.EXT_OPDEF_ORIGINAL_TYPE)) {
tgt.setValueAsString(src.getExtensionString(VersionConvertorConstants.EXT_OPDEF_ORIGINAL_TYPE));
} else {
tgt.setValue(src.asStringValue());
}
}
}

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.convertors.conv40_50.datatypes40_50.metadata40_50;
import org.hl7.fhir.convertors.context.ConversionContext40_50;
import org.hl7.fhir.convertors.conv40_50.datatypes40_50.Utilities40_50;
import org.hl7.fhir.convertors.conv40_50.datatypes40_50.general40_50.Coding40_50;
import org.hl7.fhir.convertors.conv40_50.datatypes40_50.primitive40_50.Canonical40_50;
import org.hl7.fhir.convertors.conv40_50.datatypes40_50.primitive40_50.PositiveInt40_50;
@ -12,8 +13,9 @@ public class DataRequirement40_50 {
if (src == null) return null;
org.hl7.fhir.r5.model.DataRequirement tgt = new org.hl7.fhir.r5.model.DataRequirement();
ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyElement(src, tgt);
if (src.hasType())
tgt.setType(org.hl7.fhir.r5.model.Enumerations.FHIRTypes.fromCode(convertResourceName4to5(src.getType())));
if (src.hasType()) {
Utilities40_50.convertType(src.getTypeElement(), tgt.getTypeElement());
}
for (org.hl7.fhir.r4.model.CanonicalType t : src.getProfile())
tgt.getProfile().add(Canonical40_50.convertCanonical(t));
if (src.hasSubject())
@ -34,7 +36,9 @@ public class DataRequirement40_50 {
if (src == null) return null;
org.hl7.fhir.r4.model.DataRequirement tgt = new org.hl7.fhir.r4.model.DataRequirement();
ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyElement(src, tgt);
if (src.hasType()) tgt.setType(convertResourceName5to4(src.getType().toCode()));
if (src.hasType()) {
Utilities40_50.convertType(src.getTypeElement(), tgt.getTypeElement());
}
for (org.hl7.fhir.r5.model.CanonicalType t : src.getProfile())
tgt.getProfile().add(Canonical40_50.convertCanonical(t));
if (src.hasSubject())
@ -51,22 +55,6 @@ public class DataRequirement40_50 {
return tgt;
}
private static String convertResourceName4to5(String name) {
if (name == null) return null;
if (name.equals("DeviceUseStatement")) {
return "DeviceUsage";
}
return name;
}
private static String convertResourceName5to4(String name) {
if (name == null) return null;
if (name.equals("DeviceUsage")) {
return "DeviceUseStatement";
}
return name;
}
public static org.hl7.fhir.r5.model.DataRequirement.DataRequirementCodeFilterComponent convertDataRequirementCodeFilterComponent(org.hl7.fhir.r4.model.DataRequirement.DataRequirementCodeFilterComponent src) throws FHIRException {
if (src == null) return null;
org.hl7.fhir.r5.model.DataRequirement.DataRequirementCodeFilterComponent tgt = new org.hl7.fhir.r5.model.DataRequirement.DataRequirementCodeFilterComponent();

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.convertors.conv40_50.datatypes40_50.metadata40_50;
import org.hl7.fhir.convertors.context.ConversionContext40_50;
import org.hl7.fhir.convertors.conv40_50.datatypes40_50.Utilities40_50;
import org.hl7.fhir.convertors.conv40_50.datatypes40_50.primitive40_50.Canonical40_50;
import org.hl7.fhir.convertors.conv40_50.datatypes40_50.primitive40_50.Code40_50;
import org.hl7.fhir.convertors.conv40_50.datatypes40_50.primitive40_50.Integer40_50;
@ -17,7 +18,9 @@ public class ParameterDefinition40_50 {
if (src.hasMin()) tgt.setMinElement(Integer40_50.convertInteger(src.getMinElement()));
if (src.hasMax()) tgt.setMaxElement(String40_50.convertString(src.getMaxElement()));
if (src.hasDocumentation()) tgt.setDocumentationElement(String40_50.convertString(src.getDocumentationElement()));
if (src.hasType()) tgt.setType(org.hl7.fhir.r5.model.Enumerations.FHIRTypes.fromCode(src.getType()));
if (src.hasType()) {
Utilities40_50.convertType(src.getTypeElement(), tgt.getTypeElement());
}
if (src.hasProfile()) tgt.setProfileElement(Canonical40_50.convertCanonical(src.getProfileElement()));
return tgt;
}
@ -31,7 +34,9 @@ public class ParameterDefinition40_50 {
if (src.hasMin()) tgt.setMinElement(Integer40_50.convertInteger(src.getMinElement()));
if (src.hasMax()) tgt.setMaxElement(String40_50.convertString(src.getMaxElement()));
if (src.hasDocumentation()) tgt.setDocumentationElement(String40_50.convertString(src.getDocumentationElement()));
if (src.hasType()) tgt.setType(src.getType().toCode());
if (src.hasType()) {
Utilities40_50.convertType(src.getTypeElement(), tgt.getTypeElement());
}
if (src.hasProfile()) tgt.setProfileElement(Canonical40_50.convertCanonical(src.getProfileElement()));
return tgt;
}

View File

@ -1,6 +1,8 @@
package org.hl7.fhir.convertors.conv40_50.resources40_50;
import org.hl7.fhir.convertors.VersionConvertorConstants;
import org.hl7.fhir.convertors.context.ConversionContext40_50;
import org.hl7.fhir.convertors.conv40_50.datatypes40_50.Utilities40_50;
import org.hl7.fhir.convertors.conv40_50.datatypes40_50.general40_50.CodeableConcept40_50;
import org.hl7.fhir.convertors.conv40_50.datatypes40_50.metadata40_50.ContactDetail40_50;
import org.hl7.fhir.convertors.conv40_50.datatypes40_50.metadata40_50.UsageContext40_50;
@ -18,6 +20,7 @@ import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.Enumeration;
import org.hl7.fhir.r5.model.Enumerations.VersionIndependentResourceTypesAll;
import org.hl7.fhir.r5.model.Enumerations.VersionIndependentResourceTypesAllEnumFactory;
import org.hl7.fhir.utilities.Utilities;
/*
Copyright (c) 2011+, HL7, Inc.
@ -221,8 +224,9 @@ public class OperationDefinition40_50 {
tgt.setMaxElement(String40_50.convertString(src.getMaxElement()));
if (src.hasDocumentation())
tgt.setDocumentationElement(String40_50.convertStringToMarkdown(src.getDocumentationElement()));
if (src.hasType())
tgt.getTypeElement().setValue(org.hl7.fhir.r5.model.Enumerations.FHIRTypes.fromCode(src.getType()));
if (src.hasType()) {
Utilities40_50.convertType(src.getTypeElement(), tgt.getTypeElement());
}
for (org.hl7.fhir.r4.model.CanonicalType t : src.getTargetProfile())
tgt.getTargetProfile().add(Canonical40_50.convertCanonical(t));
if (src.hasSearchType())
@ -251,8 +255,9 @@ public class OperationDefinition40_50 {
tgt.setMaxElement(String40_50.convertString(src.getMaxElement()));
if (src.hasDocumentation())
tgt.setDocumentationElement(String40_50.convertString(src.getDocumentationElement()));
if (src.hasType())
tgt.setTypeElement(new org.hl7.fhir.r4.model.CodeType(src.getType().toCode()));
if (src.hasType()) {
Utilities40_50.convertType(src.getTypeElement(), tgt.getTypeElement());
}
for (org.hl7.fhir.r5.model.CanonicalType t : src.getTargetProfile())
tgt.getTargetProfile().add(Canonical40_50.convertCanonical(t));
if (src.hasSearchType())

View File

@ -0,0 +1,73 @@
package org.hl7.fhir.convertors.conv43_50;
import org.hl7.fhir.convertors.VersionConvertorConstants;
import org.hl7.fhir.r4b.model.Enumerations.FHIRAllTypes;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.Extension;
import org.hl7.fhir.r5.model.Enumeration;
import org.hl7.fhir.r5.model.Enumerations.FHIRTypes;
import org.hl7.fhir.utilities.Utilities;
public class Utilities43_50 {
public static void convertType(org.hl7.fhir.r4b.model.Enumeration<FHIRAllTypes> src, org.hl7.fhir.r5.model.Enumeration<FHIRTypes> tgt) {
if (Utilities.existsInList(src.primitiveValue(), "Media")) {
setType(tgt, src.primitiveValue(), "DocumentReference");
} else if (Utilities.existsInList(src.primitiveValue(), "DeviceUseStatement")) {
setType(tgt, src.primitiveValue(), "DeviceUsage");
} else if (Utilities.existsInList(src.primitiveValue(), "DocumentManifest")) {
setType(tgt, src.primitiveValue(), "List");
} else if (Utilities.existsInList(src.primitiveValue(), "MedicinalProduct")) {
setType(tgt, src.primitiveValue(), "MedicinalProductDefinition");
} else if (Utilities.existsInList(src.primitiveValue(), "MedicinalProductAuthorization")) {
setType(tgt, src.primitiveValue(), "RegulatedAuthorization");
} else if (Utilities.existsInList(src.primitiveValue(), "RequestGroup")) {
setType(tgt, src.primitiveValue(), "RequestOrchestration");
} else if (Utilities.existsInList(src.primitiveValue(), "MedicinalProductIngredient")) {
setType(tgt, src.primitiveValue(), "Ingredient");
} else if (Utilities.existsInList(src.primitiveValue(), "MedicinalProductManufactured")) {
setType(tgt, src.primitiveValue(), "ManufacturedItemDefinition");
} else if (Utilities.existsInList(src.primitiveValue(), "MedicinalProductPackaged")) {
setType(tgt, src.primitiveValue(), "PackagedProductDefinition");
} else if (Utilities.existsInList(src.primitiveValue(), "MedicinalProductPharmaceutical")) {
setType(tgt, src.primitiveValue(), "AdministrableProductDefinition");
} else if (Utilities.existsInList(src.primitiveValue(), "SubstanceSpecification")) {
setType(tgt, src.primitiveValue(), "SubstanceDefinition");
} else if (Utilities.existsInList(src.primitiveValue(), "MedicinalProductContraindication", "MedicinalProductIndication", "MedicinalProductInteraction", "MedicinalProductUndesirableEffect", "ClinicalUseDefinition")) {
setType(tgt, src.primitiveValue(), "SubstanceDefinition");
} else if (Utilities.existsInList(src.primitiveValue(), "EffectEvidenceSynthesis", "CatalogEntry", "ResearchDefinition", "ResearchElementDefinition", "RiskEvidenceSynthesis",
"Contributor", "ProdCharacteristic", "SubstanceAmount")) {
setType(tgt, src.primitiveValue(), "Basic");
} else {
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRTypes.fromCode(src.primitiveValue()));
}
}
private static void setType(org.hl7.fhir.r5.model.Enumeration<FHIRTypes> tgt, String original, String value) {
tgt.setValueAsString(value);
tgt.addExtension(new Extension().setUrl(VersionConvertorConstants.EXT_OPDEF_ORIGINAL_TYPE).setValue(new CodeType(original)));
}
public static void convertType(org.hl7.fhir.r5.model.Enumeration<FHIRTypes> src, org.hl7.fhir.r4b.model.Enumeration<FHIRAllTypes> tgt) {
if (src.hasExtension(VersionConvertorConstants.EXT_OPDEF_ORIGINAL_TYPE)) {
tgt.setValueAsString(src.getExtensionString(VersionConvertorConstants.EXT_OPDEF_ORIGINAL_TYPE));
} else {
tgt.setValueAsString(src.asStringValue());
}
}
}

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.convertors.conv43_50.datatypes43_50.metadata43_50;
import org.hl7.fhir.convertors.context.ConversionContext43_50;
import org.hl7.fhir.convertors.conv43_50.Utilities43_50;
import org.hl7.fhir.convertors.conv43_50.datatypes43_50.general43_50.Coding43_50;
import org.hl7.fhir.convertors.conv43_50.datatypes43_50.primitive43_50.Canonical43_50;
import org.hl7.fhir.convertors.conv43_50.datatypes43_50.primitive43_50.PositiveInt43_50;
@ -12,8 +13,9 @@ public class DataRequirement43_50 {
if (src == null) return null;
org.hl7.fhir.r5.model.DataRequirement tgt = new org.hl7.fhir.r5.model.DataRequirement();
ConversionContext43_50.INSTANCE.getVersionConvertor_43_50().copyElement(src, tgt);
if (src.hasType())
tgt.setType(org.hl7.fhir.r5.model.Enumerations.FHIRTypes.fromCode(convertResourceName4to5(src.getType().toCode())));
if (src.hasType()) {
Utilities43_50.convertType(src.getTypeElement(), tgt.getTypeElement());
}
for (org.hl7.fhir.r4b.model.CanonicalType t : src.getProfile())
tgt.getProfile().add(Canonical43_50.convertCanonical(t));
if (src.hasSubject())
@ -34,7 +36,9 @@ public class DataRequirement43_50 {
if (src == null) return null;
org.hl7.fhir.r4b.model.DataRequirement tgt = new org.hl7.fhir.r4b.model.DataRequirement();
ConversionContext43_50.INSTANCE.getVersionConvertor_43_50().copyElement(src, tgt);
if (src.hasType()) tgt.getTypeElement().setValueAsString(convertResourceName5to4(src.getType().toCode()));
if (src.hasType()) {
Utilities43_50.convertType(src.getTypeElement(), tgt.getTypeElement());
}
for (org.hl7.fhir.r5.model.CanonicalType t : src.getProfile())
tgt.getProfile().add(Canonical43_50.convertCanonical(t));
if (src.hasSubject())
@ -51,22 +55,6 @@ public class DataRequirement43_50 {
return tgt;
}
private static String convertResourceName4to5(String name) {
if (name == null) return null;
if (name.equals("DeviceUseStatement")) {
return "DeviceUsage";
}
return name;
}
private static String convertResourceName5to4(String name) {
if (name == null) return null;
if (name.equals("DeviceUsage")) {
return "DeviceUseStatement";
}
return name;
}
public static org.hl7.fhir.r5.model.DataRequirement.DataRequirementCodeFilterComponent convertDataRequirementCodeFilterComponent(org.hl7.fhir.r4b.model.DataRequirement.DataRequirementCodeFilterComponent src) throws FHIRException {
if (src == null) return null;
org.hl7.fhir.r5.model.DataRequirement.DataRequirementCodeFilterComponent tgt = new org.hl7.fhir.r5.model.DataRequirement.DataRequirementCodeFilterComponent();

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.convertors.conv43_50.datatypes43_50.metadata43_50;
import org.hl7.fhir.convertors.context.ConversionContext43_50;
import org.hl7.fhir.convertors.conv43_50.Utilities43_50;
import org.hl7.fhir.convertors.conv43_50.datatypes43_50.primitive43_50.Canonical43_50;
import org.hl7.fhir.convertors.conv43_50.datatypes43_50.primitive43_50.Code43_50;
import org.hl7.fhir.convertors.conv43_50.datatypes43_50.primitive43_50.Integer43_50;
@ -17,7 +18,9 @@ public class ParameterDefinition43_50 {
if (src.hasMin()) tgt.setMinElement(Integer43_50.convertInteger(src.getMinElement()));
if (src.hasMax()) tgt.setMaxElement(String43_50.convertString(src.getMaxElement()));
if (src.hasDocumentation()) tgt.setDocumentationElement(String43_50.convertString(src.getDocumentationElement()));
if (src.hasType()) tgt.setType(org.hl7.fhir.r5.model.Enumerations.FHIRTypes.fromCode(src.getType().toCode()));
if (src.hasType()) {
Utilities43_50.convertType(src.getTypeElement(), tgt.getTypeElement());
}
if (src.hasProfile()) tgt.setProfileElement(Canonical43_50.convertCanonical(src.getProfileElement()));
return tgt;
}
@ -31,7 +34,9 @@ public class ParameterDefinition43_50 {
if (src.hasMin()) tgt.setMinElement(Integer43_50.convertInteger(src.getMinElement()));
if (src.hasMax()) tgt.setMaxElement(String43_50.convertString(src.getMaxElement()));
if (src.hasDocumentation()) tgt.setDocumentationElement(String43_50.convertString(src.getDocumentationElement()));
if (src.hasType()) tgt.getTypeElement().setValueAsString(src.getType().toCode());
if (src.hasType()) {
Utilities43_50.convertType(src.getTypeElement(), tgt.getTypeElement());
}
if (src.hasProfile()) tgt.setProfileElement(Canonical43_50.convertCanonical(src.getProfileElement()));
return tgt;
}

View File

@ -1,6 +1,8 @@
package org.hl7.fhir.convertors.conv43_50.resources43_50;
import org.hl7.fhir.convertors.context.ConversionContext43_50;
import org.hl7.fhir.convertors.conv40_50.datatypes40_50.Utilities40_50;
import org.hl7.fhir.convertors.conv43_50.Utilities43_50;
import org.hl7.fhir.convertors.conv43_50.datatypes43_50.general43_50.CodeableConcept43_50;
import org.hl7.fhir.convertors.conv43_50.datatypes43_50.metadata43_50.ContactDetail43_50;
import org.hl7.fhir.convertors.conv43_50.datatypes43_50.metadata43_50.UsageContext43_50;
@ -220,8 +222,9 @@ public class OperationDefinition43_50 {
tgt.setMaxElement(String43_50.convertString(src.getMaxElement()));
if (src.hasDocumentation())
tgt.setDocumentationElement(String43_50.convertStringToMarkdown(src.getDocumentationElement()));
if (src.hasType())
tgt.getTypeElement().setValue(org.hl7.fhir.r5.model.Enumerations.FHIRTypes.fromCode(src.getType().toCode()));
if (src.hasType()) {
Utilities43_50.convertType(src.getTypeElement(), tgt.getTypeElement());
}
for (org.hl7.fhir.r4b.model.CanonicalType t : src.getTargetProfile())
tgt.getTargetProfile().add(Canonical43_50.convertCanonical(t));
if (src.hasSearchType())
@ -250,8 +253,9 @@ public class OperationDefinition43_50 {
tgt.setMaxElement(String43_50.convertString(src.getMaxElement()));
if (src.hasDocumentation())
tgt.setDocumentationElement(String43_50.convertString(src.getDocumentationElement()));
if (src.hasType())
tgt.getTypeElement().setValueAsString(src.getType().toCode());
if (src.hasType()) {
Utilities43_50.convertType(src.getTypeElement(), tgt.getTypeElement());
}
for (org.hl7.fhir.r5.model.CanonicalType t : src.getTargetProfile())
tgt.getTargetProfile().add(Canonical43_50.convertCanonical(t));
if (src.hasSearchType())

View File

@ -0,0 +1,392 @@
package org.hl7.fhir.convertors.misc;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
import java.util.HashMap;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.utilities.CSVReader;
import org.hl7.fhir.utilities.Utilities;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
public class OMOPImporter {
private Connection con;
private Map<String, String> relationships = new HashMap<>();
public static void main(String[] args) throws Exception {
new OMOPImporter().process("/Users/grahamegrieve/Downloads/vocabulary_download_v5_{97cc5432-0dc9-4f14-9da2-d0624129d2f7}_1688068174909");
}
private void process(String folder) throws ClassNotFoundException, SQLException, FHIRException, FileNotFoundException, IOException {
connect();
loadRelationships(folder, true);
processVocabularies(folder, false);
processDomains(folder, false);
processConceptClasses(folder, false);
processDrugStrength(folder, false);
processConcepts(folder, false);
processConceptRelationships(folder, false);
processConceptSynonyms(folder, false);
processConceptAncestors(folder, false);
}
private void loadRelationships(String folder, boolean process) throws FHIRException, FileNotFoundException, IOException, SQLException {
CSVReader csv = new CSVReader(new FileInputStream(Utilities.path(folder, "RELATIONSHIP.csv")));
csv.setDelimiter('\t');
csv.readHeaders();
csv.setDoingQuotes(false);
int i = 0;
Statement stmt = con.createStatement();
stmt.executeUpdate("delete from Relationships");
while (csv.line()) {
relationships.put(csv.cell("relationship_id"), csv.cell("relationship_concept_id"));
if (process) {
String sql = "INSERT INTO `omop`.`Relationships` (`relationship_concept_id`, `relationship_id`, `relationship_name`, `is_hierarchical`, `defines_ancestry`, `reverse_relationship_id`) VALUES ("+
sw(csv.cell("relationship_concept_id"))+", "+
sw(csv.cell("relationship_id"))+", "+
sw(csv.cell("relationship_name"))+", "+
sw(csv.cell("is_hierarchical"))+", "+
sw(csv.cell("defines_ancestry"))+", "+
sw(csv.cell("reverse_relationship_id"))+")";
try {
stmt.executeUpdate(sql);
} catch (Exception e) {
System.out.println("error: "+e.getMessage());
System.out.println("i: "+i);
// System.out.println("sql: "+sql);
}
}
i++;
if (i % 1000 == 0) {
System.out.println(i);
}
}
csv.close();
}
private void processVocabularies(String folder, boolean process) throws FHIRException, FileNotFoundException, IOException, SQLException {
if (!process) {
return;
}
CSVReader csv = new CSVReader(new FileInputStream(Utilities.path(folder, "VOCABULARY.csv")));
csv.setDelimiter('\t');
csv.readHeaders();
csv.setDoingQuotes(false);
int i = 0;
Statement stmt = con.createStatement();
stmt.executeUpdate("delete from Vocabularies");
while (csv.line()) {
String sql = "INSERT INTO `omop`.`Vocabularies` (`vocabulary_concept_id`, `vocabulary_id`, `vocabulary_name`, `vocabulary_reference`, `vocabulary_version`) VALUES ("+
sw(csv.cell("vocabulary_concept_id"))+", "+
sw(csv.cell("vocabulary_id"))+", "+
sw(csv.cell("vocabulary_name"))+", "+
sw(csv.cell("vocabulary_reference"))+", "+
sw(csv.cell("vocabulary_version"))+")";
try {
stmt.executeUpdate(sql);
} catch (Exception e) {
System.out.println("error: "+e.getMessage());
System.out.println("i: "+i);
// System.out.println("sql: "+sql);
}
i++;
if (i % 1000 == 0) {
System.out.println(i);
}
}
csv.close();
}
private void processDrugStrength(String folder, boolean process) throws FHIRException, FileNotFoundException, IOException, SQLException {
if (!process) {
return;
}
CSVReader csv = new CSVReader(new FileInputStream(Utilities.path(folder, "DRUG_STRENGTH.csv")));
csv.setDelimiter('\t');
csv.readHeaders();
csv.setDoingQuotes(false);
int i = 0;
Statement stmt = con.createStatement();
stmt.executeUpdate("delete from DrugStrengths");
while (csv.line()) {
String sql = "INSERT INTO `omop`.`DrugStrengths` (`drug_concept_id`, `ingredient_concept_id`, `amount_value`, `amount_unit_concept_id`, `numerator_value`, `numerator_unit_concept_id`, `denominator_value`, "
+ "`denominator_unit_concept_id`, `box_size`, `valid_start_date`, `valid_end_date`, `invalid_reason`) VALUES ("+
sw(csv.cell("drug_concept_id"))+", "+
sw(csv.cell("ingredient_concept_id"))+", "+
sw(csv.cell("amount_value"))+", "+
sw(csv.cell("amount_unit_concept_id"))+", "+
sw(csv.cell("numerator_value"))+", "+
sw(csv.cell("numerator_unit_concept_id"))+", "+
sw(csv.cell("denominator_value"))+", "+
sw(csv.cell("denominator_unit_concept_id"))+", "+
sw(csv.cell("box_size"))+", "+
sw(csv.cell("valid_start_date"))+", "+
sw(csv.cell("valid_end_date"))+", "+
sw(csv.cell("invalid_reason"))+")";
try {
stmt.executeUpdate(sql);
} catch (Exception e) {
System.out.println("error: "+e.getMessage());
System.out.println("i: "+i);
System.out.println("sql: "+sql);
}
i++;
if (i % 100 == 0) {
System.out.println(i);
}
}
csv.close();
}
private void processDomains(String folder, boolean process) throws FHIRException, FileNotFoundException, IOException, SQLException {
if (!process) {
return;
}
CSVReader csv = new CSVReader(new FileInputStream(Utilities.path(folder, "DOMAIN.csv")));
csv.setDelimiter('\t');
csv.readHeaders();
csv.setDoingQuotes(false);
int i = 0;
Statement stmt = con.createStatement();
stmt.executeUpdate("delete from Domains");
while (csv.line()) {
String sql = "INSERT INTO `omop`.`Domains` (`domain_concept_id`, `domain_id`, `domain_name`) VALUES ("+
sw(csv.cell("domain_concept_id"))+", "+
sw(csv.cell("domain_id"))+", "+
sw(csv.cell("domain_name"))+")";
try {
stmt.executeUpdate(sql);
} catch (Exception e) {
System.out.println("error: "+e.getMessage());
System.out.println("i: "+i);
// System.out.println("sql: "+sql);
}
i++;
if (i % 1000 == 0) {
System.out.println(i);
}
}
csv.close();
}
private void processConceptClasses(String folder, boolean process) throws FHIRException, FileNotFoundException, IOException, SQLException {
if (!process) {
return;
}
CSVReader csv = new CSVReader(new FileInputStream(Utilities.path(folder, "CONCEPT_CLASS.csv")));
csv.setDelimiter('\t');
csv.readHeaders();
csv.setDoingQuotes(false);
int i = 0;
Statement stmt = con.createStatement();
stmt.executeUpdate("delete from ConceptClasses");
while (csv.line()) {
String sql = "INSERT INTO `omop`.`ConceptClasses` (`concept_class_concept_id`, `concept_class_id`, `concept_class_name`) VALUES ("+
sw(csv.cell("concept_class_concept_id"))+", "+
sw(csv.cell("concept_class_id"))+", "+
sw(csv.cell("concept_class_name"))+")";
try {
stmt.executeUpdate(sql);
} catch (Exception e) {
System.out.println("error: "+e.getMessage());
System.out.println("i: "+i);
// System.out.println("sql: "+sql);
}
i++;
if (i % 1000 == 0) {
System.out.println(i);
}
}
csv.close();
}
private void processConcepts(String folder, boolean process) throws FHIRException, FileNotFoundException, IOException, SQLException {
if (!process) {
return;
}
CSVReader csv = new CSVReader(new FileInputStream(Utilities.path(folder, "CONCEPT.csv")));
csv.setDelimiter('\t');
csv.readHeaders();
csv.setDoingQuotes(false);
int i = 0;
Statement stmt = con.createStatement();
while (csv.line()) {
String sql = "INSERT INTO `omop`.`Concepts` (`concept_id`, `concept_name`, `domain_id`, `vocabulary_id`, `concept_class_id`, `standard_concept`, `concept_code`, `valid_start_date`, `valid_end_date`, `invalid_reason`) VALUES ("+
sw(csv.cell("concept_id"))+", "+
sw(csv.cell("concept_name"))+", "+
sw(csv.cell("domain_id"))+", "+
sw(csv.cell("vocabulary_id"))+", "+
sw(csv.cell("concept_class_id"))+", "+
sw(csv.cell("standard_concept"))+", "+
sw(csv.cell("concept_code"))+", "+
sw(csv.cell("valid_start_date"))+", "+
sw(csv.cell("valid_end_date"))+", "+
sw(csv.cell("invalid_reason"))+")";
try {
stmt.executeUpdate(sql);
} catch (Exception e) {
System.out.println("error: "+e.getMessage());
System.out.println("i: "+i);
// System.out.println("sql: "+sql);
}
i++;
if (i % 1000 == 0) {
System.out.println(i);
}
}
csv.close();
}
private void processConceptSynonyms(String folder, boolean process) throws FHIRException, FileNotFoundException, IOException, SQLException {
if (!process) {
return;
}
CSVReader csv = new CSVReader(new FileInputStream(Utilities.path(folder, "CONCEPT_SYNONYM.csv")));
csv.setDelimiter('\t');
csv.readHeaders();
csv.setDoingQuotes(false);
int i = 0;
int ec = 0;
Statement stmt = con.createStatement();
stmt.executeUpdate("delete from ConceptSynonyms");
while (csv.line()) {
String sql = "INSERT INTO `omop`.`ConceptSynonyms` (`concept_id`, `concept_synonym_name`, `language_concept_id`) VALUES ("+
sw(csv.cell("concept_id"))+", "+
sw(csv.cell("concept_synonym_name"))+", "+
sw(csv.cell("language_concept_id"))+")";
try {
stmt.executeUpdate(sql);
} catch (Exception e) {
System.out.println("error: "+e.getMessage());
System.out.println("i: "+i);
System.out.println("sql: "+sql);
ec++;
}
i++;
if (i % 1000 == 0) {
System.out.println(i);
}
}
csv.close();
System.out.println("Finished. "+i+" rows, "+ec+" errors");
}
private void processConceptAncestors(String folder, boolean process) throws FHIRException, FileNotFoundException, IOException, SQLException {
if (!process) {
return;
}
CSVReader csv = new CSVReader(new FileInputStream(Utilities.path(folder, "CONCEPT_ANCESTOR"
+ ".csv")));
csv.setDelimiter('\t');
csv.readHeaders();
csv.setDoingQuotes(false);
int i = 0;
int ec = 0;
Statement stmt = con.createStatement();
stmt.executeUpdate("delete from ConceptAncestors");
while (csv.line()) {
String sql = "INSERT INTO `omop`.`ConceptAncestors` (`ancestor_concept_id`, `descendant_concept_id`, `min_levels_of_separation`, `max_levels_of_separation`) VALUES ("+
sw(csv.cell("ancestor_concept_id"))+", "+
sw(csv.cell("descendant_concept_id"))+", "+
sw(csv.cell("min_levels_of_separation"))+", "+
sw(csv.cell("max_levels_of_separation"))+")";
try {
stmt.executeUpdate(sql);
} catch (Exception e) {
System.out.println("error: "+e.getMessage());
System.out.println("i: "+i);
System.out.println("sql: "+sql);
ec++;
}
i++;
if (i % 1000 == 0) {
System.out.println(i);
}
}
csv.close();
System.out.println("Finished. "+i+" rows, "+ec+" errors");
}
private void processConceptRelationships(String folder, boolean process) throws FHIRException, FileNotFoundException, IOException, SQLException {
if (!process) {
return;
}
CSVReader csv = new CSVReader(new FileInputStream(Utilities.path(folder, "CONCEPT_RELATIONSHIP.csv")));
csv.setDelimiter('\t');
csv.readHeaders();
csv.setDoingQuotes(false);
int i = 0;
Statement stmt = con.createStatement();
while (csv.line()) {
String sql = "INSERT INTO `omop`.`ConceptRelationships` (`concept_id_1`, `concept_id_2`, `relationship_id`, `valid_start_date`, `valid_end_date`, `invalid_reason`) VALUES ("+
sw(csv.cell("concept_id_1"))+", "+
sw(csv.cell("concept_id_2"))+", "+
sw(relationships.get(csv.cell("relationship_id")))+", "+
sw(csv.cell("valid_start_date"))+", "+
sw(csv.cell("valid_end_date"))+", "+
sw(csv.cell("invalid_reason"))+")";
try {
stmt.executeUpdate(sql);
} catch (Exception e) {
System.out.println("error: "+e.getMessage());
System.out.println("i: "+i);
// System.out.println("sql: "+sql);
}
i++;
if (i % 100 == 0) {
System.out.println(i);
}
}
csv.close();
}
private String sw(String value) {
if (value == null) {
return "null";
}
StringBuilder b = new StringBuilder();
b.append('"');
for (char ch : value.toCharArray()) {
if (ch == '"') {
b.append('"');
}
b.append(ch);
}
b.append('"');
return b.toString();
}
private void connect() throws SQLException, ClassNotFoundException {
// Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/omop?useSSL=false","root","@AZEq|OzHLl1/[50v[CI");
}
}

View File

@ -0,0 +1,35 @@
package org.hl7.fhir.convertors.conv40_50;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
public class OperationDefinition40_50Test {
@Test
@DisplayName("Test r5 -> r4 OperationDefinition conversion.")
public void testR5_R4() throws IOException {
InputStream r4_input = this.getClass().getResourceAsStream("/opdef-4.xml");
org.hl7.fhir.r4.model.OperationDefinition r4_actual = (org.hl7.fhir.r4.model.OperationDefinition) new org.hl7.fhir.r4.formats.XmlParser().parse(r4_input);
org.hl7.fhir.r5.model.Resource r5_conv = VersionConvertorFactory_40_50.convertResource(r4_actual);
org.hl7.fhir.r5.formats.XmlParser r5_parser = new org.hl7.fhir.r5.formats.XmlParser();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
r5_parser.compose(stream, r5_conv);
org.hl7.fhir.r5.model.Resource r5_streamed = (org.hl7.fhir.r5.model.OperationDefinition) new org.hl7.fhir.r5.formats.XmlParser().parse(new ByteArrayInputStream(stream.toByteArray()));
org.hl7.fhir.r4.model.Resource r4_conv = VersionConvertorFactory_40_50.convertResource(r5_streamed);
assertTrue(r4_actual.equalsDeep(r4_conv), "should be the same");
}
}

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<OperationDefinition xmlns="http://hl7.org/fhir">
<url value="http:://false.com/OperationDefinition/operation-DiagnosticReport-addMedia" />
<name value="operation-DiagnosticReport-addMedia" />
<status value="active" />
<kind value="operation" />
<experimental value="false" />
<affectsState value="true" />
<code value="addMedia" />
<system value="false" />
<type value="false" />
<instance value="true" />
<parameter>
<name value="mediaInstance" />
<use value="in" />
<min value="1" />
<max value="1" />
<documentation value="Instance of media that should be attached to the diagnosticreport" />
<type value="Media" />
<targetProfile value="http://false.com/StructureDefinition/Media" />
</parameter>
</OperationDefinition>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -51,6 +51,7 @@ import org.hl7.fhir.r5.conformance.ElementRedirection;
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.AllowUnknownProfile;
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.ElementDefinitionCounter;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
import org.hl7.fhir.r5.elementmodel.ObjectConverter;
import org.hl7.fhir.r5.elementmodel.Property;
import org.hl7.fhir.r5.model.Base;
@ -2599,9 +2600,23 @@ public class ProfileUtilities extends TranslatingUtilities {
messages.add(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)
messages.add(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))
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));
else if (!isSubset(expBase.getValueset(), expDerived.getValueset()))
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) {
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));
} else {
boolean ok = true;
for (ValueSetExpansionContainsComponent cc : expDerived.getValueset().getExpansion().getContains()) {
ValidationResult vr = context.validateCode(null, cc.getSystem(), cc.getVersion(), cc.getCode(), null, baseVs);
if (!vr.isOk()) {
ok = false;
break;
}
}
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));
}
}
} 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));
}
}

View File

@ -1066,6 +1066,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
Set<String> unknownSystems = new HashSet<>();
String localError = null;
String localWarning = null;
if (options.isUseClient()) {
// ok, first we try to validate locally
try {
@ -1080,7 +1081,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
return res;
}
} catch (VSCheckerException e) {
localError = e.getMessage();
if (e.isWarning()) {
localWarning = e.getMessage();
} else {
localError = e.getMessage();
}
if (e.getIssues() != null) {
issues.addAll(e.getIssues());
}
@ -1097,8 +1102,15 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
return new ValidationResult(IssueSeverity.ERROR, localError, TerminologyServiceErrorClass.UNKNOWN, issues);
}
}
if (localWarning != null && tcc.getClient() == null) {
return new ValidationResult(IssueSeverity.WARNING,formatMessage(I18nConstants.UNABLE_TO_VALIDATE_CODE_WITHOUT_USING_SERVER, localWarning), TerminologyServiceErrorClass.BLOCKED_BY_OPTIONS, issues);
}
if (!options.isUseServer()) {
return new ValidationResult(IssueSeverity.WARNING,formatMessage(I18nConstants.UNABLE_TO_VALIDATE_CODE_WITHOUT_USING_SERVER, localError), TerminologyServiceErrorClass.BLOCKED_BY_OPTIONS, issues);
if (localWarning != null) {
return new ValidationResult(IssueSeverity.WARNING,formatMessage(I18nConstants.UNABLE_TO_VALIDATE_CODE_WITHOUT_USING_SERVER, localWarning), TerminologyServiceErrorClass.BLOCKED_BY_OPTIONS, issues);
} else {
return new ValidationResult(IssueSeverity.WARNING,formatMessage(I18nConstants.UNABLE_TO_VALIDATE_CODE_WITHOUT_USING_SERVER, localError), TerminologyServiceErrorClass.BLOCKED_BY_OPTIONS, issues);
}
}
String codeKey = getCodeKey(code);
if (unsupportedCodeSystems.contains(codeKey)) {

View File

@ -175,10 +175,11 @@ public abstract class ParserBase {
}
for (StructureDefinition sd : context.fetchResourcesByType(StructureDefinition.class)) {
if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION && !sd.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition/de-")) {
if(name.equals(sd.getType()) && (ns == null || ns.equals(FormatUtilities.FHIR_NS)) && !ToolingExtensions.hasExtension(sd, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"))
String type = urlTail(sd.getType());
if(name.equals(type) && (ns == null || ns.equals(FormatUtilities.FHIR_NS)) && !ToolingExtensions.hasExtension(sd, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"))
return sd;
String sns = ToolingExtensions.readStringExtension(sd, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace");
if ((name.equals(sd.getType()) || name.equals(sd.getName())) && ns != null && ns.equals(sns))
if ((name.equals(type) || name.equals(sd.getName())) && ns != null && ns.equals(sns))
return sd;
}
}
@ -186,6 +187,10 @@ public abstract class ParserBase {
return null;
}
private String urlTail(String type) {
return type == null || !type.contains("/") ? type : type.substring(type.lastIndexOf("/")+1);
}
protected StructureDefinition getDefinition(int line, int col, String name) throws FHIRFormatError {
if (name == null) {
logError(ValidationMessage.NO_RULE_DATE, line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS_CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAME), IssueSeverity.FATAL);

View File

@ -373,7 +373,7 @@ public class Property {
ok = true;
if (Utilities.isAbsoluteUrl(tr.getWorkingCode())) {
StructureDefinition sdt = context.fetchResource(StructureDefinition.class, tr.getWorkingCode());
if (sdt != null && sdt.getType().equals(t)) {
if (sdt != null && sdt.getTypeTail().equals(t)) {
url = tr.getWorkingCode();
ok = true;
}

View File

@ -25,6 +25,7 @@ import org.hl7.fhir.r5.model.Address;
import org.hl7.fhir.r5.model.Annotation;
import org.hl7.fhir.r5.model.BackboneType;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.Base64BinaryType;
import org.hl7.fhir.r5.model.BaseDateTimeType;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CanonicalType;
@ -99,7 +100,7 @@ public class DataRenderer extends Renderer implements CodeResolver {
}
// -- 2. Markdown support -------------------------------------------------------
public static String processRelativeUrls(String markdown, String path) {
if (markdown == null) {
return "";
@ -419,7 +420,7 @@ public class DataRenderer extends Renderer implements CodeResolver {
private String getExtensionLabel(Extension ext) {
StructureDefinition sd = context.getWorker().fetchResource(StructureDefinition.class, ext.getUrl());
if (sd != null && ext.getValue().isPrimitive() && sd.hasSnapshot()) {
if (sd != null && ext.hasValue() && ext.getValue().isPrimitive() && sd.hasSnapshot()) {
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
if (Utilities.existsInList(ed.getPath(), "Extension", "Extension.value[x]") && ed.hasLabel()) {
return ed.getLabel();
@ -726,6 +727,9 @@ public class DataRenderer extends Renderer implements CodeResolver {
}
} else if (type instanceof MarkdownType) {
addMarkdown(x, ((MarkdownType) type).asStringValue());
} else if (type instanceof Base64BinaryType) {
Base64BinaryType b64 = (Base64BinaryType) type;
x.tx("(base64 data - "+(b64.getValue() == null ? "0" : b64.getValue().length)+" bytes)");
} else if (type.isPrimitive()) {
x.tx(type.primitiveValue());
} else {

View File

@ -377,9 +377,10 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
x.addText(((InstantType) e).toHumanDisplay());
else if (e instanceof DateTimeType) {
renderDateTime(x, e);
} else if (e instanceof Base64BinaryType)
x.addText(new Base64().encodeAsString(((Base64BinaryType) e).getValue()));
else if (e instanceof org.hl7.fhir.r5.model.DateType) {
} else if (e instanceof Base64BinaryType) {
Base64BinaryType b64 = (Base64BinaryType) e;
x.addText("(base64 data - "+(b64.getValue() == null ? "0" : b64.getValue().length)+" bytes)");
} else if (e instanceof org.hl7.fhir.r5.model.DateType) {
org.hl7.fhir.r5.model.DateType dt = ((org.hl7.fhir.r5.model.DateType) e);
renderDate(x, dt);
} else if (e instanceof Enumeration) {
@ -853,12 +854,12 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
XhtmlNode tbl = new XhtmlNode(NodeType.Element, "table");
tbl.setAttribute("class", "grid");
XhtmlNode tr = tbl.tr();
tr.td().tx("-"); // work around problem with empty table rows
tr.td().style("display: none").tx("-"); // work around problem with empty table rows
boolean add = addColumnHeadings(tr, grandChildren);
for (BaseWrapper v : p.getValues()) {
if (v != null) {
tr = tbl.tr();
tr.td().tx("*"); // work around problem with empty table rows
tr.td().style("display: none").tx("*"); // work around problem with empty table rows
add = addColumnValues(res, tr, grandChildren, v, showCodeDetails, displayHints, path, indent) || add;
}
}

View File

@ -250,7 +250,13 @@ public abstract class ResourceRenderer extends DataRenderer {
String name = tr != null && tr.getResource() != null ? tr.getResource().getNameFromResource() : null;
if (display == null && (tr == null || tr.getResource() == null)) {
c.addText(r.getReference());
if (!Utilities.noString(r.getReference())) {
c.addText(r.getReference());
} else if (r.hasIdentifier()) {
renderIdentifier(c, r.getIdentifier());
} else {
c.addText("??");
}
} else if (context.isTechnicalMode()) {
c.addText(r.getReference());
if (display != null) {

View File

@ -8,16 +8,27 @@ import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
public class VSCheckerException extends FHIRException {
private List<OperationOutcomeIssueComponent> issues;
private boolean warning;
public VSCheckerException(String message, List<OperationOutcomeIssueComponent> issues) {
super(message);
this.issues = issues;
}
public VSCheckerException(String message, List<OperationOutcomeIssueComponent> issues, boolean warning) {
super(message);
this.issues = issues;
this.warning = warning;
}
public List<OperationOutcomeIssueComponent> getIssues() {
return issues;
}
private static final long serialVersionUID = -5889505119633054187L;
public boolean isWarning() {
return warning;
}
}

View File

@ -435,7 +435,7 @@ public class ValueSetValidator {
if (cs!=null && cs.getContent() != CodeSystemContentMode.COMPLETE) {
warningMessage = "Resolved system "+system+(cs.hasVersion() ? " (v"+cs.getVersion()+")" : "")+", but the definition is not complete";
if (!inExpansion && cs.getContent() != CodeSystemContentMode.FRAGMENT) { // we're going to give it a go if it's a fragment
throw new VSCheckerException(warningMessage, null);
throw new VSCheckerException(warningMessage, null, true);
}
}

View File

@ -62,6 +62,7 @@ public class CSVReader extends InputStreamReader {
private String[] cells;
private char delimiter = ',';
private boolean multiline;
private boolean doingQuotes = true;
public void readHeaders() throws IOException, FHIRException {
cols = parseLine();
@ -86,11 +87,13 @@ public class CSVReader extends InputStreamReader {
public String cell(String name) {
int index = -1;
for (int i = 0; i < cols.length; i++) {
if (name.equals(cols[i].trim()))
if (name.equals(cols[i].trim())) {
index = i;
break;
}
}
if (index == -1)
throw new FHIRException("no cell "+name);
throw new FHIRException("no cell "+name+" in "+cols);
String s = cells.length > index ? cells[index] : null;
if (Utilities.noString(s))
return null;
@ -143,7 +146,7 @@ public class CSVReader extends InputStreamReader {
while (more() && !finished(inQuote, res.size())) {
char c = peek();
next();
if (c == '"') {
if (c == '"' && doingQuotes) {
if (ready() && peek() == '"') {
b.append(c);
next();
@ -238,5 +241,13 @@ public class CSVReader extends InputStreamReader {
this.multiline = multiline;
}
public boolean isDoingQuotes() {
return doingQuotes;
}
public void setDoingQuotes(boolean doingQuotes) {
this.doingQuotes = doingQuotes;
}
}

View File

@ -917,6 +917,10 @@ public class I18nConstants {
public static final String ED_INVARIANT_EXPRESSION_CONFLICT = "ED_INVARIANT_EXPRESSION_CONFLICT";
public static final String ED_INVARIANT_EXPRESSION_ERROR = "ED_INVARIANT_EXPRESSION_ERROR";
public static final String SNAPSHOT_IS_EMPTY = "SNAPSHOT_IS_EMPTY";
public static final String EXTENSION_CONTEXT_UNABLE_TO_CHECK_PROFILE = "EXTENSION_CONTEXT_UNABLE_TO_CHECK_PROFILE";
public static final String EXTENSION_CONTEXT_UNABLE_TO_FIND_PROFILE = "EXTENSION_CONTEXT_UNABLE_TO_FIND_PROFILE";
public static final String TERMINOLOGY_TX_HINT = "TERMINOLOGY_TX_HINT";
public static final String TERMINOLOGY_TX_WARNING = "TERMINOLOGY_TX_WARNING";
}

View File

@ -33,6 +33,8 @@ CodeSystem_CS_VS_IncludeDetails = CodeSystem {0} has an ''all system'' value set
CodeSystem_CS_VS_Invalid = CodeSystem {0} has an ''all system'' value set of {1}, but the value set doesn''t have a single include
CODESYSTEM_CS_VS_EXP_MISMATCH = CodeSystem {0} has an ''all system'' value set of {1}, but it is an expansion with the wrong number of concepts (found {2}, expected {3})
CodeSystem_CS_VS_WrongSystem = CodeSystem {0} has an ''all system'' value set of {1}, but the value set doesn''t have a matching system ({2})
EXTENSION_CONTEXT_UNABLE_TO_CHECK_PROFILE = The extension {0} specifies a context of {1} but the validator cannot check whether the profile is valid or not at this time
EXTENSION_CONTEXT_UNABLE_TO_FIND_PROFILE = The extension {0} specifies a context of {1} but the validator cannot find that profile
Extension_EXTP_Context_Wrong = The extension {0} is not allowed to be used at this point (allowed = {1}; this element is {2})
Extension_EXTM_Context_Wrong = The modifier extension {0} is not allowed to be used at this point (allowed = {1}; this element is {2})
Extension_EXT_Count_Mismatch = Extensions count mismatch: expected {0} but found {1}
@ -971,3 +973,5 @@ ED_INVARIANT_NO_EXPRESSION = The invariant ''{0}'' has no computable expression,
ED_INVARIANT_EXPRESSION_CONFLICT = The invariant ''{0}'' has an expression ''{1}'', which differs from the earlier expression provided of ''{2}'' (invariants are allowed to repeat, but cannot differ)
ED_INVARIANT_EXPRESSION_ERROR = Error in invariant ''{0}'' with expression ''{1}'': {2}
SNAPSHOT_IS_EMPTY = The snapshot for the profile ''{0}'' is empty (which should not happen)
TERMINOLOGY_TX_HINT = {1}
TERMINOLOGY_TX_WARNING = {1}

View File

@ -356,6 +356,10 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
return new ValidationEngineBuilder(terminologyCachePath, userAgent, version, txServer, txLog, txVersion, timeTracker, canRunWithoutTerminologyServer, loggingService, THO);
}
public ValidationEngineBuilder withNoTerminologyServer() {
return new ValidationEngineBuilder(terminologyCachePath, userAgent, version, null, null, txVersion, timeTracker, true, loggingService, THO);
}
public ValidationEngine fromNothing() throws IOException {
ValidationEngine engine = new ValidationEngine();
SimpleWorkerContext.SimpleWorkerContextBuilder contextBuilder = new SimpleWorkerContext.SimpleWorkerContextBuilder().withLoggingService(loggingService);

View File

@ -1298,8 +1298,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
}
} else if (vr.getMessage() != null) {
res = false;
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
if (vr.getSeverity() == IssueSeverity.INFORMATION) {
txHint(errors, "2023-07-03", vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
} else {
res = false;
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
}
} else {
if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
removeTrackedMessagesForLocation(errors, element, path);
@ -1426,7 +1430,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
} else if (vr.getMessage() != null) {
res = false;
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
if (vr.getSeverity() == IssueSeverity.INFORMATION) {
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
} else {
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
}
} else {
res = false;
}
@ -1533,6 +1541,12 @@ 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_NOVALID_6, describeReference(binding.getValueSet(), valueset), (vr.getMessage() != null ? " (error message = " + vr.getMessage() + ")" : ""), system+"#"+code);
}
}
} else if (vr != null && vr.getMessage() != null){
if (vr.getSeverity() == IssueSeverity.INFORMATION) {
txHint(errors, "2023-07-04", vr.getTxLink(), IssueType.INFORMATIONAL, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_HINT, code, vr.getMessage());
} else {
txWarning(errors, "2023-07-04", vr.getTxLink(), IssueType.INFORMATIONAL, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_WARNING, code, vr.getMessage());
}
}
} catch (Exception e) {
if (STACK_TRACE) e.printStackTrace();
@ -1813,7 +1827,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
}
} else if (vr != null && vr.getMessage() != null) {
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
if (vr.getSeverity() == IssueSeverity.INFORMATION) {
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
} else {
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
}
}
} catch (Exception e) {
if (STACK_TRACE) e.printStackTrace();
@ -1908,7 +1926,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
// two questions
// 1. can this extension be used here?
checkExtensionContext(errors, resource, container, ex, containerStack, hostContext, isModifier);
checkExtensionContext(hostContext.getAppContext(), errors, resource, container, ex, containerStack, hostContext, isModifier);
if (isModifier)
rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), path + "[url='" + url + "']", ex.getSnapshot().getElement().get(0).getIsModifier(), I18nConstants.EXTENSION_EXT_MODIFIER_Y, url);
@ -1979,7 +1997,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
return res;
}
private boolean checkExtensionContext(List<ValidationMessage> errors, Element resource, Element container, StructureDefinition definition, NodeStack stack, ValidatorHostContext hostContext, boolean modifier) {
private boolean checkExtensionContext(Object appContext, List<ValidationMessage> errors, Element resource, Element container, StructureDefinition definition, NodeStack stack, ValidatorHostContext hostContext, boolean modifier) {
String extUrl = definition.getUrl();
boolean ok = false;
CommaSeparatedStringBuilder contexts = new CommaSeparatedStringBuilder();
@ -2002,34 +2020,41 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (ctxt.getType() == ExtensionContextType.ELEMENT) {
String en = ctxt.getExpression();
contexts.append("e:" + en);
String pu = null;
if (en.contains("#")) {
pu = en.substring(0, en.indexOf("#"));
en = en.substring(en.indexOf("#")+1);
}
if (Utilities.existsInList(en, "Element", "Any")) {
ok = true;
} else if (en.equals("Resource") && container.isResource()) {
ok = true;
}
for (String p : plist) {
if (ok) {
break;
}
if (p.equals(en)) {
ok = true;
} else {
String pn = p;
String pt = "";
if (p.contains(".")) {
pn = p.substring(0, p.indexOf("."));
pt = p.substring(p.indexOf("."));
if (checkConformsToProfile(appContext, errors, resource, container, stack, extUrl, ctxt.getExpression(), pu)) {
for (String p : plist) {
if (ok) {
break;
}
StructureDefinition sd = context.fetchTypeDefinition(pn);
while (sd != null) {
if ((sd.getType() + pt).equals(en)) {
ok = true;
break;
if (p.equals(en)) {
ok = true;
} else {
String pn = p;
String pt = "";
if (p.contains(".")) {
pn = p.substring(0, p.indexOf("."));
pt = p.substring(p.indexOf("."));
}
if (sd.getBaseDefinition() != null) {
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd);
} else {
sd = null;
StructureDefinition sd = context.fetchTypeDefinition(pn);
while (sd != null) {
if ((sd.getType() + pt).equals(en)) {
ok = true;
break;
}
if (sd.getBaseDefinition() != null) {
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd);
} else {
sd = null;
}
}
}
}
@ -2088,6 +2113,36 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
}
private boolean checkConformsToProfile(Object appContext, List<ValidationMessage> errors, Element resource, Element container, NodeStack stack, String extUrl, String expression, String pu) {
if (pu == null) {
return true;
}
if (pu.equals("http://hl7.org/fhir/StructureDefinition/"+resource.fhirType())) {
return true;
}
StructureDefinition sd = context.fetchResource(StructureDefinition.class, pu);
if (!rule(errors, "2023-07-03", IssueType.UNKNOWN, container.line(), container.col(), stack.getLiteralPath(), sd != null,I18nConstants.EXTENSION_CONTEXT_UNABLE_TO_FIND_PROFILE, extUrl, expression)) {
return false;
} else if (sd.getType().equals(resource.fhirType())) {
List<ValidationMessage> valerrors = new ArrayList<ValidationMessage>();
ValidationMode mode = new ValidationMode(ValidationReason.Expression, ProfileSource.FromExpression);
validateResource(new ValidatorHostContext(appContext, resource), valerrors, resource, resource, sd, IdStatus.OPTIONAL, new NodeStack(context, null, resource, validationLanguage), null, mode);
boolean ok = true;
List<ValidationMessage> record = new ArrayList<>();
for (ValidationMessage v : valerrors) {
ok = ok && !v.getLevel().isError();
if (v.getLevel().isError() || v.isSlicingHint()) {
record.add(v);
}
}
return ok;
} else {
warning(errors, "2023-07-03", IssueType.UNKNOWN, container.line(), container.col(), stack.getLiteralPath(), false,
I18nConstants.EXTENSION_CONTEXT_UNABLE_TO_CHECK_PROFILE, extUrl, expression, pu);
return true;
}
}
private List<StructureDefinitionContextComponent> fixContexts(String extUrl, List<StructureDefinitionContextComponent> list) {
List<StructureDefinitionContextComponent> res = new ArrayList<>();
for (StructureDefinitionContextComponent ctxt : list) {
@ -3053,6 +3108,12 @@ 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_NOVALID_18, value, describeReference(binding.getValueSet(), vs), getErrorMessage(vr.getMessage()));
}
}
} else if (vr != null && vr.getMessage() != null){
if (vr.getSeverity() == IssueSeverity.INFORMATION) {
txHint(errors, "2023-07-04", vr.getTxLink(), IssueType.INFORMATIONAL, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_HINT, value, vr.getMessage());
} else {
txWarning(errors, "2023-07-04", vr.getTxLink(), IssueType.INFORMATIONAL, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_WARNING, value, vr.getMessage());
}
}
}
}
@ -3907,7 +3968,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
long t = System.nanoTime();
StructureDefinition sd = context.fetchResource(StructureDefinition.class, url, src);
timeTracker.sd(t);
if (sd != null && (sd.getType().equals(type) || sd.getUrl().equals(type)) && sd.hasSnapshot()) {
if (sd != null && (sd.getTypeTail().equals(type) || sd.getUrl().equals(type)) && sd.hasSnapshot()) {
return sd;
}
if (sd.getAbstract()) {
@ -6273,7 +6334,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
}
// validate
if (rule(errors, NO_RULE_DATE, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), resourceName.equals(defn.getType()), I18nConstants.VALIDATION_VAL_PROFILE_WRONGTYPE,
if (rule(errors, NO_RULE_DATE, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), resourceName.equals(defn.getType()) || resourceName.equals(defn.getTypeTail()), I18nConstants.VALIDATION_VAL_PROFILE_WRONGTYPE,
defn.getType(), resourceName, defn.getVersionedUrl())) {
ok = start(hostContext, errors, element, element, defn, stack, pct, mode); // root is both definition and type
} else {

View File

@ -251,6 +251,34 @@ public class ValidationEngineTests {
System.out.println(" .. done: " + Integer.toString(e) + " errors, " + Integer.toString(w) + " warnings, " + Integer.toString(h) + " information messages");
}
@Test
public void test401USCore() throws Exception {
if (!TestUtilities.silent)
System.out.println("Test401USCore: Validate observation401_ucum.json against US-Core with no terminology server");
ValidationEngine ve = TestUtilities.getValidationEngine("hl7.fhir.r4.core#4.0.1", "n/a", FhirPublication.R4, "4.0.1");
CacheVerificationLogger logger = new CacheVerificationLogger();
IgLoader igLoader = new IgLoader(ve.getPcm(), ve.getContext(), ve.getVersion(), true);
if (!TestUtilities.silent)
System.out.println(" .. load USCore");
igLoader.loadIg(ve.getIgs(), ve.getBinaries(), "hl7.fhir.us.core#3.1.1", false);
List<String> profiles = new ArrayList<>();
OperationOutcome op = ve.validate(FhirFormat.JSON, TestingUtilities.loadTestResourceStream("validator", "observation401_ucum.json"), profiles);
if (!TestUtilities.silent)
for (OperationOutcomeIssueComponent issue : op.getIssue())
System.out.println(" - " + issue.getDetails().getText());
int e = errors(op);
int w = warnings(op);
int h = hints(op);
Assertions.assertEquals(0, e);
Assertions.assertEquals(2, w);
Assertions.assertEquals(0, h);
assertTrue(logger.verifyHasNoRequests(), "Unexpected request to TX server");
if (!TestUtilities.silent)
System.out.println(" .. done: " + Integer.toString(e) + " errors, " + Integer.toString(w) + " warnings, " + Integer.toString(h) + " information messages");
}
private int errors(OperationOutcome op) {
int i = 0;
for (OperationOutcomeIssueComponent vm : op.getIssue()) {

View File

@ -46,13 +46,22 @@ public class TestUtilities {
}
public static ValidationEngine getValidationEngine(java.lang.String src, java.lang.String txServer, FhirPublication version, java.lang.String vString) throws Exception {
TestingUtilities.injectCorePackageLoader();
final ValidationEngine validationEngine = new ValidationEngine.ValidationEngineBuilder()
.withVersion(vString)
.withUserAgent(TestConstants.USER_AGENT)
.withTerminologyCachePath(getTerminologyCacheDirectory(vString))
.withTxServer(txServer, TestConstants.TX_CACHE_LOG, version)
.fromSource(src);
TerminologyCache.setCacheErrors(true);
ValidationEngine validationEngine = null;
if ("n/a".equals(txServer)) {
validationEngine = new ValidationEngine.ValidationEngineBuilder()
.withVersion(vString)
.withUserAgent(TestConstants.USER_AGENT)
.withNoTerminologyServer()
.fromSource(src);
} else {
validationEngine = new ValidationEngine.ValidationEngineBuilder()
.withVersion(vString)
.withUserAgent(TestConstants.USER_AGENT)
.withTerminologyCachePath(getTerminologyCacheDirectory(vString))
.withTxServer(txServer, TestConstants.TX_CACHE_LOG, version)
.fromSource(src);
TerminologyCache.setCacheErrors(true);
}
return validationEngine;
}

View File

@ -20,7 +20,7 @@
<properties>
<guava_version>32.0.1-jre</guava_version>
<hapi_fhir_version>6.4.1</hapi_fhir_version>
<validator_test_case_version>1.3.13</validator_test_case_version>
<validator_test_case_version>1.3.14-SNAPSHOT</validator_test_case_version>
<jackson_version>2.14.0</jackson_version>
<junit_jupiter_version>5.9.2</junit_jupiter_version>
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>
@ -165,6 +165,12 @@
<version>${saxon_he_version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<!-- Apache POI -->
<dependency>
<groupId>org.apache.poi</groupId>