001package ca.uhn.fhir.rest.server.method;
002
003/*
004 * #%L
005 * HAPI FHIR - Server Framework
006 * %%
007 * Copyright (C) 2014 - 2019 University Health Network
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import java.lang.reflect.Method;
024import java.util.ArrayList;
025import java.util.Collection;
026import java.util.List;
027import java.util.Set;
028
029import ca.uhn.fhir.context.FhirContext;
030import ca.uhn.fhir.rest.api.QualifiedParamList;
031import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
032import ca.uhn.fhir.rest.api.server.IRequestDetails;
033import ca.uhn.fhir.rest.api.server.RequestDetails;
034import ca.uhn.fhir.rest.param.QualifierDetails;
035import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
036import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
037
038public abstract class BaseQueryParameter implements IParameter {
039
040        private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseQueryParameter.class);
041
042        public abstract List<QualifiedParamList> encode(FhirContext theContext, Object theObject) throws InternalErrorException;
043
044        public abstract String getName();
045
046        public abstract RestSearchParameterTypeEnum getParamType();
047
048        /**
049         * Returns null if blacklist is "none"
050         */
051        public Set<String> getQualifierBlacklist() {
052                return null;
053        }
054
055        /**
056         * Returns null if whitelist is "all"
057         */
058        public Set<String> getQualifierWhitelist() {
059                return null;
060        }
061
062        /**
063         * Parameter should return true if {@link #parse(FhirContext, List)} should be called even if the query string
064         * contained no values for the given parameter
065         */
066        public abstract boolean handlesMissing();
067
068        @Override
069        public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) {
070                // ignore for now
071        }
072
073        public abstract boolean isRequired();
074
075        public abstract Object parse(FhirContext theContext, List<QualifiedParamList> theString) throws InternalErrorException, InvalidRequestException;
076
077        private void parseParams(RequestDetails theRequest, List<QualifiedParamList> paramList, String theQualifiedParamName, String theQualifier) {
078                QualifierDetails qualifiers = QualifierDetails.extractQualifiersFromParameterName(theQualifier);
079                if (!qualifiers.passes(getQualifierWhitelist(), getQualifierBlacklist())) {
080                        return;
081                }
082
083                String[] value = theRequest.getParameters().get(theQualifiedParamName);
084                if (value != null) {
085                        for (String nextParam : value) {
086                                if (nextParam.contains(",") == false) {
087                                        paramList.add(QualifiedParamList.singleton(theQualifier, nextParam));
088                                } else {
089                                        paramList.add(QualifiedParamList.splitQueryStringByCommasIgnoreEscape(theQualifier, nextParam));
090                                }
091                        }
092                }
093        }
094
095
096        @Override
097        public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
098
099                List<QualifiedParamList> paramList = new ArrayList<>();
100                String name = getName();
101                parseParams(theRequest, paramList, name, null);
102
103                List<String> qualified = theRequest.getUnqualifiedToQualifiedNames().get(name);
104                if (qualified != null) {
105                        for (String nextQualified : qualified) {
106                                parseParams(theRequest, paramList, nextQualified, nextQualified.substring(name.length()));
107                        }
108                }
109
110                if (paramList.isEmpty()) {
111
112                        ourLog.debug("No value for parameter '{}' - Qualified names {} and qualifier whitelist {}", new Object[] { getName(), qualified, getQualifierWhitelist() });
113
114                        if (handlesMissing()) {
115                                return parse(theRequest.getFhirContext(), paramList);
116                        }
117                        return null;
118                }
119
120                return parse(theRequest.getFhirContext(), paramList);
121
122        }
123
124}