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 ca.uhn.fhir.context.FhirContext;
024import ca.uhn.fhir.rest.api.QualifiedParamList;
025import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
026import ca.uhn.fhir.rest.api.server.RequestDetails;
027import ca.uhn.fhir.rest.param.QualifierDetails;
028import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
029import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
030
031import java.lang.reflect.Method;
032import java.util.ArrayList;
033import java.util.Collection;
034import java.util.List;
035import java.util.Set;
036
037public abstract class BaseQueryParameter implements IParameter {
038
039        private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseQueryParameter.class);
040
041        public abstract List<QualifiedParamList> encode(FhirContext theContext, Object theObject) throws InternalErrorException;
042
043        public abstract String getName();
044
045        public abstract RestSearchParameterTypeEnum getParamType();
046
047        /**
048         * Returns null if blacklist is "none"
049         */
050        public Set<String> getQualifierBlacklist() {
051                return null;
052        }
053
054        /**
055         * Returns null if whitelist is "all"
056         */
057        public Set<String> getQualifierWhitelist() {
058                return null;
059        }
060
061        /**
062         * Parameter should return true if {@link #parse(FhirContext, List)} should be called even if the query string
063         * contained no values for the given parameter
064         */
065        public abstract boolean handlesMissing();
066
067        @Override
068        public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) {
069                // ignore for now
070        }
071
072        public abstract boolean isRequired();
073
074        public abstract Object parse(FhirContext theContext, List<QualifiedParamList> theString) throws InternalErrorException, InvalidRequestException;
075
076        private void parseParams(RequestDetails theRequest, List<QualifiedParamList> paramList, String theQualifiedParamName, String theQualifier) {
077                QualifierDetails qualifiers = QualifierDetails.extractQualifiersFromParameterName(theQualifier);
078                if (!qualifiers.passes(getQualifierWhitelist(), getQualifierBlacklist())) {
079                        return;
080                }
081
082                String[] value = theRequest.getParameters().get(theQualifiedParamName);
083                if (value != null) {
084                        for (String nextParam : value) {
085                                if (nextParam.contains(",") == false) {
086                                        paramList.add(QualifiedParamList.singleton(theQualifier, nextParam));
087                                } else {
088                                        paramList.add(QualifiedParamList.splitQueryStringByCommasIgnoreEscape(theQualifier, nextParam));
089                                }
090                        }
091                }
092        }
093
094
095        @Override
096        public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
097
098                List<QualifiedParamList> paramList = new ArrayList<>();
099                String name = getName();
100                parseParams(theRequest, paramList, name, null);
101
102                List<String> qualified = theRequest.getUnqualifiedToQualifiedNames().get(name);
103                if (qualified != null) {
104                        for (String nextQualified : qualified) {
105                                parseParams(theRequest, paramList, nextQualified, nextQualified.substring(name.length()));
106                        }
107                }
108
109                if (paramList.isEmpty()) {
110
111                        ourLog.debug("No value for parameter '{}' - Qualified names {} and qualifier whitelist {}", new Object[] { getName(), qualified, getQualifierWhitelist() });
112
113                        if (handlesMissing()) {
114                                return parse(theRequest.getFhirContext(), paramList);
115                        }
116                        return null;
117                }
118
119                return parse(theRequest.getFhirContext(), paramList);
120
121        }
122
123}