Search in sources :

Example 6 with ValidationMessage

use of org.hl7.fhir.utilities.validation.ValidationMessage in project kindling by HL7.

the class Publisher method checkExampleLinks.

private void checkExampleLinks(List<ValidationMessage> errors, ResourceDefn r) throws Exception {
    for (Example e : r.getExamples()) {
        try {
            if (e.getXml() != null) {
                List<ExampleReference> refs = new ArrayList<ExampleReference>();
                listLinks(e.getXml().getDocumentElement(), refs);
                for (ExampleReference ref : refs) {
                    if (!ref.isExempt() && !resolveLink(ref, e)) {
                        String path = ref.getPath().replace("/f:", ".").substring(1) + " (example " + e.getTitle() + ")";
                        if (ref.hasType() && page.getDefinitions().hasResource(ref.getType())) {
                            errors.add(new ValidationMessage(Source.ExampleValidator, IssueType.BUSINESSRULE, -1, -1, path, "Unable to resolve example reference to " + ref.getRef() + " in " + e.getTitle() + " (Possible Ids: " + listTargetIds(ref.getType()) + ")", "Unable to resolve example reference to " + ref.getRef() + " in <a href=\"" + e.getTitle() + ".html" + "\">" + e.getTitle() + "</a> (Possible Ids: " + listTargetIds(ref.getType()) + ")", IssueSeverity.INFORMATION));
                        } else {
                            String regex = "((http|https)://([A-Za-z0-9\\\\\\/\\.\\:\\%\\$])*)?(" + page.pipeResources() + ")\\/" + FormatUtilities.ID_REGEX + "(\\/_history\\/" + FormatUtilities.ID_REGEX + ")?";
                            if (ref.getRef().matches(regex)) {
                                errors.add(new ValidationMessage(Source.ExampleValidator, IssueType.BUSINESSRULE, -1, -1, path, "Unable to resolve example reference " + ref.getRef() + " in " + e.getTitle(), "Unable to resolve example reference " + ref.getRef() + " in <a href=\"" + e.getTitle() + ".html" + "\">" + e.getTitle() + "</a>", IssueSeverity.INFORMATION));
                            } else {
                                errors.add(new ValidationMessage(Source.ExampleValidator, IssueType.BUSINESSRULE, -1, -1, path, "Unable to resolve invalid example reference " + ref.getRef() + " in " + e.getTitle(), "Unable to resolve invalid example reference " + ref.getRef() + " in <a href=\"" + e.getTitle() + ".html" + "\">" + e.getTitle() + "</a>", IssueSeverity.WARNING));
                            }
                        }
                    // System.out.println("unresolved reference "+ref.getRef()+" at "+path);
                    }
                }
            }
        } catch (Exception ex) {
            throw new Exception("Error checking example " + e.getTitle() + ":" + ex.getMessage(), ex);
        }
    }
}
Also used : ValidationMessage(org.hl7.fhir.utilities.validation.ValidationMessage) Example(org.hl7.fhir.definitions.model.Example) ArrayList(java.util.ArrayList) TransformerException(javax.xml.transform.TransformerException) IOException(java.io.IOException) FHIRException(org.hl7.fhir.exceptions.FHIRException) FileNotFoundException(java.io.FileNotFoundException) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Example 7 with ValidationMessage

use of org.hl7.fhir.utilities.validation.ValidationMessage in project kindling by HL7.

the class BookMaker method checkCrossLinks.

