001package ca.uhn.fhir.rest.gclient;
002
003import static org.apache.commons.lang3.StringUtils.defaultString;
004
005import java.util.Arrays;
006import java.util.Collection;
007import java.util.List;
008
009import org.apache.commons.lang3.ObjectUtils;
010
011import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
012
013/*
014 * #%L
015 * HAPI FHIR - Core Library
016 * %%
017 * Copyright (C) 2014 - 2017 University Health Network
018 * %%
019 * Licensed under the Apache License, Version 2.0 (the "License");
020 * you may not use this file except in compliance with the License.
021 * You may obtain a copy of the License at
022 * 
023 *      http://www.apache.org/licenses/LICENSE-2.0
024 * 
025 * Unless required by applicable law or agreed to in writing, software
026 * distributed under the License is distributed on an "AS IS" BASIS,
027 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
028 * See the License for the specific language governing permissions and
029 * limitations under the License.
030 * #L%
031 */
032
033
034/**
035 * Token parameter type for use in fluent client interfaces
036 */
037public class TokenClientParam extends BaseClientParam  implements IParam {
038
039        private static final String[] EMPTY_STRING_LIST = new String[0];
040        
041        private String myParamName;
042
043        public TokenClientParam(String theParamName) {
044                myParamName = theParamName;
045        }
046
047        public IMatches exactly() {
048                return new IMatches() {
049                        @Override
050                        public ICriterion<TokenClientParam> code(String theCode) {
051                                return new TokenCriterion(getParamName(), null, theCode);
052                        }
053
054                        @Override
055                        public ICriterion<TokenClientParam> identifier(BaseIdentifierDt theIdentifier) {
056                                return new TokenCriterion(getParamName(), theIdentifier.getSystemElement().getValueAsString(), theIdentifier.getValueElement().getValue());
057                        }
058
059                        @Override
060                        public ICriterion<TokenClientParam> identifier(String theIdentifier) {
061                                return new TokenCriterion(getParamName(), null, theIdentifier);
062                        }
063
064                        @Override
065                        public ICriterion<TokenClientParam> identifiers(BaseIdentifierDt... theIdentifiers) {
066                                return new TokenCriterion(getParamName(), Arrays.asList(theIdentifiers));
067                        }
068
069                        @Override
070                        public ICriterion<TokenClientParam> identifiers(List<BaseIdentifierDt> theIdentifiers) {
071                                return new TokenCriterion(getParamName(), theIdentifiers);
072                        }
073
074                        @Override
075                        public ICriterion<TokenClientParam> systemAndCode(String theSystem, String theCode) {
076                                return new TokenCriterion(getParamName(), defaultString(theSystem), theCode);
077                        }
078
079                        @Override
080                        public ICriterion<TokenClientParam> systemAndIdentifier(String theSystem, String theCode) {
081                                return new TokenCriterion(getParamName(), defaultString(theSystem), theCode);
082                        }
083
084                        @Override
085                        public ICriterion<?> systemAndValues(String theSystem, String... theValues) {
086                                return new TokenCriterion(getParamName(), defaultString(theSystem), convertToList(theValues));
087                        }
088
089                        @Override
090                        public ICriterion<?> codes(String... theCodes) {
091                                return new TokenCriterion(getParamName(), convertToList(theCodes));
092                        }
093
094                        @Override
095                        public ICriterion<?> codes(Collection<String> theCodes) {
096                                return new TokenCriterion(getParamName(), theCodes);
097                        }
098
099                        
100                        
101                        private List<String> convertToList(String[] theValues) {
102                                String[] values = ObjectUtils.defaultIfNull(theValues, EMPTY_STRING_LIST);
103                                return Arrays.asList(values);
104                        }
105
106                        @Override
107                        public ICriterion<?> systemAndValues(String theSystem, Collection<String> theValues) {
108                                return new TokenCriterion(getParamName(), defaultString(theSystem), theValues);
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                /**
142                 * Creates a search criterion that matches a given system with a collection of possible 
143                 * codes (this will be used to form a comma-separated OR query) with any system value.
144                 * The URL form of this method will create a parameter like 
145                 * <code>parameter=code1,code2</code>
146                 * 
147                 * @param theCodes The codes
148                 */
149                ICriterion<?> codes(Collection<String> theCodes);
150
151
152                /**
153                 * Creates a search criterion that matches against the given identifier (system and code if both are present, or whatever is present)
154                 * 
155                 * @param theIdentifier
156                 *            The identifier
157                 * @return A criterion
158                 */
159                ICriterion<TokenClientParam> identifier(BaseIdentifierDt theIdentifier);
160
161                /**
162                 * Creates a search criterion that matches against the given identifier, with no system specified
163                 * 
164                 * @param theIdentifier
165                 *            The identifier
166                 * @return A criterion
167                 */
168                ICriterion<TokenClientParam> identifier(String theIdentifier);
169
170                /**
171                 * Creates a search criterion that matches against the given collection of identifiers (system and code if both are present, or whatever is present).
172                 * In the query URL that is generated, identifiers will be joined with a ',' to create an OR query.
173                 * 
174                 * @param theIdentifiers
175                 *            The identifier
176                 * @return A criterion
177                 */
178                ICriterion<TokenClientParam> identifiers(BaseIdentifierDt... theIdentifiers);
179
180                /**
181                 * Creates a search criterion that matches against the given collection of identifiers (system and code if both are present, or whatever is present).
182                 * In the query URL that is generated, identifiers will be joined with a ',' to create an OR query.
183                 * 
184                 * @param theIdentifiers
185                 *            The identifier
186                 * @return A criterion
187                 */
188                ICriterion<TokenClientParam> identifiers(List<BaseIdentifierDt> theIdentifiers);
189                
190                /**
191                 * Creates a search criterion that matches against the given code system and code
192                 * 
193                 * @param theSystem
194                 *            The code system (should be a URI)
195                 * @param theCode
196                 *            The code
197                 * @return A criterion
198                 */
199                ICriterion<TokenClientParam> systemAndCode(String theSystem, String theCode);
200
201                /**
202                 * Creates a search criterion that matches against the given system and identifier
203                 * 
204                 * @param theSystem
205                 *            The code system (should be a URI)
206                 * @param theIdentifier
207                 *            The identifier
208                 * @return A criterion
209                 */
210                ICriterion<TokenClientParam> systemAndIdentifier(String theSystem, String theIdentifier);
211
212                /**
213                 * Creates a search criterion that matches a given system with a collection of possible 
214                 * values (this will be used to form a comma-separated OR query)
215                 * 
216                 * @param theSystem The system, which will be used with each value
217                 * @param theValues The values
218                 */
219                ICriterion<?> systemAndValues(String theSystem, String... theValues);
220
221                /**
222                 * Creates a search criterion that matches a given system with a collection of possible 
223                 * values (this will be used to form a comma-separated OR query)
224                 * 
225                 * @param theSystem The system, which will be used with each value
226                 * @param theValues The values
227                 */
228                public ICriterion<?> systemAndValues(String theSystem, Collection<String> theValues);
229
230
231                /**
232                 * Creates a search criterion that matches a given system with a collection of possible 
233                 * codes (this will be used to form a comma-separated OR query) with any system value.
234                 * The URL form of this method will create a parameter like 
235                 * <code>parameter=code1,code2</code>
236                 * 
237                 * @param theCodes The codes
238                 */
239                ICriterion<?> codes(String...theCodes);
240
241        }
242
243}