001package ca.uhn.fhir.rest.param;
002
003/*
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2019 University Health Network
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 java.math.BigDecimal;
024import java.util.List;
025
026import org.apache.commons.lang3.StringUtils;
027import org.apache.commons.lang3.builder.ToStringBuilder;
028import org.apache.commons.lang3.builder.ToStringStyle;
029import org.hl7.fhir.instance.model.api.IPrimitiveType;
030
031import ca.uhn.fhir.context.FhirContext;
032import ca.uhn.fhir.model.api.IQueryParameterType;
033import ca.uhn.fhir.model.primitive.DecimalDt;
034import ca.uhn.fhir.model.primitive.UriDt;
035import ca.uhn.fhir.util.CoverageIgnore;
036
037public class QuantityParam extends BaseParamWithPrefix<QuantityParam> implements IQueryParameterType {
038
039        private static final long serialVersionUID = 1L;
040        private BigDecimal myValue;
041        private String mySystem;
042        private String myUnits;
043
044        /**
045         * Constructor
046         */
047        public QuantityParam() {
048                super();
049        }
050
051        /**
052         * Constructor
053         * 
054         * @param thePrefix
055         *           The comparator, or <code>null</code> for an equals comparator
056         * @param theValue
057         *           A quantity value
058         * @param theSystem
059         *           The unit system
060         * @param theUnits
061         *           The unit code
062         */
063        public QuantityParam(ParamPrefixEnum thePrefix, BigDecimal theValue, String theSystem, String theUnits) {
064                setPrefix(thePrefix);
065                setValue(theValue);
066                setSystem(theSystem);
067                setUnits(theUnits);
068        }
069
070        /**
071         * Constructor
072         * 
073         * @param thePrefix
074         *           The comparator, or <code>null</code> for an equals comparator
075         * @param theValue
076         *           A quantity value
077         * @param theSystem
078         *           The unit system
079         * @param theUnits
080         *           The unit code
081         */
082        public QuantityParam(ParamPrefixEnum thePrefix, double theValue, String theSystem, String theUnits) {
083                setPrefix(thePrefix);
084                setValue(theValue);
085                setSystem(theSystem);
086                setUnits(theUnits);
087        }
088
089        /**
090         * Constructor
091         * 
092         * @param thePrefix
093         *           The comparator, or <code>null</code> for an equals comparator
094         * @param theValue
095         *           A quantity value
096         * @param theSystem
097         *           The unit system
098         * @param theUnits
099         *           The unit code
100         */
101        public QuantityParam(ParamPrefixEnum thePrefix, long theValue, String theSystem, String theUnits) {
102                setPrefix(thePrefix);
103                setValue(theValue);
104                setSystem(theSystem);
105                setUnits(theUnits);
106        }
107
108        /**
109         * Constructor
110         * 
111         * @param theQuantity
112         *           A quantity value (with no system or units), such as "100.0" or "gt4"
113         */
114        public QuantityParam(String theQuantity) {
115                setValueAsQueryToken(null, null, null, theQuantity);
116        }
117
118        /**
119         * Constructor
120         * 
121         * @param theQuantity
122         *           A quantity value (with no system or units), such as <code>100</code>
123         */
124        public QuantityParam(long theQuantity) {
125                setValueAsQueryToken(null, null, null, Long.toString(theQuantity));
126        }
127
128        /**
129         * Constructor
130         * 
131         * @param theQuantity
132         *           A quantity value (with no system or units), such as "100.0" or "&lt;=4"
133         * @param theSystem
134         *           The unit system
135         * @param theUnits
136         *           The unit code
137         */
138        public QuantityParam(String theQuantity, String theSystem, String theUnits) {
139                setValueAsQueryToken(null, null, null, theQuantity);
140                setSystem(theSystem);
141                setUnits(theUnits);
142        }
143
144        private void clear() {
145                setPrefix(null);
146                setSystem((String) null);
147                setUnits(null);
148                setValue((BigDecimal) null);
149        }
150
151        @Override
152        String doGetQueryParameterQualifier() {
153                return null;
154        }
155
156        @Override
157        String doGetValueAsQueryToken(FhirContext theContext) {
158                StringBuilder b = new StringBuilder();
159                if (getPrefix() != null) {
160                        b.append(ParameterUtil.escapeWithDefault(getPrefix().getValue()));
161                }
162
163                b.append(ParameterUtil.escapeWithDefault(getValueAsString()));
164                b.append('|');
165                b.append(ParameterUtil.escapeWithDefault(mySystem));
166                b.append('|');
167                b.append(ParameterUtil.escapeWithDefault(myUnits));
168
169                return b.toString();
170        }
171
172        public String getValueAsString() {
173                if (myValue != null) {
174                        return myValue.toPlainString();
175                }
176                return null;
177        }
178
179        @Override
180        void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
181                clear();
182
183                if (theValue == null) {
184                        return;
185                }
186                List<String> parts = ParameterUtil.splitParameterString(theValue, '|', true);
187
188                if (parts.size() > 0 && StringUtils.isNotBlank(parts.get(0))) {
189                        String value = super.extractPrefixAndReturnRest(parts.get(0));
190                        setValue(value);
191                }
192                if (parts.size() > 1 && StringUtils.isNotBlank(parts.get(1))) {
193                        setSystem(parts.get(1));
194                }
195                if (parts.size() > 2 && StringUtils.isNotBlank(parts.get(2))) {
196                        setUnits(parts.get(2));
197                }
198
199        }
200
201        /**
202         * Returns the system, or null if none was provided
203         * <p>
204         * Note that prior to HAPI FHIR 1.5, this method returned a {@link UriDt}
205         * </p>
206         * 
207         * @since 1.5
208         */
209        public String getSystem() {
210                return mySystem;
211        }
212
213        /**
214         * @deprecated Use {{@link #getSystem()}} instead
215         */
216        @Deprecated
217        @CoverageIgnore
218        public UriDt getSystemAsUriDt() {
219                return new UriDt(mySystem);
220        }
221
222        public String getUnits() {
223                return myUnits;
224        }
225
226        /**
227         * Returns the quantity/value, or null if none was provided
228         * <p>
229         * Note that prior to HAPI FHIR 1.5, this method returned a {@link DecimalDt}
230         * </p>
231         * 
232         * @since 1.5
233         */
234        public BigDecimal getValue() {
235                return myValue;
236        }
237
238        public QuantityParam setSystem(String theSystem) {
239                mySystem = theSystem;
240                return this;
241        }
242
243        public QuantityParam setSystem(IPrimitiveType<String> theSystem) {
244                mySystem = null;
245                if (theSystem != null) {
246                        mySystem = theSystem.getValue();
247                }
248                return this;
249        }
250
251        public QuantityParam setUnits(String theUnits) {
252                myUnits = theUnits;
253                return this;
254        }
255
256        public QuantityParam setValue(BigDecimal theValue) {
257                myValue = theValue;
258                return this;
259        }
260
261        public QuantityParam setValue(IPrimitiveType<BigDecimal> theValue) {
262                myValue = null;
263                if (theValue != null) {
264                        myValue = theValue.getValue();
265                }
266                return this;
267        }
268
269        public QuantityParam setValue(String theValue) {
270                myValue = null;
271                if (theValue != null) {
272                        myValue = new BigDecimal(theValue);
273                }
274                return this;
275        }
276
277        public QuantityParam setValue(double theValue) {
278                // Use the valueOf here because the constructor gives crazy precision
279                // changes due to the floating point conversion
280                myValue = BigDecimal.valueOf(theValue);
281                return this;
282        }
283
284        public QuantityParam setValue(long theValue) {
285                // Use the valueOf here because the constructor gives crazy precision
286                // changes due to the floating point conversion
287                myValue = BigDecimal.valueOf(theValue);
288                return this;
289        }
290
291        @Override
292        public String toString() {
293                ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
294                b.append("prefix", getPrefix());
295                b.append("value", myValue);
296                b.append("system", mySystem);
297                b.append("units", myUnits);
298                if (getMissing() != null) {
299                        b.append("missing", getMissing());
300                }
301                return b.toString();
302        }
303
304}