use of org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionSlicingDiscriminatorComponent in project org.hl7.fhir.core by hapifhir.
the class InstanceValidator method sliceMatches.
/**
* @param element - the candidate that might be in the slice
* @param path - for reporting any errors. the XPath for the element
* @param slicer - the definition of how slicing is determined
* @param ed - the slice for which to test membership
* @param errors
* @param stack
* @param srcProfile
* @return
* @throws DefinitionException
* @throws DefinitionException
* @throws IOException
* @throws FHIRException
*/
private boolean sliceMatches(ValidatorHostContext hostContext, Element element, String path, ElementDefinition slicer, ElementDefinition ed, StructureDefinition profile, List<ValidationMessage> errors, List<ValidationMessage> sliceInfo, NodeStack stack, StructureDefinition srcProfile) throws DefinitionException, FHIRException {
if (!slicer.getSlicing().hasDiscriminator())
// cannot validate in this case
return false;
ExpressionNode n = (ExpressionNode) ed.getUserData("slice.expression.cache");
if (n == null) {
long t = System.nanoTime();
// GG: this approach is flawed because it treats discriminators individually rather than collectively
StringBuilder expression = new StringBuilder("true");
boolean anyFound = false;
Set<String> discriminators = new HashSet<>();
for (ElementDefinitionSlicingDiscriminatorComponent s : slicer.getSlicing().getDiscriminator()) {
String discriminator = s.getPath();
discriminators.add(discriminator);
List<ElementDefinition> criteriaElements = getCriteriaForDiscriminator(path, ed, discriminator, profile, s.getType() == DiscriminatorType.PROFILE, srcProfile);
boolean found = false;
for (ElementDefinition criteriaElement : criteriaElements) {
found = true;
if (s.getType() == DiscriminatorType.TYPE) {
String type = null;
if (!criteriaElement.getPath().contains("[") && discriminator.contains("[")) {
discriminator = discriminator.substring(0, discriminator.indexOf('['));
String lastNode = tail(discriminator);
type = tail(criteriaElement.getPath()).substring(lastNode.length());
type = type.substring(0, 1).toLowerCase() + type.substring(1);
} else if (!criteriaElement.hasType() || criteriaElement.getType().size() == 1) {
if (discriminator.contains("["))
discriminator = discriminator.substring(0, discriminator.indexOf('['));
if (criteriaElement.hasType()) {
type = criteriaElement.getType().get(0).getWorkingCode();
} else if (!criteriaElement.getPath().contains(".")) {
type = criteriaElement.getPath();
} else {
throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES, discriminator, ed.getId(), profile.getUrl()));
}
} else if (criteriaElement.getType().size() > 1) {
throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_MULTIPLE_TYPES_, discriminator, ed.getId(), profile.getUrl(), criteriaElement.typeSummary()));
} else
throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES, discriminator, ed.getId(), profile.getUrl()));
if (discriminator.isEmpty())
expression.append(" and $this is " + type);
else
expression.append(" and " + discriminator + " is " + type);
} else if (s.getType() == DiscriminatorType.PROFILE) {
if (criteriaElement.getType().size() == 0) {
throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl()));
}
if (criteriaElement.getType().size() != 1) {
throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_ONLY_ONE_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl()));
}
List<CanonicalType> list = discriminator.endsWith(".resolve()") || discriminator.equals("resolve()") ? criteriaElement.getType().get(0).getTargetProfile() : criteriaElement.getType().get(0).getProfile();
if (list.size() == 0) {
throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE_WITH_A_PROFILE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl()));
} else if (list.size() > 1) {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(" or ");
for (CanonicalType c : list) {
b.append(discriminator + ".conformsTo('" + c.getValue() + "')");
}
expression.append(" and (" + b + ")");
} else {
expression.append(" and " + discriminator + ".conformsTo('" + list.get(0).getValue() + "')");
}
} else if (s.getType() == DiscriminatorType.EXISTS) {
if (criteriaElement.hasMin() && criteriaElement.getMin() >= 1)
expression.append(" and (" + discriminator + ".exists())");
else if (criteriaElement.hasMax() && criteriaElement.getMax().equals("0"))
expression.append(" and (" + discriminator + ".exists().not())");
else
throw new FHIRException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_ELEMENT_EXISTENCE_BUT_SLICE__NEITHER_SETS_MIN1_OR_MAX0, discriminator, ed.getId()));
} else if (criteriaElement.hasFixed()) {
buildFixedExpression(ed, expression, discriminator, criteriaElement);
} else if (criteriaElement.hasPattern()) {
buildPattternExpression(ed, expression, discriminator, criteriaElement);
} else if (criteriaElement.hasBinding() && criteriaElement.getBinding().hasStrength() && criteriaElement.getBinding().getStrength().equals(BindingStrength.REQUIRED) && criteriaElement.getBinding().hasValueSet()) {
expression.append(" and (" + discriminator + " memberOf '" + criteriaElement.getBinding().getValueSet() + "')");
} else {
found = false;
}
if (found)
break;
}
if (found)
anyFound = true;
}
if (!anyFound) {
if (slicer.getSlicing().getDiscriminator().size() > 1)
throw new DefinitionException(context.formatMessage(I18nConstants.COULD_NOT_MATCH_ANY_DISCRIMINATORS__FOR_SLICE__IN_PROFILE___NONE_OF_THE_DISCRIMINATOR__HAVE_FIXED_VALUE_BINDING_OR_EXISTENCE_ASSERTIONS, discriminators, ed.getId(), profile.getUrl(), discriminators));
else
throw new DefinitionException(context.formatMessage(I18nConstants.COULD_NOT_MATCH_DISCRIMINATOR__FOR_SLICE__IN_PROFILE___THE_DISCRIMINATOR__DOES_NOT_HAVE_FIXED_VALUE_BINDING_OR_EXISTENCE_ASSERTIONS, discriminators, ed.getId(), profile.getUrl(), discriminators));
}
try {
n = fpe.parse(fixExpr(expression.toString(), null));
} catch (FHIRLexerException e) {
if (STACK_TRACE)
e.printStackTrace();
throw new FHIRException(context.formatMessage(I18nConstants.PROBLEM_PROCESSING_EXPRESSION__IN_PROFILE__PATH__, expression, profile.getUrl(), path, e.getMessage()));
}
timeTracker.fpe(t);
ed.setUserData("slice.expression.cache", n);
}
ValidatorHostContext shc = hostContext.forSlicing();
boolean pass = evaluateSlicingExpression(shc, element, path, profile, n);
if (!pass) {
slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), (context.formatMessage(I18nConstants.DOES_NOT_MATCH_SLICE_, ed.getSliceName())), "discriminator = " + Utilities.escapeXml(n.toString()), null);
for (String url : shc.getSliceRecords().keySet()) {
slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, stack.getLiteralPath(), url), context.formatMessage(I18nConstants.PROFILE__DOES_NOT_MATCH_FOR__BECAUSE_OF_THE_FOLLOWING_PROFILE_ISSUES__, url, stack.getLiteralPath(), errorSummaryForSlicingAsHtml(shc.getSliceRecords().get(url))), errorSummaryForSlicingAsText(shc.getSliceRecords().get(url)));
}
}
return pass;
}
use of org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionSlicingDiscriminatorComponent in project org.hl7.fhir.core by hapifhir.
the class StructureDefinitionSpreadsheetGenerator method itemList.
private String itemList(List l) {
StringBuilder s = new StringBuilder();
for (int i = 0; i < l.size(); i++) {
Object o = l.get(i);
String val = "";
if (o instanceof StringType) {
val = ((StringType) o).getValue();
} else if (o instanceof UriType) {
val = ((UriType) o).getValue();
} else if (o instanceof IdType) {
val = ((IdType) o).getValue();
} else if (o instanceof Enumeration<?>) {
val = o.toString();
} else if (o instanceof TypeRefComponent) {
TypeRefComponent t = (TypeRefComponent) o;
val = t.getWorkingCode();
if (val == null)
val = "";
if (val.startsWith("http://hl7.org/fhir/StructureDefinition/"))
val = val.substring(40);
if (t.hasTargetProfile())
val = val + "(" + canonicalList(t.getTargetProfile()) + ")";
if (t.hasProfile())
val = val + " {" + canonicalList(t.getProfile()) + "}";
if (t.hasAggregation())
val = val + " <<" + aggList(t.getAggregation()) + ">>";
} else if (o instanceof Coding) {
Coding t = (Coding) o;
val = (t.getSystem() == null ? "" : t.getSystem()) + (t.getCode() == null ? "" : "#" + t.getCode()) + (t.getDisplay() == null ? "" : " (" + t.getDisplay() + ")");
} else if (o instanceof ElementDefinitionConstraintComponent) {
ElementDefinitionConstraintComponent c = (ElementDefinitionConstraintComponent) o;
val = c.getKey() + ":" + c.getHuman() + " {" + c.getExpression() + "}";
} else if (o instanceof ElementDefinitionSlicingDiscriminatorComponent) {
ElementDefinitionSlicingDiscriminatorComponent c = (ElementDefinitionSlicingDiscriminatorComponent) o;
val = c.getType().toCode() + ":" + c.getPath() + "}";
} else {
val = o.toString();
val = val.substring(val.indexOf("[") + 1);
val = val.substring(0, val.indexOf("]"));
}
s = s.append(val);
if (i == 0)
s.append("\n");
}
return s.toString();
}
use of org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionSlicingDiscriminatorComponent in project org.hl7.fhir.core by hapifhir.
the class InstanceValidator method slicingSummary.
private String slicingSummary(ElementDefinitionSlicingComponent slicing) {
StringBuilder b = new StringBuilder();
b.append('[');
boolean first = true;
for (ElementDefinitionSlicingDiscriminatorComponent t : slicing.getDiscriminator()) {
if (first)
first = false;
else
b.append(",");
b.append(t.getType().toCode());
b.append(":");
b.append(t.getPath());
}
b.append(']');
b.append(slicing.getOrdered() ? ";ordered" : "");
b.append(slicing.getRules().toString());
return b.toString();
}
use of org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionSlicingDiscriminatorComponent in project org.hl7.fhir.core by hapifhir.
the class ProfileUtilities method sliceSummary.
private String sliceSummary(ElementDefinition ed) {
if (!ed.hasSlicing() && !ed.hasSliceName())
return "";
if (ed.hasSliceName())
return " (slicename = " + ed.getSliceName() + ")";
StringBuilder b = new StringBuilder();
boolean first = true;
for (ElementDefinitionSlicingDiscriminatorComponent d : ed.getSlicing().getDiscriminator()) {
if (first)
first = false;
else
b.append("|");
b.append(d.getPath());
}
return " (slicing by " + b.toString() + ")";
}
use of org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionSlicingDiscriminatorComponent in project org.hl7.fhir.core by hapifhir.
the class CSVWriter method itemList.
private String itemList(List l) {
StringBuilder s = new StringBuilder();
for (int i = 0; i < l.size(); i++) {
Object o = l.get(i);
String val = "";
if (o instanceof StringType) {
val = ((StringType) o).getValue();
} else if (o instanceof UriType) {
val = ((UriType) o).getValue();
} else if (o instanceof IdType) {
val = ((IdType) o).getValue();
} else if (o instanceof Enumeration<?>) {
val = o.toString();
} else if (o instanceof TypeRefComponent) {
TypeRefComponent t = (TypeRefComponent) o;
val = t.getWorkingCode() + (t.getProfile() == null ? "" : " {" + t.getProfile() + "}") + (t.getTargetProfile() == null ? "" : " {" + t.getTargetProfile() + "}") + (t.getAggregation() == null || t.getAggregation().isEmpty() ? "" : " (" + itemList(t.getAggregation()) + ")");
} else if (o instanceof Coding) {
Coding t = (Coding) o;
val = (t.getSystem() == null ? "" : t.getSystem()) + (t.getCode() == null ? "" : "#" + t.getCode()) + (t.getDisplay() == null ? "" : " (" + t.getDisplay() + ")");
} else if (o instanceof ElementDefinitionConstraintComponent) {
ElementDefinitionConstraintComponent c = (ElementDefinitionConstraintComponent) o;
val = c.getKey() + ":" + c.getHuman() + " {" + c.getExpression() + "}";
} else if (o instanceof ElementDefinitionSlicingDiscriminatorComponent) {
ElementDefinitionSlicingDiscriminatorComponent c = (ElementDefinitionSlicingDiscriminatorComponent) o;
val = c.getType().toCode() + ":" + c.getPath() + "}";
} else {
val = o.toString();
val = val.substring(val.indexOf("[") + 1);
val = val.substring(0, val.indexOf("]"));
}
s = s.append(val);
if (i == 0)
s.append("\n");
}
return s.toString();
}
Aggregations