001package org.hl7.fhir.r5.utils.structuremap;
002
003import org.apache.commons.lang3.NotImplementedException;
004import org.hl7.fhir.exceptions.FHIRException;
005import org.hl7.fhir.exceptions.PathEngineException;
006import org.hl7.fhir.r5.elementmodel.Element;
007import org.hl7.fhir.r5.model.Base;
008import org.hl7.fhir.r5.model.Resource;
009import org.hl7.fhir.r5.model.TypeDetails;
010import org.hl7.fhir.r5.model.ValueSet;
011import org.hl7.fhir.r5.utils.FHIRPathEngine;
012import org.hl7.fhir.r5.utils.FHIRPathUtilityClasses.FunctionDetails;
013import org.hl7.fhir.r5.utils.validation.IResourceValidator;
014import org.hl7.fhir.utilities.validation.ValidationMessage;
015
016import java.util.ArrayList;
017import java.util.List;
018
019public class FFHIRPathHostServices implements FHIRPathEngine.IEvaluationContext {
020
021  private final StructureMapUtilities structureMapUtilities;
022
023  public FFHIRPathHostServices(StructureMapUtilities structureMapUtilities) {
024    this.structureMapUtilities = structureMapUtilities;
025  }
026
027  public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
028    Variables vars = (Variables) appContext;
029    Base res = vars.get(VariableMode.INPUT, name);
030    if (res == null)
031      res = vars.get(VariableMode.OUTPUT, name);
032    List<Base> result = new ArrayList<Base>();
033    if (res != null)
034      result.add(res);
035    return result;
036  }
037
038  @Override
039  public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
040    if (!(appContext instanceof VariablesForProfiling))
041      throw new Error("Internal Logic Error (wrong type '" + appContext.getClass().getName() + "' in resolveConstantType)");
042    VariablesForProfiling vars = (VariablesForProfiling) appContext;
043    VariableForProfiling v = vars.get(null, name);
044    if (v == null)
045      throw new PathEngineException("Unknown variable '" + name + "' from variables " + vars.summary());
046    return v.getProperty().getTypes();
047  }
048
049  @Override
050  public boolean log(String argument, List<Base> focus) {
051    throw new Error("Not Implemented Yet");
052  }
053
054  @Override
055  public FunctionDetails resolveFunction(String functionName) {
056    return null; // throw new Error("Not Implemented Yet");
057  }
058
059  @Override
060  public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException {
061    throw new Error("Not Implemented Yet");
062  }
063
064  @Override
065  public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
066    throw new Error("Not Implemented Yet");
067  }
068
069  @Override
070  public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException {
071    if (structureMapUtilities.getServices() == null)
072      return null;
073    return structureMapUtilities.getServices().resolveReference(appContext, url);
074  }
075
076  private boolean noErrorValidationMessages(List<ValidationMessage> valerrors) {
077    boolean ok = true;
078    for (ValidationMessage v : valerrors)
079      ok = ok && !v.getLevel().isError();
080    return ok;
081  }
082
083  @Override
084  public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
085    IResourceValidator val = structureMapUtilities.getWorker().newValidator();
086    List<ValidationMessage> valerrors = new ArrayList<ValidationMessage>();
087    if (item instanceof Resource) {
088      val.validate(appContext, valerrors, (Resource) item, url);
089      return noErrorValidationMessages(valerrors);
090    }
091    if (item instanceof Element) {
092      val.validate(appContext, valerrors, null, (Element) item, url);
093      return noErrorValidationMessages(valerrors);
094    }
095    throw new NotImplementedException("Not done yet (FFHIRPathHostServices.conformsToProfile), when item is not element or not resource");
096  }
097
098  @Override
099  public ValueSet resolveValueSet(Object appContext, String url) {
100        return structureMapUtilities.getWorker().fetchResource(ValueSet.class, url);
101  }
102
103}