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