private void checkCrossLinks(String name, XhtmlNode node) {
    if (node.getNodeType() == NodeType.Element && node.getName().equals("a")) {
        String href = node.getAttribute("href");
        if (href != null) {
            if (!pages.containsKey(href)) {
                boolean found = false;
                if (href.endsWith(".xsd") || href.endsWith(".xml") || href.endsWith(".xml.html") || href.endsWith(".json") || href.endsWith(".zip"))
                    found = true;
                else if (pages.containsKey(href))
                    found = true;
                else if (href.startsWith("http:") || href.startsWith("https:") || href.startsWith("mailto:") || href.startsWith("ftp:"))
                    found = true;
                else if (href.startsWith("v2/") || href.startsWith("v3/") || href.startsWith("../")) {
                    found = true;
                    node.setAttribute("href", "http://hl7.org/fhir" + href);
                }
                if (!found && href.contains("#")) {
                    String[] parts = href.split("#");
                    if (parts == null || parts.length == 0) {
                        parts = new String[] { name };
                    } else if (parts[0].equals(""))
                        parts[0] = name;
                    found = pages.containsKey(parts[0]);
                    if (found && parts[1] != null && !parts[1].equals("")) {
                        found = findTarget(pages.get(parts[0]), parts[1]);
                        if (!found)
                            try {
                                if (new File("c:\\temp\\source.html").exists())
                                    new XhtmlComposer(XhtmlComposer.HTML).compose(new FileOutputStream("c:\\temp\\source.html"), pages.get(parts[0]));
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                    }
                }
                if (!found && !new File(page.getFolders().dstDir + href).exists() && !href.equals("qa.html")) {
                    issues.add(new ValidationMessage(Source.Publisher, IssueType.INFORMATIONAL, -1, -1, name, "broken link in " + name + ": <a href=\"" + href + "\">" + node.allText() + "</a>", IssueSeverity.ERROR));
                }
            }
        }
    } else {
        if (!(node.getNodeType() == NodeType.Element && "div".equals(node.getName()) && "index-only-no-book".equals(node.getAttribute("class"))))
            for (XhtmlNode c : node.getChildNodes()) checkCrossLinks(name, c);
    }
}
Also used : ValidationMessage(org.hl7.fhir.utilities.validation.ValidationMessage) FileOutputStream(java.io.FileOutputStream) XhtmlComposer(org.hl7.fhir.utilities.xhtml.XhtmlComposer) File(java.io.File) TextFile(org.hl7.fhir.utilities.TextFile) FileNotFoundException(java.io.FileNotFoundException) XhtmlNode(org.hl7.fhir.utilities.xhtml.XhtmlNode)

Example 8 with ValidationMessage

use of org.hl7.fhir.utilities.validation.ValidationMessage in project kindling by HL7.

the class OldSpreadsheetParser method parseProfileSheet.

private ConstraintStructure parseProfileSheet(Definitions definitions, Profile ap, String n, List<String> namedSheets, boolean published, String usage, List<ValidationMessage> issues, WorkGroup wg, String fmm) throws Exception {
    Sheet sheet;
    ResourceDefn resource = new ResourceDefn();
    sheet = loadSheet(n + "-Inv");
    Map<String, Invariant> invariants = null;
    if (sheet != null) {
        invariants = readInvariants(sheet, n, n + "-Inv");
    } else {
        invariants = new HashMap<String, Invariant>();
    }
    sheet = loadSheet(n);
    if (sheet == null)
        throw new Exception("The StructureDefinition referred to a tab by the name of '" + n + "', but no tab by the name could be found");
    for (int row = 0; row < sheet.rows.size(); row++) {
        ElementDefn e = processLine(resource, sheet, row, invariants, true, ap, row == 0);
        if (e != null)
            for (TypeRef t : e.getTypes()) {
                if (t.getProfile() != null && !t.getName().equals("Extension") && t.getProfile().startsWith("#")) {
                    if (!namedSheets.contains(t.getProfile().substring(1)))
                        namedSheets.add(t.getProfile().substring(1));
                }
            }
    }
    sheet = loadSheet(n + "-Extensions");
    if (sheet != null) {
        int row = 0;
        while (row < sheet.rows.size()) {
            if (sheet.getColumn(row, "Code").startsWith("!"))
                row++;
            else
                row = processExtension(resource.getRoot().getElementByName(definitions, "extensions", true, false), sheet, row, definitions, ap.metadata("extension.uri"), ap, issues, invariants, wg);
        }
    }
    sheet = loadSheet(n + "-Search");
    if (sheet != null) {
        readSearchParams(resource, sheet, true);
    }
    if (invariants != null) {
        for (Invariant inv : invariants.values()) {
            if (Utilities.noString(inv.getContext()))
                throw new Exception("Type " + resource.getRoot().getName() + " Invariant " + inv.getId() + " has no context");
            else {
                ElementDefn ed = findContext(resource.getRoot(), inv.getContext(), "Type " + resource.getRoot().getName() + " Invariant " + inv.getId() + " Context");
                // TODO: Need to resolve context based on element name, not just path
                if (ed.getName().endsWith("[x]") && !inv.getContext().endsWith("[x]"))
                    inv.setFixedName(inv.getContext().substring(inv.getContext().lastIndexOf(".") + 1));
                ed.getInvariants().put(inv.getId(), inv);
                if (Utilities.noString(inv.getXpath())) {
                    throw new Exception("Type " + resource.getRoot().getName() + " Invariant " + inv.getId() + " (" + inv.getEnglish() + ") has no XPath statement");
                } else if (inv.getXpath().contains("\""))
                    throw new Exception("Type " + resource.getRoot().getName() + " Invariant " + inv.getId() + " (" + inv.getEnglish() + ") contains a \" character");
            // if (Utilities.noString(inv.getExpression()))
            // throw new Exception("Type "+resource.getRoot().getName()+" Invariant "+inv.getId()+" ("+inv.getEnglish()+") has no Expression statement (in FHIRPath format)");
            }
        }
    }
    resource.getRoot().setProfileName(n);
    if (n.toLowerCase().equals(ap.getId()))
        throw new Exception("Duplicate Profile Name: Package id " + ap.getId() + " and profile id " + n.toLowerCase() + " are the same");
    if (profileIds.containsKey(n.toLowerCase()))
        throw new Exception("Duplicate Profile Name: " + n.toLowerCase() + " in " + ap.getId() + ", already registered in " + profileIds.get(n.toLowerCase()).getOwner());
    ConstraintStructure p = new ConstraintStructure(n.toLowerCase(), resource.getRoot().getProfileName(), resource, ig != null ? ig : definitions.getUsageIG(usage, "Parsing " + name), wg, fmm, Utilities.existsInList(ap.metadata("Experimental"), "y", "Y", "true", "TRUE", "1"));
    p.setOwner(ap.getId());
    profileIds.put(n.toLowerCase(), p);
    return p;
}
Also used : Invariant(org.hl7.fhir.definitions.model.Invariant) TypeRef(org.hl7.fhir.definitions.model.TypeRef) ElementDefn(org.hl7.fhir.definitions.model.ElementDefn) ConstraintStructure(org.hl7.fhir.definitions.model.ConstraintStructure) Sheet(org.hl7.fhir.utilities.xls.XLSXmlParser.Sheet) ResourceDefn(org.hl7.fhir.definitions.model.ResourceDefn) FHIRException(org.hl7.fhir.exceptions.FHIRException)

Example 9 with ValidationMessage

use of org.hl7.fhir.utilities.validation.ValidationMessage in project kindling by HL7.

the class OldSpreadsheetParser method parseConformancePackage.

public void parseConformancePackage(Profile ap, Definitions definitions, String folder, String usage, List<ValidationMessage> issues, WorkGroup wg) throws Exception {
    try {
        isProfile = true;
        this.folder = folder;
        checkMappings(ap);
        Sheet sheet = loadSheet("Bindings");
        if (sheet != null)
            readBindings(sheet);
        sheet = loadSheet("Metadata");
        for (int row = 0; row < sheet.rows.size(); row++) {
            String n = sheet.getColumn(row, "Name");
            String v = sheet.getColumn(row, "Value");
            if (n != null && v != null) {
                if (ap.getMetadata().containsKey(n))
                    ap.getMetadata().get(n).add(v);
                else {
                    ArrayList<String> vl = new ArrayList<String>();
                    vl.add(v);
                    ap.getMetadata().put(n, vl);
                }
            }
        }
        if (!Utilities.noString(ap.metadata("category")))
            usage = ap.metadata("category");
        if (ap.hasMetadata("name"))
            ap.setTitle(ap.metadata("name"));
        if (ap.hasMetadata("introduction"))
            ap.setIntroduction(Utilities.path(folder, ap.metadata("introduction")));
        if (ap.hasMetadata("notes"))
            ap.setNotes(Utilities.path(folder, ap.metadata("notes")));
        if (!ap.hasMetadata("id"))
            throw new Exception("Error parsing " + ap.getId() + "/" + ap.getTitle() + " no 'id' found in metadata");
        if (!ap.metadata("id").matches(FormatUtilities.ID_REGEX))
            throw new Exception("Error parsing " + ap.getId() + "/" + ap.getTitle() + " 'id' is not a valid id");
        if (wg == null)
            wg = workgroups.get(ap.metadata("workgroup"));
        if (wg == null)
            wg = committee;
        if (wg == null)
            throw new Exception("Error parsing " + ap.getId() + "/" + ap.getTitle() + " : no workgroup value in the metadata");
        if (!ap.metadata("id").equals(ap.metadata("id").toLowerCase()))
            throw new Exception("Error parsing " + ap.getId() + "/" + ap.getTitle() + " 'id' must be all lowercase");
        this.profileExtensionBase = ap.metadata("extension.uri");
        if (ig == null || ig.isCore()) {
            if (!profileExtensionBase.startsWith("http://hl7.org/fhir/StructureDefinition/") && !profileExtensionBase.startsWith("http://fhir-registry.smarthealthit.org/StructureDefinition/"))
                throw new Exception("Core extensions must have a url starting with http://hl7.org/fhir/StructureDefinition/ for " + ap.getId());
        } else {
            if (!profileExtensionBase.startsWith("http://hl7.org/fhir/StructureDefinition/" + ig.getCode() + "-"))
                throw new Exception("Core extensions must have a url starting with http://hl7.org/fhir/StructureDefinition/" + ig.getCode() + "- for " + ap.getId());
        }
        Map<String, Invariant> invariants = null;
        sheet = loadSheet("Extensions-Inv");
        if (sheet != null) {
            invariants = readInvariants(sheet, "", "Extensions-Inv");
        }
        sheet = loadSheet("Extensions");
        if (sheet != null) {
            int row = 0;
            while (row < sheet.rows.size()) {
                if (sheet.getColumn(row, "Code").startsWith("!"))
                    row++;
                else
                    row = processExtension(null, sheet, row, definitions, ap.metadata("extension.uri"), ap, issues, invariants, wg);
            }
        }
        List<String> namedSheets = new ArrayList<String>();
        if (ap.getMetadata().containsKey("published.structure")) {
            for (String n : ap.getMetadata().get("published.structure")) {
                if (!Utilities.noString(n)) {
                    if (ig != null && !ig.isCore() && !n.toLowerCase().startsWith(ig.getCode() + "-"))
                        throw new Exception("Error: published structure names must start with the implementation guide code (" + ig.getCode() + "-)");
                    String fmm = ap.metadata("fmm-" + n);
                    if (Utilities.noString(fmm))
                        fmm = ap.metadata("fmm");
                    if (Utilities.noString(fmm))
                        // default fmm value
                        fmm = "1";
                    ap.getProfiles().add(parseProfileSheet(definitions, ap, n, namedSheets, true, usage, issues, wg, fmm));
                }
            }
        }
        int i = 0;
        while (i < namedSheets.size()) {
            String fmm = ap.metadata("fmm-" + namedSheets.get(i));
            if (Utilities.noString(fmm))
                fmm = ap.metadata("fmm");
            if (Utilities.noString(fmm))
                // default fmm value
                fmm = "1";
            ap.getProfiles().add(parseProfileSheet(definitions, ap, namedSheets.get(i), namedSheets, false, usage, issues, wg, fmm));
            i++;
        }
        if (namedSheets.isEmpty() && xls.getSheets().containsKey("Search"))
            readSearchParams(ap, xls.getSheets().get("Search"), this.profileExtensionBase);
        if (xls.getSheets().containsKey("Operations"))
            readOperations(ap.getOperations(), loadSheet("Operations"));
    } catch (Exception e) {
        throw new Exception("exception parsing pack " + ap.getSource() + ": " + e.getMessage(), e);
    }
}
Also used : Invariant(org.hl7.fhir.definitions.model.Invariant) ArrayList(java.util.ArrayList) Sheet(org.hl7.fhir.utilities.xls.XLSXmlParser.Sheet) FHIRException(org.hl7.fhir.exceptions.FHIRException)

Example 10 with ValidationMessage

use of org.hl7.fhir.utilities.validation.ValidationMessage in project kindling by HL7.

the class SourceParser method loadConformancePackage.

private void loadConformancePackage(Profile ap, List<ValidationMessage> issues, WorkGroup wg) throws FileNotFoundException, IOException, Exception {
    if (ap.getSourceType() == ConformancePackageSourceType.Spreadsheet) {
        OldSpreadsheetParser sparser = new OldSpreadsheetParser(ap.getCategory(), new CSFileInputStream(ap.getSource()), Utilities.noString(ap.getId()) ? ap.getSource() : ap.getId(), ap.getSource(), definitions, srcDir, logger, registry, version, context, genDate, false, page, false, ini, wg, definitions.getProfileIds(), fpUsages, page.getConceptMaps(), exceptionIfExcelNotNormalised, page.packageInfo(), page.getRc());
        sparser.setFolder(Utilities.getDirectoryForFile(ap.getSource()));
        sparser.parseConformancePackage(ap, definitions, Utilities.getDirectoryForFile(ap.getSource()), ap.getCategory(), issues, wg);
        errors.addAll(sparser.getErrors());
    } else if (ap.getSourceType() == ConformancePackageSourceType.StructureDefinition) {
        Resource rf;
        try {
            rf = new XmlParser().parse(new CSFileInputStream(ap.getSource()));
        } catch (Exception e) {
            throw new Exception("Error parsing " + ap.getSource() + ": " + e.getMessage(), e);
        }
        if (!(rf instanceof StructureDefinition))
            throw new Exception("Error parsing Profile: not a structure definition");
        StructureDefinition sd = (StructureDefinition) rf;
        sd.setVersion(version.toCode());
        ap.putMetadata("id", sd.getId() + "-pack");
        ap.putMetadata("date", sd.getDateElement().asStringValue());
        ap.putMetadata("title", sd.getTitle());
        ap.putMetadata("status", sd.getStatus().toCode());
        ap.putMetadata("description", new XhtmlComposer(XhtmlComposer.HTML).compose(sd.getText().getDiv()));
        if (ToolingExtensions.hasExtension(sd, "http://hl7.org/fhir/StructureDefinition/structuredefinition-wg")) {
            wg = definitions.getWorkgroups().get(ToolingExtensions.readStringExtension(sd, "http://hl7.org/fhir/StructureDefinition/structuredefinition-wg"));
            ap.putMetadata("workgroup", wg.getCode());
        }
        ap.setTitle(sd.getTitle());
        new ProfileUtilities(page.getWorkerContext(), null, null).setIds(sd, false);
        ap.getProfiles().add(new ConstraintStructure(sd, definitions.getUsageIG(ap.getCategory(), "Parsing " + ap.getSource()), wg == null ? wg(sd) : wg, fmm(sd), sd.getExperimental()));
    } else if (ap.getSource() != null) {
        parseConformanceDocument(ap, ap.getId(), new CSFile(ap.getSource()), ap.getCategory(), wg);
    }
}
Also used : XmlParser(org.hl7.fhir.r5.formats.XmlParser) XLSXmlParser(org.hl7.fhir.utilities.xls.XLSXmlParser) StructureDefinition(org.hl7.fhir.r5.model.StructureDefinition) ProfileUtilities(org.hl7.fhir.r5.conformance.ProfileUtilities) CanonicalResource(org.hl7.fhir.r5.model.CanonicalResource) Resource(org.hl7.fhir.r5.model.Resource) XhtmlComposer(org.hl7.fhir.utilities.xhtml.XhtmlComposer) OldSpreadsheetParser(org.hl7.fhir.definitions.parsers.spreadsheets.OldSpreadsheetParser) CSFile(org.hl7.fhir.utilities.CSFile) ConstraintStructure(org.hl7.fhir.definitions.model.ConstraintStructure) CSFileInputStream(org.hl7.fhir.utilities.CSFileInputStream) IOException(java.io.IOException) FHIRException(org.hl7.fhir.exceptions.FHIRException) FileNotFoundException(java.io.FileNotFoundException) SAXException(org.xml.sax.SAXException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException)

Aggregations

ValidationMessage (org.hl7.fhir.utilities.validation.ValidationMessage)170 ArrayList (java.util.ArrayList)114 FHIRException (org.hl7.fhir.exceptions.FHIRException)92 Element (org.hl7.fhir.r5.elementmodel.Element)60 IOException (java.io.IOException)46 DefinitionException (org.hl7.fhir.exceptions.DefinitionException)44 StructureDefinition (org.hl7.fhir.r5.model.StructureDefinition)38 NodeStack (org.hl7.fhir.validation.instance.utils.NodeStack)30 IndexedElement (org.hl7.fhir.validation.instance.utils.IndexedElement)28 NotImplementedException (org.apache.commons.lang3.NotImplementedException)21 ProfileUtilities (org.hl7.fhir.r5.conformance.ProfileUtilities)20 ValueSet (org.hl7.fhir.r5.model.ValueSet)20 SpecialElement (org.hl7.fhir.r5.elementmodel.Element.SpecialElement)19 NamedElement (org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement)19 PathEngineException (org.hl7.fhir.exceptions.PathEngineException)18 ElementDefinition (org.hl7.fhir.r5.model.ElementDefinition)18 FileNotFoundException (java.io.FileNotFoundException)17 StructureDefinition (org.hl7.fhir.dstu3.model.StructureDefinition)16 ContactPoint (org.hl7.fhir.r5.model.ContactPoint)16 CommaSeparatedStringBuilder (org.hl7.fhir.utilities.CommaSeparatedStringBuilder)16