Merge pull request #976 from hapifhir/gg-202211-logicals
Gg 202211 logicals
This commit is contained in:
commit
23db785dc3
|
@ -691,7 +691,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
derived.setSnapshot(new StructureDefinitionSnapshotComponent());
|
||||
|
||||
try {
|
||||
checkDifferential(derived.getDifferential().getElement(), typeName(derived.getType()), derived.getUrl());
|
||||
checkDifferential(derived.getDifferential().getElement(), derived.getTypeName(), derived.getUrl());
|
||||
checkDifferentialBaseType(derived);
|
||||
|
||||
copyInheritedExtensions(base, derived);
|
||||
|
@ -712,11 +712,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
StructureDefinitionDifferentialComponent diff = cloneDiff(derived.getDifferential()); // we make a copy here because we're sometimes going to hack the differential while processing it. Have to migrate user data back afterwards
|
||||
StructureDefinitionSnapshotComponent baseSnapshot = base.getSnapshot();
|
||||
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
||||
String derivedType = derived.getType();
|
||||
if (StructureDefinitionKind.LOGICAL.equals(derived.getKind()) && derived.getType().contains("/")) {
|
||||
derivedType = derivedType.substring(derivedType.lastIndexOf("/")+1);
|
||||
}
|
||||
baseSnapshot = cloneSnapshot(baseSnapshot, base.getType(), derivedType);
|
||||
String derivedType = derived.getTypeName();
|
||||
|
||||
baseSnapshot = cloneSnapshot(baseSnapshot, base.getTypeName(), derivedType);
|
||||
}
|
||||
// if (derived.getId().equals("2.16.840.1.113883.10.20.22.2.1.1")) {
|
||||
// debug = true;
|
||||
|
@ -726,7 +724,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
checkGroupConstraints(derived);
|
||||
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
||||
for (ElementDefinition e : diff.getElement()) {
|
||||
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
|
||||
if (!e.hasUserData(GENERATED_IN_SNAPSHOT) && e.getPath().contains(".")) {
|
||||
ElementDefinition outcome = updateURLs(url, webUrl, e.copy());
|
||||
e.setUserData(GENERATED_IN_SNAPSHOT, outcome);
|
||||
derived.getSnapshot().addElement(outcome);
|
||||
|
@ -878,11 +876,11 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
private void addInheritedElementsForSpecialization(StructureDefinitionSnapshotComponent snapshot, ElementDefinition focus, String type, String path, String url, String weburl) {
|
||||
StructureDefinition sd = context.fetchTypeDefinition(type);
|
||||
if (sd != null) {
|
||||
addInheritedElementsForSpecialization(snapshot, focus, sd.getBaseDefinition(), path, url, weburl);
|
||||
// don't do this. should already be in snapshot ... addInheritedElementsForSpecialization(snapshot, focus, sd.getBaseDefinition(), path, url, weburl);
|
||||
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||
if (ed.getPath().contains(".")) {
|
||||
ElementDefinition outcome = updateURLs(url, weburl, ed.copy());
|
||||
outcome.setPath(outcome.getPath().replace(sd.getType(), path));
|
||||
outcome.setPath(outcome.getPath().replace(sd.getTypeName(), path));
|
||||
snapshot.getElement().add(outcome);
|
||||
} else {
|
||||
focus.getConstraint().addAll(ed.getConstraint());
|
||||
|
@ -935,13 +933,6 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return sd != null && type.size() == 1 && sd.getType().equals(type.get(0).getCode());
|
||||
}
|
||||
|
||||
private String typeName(String type) {
|
||||
if (Utilities.isAbsoluteUrl(type)) {
|
||||
return type.substring(type.lastIndexOf("/")+1);
|
||||
} else {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkGroupConstraints(StructureDefinition derived) {
|
||||
List<ElementDefinition> toRemove = new ArrayList<>();
|
||||
|
@ -3722,7 +3713,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
c.getPieces().add(gen.new Piece("#"+ed.getElement().getPath(), tail(ed.getElement().getPath()), ed.getElement().getPath()));
|
||||
} else {
|
||||
c.getPieces().add(gen.new Piece(null, translate("sd.table", "See ", ed.getElement().getPath()), null));
|
||||
c.getPieces().add(gen.new Piece(pfx(corePath, ed.getSource().getUserString("path"))+"#"+ed.getElement().getPath(), tail(ed.getElement().getPath())+" ("+ed.getSource().getType()+")", ed.getElement().getPath()));
|
||||
c.getPieces().add(gen.new Piece(pfx(corePath, ed.getSource().getUserString("path"))+"#"+ed.getElement().getPath(), tail(ed.getElement().getPath())+" ("+ed.getSource().getTypeName()+")", ed.getElement().getPath()));
|
||||
}
|
||||
}
|
||||
return c;
|
||||
|
@ -3842,7 +3833,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (sd == null) {
|
||||
c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, tc), tc, null)));
|
||||
} else {
|
||||
c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, tc), sd.getType(), null)));
|
||||
c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, tc), sd.getTypeName(), null)));
|
||||
}
|
||||
} else if (pkp != null && pkp.hasLinkFor(tc)) {
|
||||
c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, tc), tc, null)));
|
||||
|
@ -4118,13 +4109,13 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
List<ElementDefinition> list = new ArrayList<>();
|
||||
list.addAll(profile.getDifferential().getElement());
|
||||
if (list.isEmpty()) {
|
||||
ElementDefinition root = new ElementDefinition().setPath(profile.getType());
|
||||
root.setId(profile.getType());
|
||||
ElementDefinition root = new ElementDefinition().setPath(profile.getTypeName());
|
||||
root.setId(profile.getTypeName());
|
||||
list.add(root);
|
||||
} else {
|
||||
if (list.get(0).getPath().contains(".")) {
|
||||
ElementDefinition root = new ElementDefinition().setPath(profile.getType());
|
||||
root.setId(profile.getType());
|
||||
ElementDefinition root = new ElementDefinition().setPath(profile.getTypeName());
|
||||
root.setId(profile.getTypeName());
|
||||
list.add(0, root);
|
||||
}
|
||||
}
|
||||
|
@ -4652,7 +4643,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
choicerow.getCells().add(gen.new Cell());
|
||||
choicerow.getCells().add(gen.new Cell(null, null, "", null, null));
|
||||
choicerow.setIcon("icon_primitive.png", HierarchicalTableGenerator.TEXT_ICON_PRIMITIVE);
|
||||
Cell c = gen.new Cell(null, corePath+"datatypes.html#"+t, sd.getType(), null, null);
|
||||
Cell c = gen.new Cell(null, corePath+"datatypes.html#"+t, sd.getTypeName(), null, null);
|
||||
choicerow.getCells().add(c);
|
||||
if (!mustSupportMode && isMustSupport(tr) && element.getMustSupport()) {
|
||||
c.addPiece(gen.new Piece(null, " ", null));
|
||||
|
@ -4663,7 +4654,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
choicerow.getCells().add(gen.new Cell());
|
||||
choicerow.getCells().add(gen.new Cell(null, null, "", null, null));
|
||||
choicerow.setIcon("icon_datatype.gif", HierarchicalTableGenerator.TEXT_ICON_DATATYPE);
|
||||
Cell c = gen.new Cell(null, pkp.getLinkFor(corePath, t), sd.getType(), null, null);
|
||||
Cell c = gen.new Cell(null, pkp.getLinkFor(corePath, t), sd.getTypeName(), null, null);
|
||||
choicerow.getCells().add(c);
|
||||
if (!mustSupportMode && isMustSupport(tr) && element.getMustSupport()) {
|
||||
c.addPiece(gen.new Piece(null, " ", null));
|
||||
|
@ -4879,7 +4870,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
boolean first = true;
|
||||
for (StructureDefinition sd : children) {
|
||||
if (first) first = false; else c.addPiece(gen.new Piece(null, ", ", null));
|
||||
c.addPiece(gen.new Piece(sd.getUserString("path"), sd.getType(), null));
|
||||
c.addPiece(gen.new Piece(sd.getUserString("path"), sd.getTypeName(), null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5052,7 +5043,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
c.getPieces().add(gen.new Piece(null, type, null));
|
||||
c.getPieces().add(gen.new Piece("</code>"));
|
||||
} else {
|
||||
c.getPieces().add(gen.new Piece(sd.getUserString("path"), sd.getType(), null));
|
||||
c.getPieces().add(gen.new Piece(sd.getUserString("path"), sd.getTypeName(), null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5332,7 +5323,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
|
||||
|
||||
private ElementDefinition findElementDefinition(StructureDefinition sd, String name) {
|
||||
String path = sd.getType()+"."+name;
|
||||
String path = sd.getTypeName()+"."+name;
|
||||
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||
if (ed.getPath().equals(path))
|
||||
return ed;
|
||||
|
@ -5403,7 +5394,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (ed.getSource() == profile) {
|
||||
c.getPieces().add(gen.new Piece("#"+ed.getElement().getPath(), "See "+ed.getElement().getPath(), null));
|
||||
} else {
|
||||
c.getPieces().add(gen.new Piece(ed.getSource().getUserData("path")+"#"+ed.getElement().getPath(), "See "+ed.getSource().getType()+"."+ed.getElement().getPath(), null));
|
||||
c.getPieces().add(gen.new Piece(ed.getSource().getUserData("path")+"#"+ed.getElement().getPath(), "See "+ed.getSource().getTypeName()+"."+ed.getElement().getPath(), null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5618,7 +5609,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
private String baseType(String value) {
|
||||
StructureDefinition sd = context.fetchTypeDefinition(value);
|
||||
if (sd != null) // might be running before all SDs are available
|
||||
return sd.getType();
|
||||
return sd.getTypeName();
|
||||
if (Utilities.existsInList(value, "SimpleQuantity", "MoneyQuantity"))
|
||||
return "Quantity";
|
||||
throw new Error(context.formatMessage(I18nConstants.INTERNAL_ERROR___TYPE_NOT_KNOWN_, value));
|
||||
|
@ -6736,7 +6727,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
res.setName(name);
|
||||
res.setCardinality(cardinality);
|
||||
res.setProfileLink(profile.getUserString("path"));
|
||||
res.setResType(profile.getType());
|
||||
res.setResType(profile.getTypeName());
|
||||
StructureDefinition base = context.fetchResource(StructureDefinition.class, res.getResType());
|
||||
if (base != null)
|
||||
res.setResLink(base.getUserString("path"));
|
||||
|
@ -7163,7 +7154,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
b.append("<a href=\"");
|
||||
b.append(sd.getUserString("path"));
|
||||
b.append("\">");
|
||||
b.append(Utilities.escapeXml(sd.getType()));
|
||||
b.append(Utilities.escapeXml(sd.getTypeName()));
|
||||
b.append("</a>");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4671,7 +4671,14 @@ public String describeType() {
|
|||
return "Definition";
|
||||
}
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
String t = getType();
|
||||
return StructureDefinitionKind.LOGICAL.equals(getKind()) && t.contains("/") ? t.substring(t.lastIndexOf("/")+1) : t;
|
||||
}
|
||||
|
||||
// end addition
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -238,7 +238,8 @@ public class ToolingExtensions {
|
|||
|
||||
|
||||
|
||||
public static final String WEB_EXTENSION_STYLE = "http://build.fhir.org/ig/FHIR/fhir-tools-ig/branches/master/format-extensions.html#extension-related-extensions";
|
||||
public static final String WEB_EXTENSION_STYLE = "http://build.fhir.org/ig/FHIR/fhir-tools-ig/format-extensions.html#extension-related-extensions";
|
||||
public static final String EXT_IGDEP_COMMENT = "http://hl7.org/fhir/tools/StructureDefinition/implementationguide-dependency-comment";
|
||||
;
|
||||
|
||||
// specific extension helpers
|
||||
|
|
|
@ -739,6 +739,15 @@ public class I18nConstants {
|
|||
public static final String TYPE_SPECIFIER_NM_ILLEGAL_TYPE = "TYPE_SPECIFIER_NM_ILLEGAL_TYPE";
|
||||
public static final String TYPE_SPECIFIER_NM_ABSTRACT_TYPE = "TYPE_SPECIFIER_NM_ABSTRACT_TYPE";
|
||||
public static final String Bundle_BUNDLE_Entry_NO_LOGICAL_EXPL = "Bundle_BUNDLE_Entry_NO_LOGICAL_EXPL";
|
||||
public static final String SD_TYPE_MISSING = "SD_TYPE_MISSING";
|
||||
public static final String SD_TYPE_NOT_MATCH_NS = "SD_TYPE_NOT_MATCH_NS";
|
||||
public static final String SD_TYPE_NOT_DERIVED = "SD_TYPE_NOT_DERIVED";
|
||||
public static final String SD_TYPE_NOT_LOCAL = "SD_TYPE_NOT_LOCAL";
|
||||
public static final String SD_TYPE_NOT_LOGICAL = "SD_TYPE_NOT_LOGICAL";
|
||||
public static final String SD_CONSTRAINED_TYPE_NO_MATCH = "SD_CONSTRAINED_TYPE_NO_MATCH";
|
||||
public static final String SD_SPECIALIZED_TYPE_MATCHES = "SD_SPECIALIZED_TYPE_MATCHES";
|
||||
public static final String SD_CONSTRAINED_KIND_NO_MATCH = "SD_CONSTRAINED_KIND_NO_MATCH";
|
||||
public static final String SD_PATH_TYPE_MISMATCH = "SD_PATH_TYPE_MISMATCH";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -755,3 +755,12 @@ ELEMENT_CANNOT_BE_NULL = The element is not allowed to be 'null'
|
|||
MULTIPLE_LOGICAL_MODELS_PLURAL={0} Logical Models found in supplied profiles, so unable to parse logical model (can only be one, found {1})
|
||||
UNRECOGNISED_PROPERTY_TYPE = Invalid JSON type {0} for the element {1}; valid types = {2}
|
||||
UNRECOGNISED_PROPERTY_TYPE_WRONG = Invalid type {2} for the element {1}; valid types = {3}, JSON type = {0}
|
||||
SD_TYPE_MISSING = No type found
|
||||
SD_TYPE_NOT_MATCH_NS = The type namespace {0} SHOULD match the url namespace {1} for the definition of the type
|
||||
SD_TYPE_NOT_DERIVED = The type {0} can only be used as a type when constraining the base definition of the type
|
||||
SD_TYPE_NOT_LOCAL = The type {0} is not legal because it is not defined in the FHIR specification. Other types must have a namespace on them
|
||||
SD_TYPE_NOT_LOGICAL = The type {0} can only be defined if the kind is 'logical' not {1}
|
||||
SD_CONSTRAINED_TYPE_NO_MATCH = The type {0} must be the same as the type in the base structure {1} that is being constrained
|
||||
SD_SPECIALIZED_TYPE_MATCHES = The type {0} must not be the same as the type in the base structure {1} that is being specialised
|
||||
SD_CONSTRAINED_KIND_NO_MATCH = The kind {0} must be the same as the kind {1} in the base structure {2}
|
||||
SD_PATH_TYPE_MISMATCH = The path {1} must start with the type of the structure {0}
|
|
@ -2457,7 +2457,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
|
||||
if (context.hasBinding() && e.primitiveValue() != null) {
|
||||
ok = checkPrimitiveBinding(hostContext, errors, path, type, context, e, profile, node) && ok;
|
||||
// special cases
|
||||
if ("StructureDefinition.type".equals(context.getPath()) && "http://hl7.org/fhir/StructureDefinition/StructureDefinition".equals(profile.getUrl())) {
|
||||
ok = checkTypeValue(errors, path, e, node.getElement());
|
||||
} else {
|
||||
ok = checkPrimitiveBinding(hostContext, errors, path, type, context, e, profile, node) && ok;
|
||||
}
|
||||
}
|
||||
|
||||
if (type.equals("markdown") && htmlInMarkdownCheck != HtmlInMarkdownCheck.NONE) {
|
||||
|
@ -2501,6 +2506,40 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
return ok;
|
||||
}
|
||||
|
||||
private boolean checkTypeValue(List<ValidationMessage> errors, String path, Element e, Element sd) {
|
||||
String v = e.primitiveValue();
|
||||
if (v == null) {
|
||||
return rule(errors, IssueType.INVALID, e.line(), e.col(), path, false, I18nConstants.SD_TYPE_MISSING);
|
||||
}
|
||||
String url = sd.getChildValue("url");
|
||||
String d = sd.getChildValue("derivation");
|
||||
String k = sd.getChildValue("kind");
|
||||
if (Utilities.isAbsoluteUrl(v)) {
|
||||
warning(errors, IssueType.INVALID, e.line(), e.col(), path, ns(v).equals(ns(url)) || ns(v).equals(ns(url).replace("StructureDefinition/", "")), I18nConstants.SD_TYPE_NOT_MATCH_NS, v, url);
|
||||
return rule(errors, IssueType.INVALID, e.line(), e.col(), path, "logical".equals(k), I18nConstants.SD_TYPE_NOT_LOGICAL, v, k);
|
||||
} else {
|
||||
boolean tok = false;
|
||||
for (StructureDefinition t : context.fetchResourcesByType(StructureDefinition.class)) {
|
||||
if (t.hasUserData("package") && t.getUserString("package").startsWith("hl7.fhir.r") && v.equals(t.getType())) {
|
||||
tok = true;
|
||||
}
|
||||
}
|
||||
if (tok) {
|
||||
if (!(("http://hl7.org/fhir/StructureDefinition/"+v).equals(url))) {
|
||||
return rule(errors, IssueType.INVALID, e.line(), e.col(), path, "constraint".equals(d), I18nConstants.SD_TYPE_NOT_DERIVED, v);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return rule(errors, IssueType.INVALID, e.line(), e.col(), path, tok, I18nConstants.SD_TYPE_NOT_LOCAL, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String ns(String url) {
|
||||
return url.contains("/") ? url.substring(0, url.lastIndexOf("/")) : url;
|
||||
}
|
||||
|
||||
private Object prepWSPresentation(String s) {
|
||||
if (Utilities.noString(s)) {
|
||||
return "";
|
||||
|
|
|
@ -69,14 +69,18 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
public boolean validateStructureDefinition(List<ValidationMessage> errors, Element src, NodeStack stack) {
|
||||
boolean ok = true;
|
||||
StructureDefinition sd = null;
|
||||
String typeName = null;
|
||||
try {
|
||||
sd = loadAsSD(src);
|
||||
List<ElementDefinition> snapshot = sd.getSnapshot().getElement();
|
||||
sd.setSnapshot(null);
|
||||
typeName = sd.getTypeName();
|
||||
StructureDefinition base = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
if (warning(errors, IssueType.NOTFOUND, stack.getLiteralPath(), base != null, I18nConstants.UNABLE_TO_FIND_BASE__FOR_, sd.getBaseDefinition(), "StructureDefinition, so can't check the differential")) {
|
||||
if (rule(errors, IssueType.NOTFOUND, stack.getLiteralPath(), sd.hasDerivation(), I18nConstants.SD_MUST_HAVE_DERIVATION, sd.getUrl())) {
|
||||
rule(errors, IssueType.NOTFOUND, stack.getLiteralPath(), base.getAbstract() || sd.hasKind() && sd.getKind() == base.getKind(), I18nConstants.SD_CONSTRAINED_KIND_NO_MATCH, sd.getKind().toCode(), base.getKind().toCode(), base.getType());
|
||||
if (sd.getDerivation() == TypeDerivationRule.CONSTRAINT) {
|
||||
rule(errors, IssueType.NOTFOUND, stack.getLiteralPath(), sd.hasType() && sd.getType().equals(base.getType()), I18nConstants.SD_CONSTRAINED_TYPE_NO_MATCH, sd.getType(), base.getType());
|
||||
List<ValidationMessage> msgs = new ArrayList<>();
|
||||
ProfileUtilities pu = new ProfileUtilities(context, msgs, null);
|
||||
pu.setXver(xverManager);
|
||||
|
@ -100,6 +104,8 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
int is = sd.getSnapshot().getElement().size();
|
||||
ok = rule(errors, IssueType.NOTFOUND, stack.getLiteralPath(), was == is, I18nConstants.SNAPSHOT_EXISTING_PROBLEM, was, is) && ok;
|
||||
}
|
||||
} else {
|
||||
rule(errors, IssueType.NOTFOUND, stack.getLiteralPath(), sd.hasType() && !sd.getType().equals(base.getType()), I18nConstants.SD_SPECIALIZED_TYPE_MATCHES, sd.getType(), base.getType());
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
|
@ -116,28 +122,30 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
List<Element> differentials = src.getChildrenByName("differential");
|
||||
List<Element> snapshots = src.getChildrenByName("snapshot");
|
||||
for (Element differential : differentials) {
|
||||
ok = validateElementList(errors, differential, stack.push(differential, -1, null, null), false, snapshots.size() > 0, sd) && ok;
|
||||
ok = validateElementList(errors, differential, stack.push(differential, -1, null, null), false, snapshots.size() > 0, sd, typeName) && ok;
|
||||
}
|
||||
for (Element snapshot : snapshots) {
|
||||
ok = validateElementList(errors, snapshot, stack.push(snapshot, -1, null, null), true, true, sd) && ok;
|
||||
ok = validateElementList(errors, snapshot, stack.push(snapshot, -1, null, null), true, true, sd, typeName) && ok;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
private boolean validateElementList(List<ValidationMessage> errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd) {
|
||||
private boolean validateElementList(List<ValidationMessage> errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName) {
|
||||
boolean ok = true;
|
||||
List<Element> elements = elementList.getChildrenByName("element");
|
||||
int cc = 0;
|
||||
for (Element element : elements) {
|
||||
ok = validateElementDefinition(errors, element, stack.push(element, cc, null, null), snapshot, hasSnapshot, sd) && ok;
|
||||
ok = validateElementDefinition(errors, element, stack.push(element, cc, null, null), snapshot, hasSnapshot, sd, typeName) && ok;
|
||||
cc++;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
private boolean validateElementDefinition(List<ValidationMessage> errors, Element element, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd) {
|
||||
private boolean validateElementDefinition(List<ValidationMessage> errors, Element element, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName) {
|
||||
boolean ok = true;
|
||||
boolean typeMustSupport = false;
|
||||
String path = element.getNamedChildValue("path");
|
||||
rule(errors, IssueType.NOTFOUND, stack.getLiteralPath(), typeName == null || path == null || path.equals(typeName) || path.startsWith(typeName+"."), I18nConstants.SD_PATH_TYPE_MISMATCH, typeName, path);
|
||||
List<Element> types = element.getChildrenByName("type");
|
||||
Set<String> typeCodes = new HashSet<>();
|
||||
Set<String> characteristics = new HashSet<>();
|
||||
|
@ -173,14 +181,14 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
}
|
||||
// check the stated profile - must be a constraint on the type
|
||||
if (snapshot || sd != null) {
|
||||
ok = validateElementType(errors, type, stack.push(type, -1, null, null), sd, element.getChildValue("path")) && ok;
|
||||
ok = validateElementType(errors, type, stack.push(type, -1, null, null), sd, path) && ok;
|
||||
}
|
||||
}
|
||||
if (typeMustSupport) {
|
||||
if (snapshot) {
|
||||
ok = rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), "true".equals(element.getChildValue("mustSupport")), I18nConstants.SD_NESTED_MUST_SUPPORT_SNAPSHOT, element.getNamedChildValue("path")) && ok;
|
||||
ok = rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), "true".equals(element.getChildValue("mustSupport")), I18nConstants.SD_NESTED_MUST_SUPPORT_SNAPSHOT, path) && ok;
|
||||
} else {
|
||||
hint(errors, IssueType.EXCEPTION, stack.getLiteralPath(), hasSnapshot || "true".equals(element.getChildValue("mustSupport")), I18nConstants.SD_NESTED_MUST_SUPPORT_DIFF, element.getNamedChildValue("path"));
|
||||
hint(errors, IssueType.EXCEPTION, stack.getLiteralPath(), hasSnapshot || "true".equals(element.getChildValue("mustSupport")), I18nConstants.SD_NESTED_MUST_SUPPORT_DIFF, path);
|
||||
}
|
||||
}
|
||||
if (element.hasChild("binding")) {
|
||||
|
@ -188,7 +196,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
ok = rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), characteristics.contains("can-bind") , I18nConstants.SD_ILLEGAL_CHARACTERISTICS, "Binding", typeCodes) && ok;
|
||||
}
|
||||
Element binding = element.getNamedChild("binding");
|
||||
ok = validateBinding(errors, binding, stack.push(binding, -1, null, null), typeCodes, snapshot, element.getNamedChildValue("path")) && ok;
|
||||
ok = validateBinding(errors, binding, stack.push(binding, -1, null, null), typeCodes, snapshot, path) && ok;
|
||||
} else {
|
||||
// this is a good idea but there's plenty of cases where the rule isn't met; maybe one day it's worth investing the time to exclude these cases and bring this rule back
|
||||
// String bt = boundType(typeCodes);
|
||||
|
@ -375,7 +383,9 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
|
||||
private boolean validateBinding(List<ValidationMessage> errors, Element binding, NodeStack stack, Set<String> typeCodes, boolean snapshot, String path) {
|
||||
boolean ok = true;
|
||||
ok = rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), !snapshot || bindableType(typeCodes) != null, I18nConstants.SD_ED_BIND_NO_BINDABLE, path, typeCodes.toString()) && ok;
|
||||
if (bindableType(typeCodes) == null) {
|
||||
ok = rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), !snapshot, I18nConstants.SD_ED_BIND_NO_BINDABLE, path, typeCodes.toString()) && ok;
|
||||
}
|
||||
if (!snapshot) {
|
||||
Set<String> bindables = getListofBindableTypes(typeCodes);
|
||||
hint(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), bindables.size() <= 1, I18nConstants.SD_ED_BIND_MULTIPLE_TYPES, path, typeCodes.toString());
|
||||
|
|
Loading…
Reference in New Issue