Improved rendering of codes in include when rendering valuesets

This commit is contained in:
Grahame Grieve 2023-09-20 11:12:50 +10:00
parent e0af2b7916
commit eecc6633d3
3 changed files with 35 additions and 73 deletions

View File

@ -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<String> langs, boolean doDesignations, List<UsedConceptMap> maps, Map<String, String> designations, int index, Resource vsRes) throws FHIRException, IOException {
private boolean genInclude(XhtmlNode ul, ConceptSetComponent inc, String type, List<String> langs, boolean doDesignations, List<UsedConceptMap> maps, Map<String, String> 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<String, ConceptDefinitionComponent> getConceptsForCodes(CodeSystem e, ConceptSetComponent inc) {
private Map<String, ConceptDefinitionComponent> 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;
}
}

View File

@ -138,6 +138,15 @@ public class CommaSeparatedStringBuilder {
return self.toString();
}
public static String buildObjects(List<? extends Object> list) {
CommaSeparatedStringBuilder self = new CommaSeparatedStringBuilder();
for (Object s : list) {
self.append(s.toString());
}
return self.toString();
}
public static Set<String> toSet(String source) {
if (source == null) {
return null;

View File

@ -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");