fix NPE in validator & rendering fixes: concept map display + name rendering issue for Med Resources + fix locale date issue

This commit is contained in:
Grahame Grieve 2022-01-10 20:29:06 +11:00
parent 8706b3c4a4
commit 0bb4628f6b
5 changed files with 52 additions and 272 deletions

View File

@ -132,11 +132,25 @@ public class ConceptMapRenderer extends TerminologyRenderer {
tr.td().b().tx("Destination Code");
if (comment)
tr.td().b().tx("Comment");
tr = tbl.tr();
XhtmlNode td = tr.td().colspan(comment ? "4" : "3");
td.tx("Mapping from ");
if (grp.hasSource()) {
renderCanonical(cm, td, grp.getSource());
} else {
td.code("unspecified code system");
}
td.tx(" to ");
if (grp.hasTarget()) {
renderCanonical(cm, td, grp.getTarget());
} else {
td.code("unspecified code system");
}
for (SourceElementComponent ccl : grp.getElement()) {
tr = tbl.tr();
XhtmlNode td = tr.td();
td = tr.td();
td.addText(ccl.getCode());
display = getDisplayForConcept(systemFromCanonical(grp.getSource()), versionFromCanonical(grp.getSource()), ccl.getCode());
display = ccl.hasDisplay() ? ccl.getDisplay() : getDisplayForConcept(systemFromCanonical(grp.getSource()), versionFromCanonical(grp.getSource()), ccl.getCode());
if (display != null && !isSameCodeAndDisplay(ccl.getCode(), display))
td.tx(" ("+display+")");
TargetElementComponent ccm = ccl.getTarget().get(0);
@ -152,7 +166,7 @@ public class ConceptMapRenderer extends TerminologyRenderer {
}
td = tr.td();
td.addText(ccm.getCode());
display = getDisplayForConcept(systemFromCanonical(grp.getTarget()), versionFromCanonical(grp.getTarget()), ccm.getCode());
display = ccm.hasDisplay() ? ccm.getDisplay() : getDisplayForConcept(systemFromCanonical(grp.getTarget()), versionFromCanonical(grp.getTarget()), ccm.getCode());
if (display != null && !isSameCodeAndDisplay(ccm.getCode(), display))
td.tx(" ("+display+")");
if (comment)

View File

@ -158,9 +158,8 @@ public abstract class ResourceRenderer extends DataRenderer {
if (target.hasUserData("path")) {
x.ah(target.getUserString("path")).tx(cr.present());
} else {
url = url.substring(0, url.indexOf("|"));
x.code().tx(url);
x.tx(": "+cr.present());
x.tx(" ("+cr.present()+")");
}
}
}

View File

@ -173,7 +173,8 @@ public class ElementWrappers {
s = s + " " + family.getValues().get(0).primitiveValue().toUpperCase();
return s;
} else {
throw new Error("Now what? ("+b.fhirType()+")");
// well, we couldn't get a name from that
return null;
}
}
return null;

View File

