Search in sources :

Example 6 with XhtmlGenerator

use of org.hl7.fhir.utilities.xml.XhtmlGenerator in project kindling by HL7.

the class Publisher method processExample.

private void processExample(Example e, ResourceDefn resn, StructureDefinition profile, Profile pack, ImplementationGuideDefn ig) throws Exception {
    if (e.getType() == ExampleType.Tool)
        return;
    long time = System.currentTimeMillis();
    int level = (ig == null || ig.isCore()) ? 0 : 1;
    String prefix = (ig == null || ig.isCore()) ? "" : ig.getCode() + File.separator;
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document xdoc;
    String narrative = null;
    String n = e.getTitle();
    if (examplesProcessed.contains(prefix + n))
        return;
    examplesProcessed.add(prefix + n);
    // strip the xsi: stuff. seems to need double processing in order to
    // delete namespace crap
    xdoc = e.getXml();
    XmlGenerator xmlgen = new XmlGenerator();
    CSFile file = new CSFile(page.getFolders().dstDir + prefix + n + ".xml");
    xmlgen.generate(xdoc.getDocumentElement(), file, "http://hl7.org/fhir", xdoc.getDocumentElement().getLocalName());
    // check the narrative. We generate auto-narrative. If the resource didn't
    // have it's own original narrative, then we save it anyway
    // n
    String rt = null;
    try {
        RenderingContext lrc = page.getRc().copy().setLocalPrefix("").setTooCostlyNoteEmpty(PageProcessor.TOO_MANY_CODES_TEXT_EMPTY).setTooCostlyNoteNotEmpty(PageProcessor.TOO_MANY_CODES_TEXT_NOT_EMPTY);
        xdoc = loadDom(new FileInputStream(file), true);
        rt = xdoc.getDocumentElement().getNodeName();
        String id = XMLUtil.getNamedChildValue(xdoc.getDocumentElement(), "id");
        if (!page.getDefinitions().getBaseResources().containsKey(rt) && !id.equals(e.getId()))
            throw new Error("Resource in " + prefix + n + ".xml needs an id of value=\"" + e.getId() + "\"");
        page.getDefinitions().addNs("http://hl7.org/fhir/" + rt + "/" + id, "Example", prefix + n + ".html");
        if (rt.equals("ValueSet") || rt.equals("CodeSystem") || rt.equals("ConceptMap") || rt.equals("CapabilityStatement") || rt.equals("Library")) {
            // for these, we use the reference implementation directly
            CanonicalResource res = (CanonicalResource) loadExample(file);
            if (res.getUrl() != null && res.getUrl().startsWith("http://hl7.org/fhir"))
                res.setVersion(page.getVersion().toCode());
            boolean wantSave = false;
            if (res instanceof CapabilityStatement) {
                ((CapabilityStatement) res).setFhirVersion(page.getVersion());
                if (res.hasText() && res.getText().hasDiv())
                    wantSave = updateVersion(((CapabilityStatement) res).getText().getDiv());
            }
            if (!res.hasText() || !res.getText().hasDiv()) {
                RendererFactory.factory(res, lrc).render(res);
                wantSave = true;
            }
            if (wantSave) {
                if (page.getVersion().isR4B()) {
                    org.hl7.fhir.r4.model.Resource r4 = new org.hl7.fhir.r4.formats.XmlParser().parse(new FileInputStream(file));
                    new org.hl7.fhir.r4.formats.XmlParser().setOutputStyle(org.hl7.fhir.r4.formats.IParser.OutputStyle.PRETTY).compose(new FileOutputStream(file), r4);
                } else {
                    new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(file), res);
                }
            }
            narrative = new XhtmlComposer(XhtmlComposer.HTML).compose(res.getText().getDiv());
        } else {
            if (rt.equals("Bundle")) {
                List<Element> entries = new ArrayList<Element>();
                XMLUtil.getNamedChildren(xdoc.getDocumentElement(), "entry", entries);
                boolean wantSave = false;
                for (Element entry : entries) {
                    Element ers = XMLUtil.getFirstChild(XMLUtil.getNamedChild(entry, "resource"));
                    id = XMLUtil.getNamedChildValue(ers, "id");
                    if (id != null)
                        page.getDefinitions().addNs("http://hl7.org/fhir/" + ers.getLocalName() + "/" + id, "Example", prefix + n + ".html", true);
                    if (ers != null) {
                        String ert = ers.getLocalName();
                        String s = null;
                        if (!page.getDefinitions().getBaseResources().containsKey(ert) && !ert.equals("Binary") && !ert.equals("Parameters") && !ert.equals("Bundle")) {
                            ResourceRenderer r = RendererFactory.factory(ers.getLocalName(), lrc);
                            ResourceWrapper rw = new DOMWrappers.ResourceWrapperElement(lrc, ers, page.getDefinitions().getResourceByName(ers.getLocalName()).getProfile());
                            XhtmlNode div = rw.getNarrative();
                            if (div == null || div.isEmpty()) {
                                wantSave = true;
                                r.render(rw);
                            } else
                                s = new XhtmlComposer(true).compose(div);
                            if (s != null)
                                narrative = narrative == null ? s : narrative + "<hr/>\r\n" + s;
                        }
                        if (ert.equals("NamingSystem")) {
                            ByteArrayOutputStream bs = new ByteArrayOutputStream();
                            new XmlGenerator().generate(ers, bs);
                            bs.close();
                            NamingSystem ns = (NamingSystem) new XmlParser().parse(new ByteArrayInputStream(bs.toByteArray()));
                            if (!ns.hasUrl() || ns.getUrl().startsWith("http://hl7.org/fhir"))
                                ns.setVersion(page.getVersion().toCode());
                            ns.setUserData("path", prefix + n + ".html");
                            page.getDefinitions().getNamingSystems().add(ns);
                        }
                    }
                }
                if (wantSave)
                    new XmlGenerator().generate(xdoc.getDocumentElement(), file, "http://hl7.org/fhir", xdoc.getDocumentElement().getLocalName());
            } else {
                if (!page.getDefinitions().getBaseResources().containsKey(rt) && !rt.equals("Binary") && !rt.equals("Parameters")) {
                    ResourceRenderer r = RendererFactory.factory(xdoc.getDocumentElement().getLocalName(), lrc);
                    ResourceWrapper rw = new DOMWrappers.ResourceWrapperElement(lrc, xdoc.getDocumentElement(), page.getDefinitions().getResourceByName(xdoc.getDocumentElement().getLocalName()).getProfile());
                    XhtmlNode div = rw.getNarrative();
                    if (div == null || div.isEmpty()) {
                        narrative = new XhtmlComposer(true).compose(r.render(rw));
                        new XmlGenerator().generate(xdoc.getDocumentElement(), file, "http://hl7.org/fhir", xdoc.getDocumentElement().getLocalName());
                    } else {
                        narrative = new XhtmlComposer(true).compose(div);
                    }
                }
            }
        }
    } catch (Exception ex) {
        StringWriter errors = new StringWriter();
        ex.printStackTrace();
        XhtmlNode xhtml = new XhtmlNode(NodeType.Element, "div");
        xhtml.addTag("p").setAttribute("style", "color: maroon").addText("Error processing narrative: " + ex.getMessage());
        xhtml.addTag("p").setAttribute("style", "color: maroon").addText(errors.toString());
        narrative = new XhtmlComposer(XhtmlComposer.HTML).compose(xhtml);
    }
    if (rt.equals("ValueSet")) {
        try {
            ValueSet vs = (ValueSet) loadExample(file);
            vs.setUserData("filename", Utilities.changeFileExt(file.getName(), ""));
            vs.addExtension().setUrl(ToolingExtensions.EXT_WORKGROUP).setValue(new CodeType("fhir"));
            if (vs.getUrl().startsWith("http://hl7.org/fhir"))
                vs.setVersion(page.getVersion().toCode());
            page.getVsValidator().validate(page.getValidationErrors(), "Value set Example " + prefix + n, vs, false, false);
            if (vs.getUrl() == null)
                throw new Exception("Value set example " + e.getTitle() + " has no url");
            vs.setUserData("path", prefix + n + ".html");
            if (vs.getUrl().startsWith("http:"))
                page.getValueSets().see(vs, page.packageInfo());
            addToResourceFeed(vs, valueSetsFeed, file.getName());
            page.getDefinitions().getValuesets().see(vs, page.packageInfo());
        } catch (Exception ex) {
            if (page.getVersion().isR4B()) {
                System.out.println("Value set " + file.getAbsolutePath() + " couldn't be parsed - ignoring! msg = " + ex.getMessage());
            } else {
                throw new FHIRException("Unable to parse " + file.getAbsolutePath() + ": " + ex.getMessage(), ex);
            }
        }
    } else if (rt.equals("CodeSystem")) {
        CodeSystem cs = (CodeSystem) loadExample(file);
        if (cs.getUrl().startsWith("http://hl7.org/fhir"))
            cs.setVersion(page.getVersion().toCode());
        cs.setUserData("example", "true");
        cs.setUserData("filename", Utilities.changeFileExt(file.getName(), ""));
        cs.addExtension().setUrl(ToolingExtensions.EXT_WORKGROUP).setValue(new CodeType("fhir"));
        cs.setUserData("path", prefix + n + ".html");
        addToResourceFeed(cs, valueSetsFeed, file.getName());
        page.getCodeSystems().see(cs, page.packageInfo());
    } else if (rt.equals("ConceptMap") && !page.getVersion().isR4B()) {
        ConceptMap cm = (ConceptMap) loadExample(file);
        new ConceptMapValidator(page.getDefinitions(), e.getTitle()).validate(cm, false);
        if (cm.getUrl() == null)
            throw new Exception("Value set example " + e.getTitle() + " has no identifier");
        if (cm.getUrl().startsWith("http://hl7.org/fhir"))
            cm.setVersion(page.getVersion().toCode());
        addToResourceFeed(cm, conceptMapsFeed, file.getName());
        page.getDefinitions().getConceptMaps().see(cm, page.packageInfo());
        cm.setUserData("path", prefix + n + ".html");
        page.getConceptMaps().see(cm, page.packageInfo());
    } else if (rt.equals("Library")) {
        try {
            Library lib = (Library) loadExample(file);
            if (lib.hasUrl() && lib.getUrl().startsWith("http://hl7.org/fhir"))
                lib.setVersion(page.getVersion().toCode());
            lib.setUserData("example", "true");
            lib.setUserData("filename", Utilities.changeFileExt(file.getName(), ""));
            lib.setUserData("path", prefix + n + ".html");
            page.getWorkerContext().cacheResource(lib);
        } catch (Exception ex) {
            System.out.println("Internal exception processing Library " + file.getName() + ": " + ex.getMessage() + ". Does the libary code need regenerating?");
            ex.printStackTrace();
        }
    }
    // queue for json and canonical XML generation processing
    e.setResourceName(resn.getName());
    String canonical = "http://hl7.org/fhir/";
    org.hl7.fhir.r5.elementmodel.Element ex = Manager.parse(page.getWorkerContext(), new CSFileInputStream(page.getFolders().dstDir + prefix + n + ".xml"), FhirFormat.XML);
    new DefinitionsUsageTracker(page.getDefinitions()).updateUsage(ex);
    Manager.compose(page.getWorkerContext(), ex, new FileOutputStream(page.getFolders().dstDir + prefix + n + ".json"), FhirFormat.JSON, OutputStyle.PRETTY, canonical);
    // Manager.compose(page.getWorkerContext(), ex, new FileOutputStream(Utilities.changeFileExt(destName, ".canonical.json")), FhirFormat.JSON, OutputStyle.CANONICAL);
    // Manager.compose(page.getWorkerContext(), ex, new FileOutputStream(Utilities.changeFileExt(destName, ".canonical.xml")), FhirFormat.XML, OutputStyle.CANONICAL);
    Manager.compose(page.getWorkerContext(), ex, new FileOutputStream(page.getFolders().dstDir + prefix + n + ".ttl"), FhirFormat.TURTLE, OutputStyle.PRETTY, resn.getName().equals("Parameters") || resn.getName().equals("OperationOutcome") ? null : canonical);
    String json = TextFile.fileToString(page.getFolders().dstDir + prefix + n + ".json");
    // String json2 = "<div class=\"example\">\r\n<p>" + Utilities.escapeXml(e.getDescription()) + "</p>\r\n<p><a href=\""+ n + ".json\">Raw JSON</a> (<a href=\""+n + ".canonical.json\">Canonical</a>)</p>\r\n<pre class=\"json\">\r\n" + Utilities.escapeXml(json)
    // + "\r\n</pre>\r\n</div>\r\n";
    json = "<div class=\"example\">\r\n<p>" + Utilities.escapeXml(e.getDescription()) + "</p>\r\n<pre class=\"json\">\r\n" + Utilities.escapeXml(json) + "\r\n</pre>\r\n</div>\r\n";
    String html = TextFile.fileToString(page.getFolders().templateDir + "template-example-json.html").replace("<%example%>", json);
    html = page.processPageIncludes(n + ".json.html", html, e.getResourceName() == null ? "profile-instance:resource:" + e.getResourceName() : "resource-instance:" + e.getResourceName(), null, null, null, "Example", null, resn, resn.getWg());
    TextFile.stringToFile(html, page.getFolders().dstDir + prefix + n + ".json.html");
    page.getHTMLChecker().registerExternal(prefix + n + ".json.html");
    String ttl = TextFile.fileToString(page.getFolders().dstDir + prefix + n + ".ttl");
    ttl = "<div class=\"example\">\r\n<p>" + Utilities.escapeXml(e.getDescription()) + "</p>\r\n<pre class=\"rdf\">\r\n" + Utilities.escapeXml(ttl) + "\r\n</pre>\r\n</div>\r\n";
    html = TextFile.fileToString(page.getFolders().templateDir + "template-example-ttl.html").replace("<%example%>", ttl);
    html = page.processPageIncludes(n + ".ttl.html", html, e.getResourceName() == null ? "profile-instance:resource:" + e.getResourceName() : "resource-instance:" + e.getResourceName(), null, null, null, "Example", null, resn, resn.getWg());
    TextFile.stringToFile(html, page.getFolders().dstDir + prefix + n + ".ttl.html");
    page.getHTMLChecker().registerExternal(prefix + n + ".ttl.html");
    // reload it now, xml to xhtml of xml
    builder = factory.newDocumentBuilder();
    xdoc = builder.parse(new CSFileInputStream(file));
    XhtmlGenerator xhtml = new XhtmlGenerator(new ExampleAdorner(page.getDefinitions(), page.genlevel(level)));
    ByteArrayOutputStream b = new ByteArrayOutputStream();
    xhtml.generate(xdoc, b, n.toUpperCase().substring(0, 1) + n.substring(1), Utilities.noString(e.getId()) ? e.getDescription() : e.getDescription() + " (id = \"" + e.getId() + "\")", 0, true, n + ".xml.html");
    html = TextFile.fileToString(page.getFolders().templateDir + "template-example-xml.html").replace("<%example%>", b.toString());
    html = page.processPageIncludes(n + ".xml.html", html, resn == null ? "profile-instance:resource:" + rt : "resource-instance:" + resn.getName(), null, n + ".xml.html", profile, null, "Example", (hasNarrative(xdoc)) ? new Boolean(true) : null, ig, resn, resn.getWg());
    TextFile.stringToFile(html, page.getFolders().dstDir + prefix + n + ".xml.html");
    XhtmlDocument d = new XhtmlParser().parse(new CSFileInputStream(page.getFolders().dstDir + prefix + n + ".xml.html"), "html");
    XhtmlNode pre = d.getElement("html").getElement("body").getElement("div");
    e.setXhtm(b.toString());
    Element root = xdoc.getDocumentElement();
    Element meta = XMLUtil.getNamedChild(root, "meta");
    if (meta == null) {
        Element id = XMLUtil.getNamedChild(root, "id");
        if (id == null)
            meta = XMLUtil.insertChild(xdoc, root, "meta", FormatUtilities.FHIR_NS, 2);
        else {
            Element pid = XMLUtil.getNextSibling(id);
            if (pid == null)
                throw new Exception("not handled - id is last child in " + n);
            else
                meta = XMLUtil.insertChild(xdoc, root, "meta", FormatUtilities.FHIR_NS, pid, 2);
        }
    }
    Element tag = XMLUtil.getNamedChild(meta, "tag");
    Element label = XMLUtil.insertChild(xdoc, meta, "security", FormatUtilities.FHIR_NS, tag, 4);
    XMLUtil.addTextTag(xdoc, label, "system", FormatUtilities.FHIR_NS, "http://terminology.hl7.org/CodeSystem/v3-ActReason", 6);
    XMLUtil.addTextTag(xdoc, label, "code", FormatUtilities.FHIR_NS, "HTEST", 6);
    XMLUtil.addTextTag(xdoc, label, "display", FormatUtilities.FHIR_NS, "test health data", 6);
    XMLUtil.spacer(xdoc, label, 4);
    XMLUtil.spacer(xdoc, meta, 2);
    String destf = (!Utilities.noString(e.getId())) ? page.getFolders().dstDir + "examples" + File.separator + n + "(" + e.getId() + ").xml" : page.getFolders().dstDir + "examples" + File.separator + n + ".xml";
    FileOutputStream fs = new FileOutputStream(destf);
    XMLUtil.saveToFile(root, fs);
    fs.close();
    // now, we create an html page from the narrative
    narrative = fixExampleReferences(e.getTitle(), narrative);
    html = TextFile.fileToString(page.getFolders().templateDir + "template-example.html").replace("<%example%>", narrative == null ? "" : narrative).replace("<%example-usage%>", genExampleUsage(e, page.genlevel(level)));
    html = page.processPageIncludes(n + ".html", html, resn == null ? "profile-instance:resource:" + rt : "resource-instance:" + resn.getName(), null, profile, null, "Example", ig, resn, resn.getWg());
    TextFile.stringToFile(html, page.getFolders().dstDir + prefix + n + ".html");
    // head =
    // "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\r\n<head>\r\n <title>"+Utilities.escapeXml(e.getDescription())+"</title>\r\n <link rel=\"Stylesheet\" href=\"fhir.css\" type=\"text/css\" media=\"screen\"/>\r\n"+
    // "</head>\r\n<body>\r\n<p>&nbsp;</p>\r\n<p>"+Utilities.escapeXml(e.getDescription())+"</p>\r\n"+
    // "<p><a href=\""+n+".xml.html\">XML</a> <a href=\""+n+".json.html\">JSON</a></p>\r\n";
    // tail = "\r\n</body>\r\n</html>\r\n";
    // TextFile.stringToFile(head+narrative+tail, page.getFolders().dstDir + n +
    // ".html");
    page.getHTMLChecker().registerExternal(prefix + n + ".html");
    page.getHTMLChecker().registerExternal(prefix + n + ".xml.html");
}
Also used : ResourceWrapper(org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper) DocumentBuilderFactory(javax.xml.parsers.DocumentBuilderFactory) XhtmlParser(org.hl7.fhir.utilities.xhtml.XhtmlParser) ConceptMapValidator(org.hl7.fhir.definitions.validation.ConceptMapValidator) ArrayList(java.util.ArrayList) CSFile(org.hl7.fhir.utilities.CSFile) Document(org.w3c.dom.Document) XhtmlDocument(org.hl7.fhir.utilities.xhtml.XhtmlDocument) XhtmlDocument(org.hl7.fhir.utilities.xhtml.XhtmlDocument) ResourceRenderer(org.hl7.fhir.r5.renderers.ResourceRenderer) CapabilityStatement(org.hl7.fhir.r5.model.CapabilityStatement) ConceptMap(org.hl7.fhir.r5.model.ConceptMap) ValueSet(org.hl7.fhir.r5.model.ValueSet) CodeSystem(org.hl7.fhir.r5.model.CodeSystem) CSFileInputStream(org.hl7.fhir.utilities.CSFileInputStream) FileInputStream(java.io.FileInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) FileOutputStream(java.io.FileOutputStream) Library(org.hl7.fhir.r5.model.Library) Element(org.w3c.dom.Element) XhtmlNode(org.hl7.fhir.utilities.xhtml.XhtmlNode) XhtmlGenerator(org.hl7.fhir.utilities.xml.XhtmlGenerator) StringWriter(java.io.StringWriter) XhtmlComposer(org.hl7.fhir.utilities.xhtml.XhtmlComposer) RenderingContext(org.hl7.fhir.r5.renderers.utils.RenderingContext) XmlParser(org.hl7.fhir.r5.formats.XmlParser) XmlGenerator(org.hl7.fhir.utilities.xml.XmlGenerator) ByteArrayOutputStream(java.io.ByteArrayOutputStream) FHIRException(org.hl7.fhir.exceptions.FHIRException) ContactPoint(org.hl7.fhir.r5.model.ContactPoint) TransformerException(javax.xml.transform.TransformerException) IOException(java.io.IOException) FHIRException(org.hl7.fhir.exceptions.FHIRException) FileNotFoundException(java.io.FileNotFoundException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) NamingSystem(org.hl7.fhir.r5.model.NamingSystem) DocumentBuilder(javax.xml.parsers.DocumentBuilder) CodeType(org.hl7.fhir.r5.model.CodeType) CanonicalResource(org.hl7.fhir.r5.model.CanonicalResource) CSFileInputStream(org.hl7.fhir.utilities.CSFileInputStream)

