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