use of org.hl7.fhir.r4.model.StructureDefinition.StructureDefinitionContextComponent in project org.hl7.fhir.core by hapifhir.
the class InstanceValidator method fixContexts.
private List<StructureDefinitionContextComponent> fixContexts(String extUrl, List<StructureDefinitionContextComponent> list) {
List<StructureDefinitionContextComponent> res = new ArrayList<>();
for (StructureDefinitionContextComponent ctxt : list) {
res.add(ctxt.copy());
}
if (ToolingExtensions.EXT_FHIR_TYPE.equals(extUrl)) {
list.get(0).setExpression("ElementDefinition.type");
}
// but this creates validation errors people can't fix all over the place if we don't do this.
if ("http://hl7.org/fhir/StructureDefinition/regex".equals(extUrl)) {
StructureDefinitionContextComponent e = new StructureDefinitionContextComponent();
e.setExpression("ElementDefinition.type");
e.setType(ExtensionContextType.ELEMENT);
list.add(e);
}
if ("http://hl7.org/fhir/StructureDefinition/structuredefinition-normative-version".equals(extUrl)) {
// well, it can't be used anywhere but the list of places it can be used is quite long
list.get(0).setExpression("Element");
}
if (!VersionUtilities.isThisOrLater("4.6", context.getVersion())) {
if (Utilities.existsInList(extUrl, "http://hl7.org/fhir/StructureDefinition/capabilitystatement-expectation", "http://hl7.org/fhir/StructureDefinition/capabilitystatement-prohibited")) {
// well, they can't be used anywhere but the list of places they can be used is quite long
list.get(0).setExpression("Element");
}
}
return list;
}
use of org.hl7.fhir.r4.model.StructureDefinition.StructureDefinitionContextComponent in project org.hl7.fhir.core by hapifhir.
the class InstanceValidator method checkExtensionContext.
private boolean checkExtensionContext(List<ValidationMessage> errors, Element resource, Element container, StructureDefinition definition, NodeStack stack, ValidatorHostContext hostContext, boolean modifier) {
String extUrl = definition.getUrl();
boolean ok = false;
CommaSeparatedStringBuilder contexts = new CommaSeparatedStringBuilder();
List<String> plist = new ArrayList<>();
plist.add(stripIndexes(stack.getLiteralPath()));
for (String s : stack.getLogicalPaths()) {
String p = stripIndexes(s);
// all extensions are always allowed in ElementDefinition.example.value, and in fixed and pattern values. TODO: determine the logical paths from the path stated in the element definition....
if (Utilities.existsInList(p, "ElementDefinition.example.value", "ElementDefinition.pattern", "ElementDefinition.fixed")) {
return true;
}
plist.add(p);
}
for (StructureDefinitionContextComponent ctxt : fixContexts(extUrl, definition.getContext())) {
if (ok) {
break;
}
if (ctxt.getType() == ExtensionContextType.ELEMENT) {
String en = ctxt.getExpression();
contexts.append("e:" + en);
if (Utilities.existsInList(en, "Element", "Any")) {
ok = true;
} else if (en.equals("Resource") && container.isResource()) {
ok = true;
}
for (String p : plist) {
if (ok) {
break;
}
if (p.equals(en)) {
ok = true;
} else {
String pn = p;
String pt = "";
if (p.contains(".")) {
pn = p.substring(0, p.indexOf("."));
pt = p.substring(p.indexOf("."));
}
StructureDefinition sd = context.fetchTypeDefinition(pn);
while (sd != null) {
if ((sd.getType() + pt).equals(en)) {
ok = true;
break;
}
if (sd.getBaseDefinition() != null) {
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
} else {
sd = null;
}
}
}
}
} else if (ctxt.getType() == ExtensionContextType.EXTENSION) {
contexts.append("x:" + ctxt.getExpression());
NodeStack estack = stack.getParent();
if (estack != null && estack.getElement().fhirType().equals("Extension")) {
String ext = estack.getElement().getNamedChildValue("url");
if (ctxt.getExpression().equals(ext)) {
ok = true;
}
}
} else if (ctxt.getType() == ExtensionContextType.FHIRPATH) {
contexts.append("p:" + ctxt.getExpression());
// The context is all elements that match the FHIRPath query found in the expression.
List<Base> res = fpe.evaluate(hostContext, resource, hostContext.getRootResource(), resource, fpe.parse(ctxt.getExpression()));
if (res.contains(container)) {
ok = true;
}
} else {
throw new Error(context.formatMessage(I18nConstants.UNRECOGNISED_EXTENSION_CONTEXT_, ctxt.getTypeElement().asStringValue()));
}
}
if (!ok) {
if (definition.hasUserData(XVerExtensionManager.XVER_EXT_MARKER)) {
warning(errors, IssueType.STRUCTURE, container.line(), container.col(), stack.getLiteralPath(), false, modifier ? I18nConstants.EXTENSION_EXTM_CONTEXT_WRONG_XVER : I18nConstants.EXTENSION_EXTP_CONTEXT_WRONG_XVER, extUrl, contexts.toString(), plist.toString());
} else {
rule(errors, IssueType.STRUCTURE, container.line(), container.col(), stack.getLiteralPath(), false, modifier ? I18nConstants.EXTENSION_EXTP_CONTEXT_WRONG : I18nConstants.EXTENSION_EXTM_CONTEXT_WRONG, extUrl, contexts.toString(), plist.toString());
}
return false;
} else {
if (definition.hasContextInvariant()) {
for (StringType s : definition.getContextInvariant()) {
if (!fpe.evaluateToBoolean(hostContext, resource, hostContext.getRootResource(), container, fpe.parse(s.getValue()))) {
if (definition.hasUserData(XVerExtensionManager.XVER_EXT_MARKER)) {
warning(errors, IssueType.STRUCTURE, container.line(), container.col(), stack.getLiteralPath(), false, I18nConstants.PROFILE_EXT_NOT_HERE, extUrl, s.getValue());
return true;
} else {
rule(errors, IssueType.STRUCTURE, container.line(), container.col(), stack.getLiteralPath(), false, I18nConstants.PROFILE_EXT_NOT_HERE, extUrl, s.getValue());
return false;
}
}
}
}
return true;
}
}
use of org.hl7.fhir.r4.model.StructureDefinition.StructureDefinitionContextComponent in project org.hl7.fhir.core by hapifhir.
the class ProfileUtilities method describeExtensionContext.
public static String describeExtensionContext(StructureDefinition ext) {
StringBuilder b = new StringBuilder();
b.append("Use on ");
for (int i = 0; i < ext.getContext().size(); i++) {
StructureDefinitionContextComponent ec = ext.getContext().get(i);
if (i > 0)
b.append(i < ext.getContext().size() - 1 ? ", " : " or ");
b.append(ec.getType().getDisplay());
b.append(" ");
b.append(ec.getExpression());
}
if (ext.hasContextInvariant()) {
b.append(", with <a href=\"structuredefinition-definitions.html#StructureDefinition.contextInvariant\">Context Invariant</a> = ");
boolean first = true;
for (StringType s : ext.getContextInvariant()) {
if (first)
first = false;
else
b.append(", ");
b.append("<code>" + s.getValue() + "</code>");
}
}
return b.toString();
}
use of org.hl7.fhir.r4.model.StructureDefinition.StructureDefinitionContextComponent in project org.hl7.fhir.core by hapifhir.
the class ProfileUtilities method describeExtensionContext.
public static String describeExtensionContext(StructureDefinition ext) {
StringBuilder b = new StringBuilder();
b.append("Use on ");
for (int i = 0; i < ext.getContext().size(); i++) {
StructureDefinitionContextComponent ec = ext.getContext().get(i);
if (i > 0)
b.append(i < ext.getContext().size() - 1 ? ", " : " or ");
b.append(ec.getType().getDisplay());
b.append(" ");
b.append(ec.getExpression());
}
if (ext.hasContextInvariant()) {
b.append(", with <a href=\"structuredefinition-definitions.html#StructureDefinition.contextInvariant\">Context Invariant</a> = ");
boolean first = true;
for (StringType s : ext.getContextInvariant()) {
if (first)
first = false;
else
b.append(", ");
b.append("<code>" + s.getValue() + "</code>");
}
}
return b.toString();
}
Aggregations