001/*
002 * #%L
003 * HAPI FHIR - Core Library
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.gclient;
021
022import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
023import org.apache.commons.lang3.ObjectUtils;
024import org.hl7.fhir.instance.model.api.IBaseCoding;
025
026import java.util.Arrays;
027import java.util.Collection;
028import java.util.List;
029
030import static org.apache.commons.lang3.StringUtils.defaultString;
031
032/**
033 * Token parameter type for use in fluent client interfaces
034 */
035public class TokenClientParam extends BaseClientParam implements IParam {
036
037        private static final String[] EMPTY_STRING_LIST = new String[0];
038
039        private String myParamName;
040
041        public TokenClientParam(String theParamName) {
042                myParamName = theParamName;
043        }
044
045        public IMatches exactly() {
046                return new IMatches() {
047                        @Override
048                        public ICriterion<TokenClientParam> code(String theCode) {
049                                return new TokenCriterion(getParamName(), null, theCode);
050                        }
051
052                        @Override
053                        public ICriterion<?> codes(Collection<String> theCodes) {
054                                return new TokenCriterion(getParamName(), theCodes);
055                        }
056
057                        @Override
058                        public ICriterion<?> codes(String... theCodes) {
059                                return new TokenCriterion(getParamName(), convertToList(theCodes));
060                        }
061
062                        private List<String> convertToList(String[] theValues) {
063                                String[] values = ObjectUtils.defaultIfNull(theValues, EMPTY_STRING_LIST);
064                                return Arrays.asList(values);
065                        }
066
067                        @Override
068                        public ICriterion<TokenClientParam> identifier(BaseIdentifierDt theIdentifier) {
069                                return new TokenCriterion(
070                                                getParamName(),
071                                                theIdentifier.getSystemElement().getValueAsString(),
072                                                theIdentifier.getValueElement().getValue());
073                        }
074
075                        @Override
076                        public ICriterion<TokenClientParam> identifier(String theIdentifier) {
077                                return new TokenCriterion(getParamName(), null, theIdentifier);
078                        }
079
080                        @Override
081                        public ICriterion<TokenClientParam> identifiers(BaseIdentifierDt... theIdentifiers) {
082                                return new TokenCriterion(getParamName(), Arrays.asList(theIdentifiers));
083                        }
084
085                        @Override
086                        public ICriterion<TokenClientParam> identifiers(List<BaseIdentifierDt> theIdentifiers) {
087                                return new TokenCriterion(getParamName(), theIdentifiers);
088                        }
089
090                        @Override
091                        public ICriterion<TokenClientParam> systemAndCode(String theSystem, String theCode) {
092                                return new TokenCriterion(getParamName(), defaultString(theSystem), theCode);
093                        }
094
095                        @Override
096                        public ICriterion<TokenClientParam> systemAndIdentifier(String theSystem, String theCode) {
097                                return new TokenCriterion(getParamName(), defaultString(theSystem), theCode);
098                        }
099
100                        @Override
101                        public ICriterion<?> systemAndValues(String theSystem, Collection<String> theValues) {
102                                return new TokenCriterion(getParamName(), defaultString(theSystem), theValues);
103                        }
104
105                        @Override
106                        public ICriterion<?> systemAndValues(String theSystem, String... theValues) {
107                                return new TokenCriterion(getParamName(), defaultString(theSystem), convertToList(theValues));
108                        }
109
110                        @Override
111                        public ICriterion<?> codings(IBaseCoding... theCodings) {
112                                return new TokenCriterion(getParamName(), theCodings);
113                        }
114                };
115        }
116
117        @Override
118        public String getParamName() {
119                return myParamName;
120        }
121
122        /**
123         * Create a search criterion that matches against the given system
124         * value but does not specify a code. This means that any code/identifier with
125         * the given system should match.
126         * <p>
127         * Use {@link #exactly()} if you want to specify a code.
128         * </p>
129         */
130        public ICriterion<TokenClientParam> hasSystemWithAnyCode(String theSystem) {
131                return new TokenCriterion(getParamName(), theSystem, (String) null);
132        }
133
134        public interface IMatches {
135                /**
136                 * Creates a search criterion that matches against the given code, with no code system specified
137                 *
138                 * @param theIdentifier
139                 *           The identifier
140                 * @return A criterion
141                 */
142                ICriterion<TokenClientParam> code(String theIdentifier);
143
144                /**
145                 * Creates a search criterion that matches a given system with a collection of possible
146                 * codes (this will be used to form a comma-separated OR query) with any system value.
147                 * The URL form of this method will create a parameter like
148                 * <code>parameter=code1,code2</code>
149                 *
150                 * @param theCodes
151                 *           The codes
152                 */
153                ICriterion<?> codes(Collection<String> theCodes);
154
155                /**
156                 * Creates a search criterion that matches a given system with a collection of possible
157                 * codes (this will be used to form a comma-separated OR query) with any system value.
158                 * The URL form of this method will create a parameter like
159                 * <code>parameter=code1,code2</code>
160                 *
161                 * @param theCodes
162                 *           The codes
163                 */
164                ICriterion<?> codes(String... theCodes);
165
166                /**
167                 * Creates a search criterion that matches a given system with a collection of possible
168                 * codes (this will be used to form a comma-separated OR query) with the given
169                 * <code>Coding.system</code> and <code>Coding.value</code> values.
170                 * <p>
171                 * The URL form of this method will create a parameter like
172                 * <code>parameter=system1|code1,system2|code2</code>
173                 * </p>
174                 *
175                 * @param theCodings
176                 *           The codings
177                 */
178                ICriterion<?> codings(IBaseCoding... theCodings);
179
180                /**
181                 * Creates a search criterion that matches against the given identifier (system and code if both are present, or whatever is present)
182                 *
183                 * @param theIdentifier
184                 *           The identifier
185                 * @return A criterion
186                 */
187                ICriterion<TokenClientParam> identifier(BaseIdentifierDt theIdentifier);
188
189                /**
190                 * Creates a search criterion that matches against the given identifier, with no system specified
191                 *
192                 * @param theIdentifier
193                 *           The identifier
194                 * @return A criterion
195                 */
196                ICriterion<TokenClientParam> identifier(String theIdentifier);
197
198                /**
199                 * Creates a search criterion that matches against the given collection of identifiers (system and code if both are present, or whatever is present).
200                 * In the query URL that is generated, identifiers will be joined with a ',' to create an OR query.
201                 *
202                 * @param theIdentifiers
203                 *           The identifier
204                 * @return A criterion
205                 */
206                ICriterion<TokenClientParam> identifiers(BaseIdentifierDt... theIdentifiers);
207
208                /**
209                 * Creates a search criterion that matches against the given collection of identifiers (system and code if both are present, or whatever is present).
210                 * In the query URL that is generated, identifiers will be joined with a ',' to create an OR query.
211                 *
212                 * @param theIdentifiers
213                 *           The identifier
214                 * @return A criterion
215                 */
216                ICriterion<TokenClientParam> identifiers(List<BaseIdentifierDt> theIdentifiers);
217
218                /**
219                 * Creates a search criterion that matches against the given code system and code
220                 *
221                 * @param theSystem
222                 *           The code system (should be a URI)
223                 * @param theCode
224                 *           The code
225                 * @return A criterion
226                 */
227                ICriterion<TokenClientParam> systemAndCode(String theSystem, String theCode);
228
229                /**
230                 * Creates a search criterion that matches against the given system and identifier
231                 *
232                 * @param theSystem
233                 *           The code system (should be a URI)
234                 * @param theIdentifier
235                 *           The identifier
236                 * @return A criterion
237                 */
238                ICriterion<TokenClientParam> systemAndIdentifier(String theSystem, String theIdentifier);
239
240                /**
241                 * Creates a search criterion that matches a given system with a collection of possible
242                 * values (this will be used to form a comma-separated OR query)
243                 *
244                 * @param theSystem
245                 *           The system, which will be used with each value
246                 * @param theValues
247                 *           The values
248                 */
249                public ICriterion<?> systemAndValues(String theSystem, Collection<String> theValues);
250
251                /**
252                 * Creates a search criterion that matches a given system with a collection of possible
253                 * values (this will be used to form a comma-separated OR query)
254                 *
255                 * @param theSystem
256                 *           The system, which will be used with each value
257                 * @param theValues
258                 *           The values
259                 */
260                ICriterion<?> systemAndValues(String theSystem, String... theValues);
261        }
262}