001/*-
002 * #%L
003 * HAPI FHIR - Server Framework
004 * %%
005 * Copyright (C) 2014 - 2025 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.server.util;
021
022import ca.uhn.fhir.i18n.Msg;
023import ca.uhn.fhir.rest.api.Constants;
024import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
025import org.apache.commons.lang3.StringUtils;
026import org.apache.http.NameValuePair;
027import org.apache.http.client.utils.URLEncodedUtils;
028import org.apache.http.message.BasicNameValuePair;
029
030import java.util.List;
031
032public class MatchUrlUtil {
033
034        /**
035         * Non-instantiable
036         */
037        private MatchUrlUtil() {
038                // nothing
039        }
040
041        /**
042         * Parses a FHIR-style Match URL (Patient?identifier=http://foo|bar) into
043         * a parsed set of parameters.
044         */
045        public static List<NameValuePair> translateMatchUrl(String theMatchUrl) {
046                List<NameValuePair> parameters;
047                String matchUrl = theMatchUrl;
048                int questionMarkIndex = matchUrl.indexOf('?');
049                if (questionMarkIndex != -1) {
050                        matchUrl = matchUrl.substring(questionMarkIndex + 1);
051                }
052
053                final String[] searchList = new String[] {"|", "=>=", "=<=", "=>", "=<"};
054                final String[] replacementList = new String[] {"%7C", "=%3E%3D", "=%3C%3D", "=%3E", "=%3C"};
055                matchUrl = StringUtils.replaceEach(matchUrl, searchList, replacementList);
056                if (matchUrl.contains(" ")) {
057                        throw new InvalidRequestException(Msg.code(1744) + "Failed to parse match URL[" + theMatchUrl
058                                        + "] - URL is invalid (must not contain spaces)");
059                }
060
061                parameters = URLEncodedUtils.parse((matchUrl), Constants.CHARSET_UTF8, '&');
062
063                // One issue that has happened before is people putting a "+" sign into an email address in a match URL
064                // and having that turn into a " ". Since spaces are never appropriate for email addresses, let's just
065                // assume they really meant "+".
066                for (int i = 0; i < parameters.size(); i++) {
067                        NameValuePair next = parameters.get(i);
068                        if (next.getName().equals("email") && next.getValue().contains(" ")) {
069                                BasicNameValuePair newPair =
070                                                new BasicNameValuePair(next.getName(), next.getValue().replace(' ', '+'));
071                                parameters.set(i, newPair);
072                        }
073                }
074
075                return parameters;
076        }
077}