use of org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent in project kindling by HL7.
the class PageProcessor method getInvariantList.
private String getInvariantList(StructureDefinition profile) throws FHIRException, Exception {
List<String> txlist = new ArrayList<String>();
Map<String, List<ElementDefinitionConstraintComponent>> txmap = new HashMap<String, List<ElementDefinitionConstraintComponent>>();
for (ElementDefinition ed : profile.getSnapshot().getElement()) {
if (!"0".equals(ed.getMax())) {
List<ElementDefinitionConstraintComponent> list = new ArrayList<ElementDefinition.ElementDefinitionConstraintComponent>();
for (ElementDefinitionConstraintComponent t : ed.getConstraint()) {
if (!t.hasSource() || t.getSource().equals(profile.getUrl())) {
list.add(t);
}
}
if (!list.isEmpty()) {
txlist.add(ed.getPath());
txmap.put(ed.getPath(), list);
}
}
}
if (txlist.isEmpty())
return "";
else {
StringBuilder b = new StringBuilder();
b.append("<h4>Constraints</h4>\r\n");
b.append("<table class=\"list\">\r\n");
b.append("<tr><td width=\"60\"><b>Id</b></td><td><b>Path</b></td><td><b>Details</b></td><td><b>Requirements</b></td></tr>\r\n");
for (String path : txlist) {
List<ElementDefinitionConstraintComponent> invs = txmap.get(path);
for (ElementDefinitionConstraintComponent inv : invs) {
b.append("<tr>" + presentLevel(inv) + " <td>").append(inv.getKey()).append("</td><td>").append(path).append("</td><td>").append(Utilities.escapeXml(inv.getHuman())).append("<br/><a href=\"http://hl7.org/fhirpath\">Expression</a>: ").append(Utilities.escapeXml(inv.getExpression())).append("</td><td>").append(Utilities.escapeXml(inv.getRequirements()));
if (inv.hasExtension(ToolingExtensions.EXT_BEST_PRACTICE_EXPLANATION))
b.append(". This is (only) a best practice guideline because: <blockquote>" + processMarkdown("best practice guideline", inv.getExtensionString(ToolingExtensions.EXT_BEST_PRACTICE_EXPLANATION), "") + "</blockquote>");
b.append("</td></tr>\r\n");
}
}
b.append("</table>\r\n");
return b.toString();
}
}
use of org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent in project kindling by HL7.
the class ResourceParser method parseED.
private void parseED(ProfileUtilities pu, ElementDefn ed, ElementDefinition focus, StructureDefinition sd, String parentName) throws IOException {
ed.setMinCardinality(focus.getMin());
ed.setMaxCardinality("*".equals(focus.getMax()) ? Integer.MAX_VALUE : Integer.parseInt(focus.getMax()));
ed.setIsModifier(focus.getIsModifier());
ed.setModifierReason(focus.getIsModifierReason());
ed.setMustSupport(focus.getMustSupport());
ed.setSummaryItem(focus.getIsSummary());
ed.setRegex(ToolingExtensions.readStringExtension(focus, ToolingExtensions.EXT_REGEX));
ed.setXmlAttribute(focus.hasRepresentation(PropertyRepresentation.XMLATTR));
if (ToolingExtensions.hasExtension(focus, BuildExtensions.EXT_UML_DIR)) {
ed.setUmlDir(ToolingExtensions.readStringExtension(focus, BuildExtensions.EXT_UML_DIR));
}
if (ToolingExtensions.hasExtension(focus, BuildExtensions.EXT_UML_BREAK)) {
ed.setUmlBreak(ToolingExtensions.readBoolExtension(focus, BuildExtensions.EXT_UML_BREAK));
}
if (BuildExtensions.hasExtension(focus, BuildExtensions.EXT_SVG)) {
String svg = BuildExtensions.readStringExtension(focus, BuildExtensions.EXT_SVG);
if (svg.contains("w=")) {
ed.setSvgWidth(Integer.parseInt(svg.substring(svg.indexOf("w=") + 2)));
svg = svg.substring(0, svg.indexOf(";"));
}
ed.setSvgLeft(Integer.parseInt(svg.substring(0, svg.indexOf(","))));
ed.setSvgTop(Integer.parseInt(svg.substring(svg.indexOf(",") + 1)));
}
ed.setName(tail(focus.getPath()));
ed.setShortDefn(focus.getShort());
ed.setDefinition(focus.getDefinition());
ed.setRequirements(focus.getRequirements());
ed.setComments(focus.getComment());
if (BuildExtensions.hasExtension(focus, BuildExtensions.EXT_TODO)) {
ed.setTodo(BuildExtensions.readStringExtension(focus, BuildExtensions.EXT_TODO));
}
if (BuildExtensions.hasExtension(focus, BuildExtensions.EXT_COMMITTEE_NOTES)) {
ed.setCommitteeNotes(BuildExtensions.readStringExtension(focus, BuildExtensions.EXT_COMMITTEE_NOTES));
}
if (BuildExtensions.hasExtension(focus, BuildExtensions.EXT_HINT)) {
ed.setDisplayHint(BuildExtensions.readStringExtension(focus, BuildExtensions.EXT_HINT));
}
if (focus.hasExtension(BuildExtensions.EXT_NO_BINDING)) {
ed.setNoBindingAllowed(focus.getExtensionString(BuildExtensions.EXT_NO_BINDING).equals("true"));
}
for (StringType t : focus.getAlias()) {
ed.getAliases().add(t.getValue());
}
if (focus.hasMaxLength()) {
ed.setMaxLength(Integer.toString(focus.getMaxLength()));
}
ed.setExample(focus.getExampleFirstRep().getValue());
ed.setMeaningWhenMissing(focus.getMeaningWhenMissing());
if (ToolingExtensions.hasExtension(focus, BuildExtensions.EXT_TRANSLATABLE)) {
ed.setTranslatable(ToolingExtensions.readBoolExtension(focus, BuildExtensions.EXT_TRANSLATABLE));
}
ed.setOrderMeaning(focus.getOrderMeaning());
if (BuildExtensions.hasExtension(focus, BuildExtensions.EXT_STANDARDS_STATUS)) {
ed.setStandardsStatus(StandardsStatus.fromCode(BuildExtensions.readStringExtension(focus, BuildExtensions.EXT_STANDARDS_STATUS)));
}
if (BuildExtensions.hasExtension(focus, BuildExtensions.EXT_NORMATIVE_VERSION)) {
ed.setNormativeVersion(BuildExtensions.readStringExtension(focus, BuildExtensions.EXT_NORMATIVE_VERSION));
}
for (ElementDefinitionConstraintComponent cst : focus.getConstraint()) {
Invariant inv = new Invariant();
inv.setContext(focus.getPath());
inv.setEnglish(cst.getHuman());
if (cst.hasExtension(BuildExtensions.EXT_OCL)) {
inv.setOcl(cst.getExtensionString(BuildExtensions.EXT_OCL));
}
inv.setXpath(cst.getXpath());
inv.setId(cst.getKey());
if (cst.hasExtension(BuildExtensions.EXT_FIXED_NAME)) {
inv.setFixedName(cst.getExtensionString(BuildExtensions.EXT_FIXED_NAME));
}
inv.setSeverity(cst.getSeverity().toCode());
if (cst.hasExtension(BuildExtensions.EXT_BEST_PRACTICE)) {
inv.setSeverity("best-practice");
}
if (cst.hasExtension(BuildExtensions.EXT_TURTLE)) {
inv.setTurtle(cst.getExtensionString(BuildExtensions.EXT_TURTLE));
}
inv.setRequirements(cst.getRequirements());
inv.setExpression(cst.getExpression());
if (cst.hasExtension(BuildExtensions.EXT_BEST_PRACTICE_EXPLANATION)) {
inv.setExplanation(cst.getExtensionString(BuildExtensions.EXT_BEST_PRACTICE_EXPLANATION));
}
ed.getInvariants().put(inv.getId(), inv);
invariants.put(inv.getId(), inv);
}
for (IdType cnd : focus.getCondition()) {
Invariant inv = invariants.get(cnd.primitiveValue());
if (inv == null) {
System.out.println("Unable to find invariant " + cnd.primitiveValue());
} else {
ed.getStatedInvariants().add(inv);
}
}
for (ElementDefinitionMappingComponent map : focus.getMapping()) {
String uri = getMappingUri(sd, map.getIdentity());
if ("http://hl7.org/fhir/fivews".equals(uri)) {
ed.setW5(reverseW5(map.getMap()));
} else {
ed.getMappings().put(uri, map.getMap());
}
}
if (focus.hasContentReference()) {
ed.getTypes().add(new TypeRef("@" + focus.getContentReference().substring(1)));
} else {
for (TypeRefComponent tr : focus.getType()) {
if (!Utilities.existsInList(tr.getCode(), "Element", "BackboneElement")) {
TypeRef t = new TypeRef();
ed.getTypes().add(t);
if (tr.hasExtension("http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type")) {
t.setName(tr.getExtensionString("http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type"));
} else {
t.setName(tr.getCode());
}
if (ToolingExtensions.hasExtension(tr, BuildExtensions.EXT_HIERARCHY)) {
ed.setHierarchy(ToolingExtensions.readBoolExtension(tr, BuildExtensions.EXT_HIERARCHY));
}
for (CanonicalType u : tr.getProfile()) {
t.setProfile(u.getValue().replace("http://hl7.org/fhir/StructureDefinition/", ""));
}
for (CanonicalType u : tr.getTargetProfile()) {
String s = u.getValue().replace("http://hl7.org/fhir/StructureDefinition/", "");
if ("Resource".equals(s)) {
t.getParams().add("Any");
} else {
t.getParams().add(s);
}
}
if (t.getName().equals("Quantity") && "SimpleQuantity".equals(t.getProfile())) {
t.setName("SimpleQuantity");
t.setProfile(null);
}
if ("Resource".equals(t.getProfile())) {
t.setProfile("Any");
}
if (t.getParams().toString().equals("[ActivityDefinition, EventDefinition, EvidenceVariable, Measure, OperationDefinition, PlanDefinition, Questionnaire, SubscriptionTopic]")) {
t.getParams().clear();
t.getParams().add("Definition");
}
}
}
if (ed.getTypes().size() == STAR_TYPES_COUNT) {
ed.getTypes().clear();
ed.getTypes().add(new TypeRef("*"));
}
}
String name = parentName + Utilities.capitalize(ed.getName());
if (focus.hasExtension("http://hl7.org/fhir/StructureDefinition/structuredefinition-explicit-type-name")) {
ed.setStatedType(focus.getExtensionString("http://hl7.org/fhir/StructureDefinition/structuredefinition-explicit-type-name"));
ed.setDeclaredTypeName(ed.getStatedType());
} else if (ed.getTypes().isEmpty() && !focus.hasContentReference()) {
ed.setDeclaredTypeName(name + "Component");
}
if (focus.hasBinding()) {
ed.setBinding(parseBinding(focus.getBinding()));
}
for (ElementDefinition child : pu.getChildList(sd, focus, true, false)) {
ElementDefn c = new ElementDefn();
ed.getElements().add(c);
parseED(pu, c, child, sd, name);
}
// todo:
// private ElementDefinition derivation;
}
use of org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent in project kindling by HL7.
the class ProfileGenerator method convertElements.
public void convertElements(ElementDefn src, StructureDefinition ed, String path) throws Exception {
ElementDefinition dst = new ElementDefinition();
if (!ed.hasDifferential())
ed.setDifferential(new StructureDefinitionDifferentialComponent());
ed.getDifferential().getElement().add(dst);
String thisPath = path == null ? "Extension" : path;
dst.setId(thisPath);
dst.setPath(thisPath);
if (!Utilities.noString(src.getProfileName()))
dst.setSliceName(src.getProfileName());
dst.setShort(src.getShortDefn());
dst.setDefinition(preProcessMarkdown(src.getDefinition(), "Element Definition"));
dst.setComment(preProcessMarkdown(src.getComments(), "Element Comments"));
if (src.getMaxCardinality() != null) {
if (src.getMaxCardinality() == Integer.MAX_VALUE)
dst.setMax("*");
else
dst.setMax(src.getMaxCardinality().toString());
}
if (src.getMinCardinality() != null)
dst.setMin(src.getMinCardinality());
if (src.getFixed() != null)
dst.setFixed(src.getFixed());
if (src.hasMustSupport())
dst.setMustSupport(src.isMustSupport());
if (src.hasModifier())
dst.setIsModifier(src.isModifier());
if (dst.getIsModifier())
dst.setIsModifierReason(src.getModifierReason());
if (src.hasSummaryItem() && dst.getPath().contains("."))
dst.setIsSummaryElement(Factory.newBoolean(src.isSummary()));
for (Invariant id : src.getStatedInvariants()) dst.addCondition(id.getId());
// dDst.
for (TypeRef t : src.getTypes()) {
if (t.hasParams()) {
for (String tp : t.getParams()) {
if (definitions.hasLogicalModel(tp)) {
for (String tpn : definitions.getLogicalModel(tp).getImplementations()) {
ElementDefinition.TypeRefComponent type = dst.getType(t.getName());
String pr = "http://hl7.org/fhir/StructureDefinition/" + tpn;
type.addTargetProfile(pr);
}
} else {
ElementDefinition.TypeRefComponent type = dst.getType(t.getName());
String pr = t.hasProfile() ? t.getProfile() : // this should only happen if t.getParams().size() == 1
"http://hl7.org/fhir/StructureDefinition/" + (tp.equals("Any") ? "Resource" : tp);
if (type.getWorkingCode().equals("Reference") || type.getWorkingCode().equals("canonical") || type.getWorkingCode().equals("CodeableReference"))
type.addTargetProfile(pr);
else
type.addProfile(pr);
}
}
} else if (t.isWildcardType()) {
for (String n : TypesUtilities.wildcardTypes(version.toString())) dst.getType(n);
} else {
if (definitions != null && definitions.getConstraints().containsKey(t.getName())) {
ProfiledType ct = definitions.getConstraints().get(t.getName());
ElementDefinition.TypeRefComponent type = dst.getType(ct.getBaseType());
type.addProfile("http://hl7.org/fhir/StructureDefinition/" + ct.getName());
} else if ("Extension.url".equals(path)) {
// juat don't populate it
// ElementDefinition.TypeRefComponent tt = dst.addType();
// tt.setCodeElement(new UriType());
// tt.getFormatCommentsPre().add("Note: special primitive values do not have an assigned type. e.g. this is compiler magic. XML, JSON and RDF types provided by extension");
// ToolingExtensions.addStringExtension(tt.getCodeElement(), ToolingExtensions.EXT_JSON_TYPE, "string");
// ToolingExtensions.addStringExtension(tt.getCodeElement(), ToolingExtensions.EXT_XML_TYPE, "xs:anyURI");
// ToolingExtensions.addStringExtension(tt.getCodeElement(), ToolingExtensions.EXT_RDF_TYPE, "xs:anyURI");
} else {
ElementDefinition.TypeRefComponent type = dst.getType(t.getName());
if (t.hasProfile())
if (type.getWorkingCode().equals("Reference") || type.getWorkingCode().equals("CodeableReference"))
type.addTargetProfile(t.getProfile());
else
type.addProfile(t.getProfile());
}
}
}
if (definitions != null) {
// igtodo - catch this
for (String mu : definitions.getMapTypes().keySet()) {
if (src.hasMapping(mu)) {
addMapping(ed, dst, mu, src.getMapping(mu), null);
}
}
}
for (String in : src.getInvariants().keySet()) {
ElementDefinitionConstraintComponent con = new ElementDefinitionConstraintComponent();
Invariant inv = src.getInvariants().get(in);
con.setKey(inv.getId());
if (!con.hasKey()) {
extensionCounter++;
con.setKey("exd-" + Integer.toString(extensionCounter));
}
con.setRequirements(inv.getRequirements());
if (Utilities.noString(inv.getSeverity()))
con.setSeverity(ConstraintSeverity.ERROR);
else
con.setSeverity(ConstraintSeverity.fromCode(inv.getSeverity()));
con.setHuman(inv.getEnglish());
con.setXpath(inv.getXpath());
if (!"n/a".equals(inv.getExpression()))
con.setExpression(inv.getExpression());
dst.getConstraint().add(con);
}
if (src.hasBinding())
dst.setBinding(generateBinding(src.getBinding()));
if (src.getElements().isEmpty()) {
if (path == null)
throw new Exception("?error parsing extension");
} else {
ElementDefn url = src.getElements().get(0);
if (!url.getName().equals("url"))
throw new Exception("first child of extension should be 'url', not " + url.getName() + " for structure definition " + ed.getUrl());
convertElements(url, ed, thisPath + ".url");
// this pair might leave elements out of order, but we're going to sort them later
if (!hasValue(src)) {
ElementDefn value = new ElementDefn();
value.setName("value[x]");
value.setMinCardinality(0);
value.setMaxCardinality(0);
convertElements(value, ed, thisPath + ".value[x]");
} else {
ElementDefn ext = new ElementDefn();
// can't have an extension if you have a value
ext.setName("extension");
ext.setMaxCardinality(0);
convertElements(ext, ed, thisPath + ".extension");
}
if (src.getElements().size() == 2 && src.getElements().get(0).getName().equals("url") && src.getElements().get(1).getName().equals("value[x]")) {
ElementDefn value = src.getElements().get(1);
value.setMinCardinality(1);
convertElements(value, ed, thisPath + ".value[x]");
} else {
for (ElementDefn child : src.getElements()) {
if (child != url) {
if (child.getName().startsWith("value") && !child.getName().startsWith("valueSet"))
convertElements(child, ed, thisPath + "." + child.getName());
else {
if (child.getElements().size() == 0 || !child.getElements().get(0).getName().equals("url")) {
ElementDefn childUrl = new ElementDefn();
childUrl.setName("url");
childUrl.setXmlAttribute(true);
childUrl.getTypes().add(new TypeRef("uri"));
childUrl.setFixed(new UriType(child.getName()));
child.getElements().add(0, childUrl);
}
if (!hasValue(child)) {
ElementDefn value = new ElementDefn();
value.setName("value[x]");
value.setMinCardinality(0);
value.setMaxCardinality(0);
child.getElements().add(value);
}
convertElements(child, ed, thisPath + ".extension");
}
}
}
}
}
}
use of org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent in project kindling by HL7.
the class ProfileGenerator method addExtensionConstraint.
private ElementDefinition addExtensionConstraint(StructureDefinition sd, ElementDefinition ed) {
if (!typeIsExtension(ed))
return ed;
if (hasConstraint(ed, "ext-1"))
return ed;
ElementDefinitionConstraintComponent inv = ed.addConstraint();
inv.setKey("ext-1");
inv.setSeverity(ConstraintSeverity.ERROR);
inv.setHuman("Must have either extensions or value[x], not both");
inv.setExpression("extension.exists() != value.exists()");
inv.setXpath("exists(f:extension)!=exists(f:*[starts-with(local-name(.), \"value\")])");
inv.setSource("http://hl7.org/fhir/StructureDefinition/Extension");
return ed;
}
use of org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent in project kindling by HL7.
the class ProfileGenerator method generate.
public StructureDefinition generate(ProfiledType pt, List<ValidationMessage> issues) throws Exception {
StructureDefinition p = new StructureDefinition();
p.setId(pt.getName());
p.setUrl("http://hl7.org/fhir/StructureDefinition/" + pt.getName());
p.setBaseDefinition("http://hl7.org/fhir/StructureDefinition/" + pt.getBaseType());
p.setKind(StructureDefinitionKind.COMPLEXTYPE);
p.setType(pt.getBaseType());
p.setDerivation(TypeDerivationRule.CONSTRAINT);
p.setAbstract(false);
p.setUserData("filename", pt.getName().toLowerCase());
p.setUserData("path", "datatypes.html#" + pt.getName());
p.setFhirVersion(version);
p.setVersion(version.toCode());
ToolingExtensions.setStandardsStatus(p, StandardsStatus.NORMATIVE, "4.0.0");
p.setStatus(PublicationStatus.fromCode("active"));
ToolResourceUtilities.updateUsage(p, "core");
p.setName(pt.getName());
p.setPublisher("HL7 FHIR Standard");
p.addContact().getTelecom().add(Factory.newContactPoint(ContactPointSystem.URL, "http://hl7.org/fhir"));
p.setDescription("Base StructureDefinition for Type " + pt.getName() + ": " + pt.getDefinition());
p.setDescription(pt.getDefinition());
p.setDate(genDate.getTime());
// first, the differential
p.setName(pt.getName());
ElementDefinition e = new ElementDefinition();
String idroot = e.getId();
e.setPath(pt.getBaseType());
// e.setSliceName(pt.getName());
e.setShort(pt.getDefinition());
e.setDefinition(preProcessMarkdown(pt.getDescription(), "??"));
e.setMin(0);
e.setMax("*");
e.setIsModifier(false);
String s = definitions.getTLAs().get(pt.getName().toLowerCase());
if (s == null)
throw new Exception("There is no TLA for '" + pt.getName() + "' in fhir.ini");
ElementDefinitionConstraintComponent inv = new ElementDefinitionConstraintComponent();
inv.setKey(s + "-1");
inv.setRequirements(pt.getInvariant().getRequirements());
inv.setSeverity(ConstraintSeverity.ERROR);
inv.setHuman(pt.getInvariant().getEnglish());
if (!"n/a".equals(pt.getInvariant().getExpression())) {
fpUsages.add(new FHIRPathUsage(pt.getName(), pt.getName(), pt.getName(), null, pt.getInvariant().getExpression()));
inv.setExpression(pt.getInvariant().getExpression());
}
inv.setXpath(pt.getInvariant().getXpath());
e.getConstraint().add(inv);
p.setDifferential(new StructureDefinitionDifferentialComponent());
p.getDifferential().getElement().add(e);
StructureDefinition base = getTypeSnapshot(pt.getBaseType());
if (!pt.getRules().isEmpty()) {
// throw new Exception("todo");
for (String rule : pt.getRules().keySet()) {
String[] parts = rule.split("\\.");
String value = pt.getRules().get(rule);
ElementDefinition er = findElement(p.getDifferential(), pt.getBaseType() + '.' + parts[0]);
if (er == null) {
er = new ElementDefinition();
er.setId(pt.getBaseType() + ':' + p.getId() + '.' + parts[0]);
er.setPath(pt.getBaseType() + '.' + parts[0]);
p.getDifferential().getElement().add(er);
}
if (parts[1].equals("min"))
er.setMin(Integer.parseInt(value));
else if (parts[1].equals("max"))
er.setMax(value);
else if (parts[1].equals("defn"))
er.setDefinition(preProcessMarkdown(value, "er"));
}
List<String> errors = new ArrayList<String>();
new ProfileUtilities(context, null, pkp).sortDifferential(base, p, p.getName(), errors, true);
for (String se : errors) issues.add(new ValidationMessage(Source.ProfileValidator, IssueType.STRUCTURE, -1, -1, p.getUrl(), se, IssueSeverity.WARNING));
}
reset();
// now, the snapshot
new ProfileUtilities(context, issues, pkp).generateSnapshot(base, p, "http://hl7.org/fhir/StructureDefinition/" + pt.getBaseType(), "http://hl7.org/fhir", p.getName());
// for (ElementDefinition ed : p.getSnapshot().getElement())
// generateElementDefinition(ed, getParent(ed, p.getSnapshot().getElement()));
p.getDifferential().getElement().get(0).getType().clear();
p.getSnapshot().getElement().get(0).getType().clear();
XhtmlNode div = new XhtmlNode(NodeType.Element, "div");
div.addTag("h2").addText("Data type " + pt.getName());
div.addTag("p").addText(pt.getDefinition());
div.addTag("h3").addText("Rule");
div.addTag("p").addText(pt.getInvariant().getEnglish());
div.addTag("p").addText("XPath:");
div.addTag("blockquote").addTag("pre").addText(pt.getInvariant().getXpath());
p.setText(new Narrative());
p.getText().setStatus(NarrativeStatus.GENERATED);
p.getText().setDiv(div);
addElementConstraintToSnapshot(p);
new ProfileUtilities(context, issues, pkp).setIds(p, false);
checkHasTypes(p);
return p;
}
Aggregations