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