
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}