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.i18n.Msg; 024import ca.uhn.fhir.model.api.IQueryParameterType; 025import ca.uhn.fhir.model.base.composite.BaseQuantityDt; 026import ca.uhn.fhir.model.primitive.DecimalDt; 027import ca.uhn.fhir.model.primitive.UriDt; 028import ca.uhn.fhir.util.CoverageIgnore; 029import org.apache.commons.lang3.StringUtils; 030import org.apache.commons.lang3.builder.ToStringBuilder; 031import org.apache.commons.lang3.builder.ToStringStyle; 032import org.hl7.fhir.instance.model.api.IPrimitiveType; 033 034import java.math.BigDecimal; 035import java.util.List; 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 "<=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 * Returns the system, or null if none was provided 202 * <p> 203 * Note that prior to HAPI FHIR 1.5, this method returned a {@link UriDt} 204 * </p> 205 * 206 * @since 1.5 207 */ 208 public String getSystem() { 209 return mySystem; 210 } 211 212 /** 213 * @deprecated Use {{@link #getSystem()}} instead 214 */ 215 @Deprecated 216 @CoverageIgnore 217 public UriDt getSystemAsUriDt() { 218 return new UriDt(mySystem); 219 } 220 221 public String getUnits() { 222 return myUnits; 223 } 224 225 /** 226 * Returns the quantity/value, or null if none was provided 227 * <p> 228 * Note that prior to HAPI FHIR 1.5, this method returned a {@link DecimalDt} 229 * </p> 230 * 231 * @since 1.5 232 */ 233 public BigDecimal getValue() { 234 return myValue; 235 } 236 237 public QuantityParam setSystem(String theSystem) { 238 mySystem = theSystem; 239 return this; 240 } 241 242 public QuantityParam setSystem(IPrimitiveType<String> theSystem) { 243 mySystem = null; 244 if (theSystem != null) { 245 mySystem = theSystem.getValue(); 246 } 247 return this; 248 } 249 250 public QuantityParam setUnits(String theUnits) { 251 myUnits = theUnits; 252 return this; 253 } 254 255 public QuantityParam setValue(BigDecimal theValue) { 256 myValue = theValue; 257 return this; 258 } 259 260 public QuantityParam setValue(IPrimitiveType<BigDecimal> theValue) { 261 myValue = null; 262 if (theValue != null) { 263 myValue = theValue.getValue(); 264 } 265 return this; 266 } 267 268 public QuantityParam setValue(String theValue) { 269 myValue = null; 270 if (theValue != null) { 271 myValue = new BigDecimal(theValue); 272 } 273 return this; 274 } 275 276 public QuantityParam setValue(double theValue) { 277 // Use the valueOf here because the constructor gives crazy precision 278 // changes due to the floating point conversion 279 myValue = BigDecimal.valueOf(theValue); 280 return this; 281 } 282 283 public QuantityParam setValue(long theValue) { 284 // Use the valueOf here because the constructor gives crazy precision 285 // changes due to the floating point conversion 286 myValue = BigDecimal.valueOf(theValue); 287 return this; 288 } 289 290 @Override 291 public String toString() { 292 ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); 293 b.append("prefix", getPrefix()); 294 b.append("value", myValue); 295 b.append("system", mySystem); 296 b.append("units", myUnits); 297 if (getMissing() != null) { 298 b.append("missing", getMissing()); 299 } 300 return b.toString(); 301 } 302 303 public static QuantityParam toQuantityParam(IQueryParameterType theParam) { 304 if (theParam instanceof BaseQuantityDt) { 305 BaseQuantityDt param = (BaseQuantityDt) theParam; 306 String systemValue = param.getSystemElement().getValueAsString(); 307 String unitsValue = param.getUnitsElement().getValueAsString(); 308 ParamPrefixEnum cmpValue = 309 ParamPrefixEnum.forValue(param.getComparatorElement().getValueAsString()); 310 BigDecimal valueValue = param.getValueElement().getValue(); 311 return new QuantityParam() 312 .setSystem(systemValue) 313 .setUnits(unitsValue) 314 .setPrefix(cmpValue) 315 .setValue(valueValue); 316 } else if (theParam instanceof QuantityParam) { 317 return (QuantityParam) theParam; 318 } else { 319 throw new IllegalArgumentException(Msg.code(1948) + "Invalid quantity type: " + theParam.getClass()); 320 } 321 } 322}