001package ca.uhn.fhir.rest.param;
002
003/*
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2022 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;
034
035import static org.apache.commons.lang3.StringUtils.defaultString;
036
037public class StringParam extends BaseParam implements IQueryParameterType {
038
039        private boolean myContains;
040        private boolean myExact;
041        private String myValue;
042
043        private Boolean myNicknameExpand;
044
045
046        /**
047         * Constructor
048         */
049        public StringParam() {
050        }
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 {
074                        return null;
075                }
076        }
077
078        @Override
079        String doGetValueAsQueryToken(FhirContext theContext) {
080                return ParameterUtil.escape(myValue);
081        }
082
083        public boolean isNicknameExpand() {
084                return myNicknameExpand != null && myNicknameExpand;
085        }
086
087        public StringParam setNicknameExpand(boolean theNicknameExpand) {
088                myNicknameExpand = theNicknameExpand;
089                return this;
090        }
091
092        @Override
093        public int hashCode() {
094                return new HashCodeBuilder(17, 37)
095                        .append(myExact)
096                        .append(myContains)
097                        .append(myValue)
098                        .append(getMissing())
099                        .toHashCode();
100        }
101
102        @Override
103        void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
104                if (Constants.PARAMQUALIFIER_NICKNAME.equals(theQualifier)) {
105                        if ("name".equals(theParamName) || "given".equals(theParamName)) {
106                                myNicknameExpand = true;
107                                theQualifier = "";
108                        } else {
109                                throw new InvalidRequestException(Msg.code(2077) + "Modifier " + Constants.PARAMQUALIFIER_NICKNAME + " may only be used with 'name' and 'given' search parameters");
110                        }
111                }
112
113                if (Constants.PARAMQUALIFIER_STRING_EXACT.equals(theQualifier)) {
114                        setExact(true);
115                } else {
116                        setExact(false);
117                }
118                if (Constants.PARAMQUALIFIER_STRING_CONTAINS.equals(theQualifier)) {
119                        setContains(true);
120                } else {
121                        setContains(false);
122                }
123                myValue = ParameterUtil.unescape(theValue);
124        }
125
126        @Override
127        public boolean equals(Object obj) {
128                if (this == obj) {
129                        return true;
130                }
131                if (obj == null) {
132                        return false;
133                }
134                if (!(obj instanceof StringParam)) {
135                        return false;
136                }
137
138                StringParam other = (StringParam) obj;
139
140                EqualsBuilder eb = new EqualsBuilder();
141                eb.append(myExact, other.myExact);
142                eb.append(myContains, other.myContains);
143                eb.append(myValue, other.myValue);
144                eb.append(getMissing(), other.getMissing());
145
146                return eb.isEquals();
147        }
148
149        public String getValue() {
150                return myValue;
151        }
152
153        public StringParam setValue(String theValue) {
154                myValue = theValue;
155                return this;
156        }
157
158        public StringDt getValueAsStringDt() {
159                return new StringDt(myValue);
160        }
161
162        public String getValueNotNull() {
163                return defaultString(myValue);
164        }
165
166        /**
167         * String parameter modifier <code>:contains</code>
168         */
169        public boolean isContains() {
170                return myContains;
171        }
172
173        /**
174         * String parameter modifier <code>:contains</code>
175         */
176        public StringParam setContains(boolean theContains) {
177                myContains = theContains;
178                if (myContains) {
179                        setExact(false);
180                        setMissing(null);
181                }
182                return this;
183        }
184
185        public boolean isEmpty() {
186                return StringUtils.isEmpty(myValue);
187        }
188
189        public boolean isExact() {
190                return myExact;
191        }
192
193        public StringParam setExact(boolean theExact) {
194                myExact = theExact;
195                if (myExact) {
196                        setContains(false);
197                        setMissing(null);
198                }
199                return this;
200        }
201
202        @Override
203        public String toString() {
204                ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
205                builder.append("value", getValue());
206                if (myExact) {
207                        builder.append("exact", myExact);
208                }
209                if (myContains) {
210                        builder.append("contains", myContains);
211                }
212                if (getMissing() != null) {
213                        builder.append("missing", getMissing().booleanValue());
214                }
215                return builder.toString();
216        }
217
218}