001package org.hl7.fhir.r5.hapi.fhirpath; 002 003import ca.uhn.fhir.context.FhirContext; 004import ca.uhn.fhir.context.support.IValidationSupport; 005import ca.uhn.fhir.fhirpath.FhirPathExecutionException; 006import ca.uhn.fhir.fhirpath.IFhirPath; 007import ca.uhn.fhir.fhirpath.IFhirPathEvaluationContext; 008import ca.uhn.fhir.i18n.Msg; 009import org.hl7.fhir.exceptions.FHIRException; 010import org.hl7.fhir.exceptions.PathEngineException; 011import org.hl7.fhir.instance.model.api.IBase; 012import org.hl7.fhir.r5.hapi.ctx.HapiWorkerContext; 013import org.hl7.fhir.r5.model.Base; 014import org.hl7.fhir.r5.model.IdType; 015import org.hl7.fhir.r5.model.TypeDetails; 016import org.hl7.fhir.r5.model.ValueSet; 017import org.hl7.fhir.r5.utils.FHIRPathEngine; 018 019import javax.annotation.Nonnull; 020import java.util.List; 021import java.util.Optional; 022 023public class FhirPathR5 implements IFhirPath { 024 025 private FHIRPathEngine myEngine; 026 027 public FhirPathR5(FhirContext theCtx) { 028 IValidationSupport validationSupport = theCtx.getValidationSupport(); 029 myEngine = new FHIRPathEngine(new HapiWorkerContext(theCtx, validationSupport)); 030 myEngine.setDoNotEnforceAsSingletonRule(true); 031 } 032 033 @SuppressWarnings("unchecked") 034 @Override 035 public <T extends IBase> List<T> evaluate(IBase theInput, String thePath, Class<T> theReturnType) { 036 List<Base> result; 037 try { 038 result = myEngine.evaluate((Base) theInput, thePath); 039 } catch (FHIRException e) { 040 throw new FhirPathExecutionException(Msg.code(198) + e); 041 } 042 043 for (Base next : result) { 044 if (!theReturnType.isAssignableFrom(next.getClass())) { 045 throw new FhirPathExecutionException(Msg.code(199) + "FluentPath expression \"" + thePath + "\" returned unexpected type " + next.getClass().getSimpleName() + " - Expected " + theReturnType.getName()); 046 } 047 } 048 049 return (List<T>) result; 050 } 051 052 @Override 053 public <T extends IBase> Optional<T> evaluateFirst(IBase theInput, String thePath, Class<T> theReturnType) { 054 return evaluate(theInput, thePath, theReturnType).stream().findFirst(); 055 } 056 057 @Override 058 public void parse(String theExpression) { 059 myEngine.parse(theExpression); 060 } 061 062 @Override 063 public void setEvaluationContext(@Nonnull IFhirPathEvaluationContext theEvaluationContext) { 064 myEngine.setHostServices(new FHIRPathEngine.IEvaluationContext() { 065 066 @Override 067 public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException { 068 return null; 069 } 070 071 @Override 072 public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException { 073 return null; 074 } 075 076 @Override 077 public boolean log(String argument, List<Base> focus) { 078 return false; 079 } 080 081 @Override 082 public FunctionDetails resolveFunction(String functionName) { 083 return null; 084 } 085 086 @Override 087 public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException { 088 return null; 089 } 090 091 @Override 092 public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) { 093 return null; 094 } 095 096 @Override 097 public Base resolveReference(Object appContext, String theUrl, Base refContext) throws FHIRException { 098 return (Base) theEvaluationContext.resolveReference(new IdType(theUrl), refContext); 099 } 100 101 @Override 102 public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException { 103 return false; 104 } 105 106 @Override 107 public ValueSet resolveValueSet(Object appContext, String url) { 108 return null; 109 } 110 }); 111 } 112}