use of org.hl7.fhir.r4b.model.StructureMap.StructureMapGroupRuleTargetComponent 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.r4b.model.StructureMap.StructureMapGroupRuleTargetComponent in project org.hl7.fhir.core by hapifhir.
the class StructureMapUtilities method analyseRule.
private void analyseRule(String indent, TransformContext context, StructureMap map, VariablesForProfiling vars, StructureMapGroupComponent group, StructureMapGroupRuleComponent rule, StructureMapAnalysis result) throws FHIRException {
log(indent + "Analyse rule : " + rule.getName());
XhtmlNode tr = result.summary.addTag("tr");
XhtmlNode xs = tr.addTag("td");
XhtmlNode xt = tr.addTag("td");
VariablesForProfiling srcVars = vars.copy();
if (rule.getSource().size() != 1)
throw new FHIRException("Rule \"" + rule.getName() + "\": not handled yet");
VariablesForProfiling source = analyseSource(rule.getName(), context, srcVars, rule.getSourceFirstRep(), xs);
TargetWriter tw = new TargetWriter();
for (StructureMapGroupRuleTargetComponent t : rule.getTarget()) {
analyseTarget(rule.getName(), context, source, map, t, rule.getSourceFirstRep().getVariable(), tw, result.profiles, rule.getName());
}
tw.commit(xt);
for (StructureMapGroupRuleComponent childrule : rule.getRule()) {
analyseRule(indent + " ", context, map, source, group, childrule, result);
}
// for (StructureMapGroupRuleDependentComponent dependent : rule.getDependent()) {
// executeDependency(indent+" ", context, map, v, group, dependent); // do we need group here?
// }
}
use of org.hl7.fhir.r4b.model.StructureMap.StructureMapGroupRuleTargetComponent in project org.hl7.fhir.core by hapifhir.
the class StructureMapUtilities method runTransform.
private Base runTransform(String ruleId, TransformContext context, StructureMap map, StructureMapGroupComponent group, StructureMapGroupRuleTargetComponent tgt, Variables vars, Base dest, String element, String srcVar, boolean root) throws FHIRException {
try {
switch(tgt.getTransform()) {
case CREATE:
String tn;
if (tgt.getParameter().isEmpty()) {
// we have to work out the type. First, we see if there is a single type for the target. If there is, we use that
String[] types = dest.getTypesForProperty(element.hashCode(), element);
if (types.length == 1 && !"*".equals(types[0]) && !types[0].equals("Resource"))
tn = types[0];
else if (srcVar != null) {
tn = determineTypeFromSourceType(map, group, vars.get(VariableMode.INPUT, srcVar), types);
} else
throw new Error("Cannot determine type implicitly because there is no single input variable");
} else {
tn = getParamStringNoNull(vars, tgt.getParameter().get(0), tgt.toString());
// ok, now we resolve the type name against the import statements
for (StructureMapStructureComponent uses : map.getStructure()) {
if (uses.getMode() == StructureMapModelMode.TARGET && uses.hasAlias() && tn.equals(uses.getAlias())) {
tn = uses.getUrl();
break;
}
}
}
Base res = services != null ? services.createType(context.getAppInfo(), tn) : ResourceFactory.createResourceOrType(tn);
if (res.isResource() && !res.fhirType().equals("Parameters")) {
// res.setIdBase(tgt.getParameter().size() > 1 ? getParamString(vars, tgt.getParameter().get(0)) : UUID.randomUUID().toString().toLowerCase());
if (services != null)
res = services.createResource(context.getAppInfo(), res, root);
}
if (tgt.hasUserData("profile"))
res.setUserData("profile", tgt.getUserData("profile"));
return res;
case COPY:
return getParam(vars, tgt.getParameter().get(0));
case EVALUATE:
ExpressionNode expr = (ExpressionNode) tgt.getUserData(MAP_EXPRESSION);
if (expr == null) {
expr = fpe.parse(getParamStringNoNull(vars, tgt.getParameter().get(0), tgt.toString()));
tgt.setUserData(MAP_WHERE_EXPRESSION, expr);
}
List<Base> v = fpe.evaluate(vars, null, null, tgt.getParameter().size() == 2 ? getParam(vars, tgt.getParameter().get(0)) : new BooleanType(false), expr);
if (v.size() == 0)
return null;
else if (v.size() != 1)
throw new FHIRException("Rule \"" + ruleId + "\": Evaluation of " + expr.toString() + " returned " + v.size() + " objects");
else
return v.get(0);
case TRUNCATE:
String src = getParamString(vars, tgt.getParameter().get(0));
String len = getParamStringNoNull(vars, tgt.getParameter().get(1), tgt.toString());
if (Utilities.isInteger(len)) {
int l = Integer.parseInt(len);
if (src.length() > l)
src = src.substring(0, l);
}
return new StringType(src);
case ESCAPE:
throw new Error("Rule \"" + ruleId + "\": Transform " + tgt.getTransform().toCode() + " not supported yet");
case CAST:
src = getParamString(vars, tgt.getParameter().get(0));
if (tgt.getParameter().size() == 1)
throw new FHIRException("Implicit type parameters on cast not yet supported");
String t = getParamString(vars, tgt.getParameter().get(1));
if (t.equals("string"))
return new StringType(src);
else
throw new FHIRException("cast to " + t + " not yet supported");
case APPEND:
StringBuilder sb = new StringBuilder(getParamString(vars, tgt.getParameter().get(0)));
for (int i = 1; i < tgt.getParameter().size(); i++) sb.append(getParamString(vars, tgt.getParameter().get(i)));
return new StringType(sb.toString());
case TRANSLATE:
return translate(context, map, vars, tgt.getParameter());
case REFERENCE:
Base b = getParam(vars, tgt.getParameter().get(0));
if (b == null)
throw new FHIRException("Rule \"" + ruleId + "\": Unable to find parameter " + ((IdType) tgt.getParameter().get(0).getValue()).asStringValue());
if (!b.isResource())
throw new FHIRException("Rule \"" + ruleId + "\": Transform engine cannot point at an element of type " + b.fhirType());
else {
String id = b.getIdBase();
if (id == null) {
id = UUID.randomUUID().toString().toLowerCase();
b.setIdBase(id);
}
return new Reference().setReference(b.fhirType() + "/" + id);
}
case DATEOP:
throw new Error("Rule \"" + ruleId + "\": Transform " + tgt.getTransform().toCode() + " not supported yet");
case UUID:
return new IdType(UUID.randomUUID().toString());
case POINTER:
b = getParam(vars, tgt.getParameter().get(0));
if (b instanceof Resource)
return new UriType("urn:uuid:" + ((Resource) b).getId());
else
throw new FHIRException("Rule \"" + ruleId + "\": Transform engine cannot point at an element of type " + b.fhirType());
case CC:
CodeableConcept cc = new CodeableConcept();
cc.addCoding(buildCoding(getParamStringNoNull(vars, tgt.getParameter().get(0), tgt.toString()), getParamStringNoNull(vars, tgt.getParameter().get(1), tgt.toString())));
return cc;
case C:
Coding c = buildCoding(getParamStringNoNull(vars, tgt.getParameter().get(0), tgt.toString()), getParamStringNoNull(vars, tgt.getParameter().get(1), tgt.toString()));
return c;
default:
throw new Error("Rule \"" + ruleId + "\": Transform Unknown: " + tgt.getTransform().toCode());
}
} catch (Exception e) {
throw new FHIRException("Exception executing transform " + tgt.toString() + " on Rule \"" + ruleId + "\": " + e.getMessage(), e);
}
}
use of org.hl7.fhir.r4b.model.StructureMap.StructureMapGroupRuleTargetComponent in project org.hl7.fhir.core by hapifhir.
the class MappingSheetParser method getStructureMap.
public StructureMap getStructureMap() throws FHIRException {
StructureMap map = new StructureMap();
loadMetadata(map);
if (metadata.containsKey("copyright"))
map.setCopyright(metadata.get("copyright"));
StructureMapGroupComponent grp = map.addGroup();
for (MappingRow row : rows) {
StructureMapGroupRuleComponent rule = grp.addRule();
rule.setName(row.getSequence());
StructureMapGroupRuleSourceComponent src = rule.getSourceFirstRep();
src.setContext("src");
src.setElement(row.getIdentifier());
src.setMin(row.getCardinalityMin());
src.setMax(row.getCardinalityMax());
src.setType(row.getDataType());
src.addExtension(ToolingExtensions.EXT_MAPPING_NAME, new StringType(row.getName()));
if (row.getCondition() != null) {
src.setCheck(processCondition(row.getCondition()));
}
StructureMapGroupRuleTargetComponent tgt = rule.getTargetFirstRep();
tgt.setContext("tgt");
tgt.setElement(row.getAttribute());
tgt.addExtension(ToolingExtensions.EXT_MAPPING_TGTTYPE, new StringType(row.getType()));
tgt.addExtension(ToolingExtensions.EXT_MAPPING_TGTCARD, new StringType(row.getMinMax()));
if (row.getDtMapping() != null) {
src.setVariable("s");
tgt.setVariable("t");
tgt.setTransform(StructureMapTransform.CREATE);
StructureMapGroupRuleDependentComponent dep = rule.addDependent();
dep.setName(row.getDtMapping());
dep.addVariable("s");
dep.addVariable("t");
} else if (row.getVocabMapping() != null) {
tgt.setTransform(StructureMapTransform.TRANSLATE);
tgt.addParameter().setValue(new StringType(row.getVocabMapping()));
tgt.addParameter().setValue(new IdType("src"));
} else {
tgt.setTransform(StructureMapTransform.COPY);
}
rule.setDocumentation(row.getComments());
if (row.getDerived() != null) {
tgt = rule.addTarget();
tgt.setContext("tgt");
tgt.setElement(row.getDerived());
tgt.setTransform(StructureMapTransform.COPY);
tgt.addParameter().setValue(new StringType(row.getDerivedMapping()));
}
}
return map;
}
use of org.hl7.fhir.r4b.model.StructureMap.StructureMapGroupRuleTargetComponent in project org.hl7.fhir.core by hapifhir.
the class StructureMapUtilities method analyseTransform.
private TypeDetails analyseTransform(TransformContext context, StructureMap map, StructureMapGroupRuleTargetComponent tgt, VariableForProfiling var, VariablesForProfiling vars) throws FHIRException {
switch(tgt.getTransform()) {
case CREATE:
String p = getParamString(vars, tgt.getParameter().get(0));
return new TypeDetails(CollectionStatus.SINGLETON, p);
case COPY:
return getParam(vars, tgt.getParameter().get(0));
case EVALUATE:
ExpressionNode expr = (ExpressionNode) tgt.getUserData(MAP_EXPRESSION);
if (expr == null) {
expr = fpe.parse(getParamString(vars, tgt.getParameter().get(tgt.getParameter().size() - 1)));
tgt.setUserData(MAP_WHERE_EXPRESSION, expr);
}
return fpe.check(vars, null, expr);
case TRANSLATE:
return new TypeDetails(CollectionStatus.SINGLETON, "CodeableConcept");
case CC:
ProfiledType res = new ProfiledType("CodeableConcept");
if (tgt.getParameter().size() >= 2 && isParamId(vars, tgt.getParameter().get(1))) {
TypeDetails td = vars.get(null, getParamId(vars, tgt.getParameter().get(1))).getProperty().getTypes();
if (td != null && td.hasBinding())
// todo: do we need to check that there's no implicit translation her? I don't think we do...
res.addBinding(td.getBinding());
}
return new TypeDetails(CollectionStatus.SINGLETON, res);
case C:
return new TypeDetails(CollectionStatus.SINGLETON, "Coding");
case QTY:
return new TypeDetails(CollectionStatus.SINGLETON, "Quantity");
case REFERENCE:
VariableForProfiling vrs = vars.get(VariableMode.OUTPUT, getParamId(vars, tgt.getParameterFirstRep()));
if (vrs == null)
throw new FHIRException("Unable to resolve variable \"" + getParamId(vars, tgt.getParameterFirstRep()) + "\"");
String profile = vrs.getProperty().getProfileProperty().getStructure().getUrl();
TypeDetails td = new TypeDetails(CollectionStatus.SINGLETON);
td.addType("Reference", profile);
return td;
default:
throw new Error("Transform Unknown or not handled yet: " + tgt.getTransform().toCode());
}
}
Aggregations