View Javadoc
1   package ca.uhn.fhir.rest.param;
2   
3   /*
4    * #%L
5    * HAPI FHIR - Core Library
6    * %%
7    * Copyright (C) 2014 - 2018 University Health Network
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  
23  import ca.uhn.fhir.context.FhirContext;
24  import ca.uhn.fhir.model.api.IQueryParameterOr;
25  import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
26  import ca.uhn.fhir.model.primitive.BaseDateTimeDt;
27  import ca.uhn.fhir.model.primitive.DateDt;
28  import ca.uhn.fhir.model.primitive.DateTimeDt;
29  import ca.uhn.fhir.model.primitive.InstantDt;
30  import ca.uhn.fhir.rest.api.QualifiedParamList;
31  import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
32  import ca.uhn.fhir.util.ValidateUtil;
33  import org.apache.commons.lang3.builder.ToStringBuilder;
34  import org.apache.commons.lang3.builder.ToStringStyle;
35  import org.hl7.fhir.instance.model.api.IPrimitiveType;
36  
37  import java.util.Collections;
38  import java.util.Date;
39  import java.util.List;
40  import java.util.Objects;
41  
42  import static org.apache.commons.lang3.StringUtils.isNotBlank;
43  
44  public class DateParam extends BaseParamWithPrefix<DateParam> implements /*IQueryParameterType , */IQueryParameterOr<DateParam> {
45  
46  	private static final long serialVersionUID = 1L;
47  	
48  	private final DateParamDateTimeHolder myValue = new DateParamDateTimeHolder();
49  
50  	/**
51  	 * Constructor
52  	 */
53  	public DateParam() {
54  	}
55  
56  	/**
57  	 * Constructor
58  	 */
59  	public DateParam(ParamPrefixEnum thePrefix, Date theDate) {
60  		setPrefix(thePrefix);
61  		setValue(theDate);
62  	}
63  
64  	/**
65  	 * Constructor
66  	 */
67  	public DateParam(ParamPrefixEnum thePrefix, DateTimeDt theDate) {
68  		setPrefix(thePrefix);
69  		myValue.setValueAsString(theDate != null ? theDate.getValueAsString() : null);
70  	}
71  
72  	/**
73  	 * Constructor
74  	 */
75  	public DateParam(ParamPrefixEnum thePrefix, IPrimitiveType<Date> theDate) {
76  		setPrefix(thePrefix);
77  		myValue.setValueAsString(theDate != null ? theDate.getValueAsString() : null);
78  	}
79  
80  	/**
81  	 * Constructor
82  	 */
83  	public DateParam(ParamPrefixEnum thePrefix, long theDate) {
84  		ValidateUtil.isGreaterThan(theDate, 0, "theDate must not be 0 or negative");
85  		setPrefix(thePrefix);
86  		setValue(new Date(theDate));
87  	}
88  
89  	/**
90  	 * Constructor
91  	 */
92  	public DateParam(ParamPrefixEnum thePrefix, String theDate) {
93  		setPrefix(thePrefix);
94  		setValueAsString(theDate);
95  	}
96  
97  
98  	/**
99  	 * Constructor which takes a complete [qualifier]{date} string.
100 	 * 
101 	 * @param theString
102 	 *           The string
103 	 */
104 	public DateParam(String theString) {
105 		setValueAsQueryToken(null, null, null, theString);
106 	}
107 
108 	@Override
109 	String doGetQueryParameterQualifier() {
110 		return null;
111 	}
112 
113 	@Override
114 	String doGetValueAsQueryToken(FhirContext theContext) {
115 		StringBuilder b = new StringBuilder();
116 		if (getPrefix() != null) {
117 			b.append(ParameterUtil.escapeWithDefault(getPrefix().getValue()));
118 		}
119 		
120 		if (myValue != null) {
121 			b.append(ParameterUtil.escapeWithDefault(myValue.getValueAsString()));
122 		}
123 
124 		return b.toString();
125 	}
126 
127 	@Override
128 	void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
129 		setValueAsString(theValue);
130 	}
131 
132 	public TemporalPrecisionEnum getPrecision() {
133 		if (myValue != null) {
134 			return myValue.getPrecision();
135 		}
136 		return null;
137 	}
138 
139 	public Date getValue() {
140 		if (myValue != null) {
141 			return myValue.getValue();
142 		}
143 		return null;
144 	}
145 
146 	public DateTimeDt getValueAsDateTimeDt() {
147 		if (myValue == null) {
148 			return null;
149 		}
150 		return new DateTimeDt(myValue.getValue());
151 	}
152 
153 	public InstantDt getValueAsInstantDt() {
154 		if (myValue == null) {
155 			return null;
156 		}
157 		return new InstantDt(myValue.getValue());
158 	}
159 
160 	public String getValueAsString() {
161 		if (myValue != null) {
162 			return myValue.getValueAsString();
163 		}
164 		return null;
165 	}
166 
167 	@Override
168 	public List<DateParam> getValuesAsQueryTokens() {
169 		return Collections.singletonList(this);
170 	}
171 
172 	/**
173 	 * Returns <code>true</code> if no date/time is specified. Note that this method does not check the comparator, so a
174 	 * QualifiedDateParam with only a comparator and no date/time is considered empty.
175 	 */
176 	public boolean isEmpty() {
177 		return myValue.isEmpty();
178 	}
179 
180 	/**
181 	 * Sets the value of the param to the given date (sets to the {@link TemporalPrecisionEnum#MILLI millisecond}
182 	 * precision, and will be encoded using the system local time zone).
183 	 */
184 	public DateParam setValue(Date theValue) {
185 		myValue.setValue(theValue, TemporalPrecisionEnum.MILLI);
186 		return this;
187 	}
188 
189 	/**
190 	 * Sets the value using a FHIR Date type, such as a {@link DateDt}, or a DateTimeType.
191 	 */
192 	public void setValue(IPrimitiveType<Date> theValue) {
193 		if (theValue != null) {
194 			myValue.setValueAsString(theValue.getValueAsString());
195 		} else {
196 			myValue.setValue(null);
197 		}
198 	}
199 
200 	/**
201 	 * Accepts values with or without a prefix (e.g. <code>gt2011-01-01</code> and <code>2011-01-01</code>).
202 	 * If no prefix is provided in the given value, the {@link #getPrefix() existing prefix} is preserved
203 	 */
204 	public void setValueAsString(String theDate) {
205 		if (isNotBlank(theDate)) {
206 			ParamPrefixEnum existingPrefix = getPrefix();
207 			myValue.setValueAsString(super.extractPrefixAndReturnRest(theDate));
208 			if (getPrefix() == null) {
209 				setPrefix(existingPrefix);
210 			}
211 		} else {
212 			myValue.setValue(null);
213 		}
214 	}
215 
216 	@Override
217 	public void  setValuesAsQueryTokens(FhirContext theContext, String theParamName, QualifiedParamList theParameters) {
218 		setMissing(null);
219 		setPrefix(null);
220 		setValueAsString(null);
221 		
222 		if (theParameters.size() == 1) {
223 			setValueAsString(theParameters.get(0));
224 		} else if (theParameters.size() > 1) {
225 			throw new InvalidRequestException("This server does not support multi-valued dates for this paramater: " + theParameters);
226 		}
227 		
228 	}
229 
230 	@Override
231 	public boolean equals(Object obj) {
232 		if (obj == this) {
233 			return true;
234 		}
235 		if (!(obj instanceof DateParam)) {
236 			return false;
237 		}
238 		DateParam other = (DateParam) obj;
239 		return	Objects.equals(getValue(), other.getValue()) &&
240 					Objects.equals(getPrefix(), other.getPrefix());
241 	}
242 
243 	@Override
244 	public int hashCode() {
245 		return Objects.hash(getValue(), getPrefix());
246 	}
247 
248 	@Override
249 	public String toString() {
250 		ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
251 		b.append("prefix", getPrefix());
252 		b.append("value", getValueAsString());
253 		return b.build();
254 	}
255 
256 	public class DateParamDateTimeHolder extends BaseDateTimeDt {
257 		@Override
258 		protected TemporalPrecisionEnum getDefaultPrecisionForDatatype() {
259 			return TemporalPrecisionEnum.SECOND;
260 		}
261 
262 		@Override
263 		protected boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision) {
264 			return true;
265 		}
266 	}
267 }