001/*
002 * #%L
003 * HAPI FHIR - Core Library
004 * %%
005 * Copyright (C) 2014 - 2023 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.gclient;
021
022import static org.apache.commons.lang3.StringUtils.isNotBlank;
023
024import java.util.Date;
025
026import ca.uhn.fhir.context.FhirContext;
027import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
028import ca.uhn.fhir.model.primitive.DateTimeDt;
029import ca.uhn.fhir.rest.param.ParamPrefixEnum;
030
031/**
032 * Date parameter type for use in fluent client interfaces
033 */
034public class DateClientParam  extends BaseClientParam implements IParam {
035
036        private String myParamName;
037
038        @Override
039        public String getParamName() {
040                return myParamName;
041        }
042
043        public DateClientParam(String theParamName) {
044                myParamName = theParamName;
045        }
046
047        public IDateSpecifier after() {
048                return new DateWithPrefix(ParamPrefixEnum.GREATERTHAN);
049        }
050
051        public IDateSpecifier afterOrEquals() {
052                return new DateWithPrefix(ParamPrefixEnum.GREATERTHAN_OR_EQUALS);
053        }
054
055        public IDateSpecifier before() {
056                return new DateWithPrefix(ParamPrefixEnum.LESSTHAN);
057        }
058
059        public IDateSpecifier beforeOrEquals() {
060                return new DateWithPrefix(ParamPrefixEnum.LESSTHAN_OR_EQUALS);
061        }
062
063        public IDateSpecifier exactly() {
064                return new DateWithPrefix(ParamPrefixEnum.EQUAL);
065        }
066
067        private class Criterion implements IDateCriterion, ICriterionInternal {
068
069                private String myValue;
070                private ParamPrefixEnum myPrefix;
071                private Criterion orCriterion;
072
073                public Criterion(ParamPrefixEnum thePrefix, String theValue) {
074                        myPrefix = thePrefix;
075                        myValue = theValue;
076                }
077
078                @Override
079                public String getParameterName() {
080                        return myParamName;
081                }
082
083                @Override
084                public String getParameterValue(FhirContext theContext) {
085                        StringBuilder b = new StringBuilder();
086                        if (orCriterion != null) {
087                                String orValue = orCriterion.getParameterValue(theContext);
088                                if (isNotBlank(orValue)) {
089                                        b.append(orValue);
090                                }
091                        }
092                        if (isNotBlank(myValue)) {
093                                if (b.length() > 0) {
094                                        b.append(',');
095                                }
096                                if (myPrefix != null && myPrefix != ParamPrefixEnum.EQUAL) {
097                                        b.append(myPrefix.getValue());
098                                }
099                                b.append(myValue);
100                        }
101                        return b.toString();
102                }
103
104                @Override
105                public IDateSpecifier orAfter() {
106                        return new DateWithPrefix(ParamPrefixEnum.GREATERTHAN, this);
107                }
108
109                @Override
110                public IDateSpecifier orAfterOrEquals() {
111                        return new DateWithPrefix(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, this);
112                }
113
114                @Override
115                public IDateSpecifier orBefore() {
116                        return new DateWithPrefix(ParamPrefixEnum.LESSTHAN, this);
117                }
118
119                @Override
120                public IDateSpecifier orBeforeOrEquals() {
121                        return new DateWithPrefix(ParamPrefixEnum.LESSTHAN_OR_EQUALS, this);
122                }
123
124                @Override
125                public IDateSpecifier orExactly() {
126                        return new DateWithPrefix(ParamPrefixEnum.EQUAL, this);
127                }
128
129        }
130
131        private class DateWithPrefix implements IDateSpecifier {
132                private ParamPrefixEnum myPrefix;
133                private Criterion previous = null;
134
135                public DateWithPrefix(ParamPrefixEnum thePrefix, Criterion previous) {
136                        myPrefix = thePrefix;
137                        this.previous = previous;
138                }
139
140                public DateWithPrefix(ParamPrefixEnum thePrefix) {
141                        myPrefix = thePrefix;
142                }
143
144                @Override
145                public IDateCriterion day(Date theValue) {
146                        DateTimeDt dt = new DateTimeDt(theValue);
147                        dt.setPrecision(TemporalPrecisionEnum.DAY);
148                        return constructCriterion(dt);
149                }
150
151                @Override
152                public IDateCriterion day(String theValue) {
153                        DateTimeDt dt = new DateTimeDt(theValue);
154                        dt.setPrecision(TemporalPrecisionEnum.DAY);
155                        return constructCriterion(dt);
156                }
157
158                @Override
159                public IDateCriterion now() {
160                        DateTimeDt dt = DateTimeDt.withCurrentTime();
161                        dt.setPrecision(TemporalPrecisionEnum.SECOND);
162                        return constructCriterion(dt);
163                }
164
165                @Override
166                public IDateCriterion second(Date theValue) {
167                        DateTimeDt dt = new DateTimeDt(theValue);
168                        dt.setPrecision(TemporalPrecisionEnum.SECOND);
169                        return constructCriterion(dt);
170                }
171
172                @Override
173                public IDateCriterion second(String theValue) {
174                        DateTimeDt dt = new DateTimeDt(theValue);
175                        dt.setPrecision(TemporalPrecisionEnum.SECOND);
176                        return constructCriterion(dt);
177                }
178
179                @Override
180                public IDateCriterion millis(Date theValue) {
181                        DateTimeDt dt = new DateTimeDt(theValue);
182                        dt.setPrecision(TemporalPrecisionEnum.MILLI);
183                        return constructCriterion(dt);
184                }
185
186                @Override
187                public IDateCriterion millis(String theValue) {
188                        DateTimeDt dt = new DateTimeDt(theValue);
189                        dt.setPrecision(TemporalPrecisionEnum.MILLI);
190                        return constructCriterion(dt);
191                }
192
193                private IDateCriterion constructCriterion(DateTimeDt dt) {
194                        String valueAsString = dt.getValueAsString();
195                        Criterion criterion = new Criterion(myPrefix, valueAsString);
196                        if (previous != null) {
197                                criterion.orCriterion = previous;
198                        }
199                        return criterion;
200                }
201        }
202
203        public interface IDateSpecifier {
204
205                IDateCriterion day(Date theValue);
206
207                IDateCriterion day(String theValue);
208
209                IDateCriterion now();
210
211                IDateCriterion second(Date theValue);
212
213                IDateCriterion second(String theValue);
214
215                IDateCriterion millis(Date theValue);
216
217                IDateCriterion millis(String theValue);
218
219        }
220
221        public interface IDateCriterion extends ICriterion<DateClientParam> {
222                IDateSpecifier orAfter();
223
224                IDateSpecifier orAfterOrEquals();
225
226                IDateSpecifier orBefore();
227
228                IDateSpecifier orBeforeOrEquals();
229
230                IDateSpecifier orExactly();
231        }
232
233}