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.param;
021
022import ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.model.api.IQueryParameterType;
024import ca.uhn.fhir.model.primitive.StringDt;
025import ca.uhn.fhir.rest.api.Constants;
026import org.apache.commons.lang3.StringUtils;
027import org.apache.commons.lang3.builder.EqualsBuilder;
028import org.apache.commons.lang3.builder.HashCodeBuilder;
029import org.apache.commons.lang3.builder.ToStringBuilder;
030import org.apache.commons.lang3.builder.ToStringStyle;
031import org.slf4j.Logger;
032import org.slf4j.LoggerFactory;
033
034import static org.apache.commons.lang3.StringUtils.defaultString;
035
036public class StringParam extends BaseParam implements IQueryParameterType {
037
038        private static final Logger ourLog = LoggerFactory.getLogger(StringParam.class);
039
040        private boolean myText;
041        private boolean myContains;
042        private boolean myExact;
043        private String myValue;
044
045        private Boolean myNicknameExpand;
046
047        /**
048         * Constructor
049         */
050        public StringParam() {}
051
052        /**
053         * Constructor
054         */
055        public StringParam(String theValue) {
056                setValue(theValue);
057        }
058
059        /**
060         * Constructor
061         */
062        public StringParam(String theValue, boolean theExact) {
063                setValue(theValue);
064                setExact(theExact);
065        }
066
067        @Override
068        String doGetQueryParameterQualifier() {
069                if (isExact()) {
070                        return Constants.PARAMQUALIFIER_STRING_EXACT;
071                } else if (isContains()) {
072                        return Constants.PARAMQUALIFIER_STRING_CONTAINS;
073                } else if (isText()) {
074                        return Constants.PARAMQUALIFIER_STRING_TEXT;
075                } else {
076                        return null;
077                }
078        }
079
080        @Override
081        String doGetValueAsQueryToken(FhirContext theContext) {
082                return ParameterUtil.escape(myValue);
083        }
084
085        public boolean isNicknameExpand() {
086                return myNicknameExpand != null && myNicknameExpand;
087        }
088
089        public StringParam setNicknameExpand(boolean theNicknameExpand) {
090                myNicknameExpand = theNicknameExpand;
091                return this;
092        }
093
094        @Override
095        public int hashCode() {
096                return new HashCodeBuilder(17, 37)
097                                .append(myExact)
098                                .append(myText)
099                                .append(myContains)
100                                .append(myValue)
101                                .append(getMissing())
102                                .toHashCode();
103        }
104
105        @Override
106        void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
107                if (Constants.PARAMQUALIFIER_NICKNAME.equals(theQualifier)) {
108                        myNicknameExpand = true;
109                        theQualifier = "";
110
111                        if (!("name".equals(theParamName) || "given".equals(theParamName))) {
112                                ourLog.debug(
113                                                ":nickname qualifier was assigned to a search parameter other than one of the intended parameters \"name\" and \"given\"");
114                        }
115                }
116
117                if (Constants.PARAMQUALIFIER_STRING_EXACT.equals(theQualifier)) {
118                        setExact(true);
119                } else {
120                        setExact(false);
121                }
122                if (Constants.PARAMQUALIFIER_STRING_CONTAINS.equals(theQualifier)) {
123                        setContains(true);
124                } else {
125                        setContains(false);
126                }
127
128                setText(Constants.PARAMQUALIFIER_STRING_TEXT.equals(theQualifier));
129
130                myValue = ParameterUtil.unescape(theValue);
131        }
132
133        @Override
134        public boolean equals(Object obj) {
135                if (this == obj) {
136                        return true;
137                }
138                if (obj == null) {
139                        return false;
140                }
141                if (!(obj instanceof StringParam)) {
142                        return false;
143                }
144
145                StringParam other = (StringParam) obj;
146
147                EqualsBuilder eb = new EqualsBuilder();
148                eb.append(myExact, other.myExact);
149                eb.append(myText, other.myText);
150                eb.append(myContains, other.myContains);
151                eb.append(myValue, other.myValue);
152                eb.append(getMissing(), other.getMissing());
153
154                return eb.isEquals();
155        }
156
157        public String getValue() {
158                return myValue;
159        }
160
161        public StringParam setValue(String theValue) {
162                myValue = theValue;
163                return this;
164        }
165
166        public StringDt getValueAsStringDt() {
167                return new StringDt(myValue);
168        }
169
170        public String getValueNotNull() {
171                return defaultString(myValue);
172        }
173
174        public boolean isText() {
175                return myText;
176        }
177
178        public void setText(boolean theText) {
179                myText = theText;
180                if (myText) {
181                        setContains(false);
182                        setExact(false);
183                        setMissing(null);
184                }
185        }
186
187        /**
188         * String parameter modifier <code>:contains</code>
189         */
190        public boolean isContains() {
191                return myContains;
192        }
193
194        /**
195         * String parameter modifier <code>:contains</code>
196         */
197        public StringParam setContains(boolean theContains) {
198                myContains = theContains;
199                if (myContains) {
200                        setText(false);
201                        setExact(false);
202                        setMissing(null);
203                }
204                return this;
205        }
206
207        public boolean isEmpty() {
208                return StringUtils.isEmpty(myValue);
209        }
210
211        public boolean isExact() {
212                return myExact;
213        }
214
215        public StringParam setExact(boolean theExact) {
216                myExact = theExact;
217                if (myExact) {
218                        setText(false);
219                        setContains(false);
220                        setMissing(null);
221                }
222                return this;
223        }
224
225        @Override
226        public String toString() {
227                ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
228                builder.append("value", getValue());
229                if (myText) {
230                        builder.append("text", myText);
231                }
232                if (myExact) {
233                        builder.append("exact", myExact);
234                }
235                if (myContains) {
236                        builder.append("contains", myContains);
237                }
238                if (getMissing() != null) {
239                        builder.append("missing", getMissing().booleanValue());
240                }
241                return builder.toString();
242        }
243}