use of org.hl7.fhir.utilities.xml.SchematronWriter.Section in project kindling by HL7.
the class SchematronGenerator method insertGlobalRules.
private void insertGlobalRules(SchematronWriter sch) throws IOException {
Section s = sch.section("Global");
s.rule("f:*").assrt("@value|f:*|h:div", "global-1: All FHIR elements must have a @value or children");
s.rule("f:extension").assrt("exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])", "ext-1: Must have either extensions or value[x], not both");
s.rule("f:modifierExtension").assrt("exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])", "ext-1: Must have either extensions or value[x], not both");
}
use of org.hl7.fhir.utilities.xml.SchematronWriter.Section in project kindling by HL7.
the class SchematronGenerator method generateInvariants.
private void generateInvariants(Section section, String path, ElementDefn ed, Definitions definitions, List<String> parents, String name) throws Exception {
if (definitions.getBaseResources().containsKey(ed.typeCode()))
generateInvariants(section, path, definitions.getBaseResources().get(ed.typeCode()).getRoot(), definitions, parents, name);
// logger.log("generate: "+path+" ("+parents.toString()+")");
if (name.contains("("))
name = name.substring(0, name.indexOf("("));
if (ed.getElements().size() > 0) {
path = path == null ? "f:" + name : path + (recursesToSelf(ed) ? "/" : "") + "/f:" + name;
genInvs(section, path, ed);
genChildren(section, path, null, ed, definitions, parents);
} else {
for (TypeRef tr : ed.typeCode().equals("*") ? allTypes() : ed.getTypes()) {
String en = name;
if (en.endsWith("[x]")) {
if (definitions.getConstraints().containsKey(tr.getName()))
en = en.replace("[x]", definitions.getConstraints().get(tr.getName()).getBaseType());
else
en = en.replace("[x]", Utilities.capitalize(tr.summary()));
}
if (en.contains("("))
en = en.substring(0, en.indexOf("("));
if (en.equals("div"))
en = "h:" + en;
else
en = "f:" + en;
String sPath = path == null ? en : path + "/" + en;
genInvs(section, sPath, ed);
ElementDefn td = getType(tr, definitions);
if (td != null) {
genInvs(section, sPath, td);
genChildren(section, sPath, tr.summary(), td, definitions, parents);
}
}
}
}
use of org.hl7.fhir.utilities.xml.SchematronWriter.Section in project kindling by HL7.
the class SchematronGenerator method generate.
public void generate(OutputStream out, Definitions definitions) throws Exception {
SchematronWriter sch = new SchematronWriter(out, SchematronType.ALL_RESOURCES, "All Resources");
insertGlobalRules(sch);
for (String rn : definitions.sortedResourceNames()) {
ResourceDefn root = definitions.getResources().get(rn);
Section s = sch.section(root.getName());
ArrayList<String> parents = new ArrayList<String>();
generateInvariants(s, null, root.getRoot(), definitions, parents, root.getName());
}
Set<StructureDefinition> processed = new HashSet<StructureDefinition>();
for (StructureDefinition exd : page.getWorkerContext().getExtensionDefinitions()) {
if (exd.getSnapshot().getElement().get(0).hasConstraint() && !processed.contains(exd)) {
processed.add(exd);
Section s = sch.section("Extension: " + exd.getName());
Rule r = s.rule("f:" + (exd.getSnapshot().getElementFirstRep().getIsModifier() ? "modifierExtension" : "extension") + "[@url='" + exd.getUrl() + "']");
for (ElementDefinitionConstraintComponent inv : exd.getSnapshot().getElement().get(0).getConstraint()) {
if (!isGlobal(inv.getKey()))
r.assrt(inv.getXpath().replace("\"", "'"), inv.getKey() + ": " + inv.getHuman());
}
}
}
sch.dump();
sch.close();
}
use of org.hl7.fhir.utilities.xml.SchematronWriter.Section in project kindling by HL7.
the class PageProcessor method checkFormat.
private void checkFormat(String filename, String res, ResourceDefn r) throws FHIRException {
XhtmlNode doc;
try {
doc = new XhtmlParser().parse("<div>" + res + "</div>", null).getFirstElement();
if (doc.getFirstElement() == null || !doc.getFirstElement().getName().equals("div"))
log("file \"" + filename + "\": root element should be 'div'", LogMessageType.Error);
else if (doc.getFirstElement() == null) {
log("file \"" + filename + "\": there is no 'Scope and Usage'", LogMessageType.Error);
} else {
XhtmlNode scope = null;
XhtmlNode context = null;
for (XhtmlNode x : doc.getChildNodes()) {
if (x.getNodeType() == NodeType.Element) {
if (!x.getName().equals("div")) {
log("file \"" + filename + "\": all child elements of the root div should be 'div's too (found '" + x.getName() + "')", LogMessageType.Error);
return;
} else if (x.getChildNodes().isEmpty()) {
log("file \"" + filename + "\": div/div[" + Integer.toString(doc.getChildNodes().indexOf(x)) + "] must have at least an h2", LogMessageType.Error);
return;
} else if (!isFirstChildElementH2(x)) {
log("file \"" + filename + "\": div/div[" + Integer.toString(doc.getChildNodes().indexOf(x)) + "] must start with an h2", LogMessageType.Error);
return;
} else {
XhtmlNode fn = getH2Element(x);
String s = fn.allText();
if (!((s.equals("Scope and Usage")) || (s.equals("Boundaries and Relationships")) || (s.equals("Background and Context")))) {
log("file \"" + filename + "\": div/div[" + Integer.toString(doc.getChildNodes().indexOf(x)) + "]/h2 must be either 'Scope and Usage', 'Boundaries and Relationships', or 'Background and Context'", LogMessageType.Error);
return;
} else {
if (scope == null) {
if (s.equals("Scope and Usage")) {
scope = x;
if (r != null)
r.setRequirements(new XhtmlComposer(XhtmlComposer.HTML).composePlainText(x));
} else {
log("file \"" + filename + "\": 'Scope and Usage' must come first", LogMessageType.Error);
return;
}
if (s.equals("Boundaries and Relationships")) {
if (context != null) {
log("file \"" + filename + "\": 'Boundaries and Relationships' must come first before 'Background and Context'", LogMessageType.Error);
return;
}
}
if (s.equals("Background and Context"))
context = x;
}
}
boolean found = false;
for (XhtmlNode n : x.getChildNodes()) {
if (!found)
found = n == fn;
else {
if ("h1".equals(n.getName()) || "h2".equals(n.getName())) {
log("file \"" + filename + "\": content of a <div> inner section cannot contain h1 or h2 headings", LogMessageType.Error);
return;
}
}
}
}
}
}
}
List<String> allowed = Arrays.asList("div", "h2", "h3", "h4", "h5", "i", "b", "code", "pre", "blockquote", "p", "a", "img", "table", "thead", "tbody", "tr", "th", "td", "ol", "ul", "li", "br", "span", "em", "strong");
iterateAllChildNodes(doc, allowed);
} catch (Exception e) {
throw new FHIRException("Error processing " + filename + ": " + e.getMessage(), e);
}
}
use of org.hl7.fhir.utilities.xml.SchematronWriter.Section in project kindling by HL7.
the class SourceParser method loadResource.
private ResourceDefn loadResource(String n, Map<String, ResourceDefn> map, boolean isAbstract, boolean isTemplate, String t, boolean isInterface) throws Exception {
String folder = n;
WorkGroup wg = definitions.getWorkgroups().get(ini.getStringProperty("workgroups", n));
if (wg == null)
throw new Exception("No Workgroup found for resource " + n + ": '" + ini.getStringProperty("workgroups", n) + "'");
File f = new File(Utilities.path(srcDir, folder, n + ".svg"));
if (isTemplate) {
File spreadsheet = new CSFile((srcDir) + folder + File.separatorChar + n + "-spreadsheet.xml");
OldSpreadsheetParser sparser = new OldSpreadsheetParser("core", new CSFileInputStream(spreadsheet), spreadsheet.getName(), spreadsheet.getAbsolutePath(), definitions, srcDir, logger, registry, version, context, genDate, isAbstract, page, false, ini, wg, definitions.getProfileIds(), fpUsages, page.getConceptMaps(), exceptionIfExcelNotNormalised, page.packageInfo(), page.getRc());
ResourceDefn root;
try {
root = sparser.parseResource(isTemplate);
} catch (Exception e) {
throw new Exception("Error Parsing Resource " + n + ": " + e.getMessage(), e);
}
root.setAbstract(isAbstract);
root.setInterface(isInterface);
errors.addAll(sparser.getErrors());
setResourceProps(n, wg, root);
String sc = ini.getStringProperty("security-categorization", root.getName().toLowerCase());
if (sc != null) {
root.setSecurityCategorization(SecurityCategorization.fromCode(sc));
} else if (!Utilities.existsInList(root.getName(), "Resource", "DomainResource", "CanonicalResource", "MetadataResource", "MetadataPattern"))
throw new Exception("Must have an entry in the security-categorization section of fhir.ini for the resource " + root.getName());
for (EventDefn e : sparser.getEvents()) {
processEvent(e, root.getRoot());
}
if (map != null) {
map.put(root.getName(), root);
}
if (!isTemplate) {
definitions.getKnownResources().put(root.getName(), new DefinedCode(root.getName(), root.getRoot().getDefinition(), n));
context.getResourceNames().add(root.getName());
}
if (root.getNormativeVersion() != null || root.getNormativePackage() != null) {
root.setStatus(StandardsStatus.NORMATIVE);
}
if (f.exists()) {
parseSvgFile(f, root.getLayout(), f.getName());
}
if (map != null) {
map.put(root.getName(), root);
}
return root;
} else {
try {
new SpreadSheetReloader(context, srcDir, t, version.toCode()).process();
} catch (Exception e) {
System.out.println("Error loading spreadsheet for resource " + t + ": " + e.getMessage());
}
new SpreadSheetCreator(context, srcDir, t).generateSpreadsheet();
ResourceDefn rootNew = new ResourceParser(srcDir, definitions, context, wg, registry, version.toCode(), page.getConceptMaps()).parse(n, t);
if (f.exists()) {
parseSvgFile(f, rootNew.getLayout(), f.getName());
}
if (!isTemplate) {
definitions.getKnownResources().put(rootNew.getName(), new DefinedCode(rootNew.getName(), rootNew.getRoot().getDefinition(), n));
context.getResourceNames().add(rootNew.getName());
}
setResourceProps(n, wg, rootNew);
if (map != null) {
map.put(rootNew.getName(), rootNew);
}
return rootNew;
}
}
Aggregations