use of org.hl7.fhir.utilities.xml.SchematronWriter.Rule in project org.hl7.fhir.core by hapifhir.
the class StructureMapUtilities method parseRule.
private void parseRule(StructureMap map, List<StructureMapGroupRuleComponent> list, FHIRLexer lexer, boolean newFmt) throws FHIRException {
StructureMapGroupRuleComponent rule = new StructureMapGroupRuleComponent();
list.add(rule);
if (!newFmt) {
rule.setName(lexer.takeDottedToken());
lexer.token(":");
lexer.token("for");
}
boolean done = false;
while (!done) {
parseSource(rule, lexer);
done = !lexer.hasToken(",");
if (!done)
lexer.next();
}
if ((newFmt && lexer.hasToken("->")) || (!newFmt && lexer.hasToken("make"))) {
lexer.token(newFmt ? "->" : "make");
done = false;
while (!done) {
parseTarget(rule, lexer);
done = !lexer.hasToken(",");
if (!done)
lexer.next();
}
}
if (lexer.hasToken("then")) {
lexer.token("then");
if (lexer.hasToken("{")) {
lexer.token("{");
if (lexer.hasComment()) {
rule.setDocumentation(lexer.take().substring(2).trim());
}
lexer.skipComments();
while (!lexer.hasToken("}")) {
if (lexer.done())
throw lexer.error("premature termination expecting '}' in nested group");
parseRule(map, rule.getRule(), lexer, newFmt);
}
lexer.token("}");
} else {
done = false;
while (!done) {
parseRuleReference(rule, lexer);
done = !lexer.hasToken(",");
if (!done)
lexer.next();
}
}
} else if (lexer.hasComment()) {
rule.setDocumentation(lexer.take().substring(2).trim());
}
if (isSimpleSyntax(rule)) {
rule.getSourceFirstRep().setVariable(AUTO_VAR_NAME);
rule.getTargetFirstRep().setVariable(AUTO_VAR_NAME);
// with no parameter - e.g. imply what is to be created
rule.getTargetFirstRep().setTransform(StructureMapTransform.CREATE);
// no dependencies - imply what is to be done based on types
}
if (newFmt) {
if (lexer.isConstant()) {
if (lexer.isStringConstant()) {
rule.setName(lexer.readConstant("ruleName"));
} else {
rule.setName(lexer.take());
}
} else {
if (rule.getSource().size() != 1 || !rule.getSourceFirstRep().hasElement())
throw lexer.error("Complex rules must have an explicit name");
if (rule.getSourceFirstRep().hasType())
rule.setName(rule.getSourceFirstRep().getElement() + "-" + rule.getSourceFirstRep().getType());
else
rule.setName(rule.getSourceFirstRep().getElement());
}
lexer.token(";");
}
lexer.skipComments();
}
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 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 executeRule.
private void executeRule(String indent, TransformContext context, StructureMap map, Variables vars, StructureMapGroupComponent group, StructureMapGroupRuleComponent rule, boolean atRoot) throws FHIRException {
log(indent + "rule : " + rule.getName() + "; vars = " + vars.summary());
Variables srcVars = vars.copy();
if (rule.getSource().size() != 1)
throw new FHIRException("Rule \"" + rule.getName() + "\": not handled yet");
List<Variables> source = processSource(rule.getName(), context, srcVars, rule.getSource().get(0), map.getUrl(), indent);
if (source != null) {
for (Variables v : source) {
for (StructureMapGroupRuleTargetComponent t : rule.getTarget()) {
processTarget(rule.getName(), context, v, map, group, t, rule.getSource().size() == 1 ? rule.getSourceFirstRep().getVariable() : null, atRoot, vars);
}
if (rule.hasRule()) {
for (StructureMapGroupRuleComponent childrule : rule.getRule()) {
executeRule(indent + " ", context, map, v, group, childrule, false);
}
} else if (rule.hasDependent()) {
for (StructureMapGroupRuleDependentComponent dependent : rule.getDependent()) {
executeDependency(indent + " ", context, map, v, group, dependent);
}
} else if (rule.getSource().size() == 1 && rule.getSourceFirstRep().hasVariable() && rule.getTarget().size() == 1 && rule.getTargetFirstRep().hasVariable() && rule.getTargetFirstRep().getTransform() == StructureMapTransform.CREATE && !rule.getTargetFirstRep().hasParameter()) {
// simple inferred, map by type
System.out.println(v.summary());
Base src = v.get(VariableMode.INPUT, rule.getSourceFirstRep().getVariable());
Base tgt = v.get(VariableMode.OUTPUT, rule.getTargetFirstRep().getVariable());
String srcType = src.fhirType();
String tgtType = tgt.fhirType();
ResolvedGroup defGroup = resolveGroupByTypes(map, rule.getName(), group, srcType, tgtType);
Variables vdef = new Variables();
vdef.add(VariableMode.INPUT, defGroup.target.getInput().get(0).getName(), src);
vdef.add(VariableMode.OUTPUT, defGroup.target.getInput().get(1).getName(), tgt);
executeGroup(indent + " ", context, defGroup.targetMap, vdef, defGroup.target, false);
}
}
}
}
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.getVariable().size()) {
throw new FHIRException("Rule '" + dependent.getName() + "' has " + Integer.toString(rg.target.getInput().size()) + " but the invocation has " + Integer.toString(dependent.getVariable().size()) + " variables");
}
Variables v = new Variables();
for (int i = 0; i < rg.target.getInput().size(); i++) {
StructureMapGroupInputComponent input = rg.target.getInput().get(i);
StringType rdp = dependent.getVariable().get(i);
String var = rdp.asStringValue();
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);
}
Aggregations