use of org.hl7.fhir.utilities.xls.XLSXmlParser.Sheet in project kindling by HL7.
the class ReviewSpreadsheetGenerator method generateReviewSheet.
private void generateReviewSheet(HSSFWorkbook workbook, StructureDefinition profile) throws FHIRException {
HSSFSheet sheet = workbook.createSheet(sanitize(profile.getName()));
sheet.setColumnWidth(0, 8000);
sheet.setColumnWidth(3, 100);
HSSFFont font = workbook.createFont();
font.setBold(true);
font.setFontName("Calibri");
HSSFCellStyle style = workbook.createCellStyle();
style.setFont(font);
style.setBorderBottom(BorderStyle.THIN);
style.setFillBackgroundColor(IndexedColors.LAVENDER.getIndex());
style.setFillForegroundColor(IndexedColors.LAVENDER.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
addRow(sheet, style, "Path", "StructureDefinition", "Value Set", "Definition", "Your Comments").setRowStyle(style);
font = workbook.createFont();
font.setFontName("Calibri");
style = workbook.createCellStyle();
ElementDefinition ed = profile.getSnapshot().getElement().get(0);
String path = ed.getPath();
addRow(sheet, style, path + " : " + profile.getType(), profile.getName(), "", ed.getDefinition(), "");
processRows(workbook, path, profile, profile.getSnapshot().getElement(), 1, sheet, " ");
}
use of org.hl7.fhir.utilities.xls.XLSXmlParser.Sheet in project kindling by HL7.
the class OldSpreadsheetParser method readPackages.
private void readPackages(ResourceDefn defn, Sheet sheet) throws Exception {
if (sheet != null) {
for (int row = 0; row < sheet.rows.size(); row++) {
String name = sheet.getColumn(row, "Name");
if (name != null && !name.equals("") && !name.startsWith("!")) {
Profile pack = new Profile(sheet.getColumn(row, "IG Name"));
if (Utilities.noString(pack.getCategory()))
throw new Exception("Missing IG Name at " + getLocation(row));
if (!definitions.getIgs().containsKey(pack.getCategory()))
throw new Exception("IG Name '" + pack.getCategory() + "' is not registered in [igs] in fhir.ini at " + getLocation(row));
ImplementationGuideDefn ig = definitions.getIgs().get(pack.getCategory());
if (!Utilities.noString(ig.getSource()))
throw new Exception("Implementation Guides that have their own structured definition cannot be registered directly in a source spreadsheet (" + name + ")");
pack.setTitle(name);
// todo-profile
pack.setSource(checkFile(sheet, row, "Source", false, sheet.getColumn(row, "Filename")));
String type = sheet.getColumn(row, "Type");
if ("bundle".equalsIgnoreCase(type))
pack.setSourceType(ConformancePackageSourceType.Bundle);
else if ("spreadsheet".equalsIgnoreCase(type))
pack.setSourceType(ConformancePackageSourceType.Spreadsheet);
else if ("structuredefinition".equalsIgnoreCase(type))
pack.setSourceType(ConformancePackageSourceType.StructureDefinition);
else
throw new Exception("Unknown source type: " + type + " at " + getLocation(row));
// todo-profile
String example = checkFile(sheet, row, "Example", true, null);
if (example != null)
pack.getExamples().add(new Example(example, Utilities.fileTitle(example), "General Example for " + pack.getSource(), new File(example), true, ExampleType.XmlFile, isAbstract));
defn.getConformancePackages().add(pack);
}
}
}
}
use of org.hl7.fhir.utilities.xls.XLSXmlParser.Sheet in project kindling by HL7.
the class OldSpreadsheetParser method processLine.
private ElementDefn processLine(ResourceDefn root, Sheet sheet, int row, Map<String, Invariant> invariants, boolean profile, Profile pack, boolean firstTime) throws Exception {
ElementDefn e;
String path = sheet.getColumn(row, "Element");
if (path.startsWith("!"))
return null;
if (Utilities.noString(path))
throw new Exception("Error reading definitions - no path found @ " + getLocation(row));
if (path.contains("#"))
throw new Exception("Old path style @ " + getLocation(row));
String profileName = isProfile ? sheet.getColumn(row, "Profile Name") : "";
String discriminator = isProfile ? sheet.getColumn(row, "Discriminator") : "";
boolean isRoot = !path.contains(".");
if (isRoot) {
if (root.getRoot() != null)
throw new Exception("Definitions in " + getLocation(row) + " contain two roots: " + path + " in " + root.getName());
root.setName(path);
e = new TypeDefn();
e.setName(path);
root.setRoot((TypeDefn) e);
if (template != null)
e.copyFrom(template.getRoot(), root.getName(), templateTitle);
} else {
e = makeFromPath(root.getRoot(), path, row, profileName, true);
if (template != null) {
ElementDefn ted = getTemplateDefinition(path);
if (ted != null) {
e.copyFrom(ted, root.getName(), templateTitle);
}
}
}
e.setStandardsStatus(StandardsStatus.fromCode(sheet.getColumn(row, "Standards-Status")));
e.setNormativeVersion(sheet.getColumn(row, "Normative-Version"));
if (e.getName().startsWith("@")) {
e.setName(e.getName().substring(1));
e.setXmlAttribute(true);
}
String c = sheet.getColumn(row, "Card.");
if (c == null || c.equals("") || c.startsWith("!")) {
if (!isRoot && !profile && (template == null))
throw new Exception("Missing cardinality at " + getLocation(row) + " on " + path);
if (isRoot && (template == null)) {
e.setMinCardinality(0);
e.setMaxCardinality(Integer.MAX_VALUE);
}
} else {
String[] card = c.split("\\.\\.");
if (card.length != 2 || !Utilities.isInteger(card[0]) || (!"*".equals(card[1]) && !Utilities.isInteger(card[1])))
throw new Exception("Unable to parse Cardinality '" + c + "' " + c + " in " + getLocation(row) + " on " + path);
e.setMinCardinality(Integer.parseInt(card[0]));
e.setMaxCardinality("*".equals(card[1]) ? Integer.MAX_VALUE : Integer.parseInt(card[1]));
}
if (profileName.startsWith("#"))
throw new Exception("blah: " + profileName);
e.setProfileName(profileName);
e.setSliceDescription(isProfile ? sheet.getColumn(row, "Slice Description") : "");
for (String d : discriminator.split("\\,")) if (!Utilities.noString(d))
e.getDiscriminator().add(d);
doAliases(sheet, row, e);
if (sheet.hasColumn(row, "Must Understand"))
throw new Exception("Column 'Must Understand' has been renamed to 'Is Modifier'");
if (sheet.hasColumn(row, "Is Modifier")) {
e.setIsModifier(parseBoolean(sheet.getColumn(row, "Is Modifier"), row, null));
String reason = sheet.getColumn(row, "Modifier Reason");
if (Utilities.noString(reason) && e.getName().toLowerCase().contains("status") && sheet.getColumn(row, "Short Name").contains("error"))
reason = "This element is labelled as a modifier because it is a status element that contains status entered-in-error which means that the resource should not be treated as valid";
if (Utilities.noString(reason) && e.getName().equals("active"))
reason = "This element is labelled as a modifier because it is a status element that can indicate that a record should not be treated as valid";
if (Utilities.noString(reason)) {
System.out.println("Missing IsModifierReason on " + path);
reason = "Not known why this is labelled a modifier";
}
e.setModifierReason(reason);
}
if (isProfile) {
// later, this will get hooked in from the underlying definitions, but we need to know this now to validate the extension modifier matching
if (e.getName().equals("modifierExtension"))
e.setIsModifier(true);
e.setMustSupport(parseBoolean(sheet.getColumn(row, "Must Support"), row, null));
}
if (sheet.hasColumn(row, "Summary"))
e.setSummaryItem(parseBoolean(sheet.getColumn(row, "Summary"), row, null));
e.setRegex(sheet.getColumn(row, "Regex"));
String uml = sheet.getColumn(row, "UML");
if (uml != null) {
if (uml.contains(";")) {
String[] parts = uml.split("\\;");
e.setSvgLeft(Integer.parseInt(parts[0]));
e.setSvgTop(Integer.parseInt(parts[1]));
if (parts.length > 2)
e.setSvgWidth(Integer.parseInt(parts[2]));
e.setUmlDir("");
} else if (uml.startsWith("break:")) {
e.setUmlBreak(true);
e.setUmlDir(uml.substring(6));
} else {
e.setUmlDir(uml);
}
}
String s = sheet.getColumn(row, "Condition");
if (s != null && !s.equals(""))
throw new Exception("Found Condition in spreadsheet " + getLocation(row));
s = sheet.getColumn(row, "Inv.");
if (s != null && !s.equals("")) {
for (String sn : s.split(",")) {
if (!sn.startsWith("!")) {
Invariant inv = invariants.get(sn);
if (inv == null)
throw new Exception("unable to find Invariant '" + sn + "' " + getLocation(row));
e.getStatedInvariants().add(inv);
}
}
}
TypeParser tp = new TypeParser(version.toCode());
e.getTypes().addAll(tp.parse(sheet.getColumn(row, "Type"), isProfile, profileExtensionBase, context, !path.contains("."), this.name));
if (isRoot && e.getTypes().size() == 1 && definitions != null) {
String t = e.getTypes().get(0).getName();
if (definitions.getResourceTemplates().containsKey(t)) {
// we've got a template in play.
template = definitions.getResourceTemplates().get(t);
templateTitle = Utilities.unCamelCase(e.getName());
e.getTypes().get(0).setName(template.getRoot().getTypes().get(0).getName());
} else if (definitions.getBaseResources().containsKey(t) && definitions.getBaseResources().get(t).isInterface()) {
// we've got a template in play.
template = definitions.getBaseResources().get(t);
templateTitle = Utilities.unCamelCase(e.getName());
}
}
if (isProfile && ((path.endsWith(".extension") || path.endsWith(".modifierExtension")) && (e.getTypes().size() == 1) && e.getTypes().get(0).hasProfile()) && Utilities.noString(profileName))
throw new Exception("need to have a profile name if a profiled extension is referenced for " + e.getTypes().get(0).getProfile());
if (sheet.hasColumn(row, "Concept Domain"))
throw new Exception("Column 'Concept Domain' has been retired in " + path);
String bindingName = sheet.getColumn(row, "Binding");
if (!Utilities.noString(bindingName)) {
BindingSpecification binding = bindings.get(bindingName);
if (binding == null && definitions != null)
binding = definitions.getCommonBindings().get(bindingName);
if (binding == null) {
if (bindingName.startsWith("!"))
e.setNoBindingAllowed(true);
else
throw new Exception("Binding name " + bindingName + " could not be resolved in local spreadsheet");
}
e.setBinding(binding);
if (binding != null && !binding.getUseContexts().contains(name))
binding.getUseContexts().add(name);
} else if (e.getBinding() != null) {
if (!e.getBinding().getUseContexts().contains(name))
e.getBinding().getUseContexts().add(name);
}
if (!Utilities.noString(sheet.getColumn(row, "Short Label")))
throw new Exception("Short Label is no longer used");
if (// todo: make this a warning when a fair chunk of the spreadsheets have been converted
sheet.hasColumn(row, "Short Name"))
if (sheet.getColumn(row, "Short Name").startsWith("&"))
e.setShortDefn(e.getShortDefn() + sheet.getColumn(row, "Short Name").substring(1));
else
e.setShortDefn(sheet.getColumn(row, "Short Name"));
if (!isProfile && e.getShortDefn() == null)
throw new Exception("A short definition is required for " + e.getName() + " at " + getLocation(row));
if (sheet.hasColumn(row, "Definition"))
if (sheet.getColumn(row, "Definition").startsWith("&"))
e.setDefinition(Utilities.appendPeriod(e.getDefinition() + processDefinition(sheet.getColumn(row, "Definition")).substring(1)));
else
e.setDefinition(Utilities.appendPeriod(processDefinition(sheet.getColumn(row, "Definition"))));
if (isRoot) {
root.setDefinition(e.getDefinition());
}
if (isProfile || isLogicalModel)
e.setMaxLength(sheet.getColumn(row, "Max Length"));
if (sheet.hasColumn(row, "Requirements"))
if (sheet.getColumn(row, "Requirements").startsWith("&"))
e.setRequirements(Utilities.appendPeriod(e.getRequirements() + sheet.getColumn(row, "Requirements").substring(1)));
else
e.setRequirements(Utilities.appendPeriod(sheet.getColumn(row, "Requirements")));
if (sheet.hasColumn(row, "Comments"))
if (sheet.getColumn(row, "Comments").startsWith("&"))
e.setComments(Utilities.appendPeriod(e.getComments() + Utilities.appendPeriod(sheet.getColumn(row, "Comments").substring(1))));
else
e.setComments(Utilities.appendPeriod(Utilities.appendPeriod(sheet.getColumn(row, "Comments"))));
for (String n : mappings.keySet()) {
String ms = sheet.getColumn(row, mappings.get(n).getColumnName());
if (mappings.get(n).getColumnName().equals("Snomed Code") && !Utilities.noString(ms))
System.out.println("!!");
e.addMapping(n, ms.trim());
}
if (pack != null) {
for (String n : pack.getMappingSpaces().keySet()) {
e.addMapping(n, sheet.getColumn(row, pack.getMappingSpaces().get(n).getColumnName()).trim());
}
}
if (sheet.hasColumn("Hierarchy"))
e.setHierarchy(parseBoolean(sheet.getColumn(row, "Hierarchy"), row, null));
if (sheet.hasColumn(row, "To Do"))
e.setTodo(Utilities.appendPeriod(sheet.getColumn(row, "To Do")));
if (sheet.hasColumn(row, "Example"))
e.setExample(processValue(sheet, row, "Example", sheet.getColumn(row, "Example"), e));
processOtherExamples(e, sheet, row);
if (sheet.hasColumn(row, "Committee Notes"))
e.setCommitteeNotes(Utilities.appendPeriod(sheet.getColumn(row, "Committee Notes")));
if (sheet.hasColumn(row, "Display Hint"))
e.setDisplayHint(sheet.getColumn(row, "Display Hint"));
if (isProfile) {
e.setFixed(processValue(sheet, row, "Value", sheet.getColumn(row, "Value"), e));
e.setPattern(processValue(sheet, row, "Pattern", sheet.getColumn(row, "Pattern"), e));
} else {
if (sheet.hasColumn(row, "Default Value"))
errors.add(path + ": Default value '" + sheet.getColumn(row, "Default Value") + "' found @ " + getLocation(row));
if (sheet.hasColumn(row, "Missing Meaning"))
e.setMeaningWhenMissing(sheet.getColumn(row, "Missing Meaning"));
}
if (sheet.hasColumn(row, "w5"))
e.setW5(checkW5(sheet.getColumn(row, "w5"), path));
if (sheet.hasColumn(row, "Translatable"))
e.setTranslatable(parseBoolean(sheet.getColumn(row, "Translatable"), row, false));
if (sheet.hasColumn(row, "Order Meaning"))
e.setOrderMeaning(sheet.getColumn(row, "Order Meaning"));
return e;
}
use of org.hl7.fhir.utilities.xls.XLSXmlParser.Sheet in project kindling by HL7.
the class OldSpreadsheetParser method processValue.
private DataType processValue(Sheet sheet, int row, String column, String source, ElementDefn e) throws Exception {
if (Utilities.noString(source))
return null;
if (e.getTypes().size() != 1)
throw new Exception("Unable to process " + column + " unless a single type is specified (types = " + e.typeCode() + ") " + getLocation(row) + ", column = " + column);
String type = e.typeCode();
if (definitions != null) {
if (definitions.getConstraints().containsKey(type))
type = definitions.getConstraints().get(type).getBaseType();
} else {
StructureDefinition sd = context.fetchTypeDefinition(type);
if (// not loaded yet?
sd != null)
type = sd.getType();
if (type.equals("SimpleQuantity"))
type = "Quantity";
}
if (source.startsWith("{")) {
JsonParser json = new JsonParser();
return json.parseType(source, type);
} else if (source.startsWith("<")) {
XmlParser xml = new XmlParser();
return xml.parseType(source, type);
} else {
if (source.startsWith("\"") && source.endsWith("\""))
source = source.substring(1, source.length() - 1);
if (type.equals("string"))
return new StringType(source);
if (type.equals("boolean"))
return new BooleanType(Boolean.valueOf(source));
if (type.equals("integer"))
return new IntegerType(Integer.valueOf(source));
if (type.equals("integer64"))
return new Integer64Type(Long.valueOf(source));
if (type.equals("unsignedInt"))
return new UnsignedIntType(Integer.valueOf(source));
if (type.equals("positiveInt"))
return new PositiveIntType(Integer.valueOf(source));
if (type.equals("decimal"))
return new DecimalType(new BigDecimal(source));
if (type.equals("base64Binary"))
return new Base64BinaryType(Base64.decode(source.toCharArray()));
if (type.equals("instant"))
return new InstantType(source);
if (type.equals("uri"))
return new UriType(source);
if (type.equals("url"))
return new UrlType(source);
if (type.equals("canonical"))
return new CanonicalType(source);
if (type.equals("date"))
return new DateType(source);
if (type.equals("dateTime"))
return new DateTimeType(source);
if (type.equals("time"))
return new TimeType(source);
if (type.equals("code"))
return new CodeType(source);
if (type.equals("oid"))
return new OidType(source);
if (type.equals("uuid"))
return new UuidType(source);
if (type.equals("id"))
return new IdType(source);
if (type.startsWith("Reference(")) {
Reference r = new Reference();
r.setReference(source);
return r;
}
if (type.equals("Period")) {
if (source.contains("->")) {
String[] parts = source.split("\\-\\>");
Period p = new Period();
p.setStartElement(new DateTimeType(parts[0].trim()));
if (parts.length > 1)
p.setEndElement(new DateTimeType(parts[1].trim()));
return p;
} else
throw new Exception("format not understood parsing " + source + " into a period");
}
if (type.equals("CodeableConcept")) {
CodeableConcept cc = new CodeableConcept();
if (source.contains(":")) {
String[] parts = source.split("\\:");
String system = "";
if (parts[0].equalsIgnoreCase("SCT"))
system = "http://snomed.info/sct";
else if (parts[0].equalsIgnoreCase("LOINC"))
system = "http://loinc.org";
else if (parts[0].equalsIgnoreCase("AMTv2"))
system = "http://nehta.gov.au/amtv2";
else
system = "http://hl7.org/fhir/" + parts[0];
String code = parts[1];
String display = parts.length > 2 ? parts[2] : null;
cc.addCoding().setSystem(system).setCode(code).setDisplay(display);
} else
throw new Exception("format not understood parsing " + source + " into a codeable concept");
return cc;
}
if (type.equals("Identifier")) {
Identifier id = new Identifier();
id.setSystem("urn:ietf:rfc:3986");
id.setValue(source);
return id;
}
if (type.equals("Quantity")) {
int s = 0;
if (source.startsWith("<=") || source.startsWith("=>"))
s = 2;
else if (source.startsWith("<") || source.startsWith(">"))
s = 1;
int i = s;
while (i < source.length() && Character.isDigit(source.charAt(i))) i++;
Quantity q = new Quantity();
if (s > 0)
q.setComparator(QuantityComparator.fromCode(source.substring(0, s)));
if (i > s)
q.setValue(new BigDecimal(source.substring(s, i)));
if (i < source.length())
q.setUnit(source.substring(i).trim());
return q;
}
throw new Exception("Unable to process primitive value '" + source + "' provided for " + column + " - unhandled type " + type + " @ " + getLocation(row));
}
}
use of org.hl7.fhir.utilities.xls.XLSXmlParser.Sheet in project kindling by HL7.
the class OldSpreadsheetParser method parseLogicalModel.
public LogicalModel parseLogicalModel() throws Exception {
ResourceDefn resource = new ResourceDefn();
isLogicalModel = true;
Sheet sheet = loadSheet("Bindings");
if (sheet != null)
readBindings(sheet);
sheet = loadSheet("Invariants");
Map<String, Invariant> invariants = null;
if (sheet != null)
invariants = readInvariants(sheet, title, "Invariants");
sheet = loadSheet("Data Elements");
if (sheet == null)
throw new Exception("No Sheet found for Data Elements");
for (int row = 0; row < sheet.rows.size(); row++) {
processLine(resource, sheet, row, invariants, false, null, row == 0);
}
parseMetadata(resource);
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");
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)");
}
}
}
// EK: Future types. But those won't get there.
if (bindings != null)
resource.getRoot().getNestedBindings().putAll(bindings);
scanNestedTypes(resource, resource.getRoot(), resource.getName());
resolveElementReferences(resource, resource.getRoot());
LogicalModel lm = new LogicalModel();
lm.setResource(resource);
lm.setWg(definitions.getWorkgroups().get("fhir"));
return lm;
}
Aggregations