001package org.hl7.fhir.r4.fhirpath;
002
003import org.hl7.fhir.exceptions.FHIRException;
004import org.hl7.fhir.exceptions.PathEngineException;
005import org.hl7.fhir.r4.context.IWorkerContext;
006import org.hl7.fhir.r4.model.Base;
007import org.hl7.fhir.r4.terminologies.TerminologyFunctions;
008import org.hl7.fhir.utilities.fhirpath.FHIRPathConstantEvaluationMode;
009import org.hl7.fhir.utilities.i18n.I18nConstants;
010
011import java.util.ArrayList;
012import java.util.HashMap;
013import java.util.List;
014import java.util.Map;
015
016public abstract class BaseHostServices implements IHostApplicationServices {
017
018  protected IWorkerContext context;
019  protected Map<String, FHIRPathFunctionDefinition> functions = new HashMap<>();
020
021  public BaseHostServices(IWorkerContext context) {
022    this.context = context;
023  }
024
025  @Override
026  public FHIRPathUtilityClasses.FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
027    FHIRPathFunctionDefinition fd = functions.get(functionName);
028    return fd == null ? null : fd.details();
029  }
030
031  @Override
032  public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters) throws PathEngineException {
033    FHIRPathFunctionDefinition fd = functions.get(functionName);
034    return fd == null ? null : fd.check(engine, appContext, focus, parameters);
035  }
036
037  @Override
038  public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
039    FHIRPathFunctionDefinition fd = functions.get(functionName);
040    return fd == null ? null : fd.execute(engine, appContext, focus, parameters);
041  }
042
043  public BaseHostServices registerFunction(FHIRPathFunctionDefinition function) {
044    functions.put(function.name(), function);
045    return this;
046  }
047
048  public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, FHIRPathConstantEvaluationMode mode) throws PathEngineException {
049    if (mode == FHIRPathConstantEvaluationMode.EXPLICIT && name.equals("terminologies")) {
050      return new TypeDetails(ExpressionNode.CollectionStatus.SINGLETON, "TerminologyServices");
051    } else {
052      throw makeException(I18nConstants.FHIRPATH_UNKNOWN_CONSTANT, name);
053    }
054  }
055
056  protected FHIRException makeException(String constName, Object... args) {
057    String fmt = context.formatMessage(constName, args);
058    return new PathEngineException(fmt, constName);
059  }
060
061  public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, FHIRPathConstantEvaluationMode mode) throws PathEngineException {
062    if (mode == FHIRPathConstantEvaluationMode.EXPLICIT && name.equals("terminologies")) {
063      List<Base> res = new ArrayList<>();
064      res.add(new TerminologyFunctions.TerminologiesObject());
065      return res;
066    } else {
067      throw makeException(I18nConstants.FHIRPATH_UNKNOWN_CONSTANT, name);
068    }
069  }
070
071}