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