Gg v5114 b (#356)
* Ensure "I" flag in profile table representation is not used for underlying infrastructural constraints that exist everywhere * render multiple values for properties if they exist * fix for npe * fix for use of "current" as version * fix bad package URLs as they are loaded * RELEASE_NOTES.md * Add rendering for must support on types, profiles, targets * Add new validation for must-support on types / profiles / targets + improve extension validation * add <code> when rendering turtle to HTML * RELEASE_NOTES.md * fix notes
This commit is contained in:
parent
8eeffb8979
commit
b578cfbc0d
|
@ -1,5 +1,5 @@
|
||||||
Validator:
|
Validator:
|
||||||
* no changes with impact
|
* Add new validation for must-support on types / profiles / targets + improve Extension validation
|
||||||
|
|
||||||
Other code changes:
|
Other code changes:
|
||||||
* Ensure "I" flag in profile table representation is not used just for infrastructural constraints
|
* Ensure "I" flag in profile table representation is not used just for infrastructural constraints
|
||||||
|
@ -7,3 +7,5 @@ Other code changes:
|
||||||
* Fix for npe rendering resources based on profiles
|
* Fix for npe rendering resources based on profiles
|
||||||
* fix for use of "current" as version
|
* fix for use of "current" as version
|
||||||
* hack for past bad package URLs
|
* hack for past bad package URLs
|
||||||
|
* Add rendering for must support on types, profiles, targets
|
||||||
|
* add <code> when rendering turtle to HTML
|
|
@ -3245,14 +3245,22 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
tl = t;
|
tl = t;
|
||||||
if (t.hasTarget()) {
|
if (t.hasTarget()) {
|
||||||
c.getPieces().add(gen.new Piece(corePath+"references.html", t.getWorkingCode(), null));
|
c.getPieces().add(gen.new Piece(corePath+"references.html", t.getWorkingCode(), null));
|
||||||
|
if (isMustSupportDirect(t) && e.getMustSupport()) {
|
||||||
|
c.addPiece(gen.new Piece(null, " ", null));
|
||||||
|
c.addStyledText(translate("sd.table", "This type must be supported"), "S", "white", "red", null, false);
|
||||||
|
}
|
||||||
c.getPieces().add(gen.new Piece(null, "(", null));
|
c.getPieces().add(gen.new Piece(null, "(", null));
|
||||||
boolean tfirst = true;
|
boolean tfirst = true;
|
||||||
for (UriType u : t.getTargetProfile()) {
|
for (CanonicalType u : t.getTargetProfile()) {
|
||||||
if (tfirst)
|
if (tfirst)
|
||||||
tfirst = false;
|
tfirst = false;
|
||||||
else
|
else
|
||||||
c.addPiece(gen.new Piece(null, " | ", null));
|
c.addPiece(gen.new Piece(null, " | ", null));
|
||||||
genTargetLink(gen, profileBaseFileName, corePath, c, t, u.getValue());
|
genTargetLink(gen, profileBaseFileName, corePath, c, t, u.getValue());
|
||||||
|
if (isMustSupport(u) && e.getMustSupport()) {
|
||||||
|
c.addPiece(gen.new Piece(null, " ", null));
|
||||||
|
c.addStyledText(translate("sd.table", "This target must be supported"), "S", "white", "red", null, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c.getPieces().add(gen.new Piece(null, ")", null));
|
c.getPieces().add(gen.new Piece(null, ")", null));
|
||||||
if (t.getAggregation().size() > 0) {
|
if (t.getAggregation().size() > 0) {
|
||||||
|
@ -3289,6 +3297,10 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
c.addPiece(checkForNoChange(t, gen.new Piece((p.getValue().startsWith(corePath)? corePath: "")+ref, t.getWorkingCode(), null)));
|
c.addPiece(checkForNoChange(t, gen.new Piece((p.getValue().startsWith(corePath)? corePath: "")+ref, t.getWorkingCode(), null)));
|
||||||
|
if (isMustSupport(p) && e.getMustSupport()) {
|
||||||
|
c.addPiece(gen.new Piece(null, " ", null));
|
||||||
|
c.addStyledText(translate("sd.table", "This profile must be supported"), "S", "white", "red", null, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String tc = t.getWorkingCode();
|
String tc = t.getWorkingCode();
|
||||||
|
@ -3301,9 +3313,14 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
} else if (pkp != null && pkp.hasLinkFor(tc)) {
|
} else if (pkp != null && pkp.hasLinkFor(tc)) {
|
||||||
c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, tc), tc, null)));
|
c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, tc), tc, null)));
|
||||||
} else
|
} else {
|
||||||
c.addPiece(checkForNoChange(t, gen.new Piece(null, tc, null)));
|
c.addPiece(checkForNoChange(t, gen.new Piece(null, tc, null)));
|
||||||
}
|
}
|
||||||
|
if (isMustSupportDirect(t) && e.getMustSupport()) {
|
||||||
|
c.addPiece(gen.new Piece(null, " ", null));
|
||||||
|
c.addStyledText(translate("sd.table", "This type must be supported"), "S", "white", "red", null, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
@ -3931,6 +3948,10 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
c.getPieces().add(gen.new Piece(corePath+"datatypes.html#canonical", "canonical", null));
|
c.getPieces().add(gen.new Piece(corePath+"datatypes.html#canonical", "canonical", null));
|
||||||
else
|
else
|
||||||
c.getPieces().add(gen.new Piece(corePath+"references.html#Reference", "Reference", null));
|
c.getPieces().add(gen.new Piece(corePath+"references.html#Reference", "Reference", null));
|
||||||
|
if (isMustSupportDirect(tr) && element.getMustSupport()) {
|
||||||
|
c.addPiece(gen.new Piece(null, " ", null));
|
||||||
|
c.addStyledText(translate("sd.table", "This type must be supported"), "S", "white", "red", null, false);
|
||||||
|
}
|
||||||
c.getPieces().add(gen.new Piece(null, "(", null));
|
c.getPieces().add(gen.new Piece(null, "(", null));
|
||||||
}
|
}
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
|
@ -3938,6 +3959,10 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
if (!first)
|
if (!first)
|
||||||
c.getPieces().add(gen.new Piece(null, " | ", null));
|
c.getPieces().add(gen.new Piece(null, " | ", null));
|
||||||
genTargetLink(gen, profileBaseFileName, corePath, c, tr, rt.getValue());
|
genTargetLink(gen, profileBaseFileName, corePath, c, tr, rt.getValue());
|
||||||
|
if (isMustSupport(rt) && element.getMustSupport()) {
|
||||||
|
c.addPiece(gen.new Piece(null, " ", null));
|
||||||
|
c.addStyledText(translate("sd.table", "This target must be supported"), "S", "white", "red", null, false);
|
||||||
|
}
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
if (first)
|
if (first)
|
||||||
|
@ -3956,20 +3981,23 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
choicerow.getCells().add(gen.new Cell());
|
choicerow.getCells().add(gen.new Cell());
|
||||||
choicerow.getCells().add(gen.new Cell(null, null, "", null, null));
|
choicerow.getCells().add(gen.new Cell(null, null, "", null, null));
|
||||||
choicerow.setIcon("icon_primitive.png", HierarchicalTableGenerator.TEXT_ICON_PRIMITIVE);
|
choicerow.setIcon("icon_primitive.png", HierarchicalTableGenerator.TEXT_ICON_PRIMITIVE);
|
||||||
choicerow.getCells().add(gen.new Cell(null, corePath+"datatypes.html#"+t, sd.getType(), null, null));
|
Cell c = gen.new Cell(null, corePath+"datatypes.html#"+t, sd.getType(), null, null);
|
||||||
// } else if (definitions.getConstraints().contthnsKey(t)) {
|
choicerow.getCells().add(c);
|
||||||
// ProfiledType pt = definitions.getConstraints().get(t);
|
if (isMustSupport(tr) && element.getMustSupport()) {
|
||||||
// choicerow.getCells().add(gen.new Cell(null, null, e.getName().replace("[x]", Utilities.capitalize(pt.getBaseType())), definitions.getTypes().containsKey(t) ? definitions.getTypes().get(t).getDefinition() : null, null));
|
c.addPiece(gen.new Piece(null, " ", null));
|
||||||
// choicerow.getCells().add(gen.new Cell());
|
c.addStyledText(translate("sd.table", "This type must be supported"), "S", "white", "red", null, false);
|
||||||
// choicerow.getCells().add(gen.new Cell(null, null, "", null, null));
|
}
|
||||||
// choicerow.setIcon("icon_datatype.gif", HierarchicalTableGenerator.TEXT_ICON_DATATYPE);
|
|
||||||
// choicerow.getCells().add(gen.new Cell(null, definitions.getSrcFile(t)+".html#"+t.replace("*", "open"), t, null, null));
|
|
||||||
} else {
|
} else {
|
||||||
choicerow.getCells().add(gen.new Cell(null, null, tail(element.getPath()).replace("[x]", Utilities.capitalize(t)), sd.getDescription(), null));
|
choicerow.getCells().add(gen.new Cell(null, null, tail(element.getPath()).replace("[x]", Utilities.capitalize(t)), sd.getDescription(), null));
|
||||||
choicerow.getCells().add(gen.new Cell());
|
choicerow.getCells().add(gen.new Cell());
|
||||||
choicerow.getCells().add(gen.new Cell(null, null, "", null, null));
|
choicerow.getCells().add(gen.new Cell(null, null, "", null, null));
|
||||||
choicerow.setIcon("icon_datatype.gif", HierarchicalTableGenerator.TEXT_ICON_DATATYPE);
|
choicerow.setIcon("icon_datatype.gif", HierarchicalTableGenerator.TEXT_ICON_DATATYPE);
|
||||||
choicerow.getCells().add(gen.new Cell(null, pkp.getLinkFor(corePath, t), sd.getType(), null, null));
|
Cell c = gen.new Cell(null, pkp.getLinkFor(corePath, t), sd.getType(), null, null);
|
||||||
|
choicerow.getCells().add(c);
|
||||||
|
if (isMustSupport(tr) && element.getMustSupport()) {
|
||||||
|
c.addPiece(gen.new Piece(null, " ", null));
|
||||||
|
c.addStyledText(translate("sd.table", "This type must be supported"), "S", "white", "red", null, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (tr.hasProfile()) {
|
if (tr.hasProfile()) {
|
||||||
Cell typeCell = choicerow.getCells().get(3);
|
Cell typeCell = choicerow.getCells().get(3);
|
||||||
|
@ -3982,6 +4010,10 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
typeCell.addPiece(gen.new Piece(null, "?gen-e2?", null));
|
typeCell.addPiece(gen.new Piece(null, "?gen-e2?", null));
|
||||||
else
|
else
|
||||||
typeCell.addPiece(gen.new Piece(psd.getUserString("path"), psd.getName(), psd.present()));
|
typeCell.addPiece(gen.new Piece(psd.getUserString("path"), psd.getName(), psd.present()));
|
||||||
|
if (isMustSupport(pt) && element.getMustSupport()) {
|
||||||
|
typeCell.addPiece(gen.new Piece(null, " ", null));
|
||||||
|
typeCell.addStyledText(translate("sd.table", "This profile must be supported"), "S", "white", "red", null, false);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
typeCell.addPiece(gen.new Piece(null, ")", null));
|
typeCell.addPiece(gen.new Piece(null, ")", null));
|
||||||
|
@ -6177,6 +6209,32 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
return grp;
|
return grp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isMustSupportDirect(TypeRefComponent tr) {
|
||||||
|
return ("true".equals(ToolingExtensions.readStringExtension(tr, ToolingExtensions.EXT_MUST_SUPPORT)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMustSupport(TypeRefComponent tr) {
|
||||||
|
if ("true".equals(ToolingExtensions.readStringExtension(tr, ToolingExtensions.EXT_MUST_SUPPORT))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (isMustSupport(tr.getProfile())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return isMustSupport(tr.getTargetProfile());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMustSupport(List<CanonicalType> profiles) {
|
||||||
|
for (CanonicalType ct : profiles) {
|
||||||
|
if (isMustSupport(ct)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean isMustSupport(CanonicalType profile) {
|
||||||
|
return "true".equals(ToolingExtensions.readStringExtension(profile, ToolingExtensions.EXT_MUST_SUPPORT));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -180,6 +180,7 @@ public class ToolingExtensions {
|
||||||
public static final String EXT_OLD_CONCEPTMAP_EQUIVALENCE = "http://hl7.org/fhir/1.0/StructureDefinition/extension-ConceptMap.element.target.equivalence";
|
public static final String EXT_OLD_CONCEPTMAP_EQUIVALENCE = "http://hl7.org/fhir/1.0/StructureDefinition/extension-ConceptMap.element.target.equivalence";
|
||||||
public static final String EXT_EXP_FRAGMENT = "http://hl7.org/fhir/tools/StructureDefinition/expansion-codesystem-fragment";
|
public static final String EXT_EXP_FRAGMENT = "http://hl7.org/fhir/tools/StructureDefinition/expansion-codesystem-fragment";
|
||||||
public static final String EXT_EXP_TOOCOSTLY = "http://hl7.org/fhir/StructureDefinition/valueset-toocostly";
|
public static final String EXT_EXP_TOOCOSTLY = "http://hl7.org/fhir/StructureDefinition/valueset-toocostly";
|
||||||
|
public static final String EXT_MUST_SUPPORT = "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support";
|
||||||
|
|
||||||
// specific extension helpers
|
// specific extension helpers
|
||||||
|
|
||||||
|
@ -335,6 +336,8 @@ public class ToolingExtensions {
|
||||||
return ((DecimalType) ex.getValue()).asStringValue();
|
return ((DecimalType) ex.getValue()).asStringValue();
|
||||||
if ((ex.getValue() instanceof MarkdownType))
|
if ((ex.getValue() instanceof MarkdownType))
|
||||||
return ((MarkdownType) ex.getValue()).getValue();
|
return ((MarkdownType) ex.getValue()).getValue();
|
||||||
|
if ((ex.getValue() instanceof PrimitiveType))
|
||||||
|
return ((PrimitiveType) ex.getValue()).primitiveValue();
|
||||||
if (!(ex.getValue() instanceof StringType))
|
if (!(ex.getValue() instanceof StringType))
|
||||||
return null;
|
return null;
|
||||||
return ((StringType) ex.getValue()).getValue();
|
return ((StringType) ex.getValue()).getValue();
|
||||||
|
|
|
@ -341,6 +341,8 @@ public class I18nConstants {
|
||||||
public static final String RESOURCE_TYPE_MISMATCH_FOR___ = "Resource_type_mismatch_for___";
|
public static final String RESOURCE_TYPE_MISMATCH_FOR___ = "Resource_type_mismatch_for___";
|
||||||
public static final String SAME_ID_ON_MULTIPLE_ELEMENTS__IN_ = "Same_id_on_multiple_elements__in_";
|
public static final String SAME_ID_ON_MULTIPLE_ELEMENTS__IN_ = "Same_id_on_multiple_elements__in_";
|
||||||
public static final String SD_MUST_HAVE_DERIVATION = "SD_MUST_HAVE_DERIVATION";
|
public static final String SD_MUST_HAVE_DERIVATION = "SD_MUST_HAVE_DERIVATION";
|
||||||
|
public static final String SD_NESTED_MUST_SUPPORT_DIFF = "SD_NESTED_MUST_SUPPORT_DIFF";
|
||||||
|
public static final String SD_NESTED_MUST_SUPPORT_SNAPSHOT = "SD_NESTED_MUST_SUPPORT_SNAPSHOT";
|
||||||
public static final String SEARCHPARAMETER_BASE_WRONG = "SEARCHPARAMETER_BASE_WRONG";
|
public static final String SEARCHPARAMETER_BASE_WRONG = "SEARCHPARAMETER_BASE_WRONG";
|
||||||
public static final String SEARCHPARAMETER_EXP_WRONG = "SEARCHPARAMETER_EXP_WRONG";
|
public static final String SEARCHPARAMETER_EXP_WRONG = "SEARCHPARAMETER_EXP_WRONG";
|
||||||
public static final String SEARCHPARAMETER_NOTFOUND = "SEARCHPARAMETER_NOTFOUND";
|
public static final String SEARCHPARAMETER_NOTFOUND = "SEARCHPARAMETER_NOTFOUND";
|
||||||
|
|
|
@ -384,12 +384,12 @@ public class Turtle {
|
||||||
|
|
||||||
public String asHtml() throws Exception {
|
public String asHtml() throws Exception {
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
b.append("<pre class=\"rdf\">\r\n");
|
b.append("<pre class=\"rdf\"><code class=\"language-turtle\">\r\n");
|
||||||
commitPrefixes(b);
|
commitPrefixes(b);
|
||||||
for (Section s : sections) {
|
for (Section s : sections) {
|
||||||
commitSection(b, s);
|
commitSection(b, s);
|
||||||
}
|
}
|
||||||
b.append("</pre>\r\n");
|
b.append("</code></pre>\r\n");
|
||||||
b.append("\r\n");
|
b.append("\r\n");
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -609,3 +609,6 @@ TYPE_SPECIFIC_CHECKS_DT_QTY_NO_ANNOTATIONS = UCUM Codes that contain human reada
|
||||||
XHTML_XHTML_ELEMENT_ILLEGAL_IN_PARA = Illegal element name inside in a paragraph in the XHTML (''{0}'')
|
XHTML_XHTML_ELEMENT_ILLEGAL_IN_PARA = Illegal element name inside in a paragraph in the XHTML (''{0}'')
|
||||||
UNSUPPORTED_IDENTIFIER_PATTERN_PROPERTY_NOT_SUPPORTED_FOR_DISCRIMINATOR_FOR_SLICE = Unsupported property {3} on type {2} for pattern for discriminator({0}) for slice {1}
|
UNSUPPORTED_IDENTIFIER_PATTERN_PROPERTY_NOT_SUPPORTED_FOR_DISCRIMINATOR_FOR_SLICE = Unsupported property {3} on type {2} for pattern for discriminator({0}) for slice {1}
|
||||||
UNSUPPORTED_IDENTIFIER_PATTERN_NO_PROPERTY_NOT_SUPPORTED_FOR_DISCRIMINATOR_FOR_SLICE = Unsupported: no properties with values found on type {2} for pattern for discriminator({0}) for slice {1}
|
UNSUPPORTED_IDENTIFIER_PATTERN_NO_PROPERTY_NOT_SUPPORTED_FOR_DISCRIMINATOR_FOR_SLICE = Unsupported: no properties with values found on type {2} for pattern for discriminator({0}) for slice {1}
|
||||||
|
SD_NESTED_MUST_SUPPORT_DIFF = The element {0} has types/profiles/targets that are marked as must support, but the element itself is not marked as must-support. The inner must-supports will be ignored unless the element inherits must-support = true
|
||||||
|
SD_NESTED_MUST_SUPPORT_SNAPSHOT = The element {0} has types/profiles/targets that are marked as must support, but the element itself is not marked as must-support
|
||||||
|
|
|
@ -296,9 +296,10 @@ public class BaseValidator {
|
||||||
* Set this parameter to <code>false</code> if the validation does not pass
|
* Set this parameter to <code>false</code> if the validation does not pass
|
||||||
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
|
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
|
||||||
*/
|
*/
|
||||||
protected boolean hint(List<ValidationMessage> errors, IssueType type, String path, boolean thePass, String msg) {
|
protected boolean hint(List<ValidationMessage> errors, IssueType type, String path, boolean thePass, String theMessage, Object... theMessageArguments) {
|
||||||
if (!thePass) {
|
if (!thePass) {
|
||||||
addValidationMessage(errors, type, -1, -1, path, msg, IssueSeverity.INFORMATION, null);
|
String message = context.formatMessage(theMessage, theMessageArguments);
|
||||||
|
addValidationMessage(errors, type, -1, -1, path, message, IssueSeverity.INFORMATION, null);
|
||||||
}
|
}
|
||||||
return thePass;
|
return thePass;
|
||||||
}
|
}
|
||||||
|
|
|
@ -483,7 +483,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
|
|
||||||
private boolean isKnownExtension(String url) {
|
private boolean isKnownExtension(String url) {
|
||||||
// Added structuredefinition-expression and following extensions explicitly because they weren't defined in the version of the spec they need to be used with
|
// Added structuredefinition-expression and following extensions explicitly because they weren't defined in the version of the spec they need to be used with
|
||||||
if ((allowExamples && (url.contains("example.org") || url.contains("acme.com"))) || url.contains("nema.org") || url.startsWith("http://hl7.org/fhir/tools/StructureDefinition/") || url.equals("http://hl7.org/fhir/StructureDefinition/structuredefinition-expression") || url.equals(VersionConvertorConstants.IG_DEPENDSON_PACKAGE_EXTENSION))
|
if ((allowExamples && (url.contains("example.org") || url.contains("acme.com"))) || url.contains("nema.org") || url.startsWith("http://hl7.org/fhir/tools/StructureDefinition/") || url.equals("http://hl7.org/fhir/StructureDefinition/structuredefinition-expression"))
|
||||||
return true;
|
return true;
|
||||||
for (String s : extensionDomains)
|
for (String s : extensionDomains)
|
||||||
if (url.startsWith(s))
|
if (url.startsWith(s))
|
||||||
|
@ -1521,6 +1521,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
if (extensionUrl.equals(profile.getUrl())) {
|
if (extensionUrl.equals(profile.getUrl())) {
|
||||||
rule(errors, IssueType.INVALID, element.line(), element.col(), path + "[url='" + url + "']", hasExtensionSlice(profile, url), I18nConstants.EXTENSION_EXT_SUBEXTENSION_INVALID, url, profile.getUrl());
|
rule(errors, IssueType.INVALID, element.line(), element.col(), path + "[url='" + url + "']", hasExtensionSlice(profile, url), I18nConstants.EXTENSION_EXT_SUBEXTENSION_INVALID, url, profile.getUrl());
|
||||||
}
|
}
|
||||||
|
} else if (SpecialExtensions.isKnownExtension(url)) {
|
||||||
|
ex = SpecialExtensions.getDefinition(url);
|
||||||
} else if (rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, allowUnknownExtension(url), I18nConstants.EXTENSION_EXT_UNKNOWN_NOTHERE, url)) {
|
} else if (rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, allowUnknownExtension(url), I18nConstants.EXTENSION_EXT_UNKNOWN_NOTHERE, url)) {
|
||||||
hint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, isKnownExtension(url), I18nConstants.EXTENSION_EXT_UNKNOWN, url);
|
hint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, isKnownExtension(url), I18nConstants.EXTENSION_EXT_UNKNOWN, url);
|
||||||
}
|
}
|
||||||
|
@ -1556,6 +1558,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
return ex;
|
return ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean hasExtensionSlice(StructureDefinition profile, String sliceName) {
|
private boolean hasExtensionSlice(StructureDefinition profile, String sliceName) {
|
||||||
for (ElementDefinition ed : profile.getSnapshot().getElement()) {
|
for (ElementDefinition ed : profile.getSnapshot().getElement()) {
|
||||||
if (ed.getPath().equals("Extension.extension.url") && ed.hasFixed() && sliceName.equals(ed.getFixed().primitiveValue())) {
|
if (ed.getPath().equals("Extension.extension.url") && ed.hasFixed() && sliceName.equals(ed.getFixed().primitiveValue())) {
|
||||||
|
@ -1933,7 +1936,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
if (fetcher != null) {
|
if (fetcher != null) {
|
||||||
boolean found;
|
boolean found;
|
||||||
try {
|
try {
|
||||||
found = isDefinitionURL(url) || (allowExamples && (url.contains("example.org") || url.contains("acme.com")) || url.contains("acme.org")) || (url.startsWith("http://hl7.org/fhir/tools")) || fetcher.resolveURL(appContext, path, url);
|
found = isDefinitionURL(url) || (allowExamples && (url.contains("example.org") || url.contains("acme.com")) || url.contains("acme.org")) || (url.startsWith("http://hl7.org/fhir/tools")) || fetcher.resolveURL(appContext, path, url) ||
|
||||||
|
SpecialExtensions.isKnownExtension(url);
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
found = false;
|
found = false;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -28,6 +28,7 @@ import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||||
import org.hl7.fhir.r5.model.SearchParameter;
|
import org.hl7.fhir.r5.model.SearchParameter;
|
||||||
import org.hl7.fhir.r5.model.ValueSet;
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
||||||
|
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.VersionUtilities;
|
import org.hl7.fhir.utilities.VersionUtilities;
|
||||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||||
|
@ -95,6 +96,69 @@ public class StructureDefinitionValidator extends BaseValidator {
|
||||||
} catch (FHIRException | IOException e) {
|
} catch (FHIRException | IOException e) {
|
||||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.ERROR_GENERATING_SNAPSHOT, e.getMessage());
|
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.ERROR_GENERATING_SNAPSHOT, e.getMessage());
|
||||||
}
|
}
|
||||||
|
List<Element> differentials = src.getChildrenByName("differential");
|
||||||
|
List<Element> snapshots = src.getChildrenByName("snapshot");
|
||||||
|
for (Element differential : differentials) {
|
||||||
|
validateElementList(errors, differential, stack.push(differential, -1, null, null), false, snapshots.size() > 0);
|
||||||
|
}
|
||||||
|
for (Element snapshot : snapshots) {
|
||||||
|
validateElementList(errors, snapshot, stack.push(snapshot, -1, null, null), true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateElementList(List<ValidationMessage> errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot) {
|
||||||
|
List<Element> elements = elementList.getChildrenByName("element");
|
||||||
|
int cc = 0;
|
||||||
|
for (Element element : elements) {
|
||||||
|
validateElementDefinition(errors, element, stack.push(element, cc, null, null), snapshot, hasSnapshot);
|
||||||
|
cc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateElementDefinition(List<ValidationMessage> errors, Element element, NodeStack stack, boolean snapshot, boolean hasSnapshot) {
|
||||||
|
boolean typeMustSupport = false;
|
||||||
|
List<Element> types = element.getChildrenByName("type");
|
||||||
|
for (Element type : types) {
|
||||||
|
if (hasMustSupportExtension(type)) {
|
||||||
|
typeMustSupport = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (typeMustSupport) {
|
||||||
|
if (snapshot) {
|
||||||
|
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), "true".equals(element.getChildValue("mustSupport")), I18nConstants.SD_NESTED_MUST_SUPPORT_SNAPSHOT, element.getNamedChildValue("path"));
|
||||||
|
} else {
|
||||||
|
hint(errors, IssueType.EXCEPTION, stack.getLiteralPath(), hasSnapshot || "true".equals(element.getChildValue("mustSupport")), I18nConstants.SD_NESTED_MUST_SUPPORT_DIFF, element.getNamedChildValue("path"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasMustSupportExtension(Element type) {
|
||||||
|
if ("true".equals(getExtensionValue(type, ToolingExtensions.EXT_MUST_SUPPORT))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
List<Element> profiles = type.getChildrenByName("profile");
|
||||||
|
for (Element profile : profiles) {
|
||||||
|
if ("true".equals(getExtensionValue(profile, ToolingExtensions.EXT_MUST_SUPPORT))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
profiles = type.getChildrenByName("targetProfile");
|
||||||
|
for (Element profile : profiles) {
|
||||||
|
if ("true".equals(getExtensionValue(profile, ToolingExtensions.EXT_MUST_SUPPORT))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getExtensionValue(Element element, String url) {
|
||||||
|
List<Element> extensions = element.getChildrenByName("extension");
|
||||||
|
for (Element extension : extensions) {
|
||||||
|
if (url.equals(extension.getNamedChildValue("url"))) {
|
||||||
|
return extension.getNamedChildValue("value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private StructureDefinition loadAsSD(Element src) throws FHIRException, IOException {
|
private StructureDefinition loadAsSD(Element src) throws FHIRException, IOException {
|
||||||
|
|
Loading…
Reference in New Issue