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