diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java index 37791e26e..61e2d8f76 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java @@ -15,8 +15,10 @@ import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRFormatError; import org.hl7.fhir.exceptions.TerminologyServiceException; import org.hl7.fhir.r5.comparison.VersionComparisonAnnotation; +import org.hl7.fhir.r5.context.TerminologyCache; import org.hl7.fhir.r5.context.IWorkerContext.CodingValidationRequest; import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult; +import org.hl7.fhir.r5.context.TerminologyCache.CacheToken; import org.hl7.fhir.r5.model.Base; import org.hl7.fhir.r5.model.BooleanType; import org.hl7.fhir.r5.model.CanonicalResource; @@ -26,8 +28,10 @@ import org.hl7.fhir.r5.model.Coding; import org.hl7.fhir.r5.model.ConceptMap; import org.hl7.fhir.r5.model.DataType; import org.hl7.fhir.r5.model.Enumerations.FilterOperator; +import org.hl7.fhir.r5.model.Enumerations.PublicationStatus; import org.hl7.fhir.r5.model.Extension; import org.hl7.fhir.r5.model.ExtensionHelper; +import org.hl7.fhir.r5.model.Parameters; import org.hl7.fhir.r5.model.PrimitiveType; import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.StringType; @@ -38,6 +42,7 @@ import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent; import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceDesignationComponent; import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent; +import org.hl7.fhir.r5.model.ValueSet.ValueSetComposeComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent; @@ -48,9 +53,11 @@ import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext; import org.hl7.fhir.r5.terminologies.CodeSystemUtilities; import org.hl7.fhir.r5.terminologies.ValueSetUtilities; import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.utilities.LoincLinker; import org.hl7.fhir.utilities.Utilities; +import org.hl7.fhir.utilities.i18n.I18nConstants; import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator; import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Row; import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.TableModel; @@ -1142,7 +1149,7 @@ public class ValueSetRenderer extends TerminologyRenderer { } } - private boolean genInclude(XhtmlNode ul, ConceptSetComponent inc, String type, List langs, boolean doDesignations, List maps, Map designations, int index, Resource vsRes) throws FHIRException, IOException { + private boolean genInclude(XhtmlNode ul, ConceptSetComponent inc, String type, List langs, boolean doDesignations, List maps, Map designations, int index, ValueSet vsRes) throws FHIRException, IOException { boolean hasExtensions = false; XhtmlNode li; li = ul.li(); @@ -1165,7 +1172,7 @@ public class ValueSetRenderer extends TerminologyRenderer { } // for performance reasons, we do all the fetching in one batch - definitions = getConceptsForCodes(e, inc); + definitions = getConceptsForCodes(e, inc, vsRes, index); XhtmlNode t = li.table("none"); @@ -1361,7 +1368,7 @@ public class ValueSetRenderer extends TerminologyRenderer { } - private Map getConceptsForCodes(CodeSystem e, ConceptSetComponent inc) { + private Map getConceptsForCodes(CodeSystem e, ConceptSetComponent inc, ValueSet source, int index) { if (e == null) { e = getContext().getWorker().fetchCodeSystem(inc.getSystem()); } @@ -1369,13 +1376,21 @@ public class ValueSetRenderer extends TerminologyRenderer { ValueSetExpansionComponent vse = null; if (!context.isNoSlowLookup()) { // && !getContext().getWorker().hasCache()) { removed GG 20220107 like what is this trying to do? try { - ValueSetExpansionOutcome vso = getContext().getWorker().expandVS(inc, false, false); + + ValueSet vs = new ValueSet(); + vs.setUrl(source.getUrl()+"-inc-"+index); + vs.setStatus(PublicationStatus.ACTIVE); + vs.setCompose(new ValueSetComposeComponent()); + vs.getCompose().setInactive(false); + vs.getCompose().getInclude().add(inc); + + ValueSetExpansionOutcome vso = getContext().getWorker().expandVS(vs, true, false); ValueSet valueset = vso.getValueset(); if (valueset == null) throw new TerminologyServiceException("Error Expanding ValueSet: "+vso.getError()); vse = valueset.getExpansion(); - } catch (TerminologyServiceException e1) { + } catch (Exception e1) { return null; } } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/CommaSeparatedStringBuilder.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/CommaSeparatedStringBuilder.java index b303948e3..757292b47 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/CommaSeparatedStringBuilder.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/CommaSeparatedStringBuilder.java @@ -138,6 +138,15 @@ public class CommaSeparatedStringBuilder { return self.toString(); } + + public static String buildObjects(List list) { + CommaSeparatedStringBuilder self = new CommaSeparatedStringBuilder(); + for (Object s : list) { + self.append(s.toString()); + } + return self.toString(); + } + public static Set toSet(String source) { if (source == null) { return null; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java index dd4fb3960..93e24a7c8 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java @@ -173,6 +173,8 @@ import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPo import org.hl7.fhir.r5.utils.validation.constants.IdStatus; import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy; import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; +import org.hl7.fhir.utilities.HL7WorkGroups; +import org.hl7.fhir.utilities.HL7WorkGroups.HL7WorkGroup; import org.hl7.fhir.utilities.MarkDownProcessor; import org.hl7.fhir.utilities.SIDUtilities; import org.hl7.fhir.utilities.StandardsStatus; @@ -5403,84 +5405,20 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } if (rule(errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), wg != null, I18nConstants.VALIDATION_HL7_WG_NEEDED, ToolingExtensions.EXT_WORKGROUP)) { - String name = nameForWG(wg); - String url = urlForWG(wg); - if (rule(errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), name != null, I18nConstants.VALIDATION_HL7_WG_UNKNOWN, wg)) { - String rpub = "HL7 International / "+name; + HL7WorkGroup wgd = HL7WorkGroups.find(wg); + if (rule(errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), wgd != null, I18nConstants.VALIDATION_HL7_WG_UNKNOWN, wg)) { + String rpub = "HL7 International / "+wgd.getName(); if (warning(errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), pub != null, I18nConstants.VALIDATION_HL7_PUBLISHER_MISSING, wg, rpub)) { warningOrError(pub.contains("/"), errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), rpub.equals(pub), I18nConstants.VALIDATION_HL7_PUBLISHER_MISMATCH, wg, rpub, pub); } warning(errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), - Utilities.startsWithInList(url, urls), I18nConstants.VALIDATION_HL7_WG_URL, wg, url); + Utilities.startsWithInList( wgd.getLink(), urls), I18nConstants.VALIDATION_HL7_WG_URL, wg, wgd.getLink()); return true; } } return false; } - private String urlForWG(String wg) { - switch (wg) { - case "cbcc": return "http://www.hl7.org/Special/committees/homehealth"; - case "cds": return "http://www.hl7.org/Special/committees/dss"; - case "cqi": return "http://www.hl7.org/Special/committees/cqi"; - case "cg": return "http://www.hl7.org/Special/committees/clingenomics"; - case "dev": return "http://www.hl7.org/Special/committees/healthcaredevices"; - case "ehr": return "http://www.hl7.org/special/committees/ehr"; - case "fhir": return "http://www.hl7.org/Special/committees/fiwg"; - case "fm": return "http://www.hl7.org/Special/committees/fm"; - case "hsi": return "http://www.hl7.org/Special/committees/hsi"; - case "ii": return "http://www.hl7.org/Special/committees/imagemgt"; - case "inm": return "http://www.hl7.org/special/committees/inm"; - case "mnm": return "http://www.hl7.org/special/committees/mnm"; - case "its": return "http://www.hl7.org/special/committees/xml"; - case "oo": return "http://www.hl7.org/Special/committees/orders"; - case "pa": return "http://www.hl7.org/Special/committees/pafm"; - case "pc": return "http://www.hl7.org/Special/committees/patientcare"; - case "pe": return "http://www.hl7.org/Special/committees/patientempowerment"; - case "pher": return "http://www.hl7.org/Special/committees/pher"; - case "phx": return "http://www.hl7.org/Special/committees/medication"; - case "brr": return "http://www.hl7.org/Special/committees/rcrim"; - case "sd": return "http://www.hl7.org/Special/committees/structure"; - case "sec": return "http://www.hl7.org/Special/committees/secure"; - case "us": return "http://www.hl7.org/Special/Committees/usrealm"; - case "vocab": return "http://www.hl7.org/Special/committees/Vocab"; - case "aid": return "http://www.hl7.org/Special/committees/java"; - } - return null; - } - - private String nameForWG(String wg) { - switch (wg) { - - case "cbcc": return "Community Based Collaborative Care"; - case "cds": return "Clinical Decision Support"; - case "cqi": return "Clinical Quality Information"; - case "cg": return "Clinical Genomics"; - case "dev": return "Health Care Devices"; - case "ehr": return "Electronic Health Records"; - case "fhir": return "FHIR Infrastructure"; - case "fm": return "Financial Management"; - case "hsi": return "Health Standards Integration"; - case "ii": return "Imaging Integration"; - case "inm": return "Infrastructure And Messaging"; - case "mnm": return "Modeling and Methodology"; - case "its": return "Implementable Technology Specifications"; - case "oo": return "Orders and Observations"; - case "pa": return "Patient Administration"; - case "pc": return "Patient Care"; - case "pe": return "Patient Empowerment"; - case "pher": return "Public Health and Emergency Response"; - case "phx": return "Pharmacy"; - case "brr": return "Biomedical Research and Regulation"; - case "sd": return "Structured Documents"; - case "sec": return "Security"; - case "us": return "US Realm Taskforce"; - case "vocab": return "Terminology Infrastructure"; - case "aid": return "Application Implementation and Design"; - } - return null; - } - private boolean statusCodesConsistent(String status, String standardsStatus) { switch (standardsStatus) { case "draft": return Utilities.existsInList(status, "draft");