Aggregations

ByteArrayOutputStream (java.io.ByteArrayOutputStream)4 DocumentBuilder (javax.xml.parsers.DocumentBuilder)4 DocumentBuilderFactory (javax.xml.parsers.DocumentBuilderFactory)4 CSFile (org.hl7.fhir.utilities.CSFile)4 CSFileInputStream (org.hl7.fhir.utilities.CSFileInputStream)4 XhtmlGenerator (org.hl7.fhir.utilities.xml.XhtmlGenerator)4 XhtmlDocument (org.hl7.fhir.utilities.xhtml.XhtmlDocument)3 Document (org.w3c.dom.Document)3 File (java.io.File)2 FileNotFoundException (java.io.FileNotFoundException)2 FileOutputStream (java.io.FileOutputStream)2 IOException (java.io.IOException)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 ArrayList (java.util.ArrayList)2 TransformerException (javax.xml.transform.TransformerException)2 ElementDefn (org.hl7.fhir.definitions.model.ElementDefn)2 FHIRException (org.hl7.fhir.exceptions.FHIRException)2 XmlParser (org.hl7.fhir.r5.formats.XmlParser)2 ContactPoint (org.hl7.fhir.r5.model.ContactPoint)2 IniFile (org.hl7.fhir.utilities.IniFile)2