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}