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