001/*
002 * #%L
003 * HAPI FHIR - Client Framework
004 * %%
005 * Copyright (C) 2014 - 2024 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.rest.client.impl;
021
022import ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.rest.api.EncodingEnum;
024import ca.uhn.fhir.rest.api.RequestTypeEnum;
025import ca.uhn.fhir.rest.client.api.Header;
026import ca.uhn.fhir.rest.client.api.IHttpClient;
027import ca.uhn.fhir.rest.client.api.IHttpRequest;
028import ca.uhn.fhir.rest.client.api.IRestfulClientFactory;
029import ca.uhn.fhir.util.UrlUtil;
030
031import java.util.ArrayList;
032import java.util.List;
033import java.util.Map;
034import java.util.Map.Entry;
035
036public abstract class BaseHttpClientInvocation {
037
038        private final FhirContext myContext;
039        private final List<Header> myHeaders;
040
041        public BaseHttpClientInvocation(FhirContext myContext) {
042                this.myContext = myContext;
043                this.myHeaders = new ArrayList<Header>();
044        }
045
046        public void addHeader(String theName, String theValue) {
047                myHeaders.add(new Header(theName, theValue));
048        }
049
050        /**
051         * Create an HTTP request out of this client request
052         *
053         * @param theUrlBase
054         *            The FHIR server base url (with a trailing "/")
055         * @param theExtraParams
056         *            Any extra request parameters the server wishes to add
057         * @param theEncoding
058         *            The encoding to use for any serialized content sent to the
059         *            server
060         */
061        public abstract IHttpRequest asHttpRequest(
062                        String theUrlBase,
063                        Map<String, List<String>> theExtraParams,
064                        EncodingEnum theEncoding,
065                        Boolean thePrettyPrint);
066
067        /**
068         * Create an HTTP request for the given url, encoding and request-type
069         *
070         * @param theUrl
071         *            The complete FHIR url to which the http request will be sent
072         * @param theEncoding
073         *            The encoding to use for any serialized content sent to the
074         *            server
075         * @param theRequestType
076         *            the type of HTTP request (GET, DELETE, ..)
077         */
078        protected IHttpRequest createHttpRequest(String theUrl, EncodingEnum theEncoding, RequestTypeEnum theRequestType) {
079                IHttpClient httpClient = getRestfulClientFactory()
080                                .getHttpClient(new StringBuilder(theUrl), null, null, theRequestType, myHeaders);
081                return httpClient.createGetRequest(getContext(), theEncoding);
082        }
083
084        /**
085         * Returns the FHIR context associated with this client
086         * @return the myContext
087         */
088        public FhirContext getContext() {
089                return myContext;
090        }
091
092        /**
093         * Returns the http headers to be sent with the request
094         */
095        public List<Header> getHeaders() {
096                return myHeaders;
097        }
098
099        /**
100         * Get the restfull client factory
101         */
102        public IRestfulClientFactory getRestfulClientFactory() {
103                return myContext.getRestfulClientFactory();
104        }
105
106        public static void appendExtraParamsWithQuestionMark(
107                        Map<String, List<String>> theExtraParams, StringBuilder theUrlBuilder, boolean theWithQuestionMark) {
108                if (theExtraParams == null) {
109                        return;
110                }
111                boolean first = theWithQuestionMark;
112
113                if (theExtraParams.isEmpty() == false) {
114                        for (Entry<String, List<String>> next : theExtraParams.entrySet()) {
115                                for (String nextValue : next.getValue()) {
116                                        if (first) {
117                                                theUrlBuilder.append('?');
118                                                first = false;
119                                        } else {
120                                                theUrlBuilder.append('&');
121                                        }
122                                        theUrlBuilder.append(UrlUtil.escapeUrlParam(next.getKey()));
123                                        theUrlBuilder.append('=');
124                                        theUrlBuilder.append(UrlUtil.escapeUrlParam(nextValue));
125                                }
126                        }
127                }
128        }
129}