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.param;
021
022import ca.uhn.fhir.i18n.Msg;
023import ca.uhn.fhir.parser.DataFormatException;
024
025import static org.apache.commons.lang3.StringUtils.isBlank;
026
027public abstract class BaseParamWithPrefix<T extends BaseParam> extends BaseParam {
028
029        private static final long serialVersionUID = 1L;
030        private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseParamWithPrefix.class);
031
032        public static final String MSG_PREFIX_INVALID_FORMAT = "Invalid date/time/quantity format: ";
033
034        private ParamPrefixEnum myPrefix;
035
036        /**
037         * Constructor
038         */
039        // Default since this is internal
040        BaseParamWithPrefix() {
041                super();
042        }
043
044        /**
045         * Eg. if this is invoked with "gt2012-11-02", sets the prefix to GREATER_THAN and returns "2012-11-02"
046         */
047        String extractPrefixAndReturnRest(String theString) {
048                int offset = 0;
049                while (true) {
050                        if (theString.length() == offset) {
051                                break;
052                        } else {
053                                char nextChar = theString.charAt(offset);
054                                if (nextChar == '-' || nextChar == '%' || Character.isDigit(nextChar)) {
055                                        break;
056                                }
057                        }
058                        offset++;
059                }
060
061                if (offset > 0 && theString.length() == offset) {
062                        throw new DataFormatException(Msg.code(1940) + MSG_PREFIX_INVALID_FORMAT + "\"" + theString + "\"");
063                }
064
065                String prefix = theString.substring(0, offset);
066                if (!isBlank(prefix)) {
067
068                        myPrefix = ParamPrefixEnum.forValue(prefix);
069
070                        if (myPrefix == null) {
071                                // prefix doesn't match standard values.  Try legacy values
072                                switch (prefix) {
073                                        case ">=":
074                                                myPrefix = ParamPrefixEnum.GREATERTHAN_OR_EQUALS;
075                                                break;
076                                        case ">":
077                                                myPrefix = ParamPrefixEnum.GREATERTHAN;
078                                                break;
079                                        case "<=":
080                                                myPrefix = ParamPrefixEnum.LESSTHAN_OR_EQUALS;
081                                                break;
082                                        case "<":
083                                                myPrefix = ParamPrefixEnum.LESSTHAN;
084                                                break;
085                                        case "~":
086                                                myPrefix = ParamPrefixEnum.APPROXIMATE;
087                                                break;
088                                        case "=":
089                                                myPrefix = ParamPrefixEnum.EQUAL;
090                                                break;
091                                        default:
092                                                throw new DataFormatException(Msg.code(1941) + "Invalid prefix: \"" + prefix + "\"");
093                                }
094                                ourLog.warn(
095                                                "Date parameter has legacy prefix '{}' which has been removed from FHIR. This should be replaced with '{}'",
096                                                prefix,
097                                                myPrefix.getValue());
098                        }
099                }
100
101                return theString.substring(offset);
102        }
103
104        /**
105         * Returns the prefix used by this parameter (e.g. "<code>gt</code>", or "<code>eq</code>")
106         */
107        public ParamPrefixEnum getPrefix() {
108                return myPrefix;
109        }
110
111        /**
112         * Sets the prefix used by this parameter (e.g. "<code>gt</code>", or "<code>eq</code>")
113         */
114        @SuppressWarnings("unchecked")
115        public T setPrefix(ParamPrefixEnum thePrefix) {
116                myPrefix = thePrefix;
117                return (T) this;
118        }
119}