001package ca.uhn.fhir.rest.param; 002 003/* 004 * #%L 005 * HAPI FHIR - Core Library 006 * %% 007 * Copyright (C) 2014 - 2017 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 static org.apache.commons.lang3.StringUtils.isNotBlank; 024 025import java.util.*; 026 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.IQueryParameterOr; 033import ca.uhn.fhir.model.api.TemporalPrecisionEnum; 034import ca.uhn.fhir.model.primitive.*; 035import ca.uhn.fhir.rest.api.QualifiedParamList; 036import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; 037import ca.uhn.fhir.util.ValidateUtil; 038 039public class DateParam extends BaseParamWithPrefix<DateParam> implements /*IQueryParameterType , */IQueryParameterOr<DateParam> { 040 041 private static final long serialVersionUID = 1L; 042 043 private final DateParamDateTimeHolder myValue = new DateParamDateTimeHolder(); 044 045 /** 046 * Constructor 047 */ 048 public DateParam() { 049 } 050 051 /** 052 * Constructor 053 */ 054 public DateParam(ParamPrefixEnum thePrefix, Date theDate) { 055 setPrefix(thePrefix); 056 setValue(theDate); 057 } 058 059 /** 060 * Constructor 061 */ 062 public DateParam(ParamPrefixEnum thePrefix, DateTimeDt theDate) { 063 setPrefix(thePrefix); 064 myValue.setValueAsString(theDate != null ? theDate.getValueAsString() : null); 065 } 066 067 /** 068 * Constructor 069 */ 070 public DateParam(ParamPrefixEnum thePrefix, IPrimitiveType<Date> theDate) { 071 setPrefix(thePrefix); 072 myValue.setValueAsString(theDate != null ? theDate.getValueAsString() : null); 073 } 074 075 /** 076 * Constructor 077 */ 078 public DateParam(ParamPrefixEnum thePrefix, long theDate) { 079 ValidateUtil.isGreaterThan(theDate, 0, "theDate must not be 0 or negative"); 080 setPrefix(thePrefix); 081 setValue(new Date(theDate)); 082 } 083 084 /** 085 * Constructor 086 */ 087 public DateParam(ParamPrefixEnum thePrefix, String theDate) { 088 setPrefix(thePrefix); 089 setValueAsString(theDate); 090 } 091 092 093 /** 094 * Constructor which takes a complete [qualifier]{date} string. 095 * 096 * @param theString 097 * The string 098 */ 099 public DateParam(String theString) { 100 setValueAsQueryToken(null, null, null, theString); 101 } 102 103 @Override 104 String doGetQueryParameterQualifier() { 105 return null; 106 } 107 108 @Override 109 String doGetValueAsQueryToken(FhirContext theContext) { 110 StringBuilder b = new StringBuilder(); 111 if (getPrefix() != null) { 112 b.append(ParameterUtil.escapeWithDefault(getPrefix().getValue())); 113 } 114 115 if (myValue != null) { 116 b.append(ParameterUtil.escapeWithDefault(myValue.getValueAsString())); 117 } 118 119 return b.toString(); 120 } 121 122 @Override 123 void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) { 124 setValueAsString(theValue); 125 } 126 127 public TemporalPrecisionEnum getPrecision() { 128 if (myValue != null) { 129 return myValue.getPrecision(); 130 } 131 return null; 132 } 133 134 public Date getValue() { 135 if (myValue != null) { 136 return myValue.getValue(); 137 } 138 return null; 139 } 140 141 public DateTimeDt getValueAsDateTimeDt() { 142 if (myValue == null) { 143 return null; 144 } 145 return new DateTimeDt(myValue.getValue()); 146 } 147 148 public InstantDt getValueAsInstantDt() { 149 if (myValue == null) { 150 return null; 151 } 152 return new InstantDt(myValue.getValue()); 153 } 154 155 public String getValueAsString() { 156 if (myValue != null) { 157 return myValue.getValueAsString(); 158 } 159 return null; 160 } 161 162 @Override 163 public List<DateParam> getValuesAsQueryTokens() { 164 return Collections.singletonList(this); 165 } 166 167 /** 168 * Returns <code>true</code> if no date/time is specified. Note that this method does not check the comparator, so a 169 * QualifiedDateParam with only a comparator and no date/time is considered empty. 170 */ 171 public boolean isEmpty() { 172 return myValue.isEmpty(); 173 } 174 175 /** 176 * Sets the value of the param to the given date (sets to the {@link TemporalPrecisionEnum#MILLI millisecond} 177 * precision, and will be encoded using the system local time zone). 178 */ 179 public DateParam setValue(Date theValue) { 180 myValue.setValue(theValue, TemporalPrecisionEnum.MILLI); 181 return this; 182 } 183 184 /** 185 * Sets the value using a FHIR Date type, such as a {@link DateDt}, or a DateTimeType. 186 */ 187 public void setValue(IPrimitiveType<Date> theValue) { 188 if (theValue != null) { 189 myValue.setValueAsString(theValue.getValueAsString()); 190 } else { 191 myValue.setValue(null); 192 } 193 } 194 195 /** 196 * Accepts values with or without a prefix (e.g. <code>gt2011-01-01</code> and <code>2011-01-01</code>). 197 * If no prefix is provided in the given value, the {@link #getPrefix() existing prefix} is preserved 198 */ 199 public void setValueAsString(String theDate) { 200 if (isNotBlank(theDate)) { 201 ParamPrefixEnum existingPrefix = getPrefix(); 202 myValue.setValueAsString(super.extractPrefixAndReturnRest(theDate)); 203 if (getPrefix() == null) { 204 setPrefix(existingPrefix); 205 } 206 } else { 207 myValue.setValue(null); 208 } 209 } 210 211 @Override 212 public void setValuesAsQueryTokens(FhirContext theContext, String theParamName, QualifiedParamList theParameters) { 213 setMissing(null); 214 setPrefix(null); 215 setValueAsString(null); 216 217 if (theParameters.size() == 1) { 218 setValueAsString(theParameters.get(0)); 219 } else if (theParameters.size() > 1) { 220 throw new InvalidRequestException("This server does not support multi-valued dates for this paramater: " + theParameters); 221 } 222 223 } 224 225 226 @Override 227 public String toString() { 228 ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); 229 b.append("prefix", getPrefix()); 230 b.append("value", getValueAsString()); 231 return b.build(); 232 } 233 234 public class DateParamDateTimeHolder extends BaseDateTimeDt { 235 @Override 236 protected TemporalPrecisionEnum getDefaultPrecisionForDatatype() { 237 return TemporalPrecisionEnum.SECOND; 238 } 239 240 @Override 241 protected boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision) { 242 return true; 243 } 244 245 } 246 247 248}