@ -31,10 +31,13 @@ package org.hl7.fhir.r5.utils;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.hl7.fhir.r5.model.Bundle;
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r5.model.Bundle.BundleLinkComponent;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.ContactPoint;
@ -61,6 +64,7 @@ import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
public class ResourceUtilities {
public final static String FHIR_LANGUAGE = "urn:ietf:bcp:47";
private static JurisdictionLocales jl = new JurisdictionLocales();
public static boolean isAnError(OperationOutcome error) {
for (OperationOutcomeIssueComponent t : error.getIssue())
@ -120,275 +124,37 @@ public class ResourceUtilities {
resource.setMeta(new Meta());
return resource.getMeta();
}
// public static String representDataElementCollection(IWorkerContext context, Bundle bundle, boolean profileLink, String linkBase) {
// StringBuilder b = new StringBuilder();
// DataElement common = showDECHeader(b, bundle);
// b.append("<table class=\"grid\">\r\n");
// List<String> cols = chooseColumns(bundle, common, b, profileLink);
// for (BundleEntryComponent e : bundle.getEntry()) {
// DataElement de = (DataElement) e.getResource();
// renderDE(de, cols, b, profileLink, linkBase);
// }
// b.append("</table>\r\n");
// return b.toString();
// }
//
//
// private static void renderDE(DataElement de, List<String> cols, StringBuilder b, boolean profileLink, String linkBase) {
// b.append("<tr>");
// for (String col : cols) {
// String v;
// ElementDefinition dee = de.getElement().get(0);
// if (col.equals("DataElement.name")) {
// v = de.hasName() ? Utilities.escapeXml(de.getName()) : "";
// } else if (col.equals("DataElement.status")) {
// v = de.hasStatusElement() ? de.getStatusElement().asStringValue() : "";
// } else if (col.equals("DataElement.code")) {
// v = renderCoding(dee.getCode());
// } else if (col.equals("DataElement.type")) {
// v = dee.hasType() ? Utilities.escapeXml(dee.getType().get(0).getCode()) : "";
// } else if (col.equals("DataElement.units")) {
// v = renderDEUnits(ToolingExtensions.getAllowedUnits(dee));
// } else if (col.equals("DataElement.binding")) {
// v = renderBinding(dee.getBinding());
// } else if (col.equals("DataElement.minValue")) {
// v = ToolingExtensions.hasExtension(de, "http://hl7.org/fhir/StructureDefinition/minValue") ? Utilities.escapeXml(ToolingExtensions.readPrimitiveExtension(de, "http://hl7.org/fhir/StructureDefinition/minValue").asStringValue()) : "";
// } else if (col.equals("DataElement.maxValue")) {
// v = ToolingExtensions.hasExtension(de, "http://hl7.org/fhir/StructureDefinition/maxValue") ? Utilities.escapeXml(ToolingExtensions.readPrimitiveExtension(de, "http://hl7.org/fhir/StructureDefinition/maxValue").asStringValue()) : "";
// } else if (col.equals("DataElement.maxLength")) {
// v = ToolingExtensions.hasExtension(de, "http://hl7.org/fhir/StructureDefinition/maxLength") ? Utilities.escapeXml(ToolingExtensions.readPrimitiveExtension(de, "http://hl7.org/fhir/StructureDefinition/maxLength").asStringValue()) : "";
// } else if (col.equals("DataElement.mask")) {
// v = ToolingExtensions.hasExtension(de, "http://hl7.org/fhir/StructureDefinition/mask") ? Utilities.escapeXml(ToolingExtensions.readPrimitiveExtension(de, "http://hl7.org/fhir/StructureDefinition/mask").asStringValue()) : "";
// } else
// throw new Error("Unknown column name: "+col);
//
// b.append("<td>"+v+"</td>");
// }
// if (profileLink) {
// b.append("<td><a href=\""+linkBase+"-"+de.getId()+".html\">Profile</a>, <a href=\"http://www.opencem.org/#/20140917/Intermountain/"+de.getId()+"\">CEM</a>");
// if (ToolingExtensions.hasExtension(de, ToolingExtensions.EXT_CIMI_REFERENCE))
// b.append(", <a href=\""+ToolingExtensions.readStringExtension(de, ToolingExtensions.EXT_CIMI_REFERENCE)+"\">CIMI</a>");
// b.append("</td>");
// }
// b.append("</tr>\r\n");
// }
private static String renderBinding(ElementDefinitionBindingComponent binding) {
// TODO Auto-generated method stub
public static Locale getLocale(CanonicalResource cr) {
return getLocale(cr.getLanguage(), cr.getJurisdiction());
}
public static Locale getLocale(String lang, List<CodeableConcept> jurisdictions) {
if (lang != null && lang.contains("-")) {
return new Locale(lang);
}
for (CodeableConcept cc : jurisdictions) {
Locale locale = getLocale(lang, cc);
if (locale != null) {
return locale;
}
}
return null;
}
private static String renderDEUnits(DataType units) {
if (units == null || units.isEmpty())
return "";
if (units instanceof CodeableConcept)
return renderCodeable((CodeableConcept) units);
else
return "<a href=\""+Utilities.escapeXml(((Reference) units).getReference())+"\">"+Utilities.escapeXml(((Reference) units).getReference())+"</a>";
}
private static String renderCodeable(CodeableConcept units) {
if (units == null || units.isEmpty())
return "";
String v = renderCoding(units.getCoding());
if (units.hasText())
v = v + " " +Utilities.escapeXml(units.getText());
return v;
}
private static String renderCoding(List<Coding> codes) {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
for (Coding c : codes)
b.append(renderCoding(c));
return b.toString();
}
private static String renderCoding(Coding code) {
if (code == null || code.isEmpty())
return "";
else
return "<span title=\""+Utilities.escapeXml(code.getSystem())+"\">"+Utilities.escapeXml(code.getCode())+"</span>";
}
// private static List<String> chooseColumns(Bundle bundle, DataElement common, StringBuilder b, boolean profileLink) {
// b.append("<tr>");
// List<String> results = new ArrayList<String>();
// results.add("DataElement.name");
// b.append("<td width=\"250\"><b>Name</b></td>");
// if (!common.hasStatus()) {
// results.add("DataElement.status");
// b.append("<td><b>Status</b></td>");
// }
// if (hasCode(bundle)) {
// results.add("DataElement.code");
// b.append("<td><b>Code</b></td>");
// }
// if (!common.getElement().get(0).hasType() && hasType(bundle)) {
// results.add("DataElement.type");
// b.append("<td><b>Type</b></td>");
// }
// if (hasUnits(bundle)) {
// results.add("DataElement.units");
// b.append("<td><b>Units</b></td>");
// }
// if (hasBinding(bundle)) {
// results.add("DataElement.binding");
// b.append("<td><b>Binding</b></td>");
// }
// if (hasExtension(bundle, "http://hl7.org/fhir/StructureDefinition/minValue")) {
// results.add("DataElement.minValue");
// b.append("<td><b>Min Value</b></td>");
// }
// if (hasExtension(bundle, "http://hl7.org/fhir/StructureDefinition/maxValue")) {
// results.add("DataElement.maxValue");
// b.append("<td><b>Max Value</b></td>");
// }
// if (hasExtension(bundle, "http://hl7.org/fhir/StructureDefinition/maxLength")) {
// results.add("DataElement.maxLength");
// b.append("<td><b>Max Length</b></td>");
// }
// if (hasExtension(bundle, "http://hl7.org/fhir/StructureDefinition/mask")) {
// results.add("DataElement.mask");
// b.append("<td><b>Mask</b></td>");
// }
// if (profileLink)
// b.append("<td><b>Links</b></td>");
// b.append("</tr>\r\n");
// return results;
// }
//
// private static boolean hasExtension(Bundle bundle, String url) {
// for (BundleEntryComponent e : bundle.getEntry()) {
// DataElement de = (DataElement) e.getResource();
// if (ToolingExtensions.hasExtension(de, url))
// return true;
// }
// return false;
// }
//
// private static boolean hasBinding(Bundle bundle) {
// for (BundleEntryComponent e : bundle.getEntry()) {
// DataElement de = (DataElement) e.getResource();
// if (de.getElement().get(0).hasBinding())
// return true;
// }
// return false;
// }
//
// private static boolean hasCode(Bundle bundle) {
// for (BundleEntryComponent e : bundle.getEntry()) {
// DataElement de = (DataElement) e.getResource();
// if (de.getElement().get(0).hasCode())
// return true;
// }
// return false;
// }
//
// private static boolean hasType(Bundle bundle) {
// for (BundleEntryComponent e : bundle.getEntry()) {
// DataElement de = (DataElement) e.getResource();
// if (de.getElement().get(0).hasType())
// return true;
// }
// return false;
// }
//
// private static boolean hasUnits(Bundle bundle) {
// for (BundleEntryComponent e : bundle.getEntry()) {
// DataElement de = (DataElement) e.getResource();
// if (ToolingExtensions.getAllowedUnits(de.getElement().get(0)) != null)
// return true;
// }
// return false;
// }
//
// private static DataElement showDECHeader(StringBuilder b, Bundle bundle) {
// DataElement meta = new DataElement();
// DataElement prototype = (DataElement) bundle.getEntry().get(0).getResource();
// meta.setPublisher(prototype.getPublisher());
// meta.getContact().addAll(prototype.getContact());
// meta.setStatus(prototype.getStatus());
// meta.setDate(prototype.getDate());
// meta.addElement().getType().addAll(prototype.getElement().get(0).getType());
//
// for (BundleEntryComponent e : bundle.getEntry()) {
// DataElement de = (DataElement) e.getResource();
// if (!Base.compareDeep(de.getPublisherElement(), meta.getPublisherElement(), false))
// meta.setPublisherElement(null);
// if (!Base.compareDeep(de.getContact(), meta.getContact(), false))
// meta.getContact().clear();
// if (!Base.compareDeep(de.getStatusElement(), meta.getStatusElement(), false))
// meta.setStatusElement(null);
// if (!Base.compareDeep(de.getDateElement(), meta.getDateElement(), false))
// meta.setDateElement(null);
// if (!Base.compareDeep(de.getElement().get(0).getType(), meta.getElement().get(0).getType(), false))
// meta.getElement().get(0).getType().clear();
// }
// if (meta.hasPublisher() || meta.hasContact() || meta.hasStatus() || meta.hasDate() /* || meta.hasType() */) {
// b.append("<table class=\"grid\">\r\n");
// if (meta.hasPublisher())
// b.append("<tr><td>Publisher:</td><td>"+meta.getPublisher()+"</td></tr>\r\n");
// if (meta.hasContact()) {
// b.append("<tr><td>Contacts:</td><td>");
// boolean firsti = true;
// for (ContactDetail c : meta.getContact()) {
// if (firsti)
// firsti = false;
// else
// b.append("<br/>");
// if (c.hasName())
// b.append(Utilities.escapeXml(c.getName())+": ");
// boolean first = true;
// for (ContactPoint cp : c.getTelecom()) {
// if (first)
// first = false;
// else
// b.append(", ");
// renderContactPoint(b, cp);
// }
// }
// b.append("</td></tr>\r\n");
// }
// if (meta.hasStatus())
// b.append("<tr><td>Status:</td><td>"+meta.getStatus().toString()+"</td></tr>\r\n");
// if (meta.hasDate())
// b.append("<tr><td>Date:</td><td>"+meta.getDateElement().asStringValue()+"</td></tr>\r\n");
// if (meta.getElement().get(0).hasType())
// b.append("<tr><td>Type:</td><td>"+renderType(meta.getElement().get(0).getType())+"</td></tr>\r\n");
// b.append("</table>\r\n");
// }
// return meta;
// }
private static String renderType(List<TypeRefComponent> type) {
if (type == null || type.isEmpty())
return "";
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
for (TypeRefComponent c : type)
b.append(renderType(c));
return b.toString();
}
private static String renderType(TypeRefComponent type) {
if (type == null || type.isEmpty())
return "";
return type.getWorkingCode();
}
public static void renderContactPoint(StringBuilder b, ContactPoint cp) {
if (cp != null && !cp.isEmpty()) {
if (cp.getSystem() == ContactPointSystem.EMAIL)
b.append("<a href=\"mailto:"+cp.getValue()+"\">"+cp.getValue()+"</a>");
else if (cp.getSystem() == ContactPointSystem.FAX)
b.append("Fax: "+cp.getValue());
else if (cp.getSystem() == ContactPointSystem.OTHER)
b.append("<a href=\""+cp.getValue()+"\">"+cp.getValue()+"</a>");
else
b.append(cp.getValue());
private static Locale getLocale(String lang, CodeableConcept cc) {
if (cc.hasCoding("http://unstats.un.org/unsd/methods/m49/m49.htm", "001")) {
return new Locale("en-US");
}
}
String c = cc.getCode("urn:iso:std:iso:3166:-2");
String l = jl.get(c);
if (l == null) {
return null;
} else if (lang != null) {
return new Locale(lang+"-"+l.substring(l.indexOf("-")+1));
} else {
return new Locale(l);
}
}
}

View File

@ -4656,7 +4656,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
timeTracker.sd(t);
trackUsage(profile, hostContext, element);
if (rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(),
profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE_TYPE, special.toHuman(), resourceName)) {
profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE_TYPE, special == null ? "??" : special.toHuman(), resourceName)) {
validateResource(hc, errors, resource, element, profile, idstatus, stack);
}
} else {