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.gclient;
021
022import ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
024import ca.uhn.fhir.model.primitive.DateTimeDt;
025import ca.uhn.fhir.rest.param.ParamPrefixEnum;
026
027import java.util.Date;
028
029import static org.apache.commons.lang3.StringUtils.isNotBlank;
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        private class DateWithPrefix implements IDateSpecifier {
131                private ParamPrefixEnum myPrefix;
132                private Criterion previous = null;
133
134                public DateWithPrefix(ParamPrefixEnum thePrefix, Criterion previous) {
135                        myPrefix = thePrefix;
136                        this.previous = previous;
137                }
138
139                public DateWithPrefix(ParamPrefixEnum thePrefix) {
140                        myPrefix = thePrefix;
141                }
142
143                @Override
144                public IDateCriterion day(Date theValue) {
145                        DateTimeDt dt = new DateTimeDt(theValue);
146                        dt.setPrecision(TemporalPrecisionEnum.DAY);
147                        return constructCriterion(dt);
148                }
149
150                @Override
151                public IDateCriterion day(String theValue) {
152                        DateTimeDt dt = new DateTimeDt(theValue);
153                        dt.setPrecision(TemporalPrecisionEnum.DAY);
154                        return constructCriterion(dt);
155                }
156
157                @Override
158                public IDateCriterion now() {
159                        DateTimeDt dt = DateTimeDt.withCurrentTime();
160                        dt.setPrecision(TemporalPrecisionEnum.SECOND);
161                        return constructCriterion(dt);
162                }
163
164                @Override
165                public IDateCriterion second(Date theValue) {
166                        DateTimeDt dt = new DateTimeDt(theValue);
167                        dt.setPrecision(TemporalPrecisionEnum.SECOND);
168                        return constructCriterion(dt);
169                }
170
171                @Override
172                public IDateCriterion second(String theValue) {
173                        DateTimeDt dt = new DateTimeDt(theValue);
174                        dt.setPrecision(TemporalPrecisionEnum.SECOND);
175                        return constructCriterion(dt);
176                }
177
178                @Override
179                public IDateCriterion millis(Date theValue) {
180                        DateTimeDt dt = new DateTimeDt(theValue);
181                        dt.setPrecision(TemporalPrecisionEnum.MILLI);
182                        return constructCriterion(dt);
183                }
184
185                @Override
186                public IDateCriterion millis(String theValue) {
187                        DateTimeDt dt = new DateTimeDt(theValue);
188                        dt.setPrecision(TemporalPrecisionEnum.MILLI);
189                        return constructCriterion(dt);
190                }
191
192                private IDateCriterion constructCriterion(DateTimeDt dt) {
193                        String valueAsString = dt.getValueAsString();
194                        Criterion criterion = new Criterion(myPrefix, valueAsString);
195                        if (previous != null) {
196                                criterion.orCriterion = previous;
197                        }
198                        return criterion;
199                }
200        }
201
202        public interface IDateSpecifier {
203
204                IDateCriterion day(Date theValue);
205
206                IDateCriterion day(String theValue);
207
208                IDateCriterion now();
209
210                IDateCriterion second(Date theValue);
211
212                IDateCriterion second(String theValue);
213
214                IDateCriterion millis(Date theValue);
215
216                IDateCriterion millis(String theValue);
217        }
218
219        public interface IDateCriterion extends ICriterion<DateClientParam> {
220                IDateSpecifier orAfter();
221
222                IDateSpecifier orAfterOrEquals();
223
224                IDateSpecifier orBefore();
225
226                IDateSpecifier orBeforeOrEquals();
227
228                IDateSpecifier orExactly();
229        }
230}