Add support for choice groups, and markdownify some elements
This commit is contained in:
parent
a964d4fcd5
commit
2adb9a7b68
|
@ -78,6 +78,9 @@ import org.hl7.fhir.r5.model.Enumeration;
|
||||||
import org.hl7.fhir.r5.model.Enumerations.BindingStrength;
|
import org.hl7.fhir.r5.model.Enumerations.BindingStrength;
|
||||||
import org.hl7.fhir.r5.model.Enumerations.FHIRVersion;
|
import org.hl7.fhir.r5.model.Enumerations.FHIRVersion;
|
||||||
import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
|
import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
|
||||||
|
import org.hl7.fhir.r5.model.ExpressionNode;
|
||||||
|
import org.hl7.fhir.r5.model.ExpressionNode.Kind;
|
||||||
|
import org.hl7.fhir.r5.model.ExpressionNode.Operation;
|
||||||
import org.hl7.fhir.r5.model.Extension;
|
import org.hl7.fhir.r5.model.Extension;
|
||||||
import org.hl7.fhir.r5.model.IdType;
|
import org.hl7.fhir.r5.model.IdType;
|
||||||
import org.hl7.fhir.r5.model.IntegerType;
|
import org.hl7.fhir.r5.model.IntegerType;
|
||||||
|
@ -99,6 +102,8 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||||
import org.hl7.fhir.r5.renderers.TerminologyRenderer;
|
import org.hl7.fhir.r5.renderers.TerminologyRenderer;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||||
|
import org.hl7.fhir.r5.utils.FHIRLexer;
|
||||||
|
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
||||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||||
import org.hl7.fhir.r5.utils.TranslatingUtilities;
|
import org.hl7.fhir.r5.utils.TranslatingUtilities;
|
||||||
import org.hl7.fhir.r5.utils.XVerExtensionManager;
|
import org.hl7.fhir.r5.utils.XVerExtensionManager;
|
||||||
|
@ -200,6 +205,30 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ElementChoiceGroup {
|
||||||
|
private Row row;
|
||||||
|
private String name;
|
||||||
|
private boolean mandatory;
|
||||||
|
private List<String> elements = new ArrayList<>();
|
||||||
|
|
||||||
|
public ElementChoiceGroup(String name, boolean mandatory) {
|
||||||
|
super();
|
||||||
|
this.name = name;
|
||||||
|
this.mandatory = mandatory;
|
||||||
|
}
|
||||||
|
public Row getRow() {
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
public List<String> getElements() {
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
public void setRow(Row row) {
|
||||||
|
this.row = row;
|
||||||
|
}
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final int MAX_RECURSION_LIMIT = 10;
|
private static final int MAX_RECURSION_LIMIT = 10;
|
||||||
|
|
||||||
|
@ -268,6 +297,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
|
|
||||||
// note that ProfileUtilities are used re-entrantly internally, so nothing with process state can be here
|
// note that ProfileUtilities are used re-entrantly internally, so nothing with process state can be here
|
||||||
private final IWorkerContext context;
|
private final IWorkerContext context;
|
||||||
|
private FHIRPathEngine fpe;
|
||||||
private List<ValidationMessage> messages;
|
private List<ValidationMessage> messages;
|
||||||
private List<String> snapshotStack = new ArrayList<String>();
|
private List<String> snapshotStack = new ArrayList<String>();
|
||||||
private ProfileKnowledgeProvider pkp;
|
private ProfileKnowledgeProvider pkp;
|
||||||
|
@ -284,6 +314,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.messages = messages;
|
this.messages = messages;
|
||||||
this.pkp = pkp;
|
this.pkp = pkp;
|
||||||
|
if (context != null) {
|
||||||
|
this.fpe = new FHIRPathEngine(context, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class UnusedTracker {
|
public static class UnusedTracker {
|
||||||
|
@ -538,6 +571,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
processPaths("", derived.getSnapshot(), baseSnapshot, diff, baseCursor, diffCursor, baseSnapshot.getElement().size()-1,
|
processPaths("", derived.getSnapshot(), baseSnapshot, diff, baseCursor, diffCursor, baseSnapshot.getElement().size()-1,
|
||||||
derived.getDifferential().hasElement() ? derived.getDifferential().getElement().size()-1 : -1, url, webUrl, derived.present(), null, null, false, base.getUrl(), null, false, null, new ArrayList<ElementRedirection>(), base);
|
derived.getDifferential().hasElement() ? derived.getDifferential().getElement().size()-1 : -1, url, webUrl, derived.present(), null, null, false, base.getUrl(), null, false, null, new ArrayList<ElementRedirection>(), base);
|
||||||
|
checkGroupConstraints(derived);
|
||||||
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
||||||
for (ElementDefinition e : diff.getElement()) {
|
for (ElementDefinition e : diff.getElement()) {
|
||||||
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
|
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
|
||||||
|
@ -666,6 +700,81 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
derived.clearUserData("profileutils.snapshot.generating");
|
derived.clearUserData("profileutils.snapshot.generating");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkGroupConstraints(StructureDefinition derived) {
|
||||||
|
List<ElementDefinition> toRemove = new ArrayList<>();
|
||||||
|
// List<ElementDefinition> processed = new ArrayList<>();
|
||||||
|
for (ElementDefinition element : derived.getSnapshot().getElement()) {
|
||||||
|
if (!toRemove.contains(element) && !element.hasSlicing() && !"0".equals(element.getMax())) {
|
||||||
|
checkForChildrenInGroup(derived, toRemove, element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
derived.getSnapshot().getElement().removeAll(toRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkForChildrenInGroup(StructureDefinition derived, List<ElementDefinition> toRemove, ElementDefinition element) throws Error {
|
||||||
|
List<ElementDefinition> children = getChildren(derived, element);
|
||||||
|
List<ElementChoiceGroup> groups = readChoices(element, children);
|
||||||
|
for (ElementChoiceGroup group : groups) {
|
||||||
|
System.out.println(children);
|
||||||
|
String mandated = null;
|
||||||
|
Set<String> names = new HashSet<>();
|
||||||
|
for (ElementDefinition ed : children) {
|
||||||
|
String name = tail(ed.getPath());
|
||||||
|
if (names.contains(name)) {
|
||||||
|
throw new Error("huh?");
|
||||||
|
} else {
|
||||||
|
names.add(name);
|
||||||
|
}
|
||||||
|
if (group.getElements().contains(name)) {
|
||||||
|
if (ed.getMin() == 1) {
|
||||||
|
if (mandated == null) {
|
||||||
|
mandated = name;
|
||||||
|
} else {
|
||||||
|
throw new Error("Error: there are two mandatory elements in "+derived.getUrl()+" when there can only be one: "+mandated+" and "+name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mandated != null) {
|
||||||
|
for (ElementDefinition ed : children) {
|
||||||
|
String name = tail(ed.getPath());
|
||||||
|
if (group.getElements().contains(name) && !mandated.equals(name)) {
|
||||||
|
ed.setMax("0");
|
||||||
|
addAllChildren(derived, ed, toRemove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ElementDefinition> getChildren(StructureDefinition derived, ElementDefinition element) {
|
||||||
|
List<ElementDefinition> elements = derived.getSnapshot().getElement();
|
||||||
|
int index = elements.indexOf(element) + 1;
|
||||||
|
String path = element.getPath()+".";
|
||||||
|
List<ElementDefinition> list = new ArrayList<>();
|
||||||
|
while (index < elements.size()) {
|
||||||
|
ElementDefinition e = elements.get(index);
|
||||||
|
String p = e.getPath();
|
||||||
|
if (p.startsWith(path) && !e.hasSliceName()) {
|
||||||
|
if (!p.substring(path.length()).contains(".")) {
|
||||||
|
list.add(e);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addAllChildren(StructureDefinition derived, ElementDefinition element, List<ElementDefinition> toRemove) {
|
||||||
|
List<ElementDefinition> children = getChildList(derived, element);
|
||||||
|
for (ElementDefinition child : children) {
|
||||||
|
toRemove.add(child);
|
||||||
|
addAllChildren(derived, child, toRemove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void checkDifferential(List<ElementDefinition> elements, String type, String url) {
|
private void checkDifferential(List<ElementDefinition> elements, String type, String url) {
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (ElementDefinition ed : elements) {
|
for (ElementDefinition ed : elements) {
|
||||||
|
@ -3620,12 +3729,17 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
Row currRow = row;
|
Row currRow = row;
|
||||||
|
List<ElementChoiceGroup> groups = readChoices(element, children);
|
||||||
boolean isExtension = Utilities.existsInList(tail(element.getPath()), "extension", "modifierExtension");
|
boolean isExtension = Utilities.existsInList(tail(element.getPath()), "extension", "modifierExtension");
|
||||||
for (ElementDefinition child : children) {
|
for (ElementDefinition child : children) {
|
||||||
if (!child.hasSliceName())
|
if (!child.hasSliceName()) {
|
||||||
currRow = row;
|
currRow = row;
|
||||||
if (logicalModel || !child.getPath().endsWith(".id") || (child.getPath().endsWith(".id") && (profile != null) && (profile.getDerivation() == TypeDerivationRule.CONSTRAINT)))
|
}
|
||||||
currRow = genElement(defPath, gen, currRow.getSubRows(), child, all, profiles, showMissing, profileBaseFileName, isExtension, snapshot, corePath, imagePath, false, logicalModel, isConstraintMode, allInvariants, currRow, mustSupport);
|
Row childRow = chooseChildRowByGroup(gen, currRow, groups, child, element, isConstraintMode);
|
||||||
|
|
||||||
|
if (logicalModel || !child.getPath().endsWith(".id") || (child.getPath().endsWith(".id") && (profile != null) && (profile.getDerivation() == TypeDerivationRule.CONSTRAINT))) {
|
||||||
|
currRow = genElement(defPath, gen, childRow.getSubRows(), child, all, profiles, showMissing, profileBaseFileName, isExtension, snapshot, corePath, imagePath, false, logicalModel, isConstraintMode, allInvariants, currRow, mustSupport);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// if (!snapshot && (extensions == null || !extensions))
|
// if (!snapshot && (extensions == null || !extensions))
|
||||||
// for (ElementDefinition child : children)
|
// for (ElementDefinition child : children)
|
||||||
|
@ -3639,6 +3753,34 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
return slicingRow;
|
return slicingRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Row chooseChildRowByGroup(HierarchicalTableGenerator gen, Row row, List<ElementChoiceGroup> groups, ElementDefinition element, ElementDefinition parent, boolean isConstraintMode) {
|
||||||
|
String name = tail(element.getPath());
|
||||||
|
for (ElementChoiceGroup grp : groups) {
|
||||||
|
if (grp.getElements().contains(name)) {
|
||||||
|
if (grp.getRow() == null) {
|
||||||
|
grp.setRow(makeChoiceElementRow(gen, row, grp, parent, isConstraintMode));
|
||||||
|
}
|
||||||
|
return grp.getRow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Row makeChoiceElementRow(HierarchicalTableGenerator gen, Row prow, ElementChoiceGroup grp, ElementDefinition parent, boolean isConstraintMode) {
|
||||||
|
Row row = gen.new Row();
|
||||||
|
row.setAnchor(parent.getPath()+"-"+grp.getName());
|
||||||
|
row.setColor(getRowColor(parent, isConstraintMode));
|
||||||
|
row.setLineColor(1);
|
||||||
|
row.setIcon("icon_choice.gif", HierarchicalTableGenerator.TEXT_ICON_CHOICE);
|
||||||
|
row.getCells().add(gen.new Cell(null, null, "(Choice of one)", "", null));
|
||||||
|
row.getCells().add(gen.new Cell());
|
||||||
|
row.getCells().add(gen.new Cell(null, null, (grp.mandatory ? "1" : "0")+"..1", "", null));
|
||||||
|
row.getCells().add(gen.new Cell());
|
||||||
|
row.getCells().add(gen.new Cell());
|
||||||
|
prow.getSubRows().add(row);
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
public Cell genElementNameCell(HierarchicalTableGenerator gen, ElementDefinition element, String profileBaseFileName, boolean snapshot, String corePath,
|
public Cell genElementNameCell(HierarchicalTableGenerator gen, ElementDefinition element, String profileBaseFileName, boolean snapshot, String corePath,
|
||||||
String imagePath, boolean root, boolean logicalModel, boolean allInvariants, StructureDefinition profile, Row typesRow, Row row, boolean hasDef,
|
String imagePath, boolean root, boolean logicalModel, boolean allInvariants, StructureDefinition profile, Row typesRow, Row row, boolean hasDef,
|
||||||
boolean ext, UnusedTracker used, String ref, String sName) throws IOException {
|
boolean ext, UnusedTracker used, String ref, String sName) throws IOException {
|
||||||
|
@ -3985,7 +4127,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
if (root) {
|
if (root) {
|
||||||
if (profile.getAbstract()) {
|
if (profile.getAbstract()) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.addPiece(gen.new Piece(null, "This is an abstract profile", null));
|
c.addPiece(gen.new Piece(null, "This is an abstract profile", null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3993,10 +4135,10 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, "\""+buildJson(definition.getFixed())+"\"", null).addStyle("color: darkgreen")));
|
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, "\""+buildJson(definition.getFixed())+"\"", null).addStyle("color: darkgreen")));
|
||||||
} else {
|
} else {
|
||||||
if (definition != null && definition.hasShort()) {
|
if (definition != null && definition.hasShort()) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.addPiece(checkForNoChange(definition.getShortElement(), gen.new Piece(null, gt(definition.getShortElement()), null)));
|
c.addPiece(checkForNoChange(definition.getShortElement(), gen.new Piece(null, gt(definition.getShortElement()), null)));
|
||||||
} else if (fallback != null && fallback.hasShort()) {
|
} else if (fallback != null && fallback.hasShort()) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.addPiece(gen.new Piece(null, gt(fallback.getShortElement()), null).addStyle("opacity: 0.5"));
|
c.addPiece(gen.new Piece(null, gt(fallback.getShortElement()), null).addStyle("opacity: 0.5"));
|
||||||
}
|
}
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
|
@ -4041,7 +4183,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (definition.hasSlicing()) {
|
if (definition.hasSlicing()) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(gen.new Piece(null, translate("sd.table", "Slice")+": ", null).addStyle("font-weight:bold"));
|
c.getPieces().add(gen.new Piece(null, translate("sd.table", "Slice")+": ", null).addStyle("font-weight:bold"));
|
||||||
c.getPieces().add(gen.new Piece(null, describeSlice(definition.getSlicing()), null));
|
c.getPieces().add(gen.new Piece(null, describeSlice(definition.getSlicing()), null));
|
||||||
}
|
}
|
||||||
|
@ -4095,7 +4237,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (definition.hasFixed()) {
|
if (definition.hasFixed()) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, translate("sd.table", "Fixed Value")+": ", null).addStyle("font-weight:bold")));
|
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, translate("sd.table", "Fixed Value")+": ", null).addStyle("font-weight:bold")));
|
||||||
if (!useTableForFixedValues || definition.getFixed().isPrimitive()) {
|
if (!useTableForFixedValues || definition.getFixed().isPrimitive()) {
|
||||||
String s = buildJson(definition.getFixed());
|
String s = buildJson(definition.getFixed());
|
||||||
|
@ -4113,7 +4255,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
c.getPieces().add(p);
|
c.getPieces().add(p);
|
||||||
}
|
}
|
||||||
} else if (definition.hasPattern()) {
|
} else if (definition.hasPattern()) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, translate("sd.table", "Required Pattern")+": ", null).addStyle("font-weight:bold")));
|
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, translate("sd.table", "Required Pattern")+": ", null).addStyle("font-weight:bold")));
|
||||||
if (!useTableForFixedValues || definition.getPattern().isPrimitive())
|
if (!useTableForFixedValues || definition.getPattern().isPrimitive())
|
||||||
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, buildJson(definition.getPattern()), null).addStyle("color: darkgreen")));
|
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, buildJson(definition.getPattern()), null).addStyle("color: darkgreen")));
|
||||||
|
@ -4123,13 +4265,13 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
} else if (definition.hasExample()) {
|
} else if (definition.hasExample()) {
|
||||||
for (ElementDefinitionExampleComponent ex : definition.getExample()) {
|
for (ElementDefinitionExampleComponent ex : definition.getExample()) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(checkForNoChange(ex, gen.new Piece(null, translate("sd.table", "Example")+("".equals("General")? "" : " "+ex.getLabel())+": ", null).addStyle("font-weight:bold")));
|
c.getPieces().add(checkForNoChange(ex, gen.new Piece(null, translate("sd.table", "Example")+("".equals("General")? "" : " "+ex.getLabel())+": ", null).addStyle("font-weight:bold")));
|
||||||
c.getPieces().add(checkForNoChange(ex, gen.new Piece(null, buildJson(ex.getValue()), null).addStyle("color: darkgreen")));
|
c.getPieces().add(checkForNoChange(ex, gen.new Piece(null, buildJson(ex.getValue()), null).addStyle("color: darkgreen")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (definition.hasMaxLength() && definition.getMaxLength()!=0) {
|
if (definition.hasMaxLength() && definition.getMaxLength()!=0) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(checkForNoChange(definition.getMaxLengthElement(), gen.new Piece(null, "Max Length: ", null).addStyle("font-weight:bold")));
|
c.getPieces().add(checkForNoChange(definition.getMaxLengthElement(), gen.new Piece(null, "Max Length: ", null).addStyle("font-weight:bold")));
|
||||||
c.getPieces().add(checkForNoChange(definition.getMaxLengthElement(), gen.new Piece(null, Integer.toString(definition.getMaxLength()), null).addStyle("color: darkgreen")));
|
c.getPieces().add(checkForNoChange(definition.getMaxLengthElement(), gen.new Piece(null, Integer.toString(definition.getMaxLength()), null).addStyle("color: darkgreen")));
|
||||||
}
|
}
|
||||||
|
@ -4367,7 +4509,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (definition.hasSlicing()) {
|
if (definition.hasSlicing()) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(gen.new Piece(null, "Slice: ", null).addStyle("font-weight:bold"));
|
c.getPieces().add(gen.new Piece(null, "Slice: ", null).addStyle("font-weight:bold"));
|
||||||
c.getPieces().add(gen.new Piece(null, describeSlice(definition.getSlicing()), null));
|
c.getPieces().add(gen.new Piece(null, describeSlice(definition.getSlicing()), null));
|
||||||
}
|
}
|
||||||
|
@ -4389,12 +4531,16 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ElementDefinitionConstraintComponent inv : definition.getConstraint()) {
|
for (ElementDefinitionConstraintComponent inv : definition.getConstraint()) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(checkForNoChange(inv, gen.new Piece(null, inv.getKey()+": ", null).addStyle("font-weight:bold")));
|
c.getPieces().add(checkForNoChange(inv, gen.new Piece(null, inv.getKey()+": ", null).addStyle("font-weight:bold")));
|
||||||
|
if (inv.getHumanElement().hasExtension("http://hl7.org/fhir/StructureDefinition/rendering-markdown")) {
|
||||||
|
c.addMarkdown(inv.getHumanElement().getExtensionString("http://hl7.org/fhir/StructureDefinition/rendering-markdown"));
|
||||||
|
} else {
|
||||||
c.getPieces().add(checkForNoChange(inv, gen.new Piece(null, inv.getHuman(), null)));
|
c.getPieces().add(checkForNoChange(inv, gen.new Piece(null, inv.getHuman(), null)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (definition.hasFixed()) {
|
if (definition.hasFixed()) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, "Fixed Value: ", null).addStyle("font-weight:bold")));
|
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, "Fixed Value: ", null).addStyle("font-weight:bold")));
|
||||||
String s = buildJson(definition.getFixed());
|
String s = buildJson(definition.getFixed());
|
||||||
String link = null;
|
String link = null;
|
||||||
|
@ -4402,18 +4548,18 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
link = pkp.getLinkForUrl(corePath, s);
|
link = pkp.getLinkForUrl(corePath, s);
|
||||||
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(link, s, null).addStyle("color: darkgreen")));
|
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(link, s, null).addStyle("color: darkgreen")));
|
||||||
} else if (definition.hasPattern()) {
|
} else if (definition.hasPattern()) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, "Required Pattern: ", null).addStyle("font-weight:bold")));
|
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, "Required Pattern: ", null).addStyle("font-weight:bold")));
|
||||||
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, buildJson(definition.getPattern()), null).addStyle("color: darkgreen")));
|
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, buildJson(definition.getPattern()), null).addStyle("color: darkgreen")));
|
||||||
} else if (definition.hasExample()) {
|
} else if (definition.hasExample()) {
|
||||||
for (ElementDefinitionExampleComponent ex : definition.getExample()) {
|
for (ElementDefinitionExampleComponent ex : definition.getExample()) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(checkForNoChange(ex, gen.new Piece(null, "Example'"+("".equals("General")? "" : " "+ex.getLabel()+"'")+": ", null).addStyle("font-weight:bold")));
|
c.getPieces().add(checkForNoChange(ex, gen.new Piece(null, "Example'"+("".equals("General")? "" : " "+ex.getLabel()+"'")+": ", null).addStyle("font-weight:bold")));
|
||||||
c.getPieces().add(checkForNoChange(ex, gen.new Piece(null, buildJson(ex.getValue()), null).addStyle("color: darkgreen")));
|
c.getPieces().add(checkForNoChange(ex, gen.new Piece(null, buildJson(ex.getValue()), null).addStyle("color: darkgreen")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (definition.hasMaxLength() && definition.getMaxLength()!=0) {
|
if (definition.hasMaxLength() && definition.getMaxLength()!=0) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(checkForNoChange(definition.getMaxLengthElement(), gen.new Piece(null, "Max Length: ", null).addStyle("font-weight:bold")));
|
c.getPieces().add(checkForNoChange(definition.getMaxLengthElement(), gen.new Piece(null, "Max Length: ", null).addStyle("font-weight:bold")));
|
||||||
c.getPieces().add(checkForNoChange(definition.getMaxLengthElement(), gen.new Piece(null, Integer.toString(definition.getMaxLength()), null).addStyle("color: darkgreen")));
|
c.getPieces().add(checkForNoChange(definition.getMaxLengthElement(), gen.new Piece(null, Integer.toString(definition.getMaxLength()), null).addStyle("color: darkgreen")));
|
||||||
}
|
}
|
||||||
|
@ -4434,14 +4580,14 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (definition.hasDefinition()) {
|
if (definition.hasDefinition()) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(gen.new Piece(null, "Definition: ", null).addStyle("font-weight:bold"));
|
c.getPieces().add(gen.new Piece(null, "Definition: ", null).addStyle("font-weight:bold"));
|
||||||
c.addPiece(gen.new Piece("br"));
|
c.addPiece(gen.new Piece("br"));
|
||||||
c.addMarkdown(definition.getDefinition());
|
c.addMarkdown(definition.getDefinition());
|
||||||
// c.getPieces().add(checkForNoChange(definition.getCommentElement(), gen.new Piece(null, definition.getComment(), null)));
|
// c.getPieces().add(checkForNoChange(definition.getCommentElement(), gen.new Piece(null, definition.getComment(), null)));
|
||||||
}
|
}
|
||||||
if (definition.getComment()!=null) {
|
if (definition.getComment()!=null) {
|
||||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(gen.new Piece(null, "Comments: ", null).addStyle("font-weight:bold"));
|
c.getPieces().add(gen.new Piece(null, "Comments: ", null).addStyle("font-weight:bold"));
|
||||||
c.addPiece(gen.new Piece("br"));
|
c.addPiece(gen.new Piece("br"));
|
||||||
c.addMarkdown(definition.getComment());
|
c.addMarkdown(definition.getComment());
|
||||||
|
@ -5935,6 +6081,64 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<ElementChoiceGroup> readChoices(ElementDefinition ed, List<ElementDefinition> children) {
|
||||||
|
List<ElementChoiceGroup> result = new ArrayList<>();
|
||||||
|
for (ElementDefinitionConstraintComponent c : ed.getConstraint()) {
|
||||||
|
ElementChoiceGroup grp = processConstraint(children, c);
|
||||||
|
if (grp != null) {
|
||||||
|
result.add(grp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ElementChoiceGroup processConstraint(List<ElementDefinition> children, ElementDefinitionConstraintComponent c) {
|
||||||
|
if (!c.hasExpression()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ExpressionNode expr = fpe.parse(c.getExpression());
|
||||||
|
if (expr.getKind() != Kind.Group || expr.getOpNext() == null || !(expr.getOperation() == Operation.Equals || expr.getOperation() == Operation.LessOrEqual)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ExpressionNode n1 = expr.getGroup();
|
||||||
|
ExpressionNode n2 = expr.getOpNext();
|
||||||
|
if (n2.getKind() != Kind.Constant || n2.getInner() != null || n2.getOpNext() != null || !"1".equals(n2.getConstant().primitiveValue())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ElementChoiceGroup grp = new ElementChoiceGroup(c.getKey(), expr.getOperation() == Operation.Equals);
|
||||||
|
while (n1 != null) {
|
||||||
|
if (n1.getKind() != Kind.Name || n1.getInner() != null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
grp.elements.add(n1.getName());
|
||||||
|
if (n1.getOperation() == null || n1.getOperation() == Operation.Union) {
|
||||||
|
n1 = n1.getOpNext();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int total = 0;
|
||||||
|
for (String n : grp.elements) {
|
||||||
|
boolean found = false;
|
||||||
|
for (ElementDefinition child : children) {
|
||||||
|
String name = tail(child.getPath());
|
||||||
|
if (n.equals(name)) {
|
||||||
|
found = true;
|
||||||
|
if (!"0".equals(child.getMax())) {
|
||||||
|
total++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (total <= 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return grp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -319,6 +319,20 @@ public class FHIRPathEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FHIRPathEngine(IWorkerContext worker, ProfileUtilities utilities) {
|
||||||
|
super();
|
||||||
|
this.worker = worker;
|
||||||
|
profileUtilities = utilities;
|
||||||
|
for (StructureDefinition sd : worker.getStructures()) {
|
||||||
|
if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION && sd.getKind() != StructureDefinitionKind.LOGICAL) {
|
||||||
|
allTypes.put(sd.getName(), sd);
|
||||||
|
}
|
||||||
|
if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE) {
|
||||||
|
primitiveTypes.add(sd.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// --- 3 methods to override in children -------------------------------------------------------
|
// --- 3 methods to override in children -------------------------------------------------------
|
||||||
// if you don't override, it falls through to the using the base reference implementation
|
// if you don't override, it falls through to the using the base reference implementation
|
||||||
|
|
Loading…
Reference in New Issue