001package ca.uhn.fhir.rest.param;
002
003/*
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2023 Smile CDR, Inc.
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import ca.uhn.fhir.context.FhirContext;
024import ca.uhn.fhir.i18n.Msg;
025import ca.uhn.fhir.model.api.IQueryParameterType;
026import ca.uhn.fhir.model.primitive.StringDt;
027import ca.uhn.fhir.rest.api.Constants;
028import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
029import org.apache.commons.lang3.StringUtils;
030import org.apache.commons.lang3.builder.EqualsBuilder;
031import org.apache.commons.lang3.builder.HashCodeBuilder;
032import org.apache.commons.lang3.builder.ToStringBuilder;
033import org.apache.commons.lang3.builder.ToStringStyle;
034import org.slf4j.Logger;
035import org.slf4j.LoggerFactory;
036
037import static org.apache.commons.lang3.StringUtils.defaultString;
038
039public class StringParam extends BaseParam implements IQueryParameterType {
040
041        private static final Logger ourLog = LoggerFactory.getLogger(StringParam.class);
042
043        private boolean myText;
044        private boolean myContains;
045        private boolean myExact;
046        private String myValue;
047
048        private Boolean myNicknameExpand;
049
050
051        /**
052         * Constructor
053         */
054        public StringParam() {
055        }
056
057        /**
058         * Constructor
059         */
060        public StringParam(String theValue) {
061                setValue(theValue);
062        }
063
064        /**
065         * Constructor
066         */
067        public StringParam(String theValue, boolean theExact) {
068                setValue(theValue);
069                setExact(theExact);
070        }
071
072        @Override
073        String doGetQueryParameterQualifier() {
074                if (isExact()) {
075                        return Constants.PARAMQUALIFIER_STRING_EXACT;
076                } else if (isContains()) {
077                        return Constants.PARAMQUALIFIER_STRING_CONTAINS;
078                } else if (isText()) {
079                        return Constants.PARAMQUALIFIER_STRING_TEXT;
080                } else {
081                        return null;
082                }
083        }
084
085        @Override
086        String doGetValueAsQueryToken(FhirContext theContext) {
087                return ParameterUtil.escape(myValue);
088        }
089
090        public boolean isNicknameExpand() {
091                return myNicknameExpand != null && myNicknameExpand;
092        }
093
094        public StringParam setNicknameExpand(boolean theNicknameExpand) {
095                myNicknameExpand = theNicknameExpand;
096                return this;
097        }
098
099        @Override
100        public int hashCode() {
101                return new HashCodeBuilder(17, 37)
102                        .append(myExact)
103                        .append(myText)
104                        .append(myContains)
105                        .append(myValue)
106                        .append(getMissing())
107                        .toHashCode();
108        }
109
110        @Override
111        void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
112                if (Constants.PARAMQUALIFIER_NICKNAME.equals(theQualifier)) {
113                        myNicknameExpand = true;
114                        theQualifier = "";
115
116                        if (!("name".equals(theParamName) || "given".equals(theParamName))){
117                                ourLog.debug(":nickname qualifier was assigned to a search parameter other than one of the intended parameters \"name\" and \"given\"");
118                        }
119                }
120
121                if (Constants.PARAMQUALIFIER_STRING_EXACT.equals(theQualifier)) {
122                        setExact(true);
123                } else {
124                        setExact(false);
125                }
126                if (Constants.PARAMQUALIFIER_STRING_CONTAINS.equals(theQualifier)) {
127                        setContains(true);
128                } else {
129                        setContains(false);
130                }
131
132                setText( Constants.PARAMQUALIFIER_STRING_TEXT.equals(theQualifier) );
133
134                myValue = ParameterUtil.unescape(theValue);
135        }
136
137        @Override
138        public boolean equals(Object obj) {
139                if (this == obj) {
140                        return true;
141                }
142                if (obj == null) {
143                        return false;
144                }
145                if (!(obj instanceof StringParam)) {
146                        return false;
147                }
148
149                StringParam other = (StringParam) obj;
150
151                EqualsBuilder eb = new EqualsBuilder();
152                eb.append(myExact, other.myExact);
153                eb.append(myText, other.myText);
154                eb.append(myContains, other.myContains);
155                eb.append(myValue, other.myValue);
156                eb.append(getMissing(), other.getMissing());
157
158                return eb.isEquals();
159        }
160
161        public String getValue() {
162                return myValue;
163        }
164
165        public StringParam setValue(String theValue) {
166                myValue = theValue;
167                return this;
168        }
169
170        public StringDt getValueAsStringDt() {
171                return new StringDt(myValue);
172        }
173
174        public String getValueNotNull() {
175                return defaultString(myValue);
176        }
177
178        public boolean isText() { return myText; }
179
180        public void setText(boolean theText) {
181                myText = theText;
182                if (myText) {
183                        setContains(false);
184                        setExact(false);
185                        setMissing(null);
186
187                }
188        }
189
190        /**
191         * String parameter modifier <code>:contains</code>
192         */
193        public boolean isContains() {
194                return myContains;
195        }
196
197        /**
198         * String parameter modifier <code>:contains</code>
199         */
200        public StringParam setContains(boolean theContains) {
201                myContains = theContains;
202                if (myContains) {
203                        setText(false);
204                        setExact(false);
205                        setMissing(null);
206                }
207                return this;
208        }
209
210        public boolean isEmpty() {
211                return StringUtils.isEmpty(myValue);
212        }
213
214        public boolean isExact() {
215                return myExact;
216        }
217
218        public StringParam setExact(boolean theExact) {
219                myExact = theExact;
220                if (myExact) {
221                        setText(false);
222                        setContains(false);
223                        setMissing(null);
224                }
225                return this;
226        }
227
228        @Override
229        public String toString() {
230                ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
231                builder.append("value", getValue());
232                if (myText) {
233                        builder.append("text", myText);
234                }
235                if (myExact) {
236                        builder.append("exact", myExact);
237                }
238                if (myContains) {
239                        builder.append("contains", myContains);
240                }
241                if (getMissing() != null) {
242                        builder.append("missing", getMissing().booleanValue());
243                }
244                return builder.toString();
245        }
246
247}