mirror of
https://github.com/hapifhir/org.hl7.fhir.core.git
synced 2025-03-07 03:49:15 +00:00
improvements to code system rendering + fix date/time rendering tests
This commit is contained in:
parent
162cf6f049
commit
6a735d4319
@ -498,6 +498,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
||||
|
||||
@Override
|
||||
public CodeSystem fetchCodeSystem(String system) {
|
||||
if (system.contains("|")) {
|
||||
String s = system.substring(0, system.indexOf("|"));
|
||||
String v = system.substring(system.indexOf("|")+1);
|
||||
return fetchCodeSystem(s, v);
|
||||
}
|
||||
CodeSystem cs;
|
||||
synchronized (lock) {
|
||||
cs = codeSystems.get(system);
|
||||
@ -511,6 +516,23 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
||||
return cs;
|
||||
}
|
||||
|
||||
public CodeSystem fetchCodeSystem(String system, String version) {
|
||||
if (version == null) {
|
||||
return fetchCodeSystem(system);
|
||||
}
|
||||
CodeSystem cs;
|
||||
synchronized (lock) {
|
||||
cs = codeSystems.get(system, version);
|
||||
}
|
||||
if (cs == null && locator != null) {
|
||||
locator.findResource(this, system);
|
||||
synchronized (lock) {
|
||||
cs = codeSystems.get(system);
|
||||
}
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSystem(String system) throws TerminologyServiceException {
|
||||
synchronized (lock) {
|
||||
|
@ -476,6 +476,7 @@ public interface IWorkerContext {
|
||||
* @return
|
||||
*/
|
||||
public CodeSystem fetchCodeSystem(String system);
|
||||
public CodeSystem fetchCodeSystem(String system, String version);
|
||||
|
||||
/**
|
||||
* True if the underlying terminology service provider will do
|
||||
|
@ -94,8 +94,10 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
||||
private void generateProperties(XhtmlNode x, CodeSystem cs) {
|
||||
if (cs.hasProperty()) {
|
||||
boolean hasRendered = false;
|
||||
boolean hasURI = false;
|
||||
for (PropertyComponent p : cs.getProperty()) {
|
||||
hasRendered = hasRendered || !p.getCode().equals(ToolingExtensions.getPresentation(p, p.getCodeElement()));
|
||||
hasURI = hasURI || p.hasUri();
|
||||
}
|
||||
|
||||
x.para().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Properties", getContext().getLang()));
|
||||
@ -105,18 +107,22 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Name", getContext().getLang()));
|
||||
}
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Code", getContext().getLang()));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "URL", getContext().getLang()));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Description", getContext().getLang()));
|
||||
if (hasURI) {
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "URL", getContext().getLang()));
|
||||
}
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Type", getContext().getLang()));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Description", getContext().getLang()));
|
||||
for (PropertyComponent p : cs.getProperty()) {
|
||||
tr = tbl.tr();
|
||||
if (hasRendered) {
|
||||
tr.td().tx(ToolingExtensions.getPresentation(p, p.getCodeElement()));
|
||||
}
|
||||
tr.td().tx(p.getCode());
|
||||
tr.td().tx(p.getUri());
|
||||
tr.td().tx(p.getDescription());
|
||||
if (hasURI) {
|
||||
tr.td().tx(p.getUri());
|
||||
}
|
||||
tr.td().tx(p.hasType() ? p.getType().toCode() : "");
|
||||
tr.td().tx(p.getDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -141,6 +147,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
||||
boolean hierarchy = false;
|
||||
boolean version = false;
|
||||
boolean ignoreStatus = false;
|
||||
boolean isSupplement = cs.getContent() == CodeSystemContentMode.SUPPLEMENT;
|
||||
List<PropertyComponent> properties = new ArrayList<>();
|
||||
for (PropertyComponent cp : cs.getProperty()) {
|
||||
if (showPropertyInTable(cp)) {
|
||||
@ -170,7 +177,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
||||
List<String> langs = new ArrayList<>();
|
||||
addMapHeaders(addTableHeaderRowStandard(t, hierarchy, display, definitions, commentS, version, deprecated, properties, null, false), maps);
|
||||
for (ConceptDefinitionComponent c : csNav.getConcepts(null)) {
|
||||
hasExtensions = addDefineRowToTable(t, c, 0, hierarchy, display, definitions, commentS, version, deprecated, maps, cs.getUrl(), cs, properties, csNav, langs) || hasExtensions;
|
||||
hasExtensions = addDefineRowToTable(t, c, 0, hierarchy, display, definitions, commentS, version, deprecated, maps, cs.getUrl(), cs, properties, csNav, langs, isSupplement) || hasExtensions;
|
||||
}
|
||||
if (langs.size() > 0) {
|
||||
Collections.sort(langs);
|
||||
@ -223,10 +230,10 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
||||
return true;
|
||||
}
|
||||
String uri = cp.getUri();
|
||||
String code = null;
|
||||
if (Utilities.noString(uri)){
|
||||
return false;
|
||||
return true; // do we always want to render properties in this case? Not sure...
|
||||
}
|
||||
String code = null;
|
||||
if (uri.contains("#")) {
|
||||
code = uri.substring(uri.indexOf("#")+1);
|
||||
uri = uri.substring(0, uri.indexOf("#"));
|
||||
@ -290,7 +297,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
||||
|
||||
|
||||
|
||||
private boolean addDefineRowToTable(XhtmlNode t, ConceptDefinitionComponent c, int level, boolean hasHierarchy, boolean hasDisplay, boolean hasDefinitions, boolean comment, boolean version, boolean deprecated, List<UsedConceptMap> maps, String system, CodeSystem cs, List<PropertyComponent> properties, CodeSystemNavigator csNav, List<String> langs) throws FHIRFormatError, DefinitionException, IOException {
|
||||
private boolean addDefineRowToTable(XhtmlNode t, ConceptDefinitionComponent c, int level, boolean hasHierarchy, boolean hasDisplay, boolean hasDefinitions, boolean comment, boolean version, boolean deprecated, List<UsedConceptMap> maps, String system, CodeSystem cs, List<PropertyComponent> properties, CodeSystemNavigator csNav, List<String> langs, boolean isSupplement) throws FHIRFormatError, DefinitionException, IOException {
|
||||
boolean hasExtensions = false;
|
||||
XhtmlNode tr = t.tr();
|
||||
XhtmlNode td = tr.td();
|
||||
@ -300,7 +307,12 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
||||
String s = Utilities.padLeft("", '\u00A0', level*2);
|
||||
td.addText(s);
|
||||
}
|
||||
td.attribute("style", "white-space:nowrap").addText(c.getCode());
|
||||
String link = isSupplement ? getLinkForCode(cs.getSupplements(), null, c.getCode()) : null;
|
||||
if (link != null) {
|
||||
td.ah(link).attribute("style", "white-space:nowrap").addText(c.getCode());
|
||||
} else {
|
||||
td.attribute("style", "white-space:nowrap").addText(c.getCode());
|
||||
}
|
||||
XhtmlNode a;
|
||||
if (c.hasCodeElement()) {
|
||||
td.an(cs.getId()+"-" + Utilities.nmtokenize(c.getCode()));
|
||||
@ -450,7 +462,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
||||
}
|
||||
List<ConceptDefinitionComponent> ocl = csNav.getOtherChildren(c);
|
||||
for (ConceptDefinitionComponent cc : csNav.getConcepts(c)) {
|
||||
hasExtensions = addDefineRowToTable(t, cc, level+1, hasHierarchy, hasDisplay, hasDefinitions, comment, version, deprecated, maps, system, cs, properties, csNav, langs) || hasExtensions;
|
||||
hasExtensions = addDefineRowToTable(t, cc, level+1, hasHierarchy, hasDisplay, hasDefinitions, comment, version, deprecated, maps, system, cs, properties, csNav, langs, isSupplement) || hasExtensions;
|
||||
}
|
||||
for (ConceptDefinitionComponent cc : ocl) {
|
||||
tr = t.tr();
|
||||
|
@ -711,6 +711,38 @@ public class DataRenderer extends Renderer {
|
||||
}
|
||||
}
|
||||
|
||||
protected String getLinkForCode(String system, String version, String code) {
|
||||
if ("http://snomed.info/sct".equals(system)) {
|
||||
if (!Utilities.noString(code)) {
|
||||
return "http://snomed.info/id/"+code;
|
||||
} else {
|
||||
return "https://browser.ihtsdotools.org/";
|
||||
}
|
||||
} else if ("http://loinc.org".equals(system)) {
|
||||
if (!Utilities.noString(code)) {
|
||||
return "https://loinc.org/"+code;
|
||||
} else {
|
||||
return "https://loinc.org/";
|
||||
}
|
||||
} else if ("http://www.nlm.nih.gov/research/umls/rxnorm".equals(system)) {
|
||||
if (!Utilities.noString(code)) {
|
||||
return "https://mor.nlm.nih.gov/RxNav/search?searchBy=RXCUI&searchTerm="+code;
|
||||
} else {
|
||||
return "https://www.nlm.nih.gov/research/umls/rxnorm/index.html";
|
||||
}
|
||||
} else {
|
||||
CodeSystem cs = context.getWorker().fetchCodeSystem(system, version);
|
||||
if (cs != null && cs.hasUserData("path")) {
|
||||
if (!Utilities.noString(code)) {
|
||||
return cs.getUserString("path")+"#"+Utilities.nmtokenize(code);
|
||||
} else {
|
||||
return cs.getUserString("path");
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void renderCodingWithDetails(XhtmlNode x, Coding c) {
|
||||
String s = "";
|
||||
if (c.hasDisplayElement())
|
||||
@ -720,22 +752,13 @@ public class DataRenderer extends Renderer {
|
||||
|
||||
|
||||
String sn = describeSystem(c.getSystem());
|
||||
if ("http://snomed.info/sct".equals(c.getSystem())) {
|
||||
if (c.hasCode()) {
|
||||
x.ah("http://snomed.info/id/"+c.getCode()).tx(sn);
|
||||
} else {
|
||||
x.ah("https://browser.ihtsdotools.org/").tx(sn);
|
||||
}
|
||||
} else if ("http://loinc.org".equals(c.getSystem())) {
|
||||
x.ah("https://loinc.org/").tx(sn);
|
||||
String link = getLinkForCode(c.getSystem(), c.getVersion(), c.getCode());
|
||||
if (link != null) {
|
||||
x.ah(link).tx(sn);
|
||||
} else {
|
||||
CodeSystem cs = context.getWorker().fetchCodeSystem(c.getSystem());
|
||||
if (cs != null && cs.hasUserData("path")) {
|
||||
x.ah(cs.getUserString("path")).tx(sn);
|
||||
} else {
|
||||
x.tx(sn);
|
||||
}
|
||||
x.tx(sn);
|
||||
}
|
||||
|
||||
x.tx(" ");
|
||||
x.tx(c.getCode());
|
||||
if (!Utilities.noString(s)) {
|
||||
|
@ -55,15 +55,17 @@ public class NarrativeGeneratorTests {
|
||||
}
|
||||
|
||||
|
||||
private void checkDateTimeRendering(String src, String lang, String country, ZoneId tz, FormatStyle fmt, ResourceRendererMode mode, String expected) throws FHIRFormatError, DefinitionException, IOException {
|
||||
private void checkDateTimeRendering(String src, String lang, String country, ZoneId tz, String fmt, ResourceRendererMode mode, String expected) throws FHIRFormatError, DefinitionException, IOException {
|
||||
rc.setLocale(new java.util.Locale(lang, country));
|
||||
rc.setTimeZoneId(tz);
|
||||
if (fmt == null) {
|
||||
rc.setDateTimeFormat(null);
|
||||
rc.setDateFormat(null);
|
||||
} else {
|
||||
rc.setDateTimeFormat(DateTimeFormatter.ofLocalizedDateTime(fmt).withLocale(rc.getLocale()));
|
||||
rc.setDateFormat(DateTimeFormatter.ofLocalizedDate(fmt).withLocale(rc.getLocale()));
|
||||
// really, it would be better to test patterns based on FormatStyle here, since
|
||||
// that's what will be used in the real world, but
|
||||
rc.setDateTimeFormat(DateTimeFormatter.ofPattern(fmt));
|
||||
rc.setDateFormat(DateTimeFormatter.ofPattern(fmt));
|
||||
}
|
||||
rc.setMode(mode);
|
||||
|
||||
@ -76,42 +78,33 @@ public class NarrativeGeneratorTests {
|
||||
Assert.assertEquals("<p>"+expected+"</p>", actual);
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void testDateTimeLocaleConsistency() throws FHIRFormatError, DefinitionException, IOException {
|
||||
// Locale locale = new java.util.Locale("en", "AU");
|
||||
// DateTimeFormatter fmt = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withLocale(locale);
|
||||
// ZonedDateTime zdt = ZonedDateTime.parse("2021-11-19T14:13:12Z");
|
||||
// Assert.assertEquals("19 Nov. 2021, 2:13:12 pm", fmt.format(zdt));
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @Test
|
||||
// public void testDateTimeRendering1() throws FHIRFormatError, DefinitionException, IOException {
|
||||
// checkDateTimeRendering("2021-11-19T14:13:12Z", "en", "AU", ZoneId.of("UTC"), null, ResourceRendererMode.TECHNICAL, "2021-11-19T14:13:12Z");
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @Test
|
||||
// public void testDateTimeRendering2() throws FHIRFormatError, DefinitionException, IOException {
|
||||
// checkDateTimeRendering("2021-11-19T14:13:12Z", "en", "AU", ZoneId.of("Australia/Sydney"), null, ResourceRendererMode.TECHNICAL, "2021-11-20T01:13:12+11:00");
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testDateTimeRendering3() throws FHIRFormatError, DefinitionException, IOException {
|
||||
// checkDateTimeRendering("2021-11-19T14:13:12Z", "en", "AU", ZoneId.of("UTC"), FormatStyle.SHORT, ResourceRendererMode.TECHNICAL, "19/11/21, 2:13 pm");
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @Test
|
||||
// public void testDateTimeRendering4() throws FHIRFormatError, DefinitionException, IOException {
|
||||
// checkDateTimeRendering("2021-11-19T14:13:12Z", "en", "AU", ZoneId.of("UTC"), null, ResourceRendererMode.END_USER, "19/11/21, 2:13 pm");
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @Test
|
||||
// public void testDateTimeRendering5() throws FHIRFormatError, DefinitionException, IOException {
|
||||
// checkDateTimeRendering("2021-11-19", "en", "AU", ZoneId.of("UTC"), null, ResourceRendererMode.END_USER, "19/11/21");
|
||||
// }
|
||||
//
|
||||
@Test
|
||||
public void testDateTimeRendering1() throws FHIRFormatError, DefinitionException, IOException {
|
||||
checkDateTimeRendering("2021-11-19T14:13:12Z", "en", "AU", ZoneId.of("UTC"), null, ResourceRendererMode.TECHNICAL, "2021-11-19T14:13:12Z");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDateTimeRendering2() throws FHIRFormatError, DefinitionException, IOException {
|
||||
checkDateTimeRendering("2021-11-19T14:13:12Z", "en", "AU", ZoneId.of("Australia/Sydney"), null, ResourceRendererMode.TECHNICAL, "2021-11-20T01:13:12+11:00");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDateTimeRendering3() throws FHIRFormatError, DefinitionException, IOException {
|
||||
checkDateTimeRendering("2021-11-19T14:13:12Z", "en", "AU", ZoneId.of("UTC"), "yyyy/MM/dd hh:mm:ss", ResourceRendererMode.TECHNICAL, "2021/11/19 02:13:12");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDateTimeRendering4() throws FHIRFormatError, DefinitionException, IOException {
|
||||
checkDateTimeRendering("2021-11-19T14:13:12Z", "en", "AU", ZoneId.of("UTC"), null, ResourceRendererMode.END_USER, "19/11/21, 2:13 pm");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDateTimeRendering5() throws FHIRFormatError, DefinitionException, IOException {
|
||||
checkDateTimeRendering("2021-11-19", "en", "AU", ZoneId.of("UTC"), null, ResourceRendererMode.END_USER, "19/11/21");
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user