diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/CodeSystemRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/CodeSystemRenderer.java index 7abab153f..a0f681e3e 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/CodeSystemRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/CodeSystemRenderer.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Map; import org.hl7.fhir.exceptions.DefinitionException; +import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRFormatError; import org.hl7.fhir.r5.model.CodeSystem; import org.hl7.fhir.r5.model.Enumerations.CodeSystemContentMode; @@ -138,23 +139,29 @@ public class CodeSystemRenderer extends TerminologyRenderer { } } + private String sentenceForContent(CodeSystemContentMode mode) { + switch (mode) { + case COMPLETE: return "This code system defines the following codes:"; + case EXAMPLE: return "This code system provides some example codes:"; + case FRAGMENT: return "This code system provides a fragment that includes following codes:"; + case NOTPRESENT: return "This code system defines codes, but no codes are represented here"; + case SUPPLEMENT: return "This code system defines properties on the following codes:"; + } + throw new FHIRException("Unknown CodeSystemContentMode mode"); + } + private boolean generateCodeSystemContent(XhtmlNode x, CodeSystem cs, boolean hasExtensions, List maps, boolean props) throws FHIRFormatError, DefinitionException, IOException { if (props) { x.para().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Concepts", getContext().getLang())); } XhtmlNode p = x.para(); - p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), "This code system ")); - p.code().tx(cs.getUrl()); - if (cs.getContent() == CodeSystemContentMode.COMPLETE) - p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), " defines the following codes")+":"); - else if (cs.getContent() == CodeSystemContentMode.EXAMPLE) - p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), " defines some example codes")+":"); - else if (cs.getContent() == CodeSystemContentMode.FRAGMENT ) - p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), " defines many codes, of which the following are a subset")+":"); - else if (cs.getContent() == CodeSystemContentMode.NOTPRESENT ) { - p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), " defines many codes, but they are not represented here")); + p.param("cs").code().tx(cs.getUrl()); + p.paramValue("code-count", CodeSystemUtilities.countCodes(cs)); + p.sentenceForParams(sentenceForContent(cs.getContent())); + if (cs.getContent() == CodeSystemContentMode.NOTPRESENT) { return false; } + XhtmlNode t = x.table( "codes"); boolean definitions = false; boolean commentS = false; @@ -198,7 +205,7 @@ public class CodeSystemRenderer extends TerminologyRenderer { if (langs.size() > 0) { Collections.sort(langs); x.para().b().tx("Additional Language Displays"); - t = x.table( "codes"); + t = x.table("codes"); XhtmlNode tr = t.tr(); tr.td().b().tx("Code"); for (String lang : langs) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemUtilities.java index 6443cfb0a..8ef378e34 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemUtilities.java @@ -708,5 +708,17 @@ public class CodeSystemUtilities { } return false; } + + public static int countCodes(CodeSystem cs) { + return countCodes(cs.getConcept()); + } + + private static int countCodes(List concept) { + int t = concept.size(); + for (ConceptDefinitionComponent cd : concept) { + t = t + (cd.hasConcept() ? countCodes(cd.getConcept()) : 0); + } + return t; + } } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java index 9d9b6433b..f4bad9f07 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java @@ -37,6 +37,7 @@ import java.io.IOException; import java.io.Serializable; import java.util.HashMap; import java.util.List; +import java.util.ArrayList; import java.util.Map; import org.hl7.fhir.exceptions.FHIRException; @@ -52,7 +53,6 @@ import ca.uhn.fhir.model.primitive.XhtmlDt; public class XhtmlNode extends XhtmlFluent implements IBaseXhtml { private static final long serialVersionUID = -4362547161441436492L; - public static class Location implements Serializable { private static final long serialVersionUID = -4079302502900219721L; private int line; @@ -87,6 +87,8 @@ public class XhtmlNode extends XhtmlFluent implements IBaseXhtml { private boolean notPretty; private boolean seperated; private Boolean emptyExpanded; + private Map namedParams; + private Map namedParamValues; public XhtmlNode() { super(); @@ -769,5 +771,70 @@ public class XhtmlNode extends XhtmlFluent implements IBaseXhtml { return span("color: "+color, null); } - + public XhtmlNode param(String name) { + XhtmlNode node = new XhtmlNode(NodeType.Element, "p"); // this node is dead will never appear anywhere, but we are in paragraph mode + if (namedParams == null) { + namedParams = new HashMap<>(); + } + namedParams.put(name, node); + return node; + } + + + public void paramValue(String name, String value) { + if (namedParamValues == null) { + namedParamValues = new HashMap<>(); + } + namedParamValues.put(name, value); + } + + public void paramValue(String name, int value) { + if (namedParamValues == null) { + namedParamValues = new HashMap<>(); + } + namedParamValues.put(name, Integer.toString(value)); + } + + public void sentenceForParams(String structure) throws FHIRException, IOException { + XhtmlNode script = new XhtmlParser().parseFragment("
"+structure+"
"); + for (XhtmlNode n : script.getChildNodes()) { + if ("param".equals(n.getName())) { + XhtmlNode node = namedParams.get(n.getAttribute("name")); + if (node != null) { + this.getChildNodes().addAll(node.getChildNodes()); + } + } else if ("if".equals(n.getName())) { + String test = n.getAttribute("test"); + if (passesTest(test)) { + this.getChildNodes().addAll(n.getChildNodes()); + } + } else { + this.getChildNodes().add(n); + } + } + namedParams = null; + namedParamValues = null; + } + + + private boolean passesTest(String test) { + String[] p = test.split("\\s+"); + if (p.length != 3) { + return false; + } + if (!namedParamValues.containsKey(p[0])) { + return false; + } + String pv = namedParamValues.get(p[0]); + switch (p[1]) { + case "=": return p[2].equalsIgnoreCase(pv); + case "!=": return !p[2].equalsIgnoreCase(pv); + case "<": return Utilities.isInteger(p[2]) && Utilities.isInteger(pv) && Integer.parseInt(pv) < Integer.parseInt(p[2]); + case "<=": return Utilities.isInteger(p[2]) && Utilities.isInteger(pv) && Integer.parseInt(pv) <= Integer.parseInt(p[2]); + case ">": return Utilities.isInteger(p[2]) && Utilities.isInteger(pv) && Integer.parseInt(pv) > Integer.parseInt(p[2]); + case ">=": return Utilities.isInteger(p[2]) && Utilities.isInteger(pv) && Integer.parseInt(pv) >= Integer.parseInt(p[2]); + } + return false; + } + } \ No newline at end of file diff --git a/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/tests/XhtmlNodeTest.java b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/tests/XhtmlNodeTest.java index 45d1e4160..659387e22 100644 --- a/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/tests/XhtmlNodeTest.java +++ b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/tests/XhtmlNodeTest.java @@ -7,6 +7,7 @@ import java.io.ObjectOutputStream; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRFormatError; import org.hl7.fhir.utilities.TextFile; +import org.hl7.fhir.utilities.xhtml.NodeType; import org.hl7.fhir.utilities.xhtml.XhtmlComposer; import org.hl7.fhir.utilities.xhtml.XhtmlNode; import org.hl7.fhir.utilities.xhtml.XhtmlParser; @@ -150,5 +151,62 @@ public class XhtmlNodeTest { Assertions.assertEquals(src.trim(), xml.trim()); } + @Test + public void testComposeScripted1() throws IOException { + XhtmlNode x = new XhtmlNode(NodeType.Element, "div"); + x.para().tx("This is a paragraph"); + Assertions.assertEquals("

This is a paragraph

", new XhtmlComposer(true, false).compose(x)); + } + @Test + public void testComposeScripted2() throws IOException { + XhtmlNode x = new XhtmlNode(NodeType.Element, "div"); + XhtmlNode p = x.para(); + p.tx("This is "); + p.tx("a paragraph"); + Assertions.assertEquals("

This is a paragraph

", new XhtmlComposer(true, false).compose(x)); + } + + @Test + public void testComposeScripted3() throws IOException { + XhtmlNode x = new XhtmlNode(NodeType.Element, "div"); + XhtmlNode p = x.para(); + p.tx("This is a "); + p.b().tx("long"); + p.tx(" paragraph"); + Assertions.assertEquals("

This is a long paragraph

", new XhtmlComposer(true, false).compose(x)); + } + + @Test + public void testComposeScripted4() throws IOException { + XhtmlNode x = new XhtmlNode(NodeType.Element, "div"); + XhtmlNode p = x.para(); + p.param("long").b().tx("long"); + p.sentenceForParams("This is a paragraph"); + Assertions.assertEquals("

This is a long paragraph

", new XhtmlComposer(true, false).compose(x)); + } + + + @Test + public void testComposeScripted5() throws IOException { + XhtmlNode x = new XhtmlNode(NodeType.Element, "div"); + XhtmlNode p = x.para(); + p.param("long").b().tx("long"); + p.paramValue("count", "2"); + p.sentenceForParams("This is a paragraphs"); + Assertions.assertEquals("

This is a long paragraphs

", new XhtmlComposer(true, false).compose(x)); + } + + + @Test + public void testComposeScripted6() throws IOException { + XhtmlNode x = new XhtmlNode(NodeType.Element, "div"); + XhtmlNode p = x.para(); + p.param("long").b().tx("long"); + p.paramValue("count", "1"); + p.sentenceForParams("This is a paragraphs"); + Assertions.assertEquals("

This is a long paragraph

", new XhtmlComposer(true, false).compose(x)); + } + + } \ No newline at end of file