use of org.hl7.fhir.utilities.xml.SchematronWriter.Rule in project org.hl7.fhir.core by hapifhir.
the class StructureMapUtilities method processTarget.
private void processTarget(String ruleId, TransformContext context, Variables vars, StructureMap map, StructureMapGroupComponent group, StructureMapGroupRuleTargetComponent tgt, String srcVar, boolean atRoot, Variables sharedVars) throws FHIRException {
Base dest = null;
if (tgt.hasContext()) {
dest = vars.get(VariableMode.OUTPUT, tgt.getContext());
if (dest == null)
throw new FHIRException("Rule \"" + ruleId + "\": target context not known: " + tgt.getContext());
if (!tgt.hasElement())
throw new FHIRException("Rule \"" + ruleId + "\": Not supported yet");
}
Base v = null;
if (tgt.hasTransform()) {
v = runTransform(ruleId, context, map, group, tgt, vars, dest, tgt.getElement(), srcVar, atRoot);
if (v != null && dest != null)
// reset v because some implementations may have to rewrite v when setting the value
v = dest.setProperty(tgt.getElement().hashCode(), tgt.getElement(), v);
} else if (dest != null) {
if (tgt.hasListMode(StructureMapTargetListMode.SHARE)) {
v = sharedVars.get(VariableMode.SHARED, tgt.getListRuleId());
if (v == null) {
v = dest.makeProperty(tgt.getElement().hashCode(), tgt.getElement());
sharedVars.add(VariableMode.SHARED, tgt.getListRuleId(), v);
}
} else {
v = dest.makeProperty(tgt.getElement().hashCode(), tgt.getElement());
}
}
if (tgt.hasVariable() && v != null)
vars.add(VariableMode.OUTPUT, tgt.getVariable(), v);
}
use of org.hl7.fhir.utilities.xml.SchematronWriter.Rule in project org.hl7.fhir.core by hapifhir.
the class StructureMapUtilities method resolveGroupReference.
private ResolvedGroup resolveGroupReference(StructureMap map, StructureMapGroupComponent source, String name) throws FHIRException {
String kn = "ref^" + name;
if (source.hasUserData(kn))
return (ResolvedGroup) source.getUserData(kn);
ResolvedGroup res = new ResolvedGroup();
res.targetMap = null;
res.target = null;
for (StructureMapGroupComponent grp : map.getGroup()) {
if (grp.getName().equals(name)) {
if (res.targetMap == null) {
res.targetMap = map;
res.target = grp;
} else
throw new FHIRException("Multiple possible matches for rule '" + name + "'");
}
}
if (res.targetMap != null) {
source.setUserData(kn, res);
return res;
}
for (UriType imp : map.getImport()) {
List<StructureMap> impMapList = findMatchingMaps(imp.getValue());
if (impMapList.size() == 0)
throw new FHIRException("Unable to find map(s) for " + imp.getValue());
for (StructureMap impMap : impMapList) {
if (!impMap.getUrl().equals(map.getUrl())) {
for (StructureMapGroupComponent grp : impMap.getGroup()) {
if (grp.getName().equals(name)) {
if (res.targetMap == null) {
res.targetMap = impMap;
res.target = grp;
} else
throw new FHIRException("Multiple possible matches for rule group '" + name + "' in " + res.targetMap.getUrl() + "#" + res.target.getName() + " and " + impMap.getUrl() + "#" + grp.getName());
}
}
}
}
}
if (res.target == null)
throw new FHIRException("No matches found for rule '" + name + "'. Reference found in " + map.getUrl());
source.setUserData(kn, res);
return res;
}
use of org.hl7.fhir.utilities.xml.SchematronWriter.Rule in project org.hl7.fhir.core by hapifhir.
the class StructureMapUtilities method executeDependency.
private void executeDependency(String indent, TransformContext context, StructureMap map, Variables vin, StructureMapGroupComponent group, StructureMapGroupRuleDependentComponent dependent) throws FHIRException {
ResolvedGroup rg = resolveGroupReference(map, group, dependent.getName());
if (rg.target.getInput().size() != dependent.getParameter().size()) {
throw new FHIRException("Rule '" + dependent.getName() + "' has " + rg.target.getInput().size() + " but the invocation has " + dependent.getParameter().size() + " variables");
}
Variables v = new Variables();
for (int i = 0; i < rg.target.getInput().size(); i++) {
StructureMapGroupInputComponent input = rg.target.getInput().get(i);
StructureMapGroupRuleTargetParameterComponent rdp = dependent.getParameter().get(i);
String var = rdp.getValue().primitiveValue();
VariableMode mode = input.getMode() == StructureMapInputMode.SOURCE ? VariableMode.INPUT : VariableMode.OUTPUT;
Base vv = vin.get(mode, var);
if (// * once source, always source. but target can be treated as source at user convenient
vv == null && mode == VariableMode.INPUT)
vv = vin.get(VariableMode.OUTPUT, var);
if (vv == null)
throw new FHIRException("Rule '" + dependent.getName() + "' " + mode.toString() + " variable '" + input.getName() + "' named as '" + var + "' has no value (vars = " + vin.summary() + ")");
v.add(mode, input.getName(), vv);
}
executeGroup(indent + " ", context, rg.targetMap, v, rg.target, false);
}
use of org.hl7.fhir.utilities.xml.SchematronWriter.Rule in project org.hl7.fhir.core by hapifhir.
the class StructureMapUtilities method resolveGroupByTypes.
private ResolvedGroup resolveGroupByTypes(StructureMap map, String ruleid, StructureMapGroupComponent source, String srcType, String tgtType) throws FHIRException {
String kn = "types^" + srcType + ":" + tgtType;
if (source.hasUserData(kn))
return (ResolvedGroup) source.getUserData(kn);
ResolvedGroup res = new ResolvedGroup();
res.targetMap = null;
res.target = null;
for (StructureMapGroupComponent grp : map.getGroup()) {
if (matchesByType(map, grp, srcType, tgtType)) {
if (res.targetMap == null) {
res.targetMap = map;
res.target = grp;
} else
throw new FHIRException("Multiple possible matches looking for rule for '" + srcType + "/" + tgtType + "', from rule '" + ruleid + "'");
}
}
if (res.targetMap != null) {
source.setUserData(kn, res);
return res;
}
for (UriType imp : map.getImport()) {
List<StructureMap> impMapList = findMatchingMaps(imp.getValue());
if (impMapList.size() == 0)
throw new FHIRException("Unable to find map(s) for " + imp.getValue());
for (StructureMap impMap : impMapList) {
if (!impMap.getUrl().equals(map.getUrl())) {
for (StructureMapGroupComponent grp : impMap.getGroup()) {
if (matchesByType(impMap, grp, srcType, tgtType)) {
if (res.targetMap == null) {
res.targetMap = impMap;
res.target = grp;
} else
throw new FHIRException("Multiple possible matches for rule for '" + srcType + "/" + tgtType + "' in " + res.targetMap.getUrl() + " and " + impMap.getUrl() + ", from rule '" + ruleid + "'");
}
}
}
}
}
if (res.target == null)
throw new FHIRException("No matches found for rule for '" + srcType + " to " + tgtType + "' from " + map.getUrl() + ", from rule '" + ruleid + "'");
source.setUserData(kn, res);
return res;
}
use of org.hl7.fhir.utilities.xml.SchematronWriter.Rule in project org.hl7.fhir.core by hapifhir.
the class StructureMapUtilities method processSource.
private List<Variables> processSource(String ruleId, TransformContext context, Variables vars, StructureMapGroupRuleSourceComponent src, String pathForErrors, String indent) throws FHIRException {
List<Base> items;
if (src.getContext().equals("@search")) {
ExpressionNode expr = (ExpressionNode) src.getUserData(MAP_SEARCH_EXPRESSION);
if (expr == null) {
expr = fpe.parse(src.getElement());
src.setUserData(MAP_SEARCH_EXPRESSION, expr);
}
// string is a holder of nothing to ensure that variables are processed correctly
String search = fpe.evaluateToString(vars, null, null, new StringType(), expr);
items = services.performSearch(context.getAppInfo(), search);
} else {
items = new ArrayList<Base>();
Base b = vars.get(VariableMode.INPUT, src.getContext());
if (b == null)
throw new FHIRException("Unknown input variable " + src.getContext() + " in " + pathForErrors + " rule " + ruleId + " (vars = " + vars.summary() + ")");
if (!src.hasElement())
items.add(b);
else {
getChildrenByName(b, src.getElement(), items);
if (items.size() == 0 && src.hasDefaultValue())
items.add(src.getDefaultValueElement());
}
}
if (src.hasType()) {
List<Base> remove = new ArrayList<Base>();
for (Base item : items) {
if (item != null && !isType(item, src.getType())) {
remove.add(item);
}
}
items.removeAll(remove);
}
if (src.hasCondition()) {
ExpressionNode expr = (ExpressionNode) src.getUserData(MAP_WHERE_EXPRESSION);
if (expr == null) {
expr = fpe.parse(src.getCondition());
// fpe.check(context.appInfo, ??, ??, expr)
src.setUserData(MAP_WHERE_EXPRESSION, expr);
}
List<Base> remove = new ArrayList<Base>();
for (Base item : items) {
if (!fpe.evaluateToBoolean(vars, null, null, item, expr)) {
log(indent + " condition [" + src.getCondition() + "] for " + item.toString() + " : false");
remove.add(item);
} else
log(indent + " condition [" + src.getCondition() + "] for " + item.toString() + " : true");
}
items.removeAll(remove);
}
if (src.hasCheck()) {
ExpressionNode expr = (ExpressionNode) src.getUserData(MAP_WHERE_CHECK);
if (expr == null) {
expr = fpe.parse(src.getCheck());
// fpe.check(context.appInfo, ??, ??, expr)
src.setUserData(MAP_WHERE_CHECK, expr);
}
List<Base> remove = new ArrayList<Base>();
for (Base item : items) {
if (!fpe.evaluateToBoolean(vars, null, null, item, expr))
throw new FHIRException("Rule \"" + ruleId + "\": Check condition failed");
}
}
if (src.hasLogMessage()) {
ExpressionNode expr = (ExpressionNode) src.getUserData(MAP_WHERE_LOG);
if (expr == null) {
expr = fpe.parse(src.getLogMessage());
// fpe.check(context.appInfo, ??, ??, expr)
src.setUserData(MAP_WHERE_LOG, expr);
}
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
for (Base item : items) b.appendIfNotNull(fpe.evaluateToString(vars, null, null, item, expr));
if (b.length() > 0)
services.log(b.toString());
}
if (src.hasListMode() && !items.isEmpty()) {
switch(src.getListMode()) {
case FIRST:
Base bt = items.get(0);
items.clear();
items.add(bt);
break;
case NOTFIRST:
if (items.size() > 0)
items.remove(0);
break;
case LAST:
bt = items.get(items.size() - 1);
items.clear();
items.add(bt);
break;
case NOTLAST:
if (items.size() > 0)
items.remove(items.size() - 1);
break;
case ONLYONE:
if (items.size() > 1)
throw new FHIRException("Rule \"" + ruleId + "\": Check condition failed: the collection has more than one item");
break;
case NULL:
}
}
List<Variables> result = new ArrayList<Variables>();
for (Base r : items) {
Variables v = vars.copy();
if (src.hasVariable())
v.add(VariableMode.INPUT, src.getVariable(), r);
result.add(v);
}
return result;
}
Aggregations