001package ca.uhn.fhir.rest.param;
002
003/*-
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2022 Smile CDR, Inc.
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import ca.uhn.fhir.i18n.Msg;
024import ca.uhn.fhir.parser.DataFormatException;
025
026import static org.apache.commons.lang3.StringUtils.isBlank;
027
028public abstract class BaseParamWithPrefix<T extends BaseParam> extends BaseParam {
029
030        private static final long serialVersionUID = 1L;
031        private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseParamWithPrefix.class);
032
033
034        public static final String MSG_PREFIX_INVALID_FORMAT = "Invalid date/time/quantity format: ";
035
036        private ParamPrefixEnum myPrefix;
037
038        /**
039         * Constructor
040         */
041        // Default since this is internal
042        BaseParamWithPrefix() {
043                super();
044        }
045
046        /**
047         * Eg. if this is invoked with "gt2012-11-02", sets the prefix to GREATER_THAN and returns "2012-11-02"
048         */
049        String extractPrefixAndReturnRest(String theString) {
050                int offset = 0;
051                while (true) {
052                        if (theString.length() == offset) {
053                                break;
054                        } else {
055                                char nextChar = theString.charAt(offset);
056                                if (nextChar == '-' || nextChar == '%' || Character.isDigit(nextChar)) {
057                                        break;
058                                }
059                        }
060                        offset++;
061                }
062
063                if (offset > 0 && theString.length() == offset) {
064                        throw new DataFormatException(Msg.code(1940) + MSG_PREFIX_INVALID_FORMAT + "\"" + theString + "\"");
065                }
066
067                String prefix = theString.substring(0, offset);
068                if (!isBlank(prefix)) {
069                
070                        myPrefix = ParamPrefixEnum.forValue(prefix);
071
072                        if (myPrefix == null) {
073                                // prefix doesn't match standard values.  Try legacy values
074                                switch (prefix) {
075                                case ">=":
076                                        myPrefix = ParamPrefixEnum.GREATERTHAN_OR_EQUALS;
077                                        break;
078                                case ">":
079                                        myPrefix = ParamPrefixEnum.GREATERTHAN;
080                                        break;
081                                case "<=":
082                                        myPrefix = ParamPrefixEnum.LESSTHAN_OR_EQUALS;
083                                        break;
084                                case "<":
085                                        myPrefix = ParamPrefixEnum.LESSTHAN;
086                                        break;
087                                case "~":
088                                        myPrefix = ParamPrefixEnum.APPROXIMATE;
089                                        break;
090                                case "=":
091                                        myPrefix = ParamPrefixEnum.EQUAL;
092                                        break;
093                                default :
094                                        throw new DataFormatException(Msg.code(1941) + "Invalid prefix: \"" + prefix + "\"");
095                                }
096                                ourLog.warn("Date parameter has legacy prefix '{}' which has been removed from FHIR. This should be replaced with '{}'", prefix, myPrefix.getValue());
097                        }
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
120}