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.api;
021
022import org.slf4j.Logger;
023import org.slf4j.LoggerFactory;
024
025import java.util.List;
026import java.util.StringTokenizer;
027
028import static org.apache.commons.lang3.StringUtils.trim;
029
030/**
031 * Parses and stores the value(s) within HTTP Cache-Control headers
032 */
033public class CacheControlDirective {
034
035        private static final String MAX_RESULTS_EQUALS = Constants.CACHE_CONTROL_MAX_RESULTS + "=";
036        private static final Logger ourLog = LoggerFactory.getLogger(CacheControlDirective.class);
037        private boolean myNoCache;
038        private boolean myNoStore;
039        private Integer myMaxResults;
040
041        /**
042         * Constructor
043         */
044        public CacheControlDirective() {
045                super();
046        }
047
048        /**
049         * If the {@link #isNoStore() no-store} directive is set, this HAPI FHIR extention
050         * to the <code>Cache-Control</code> header called <code>max-results=123</code>
051         * specified the maximum number of results which will be fetched from the
052         * database before returning.
053         */
054        public Integer getMaxResults() {
055                return myMaxResults;
056        }
057
058        /**
059         * If the {@link #isNoStore() no-store} directive is set, this HAPI FHIR extention
060         * to the <code>Cache-Control</code> header called <code>max-results=123</code>
061         * specified the maximum number of results which will be fetched from the
062         * database before returning.
063         */
064        public CacheControlDirective setMaxResults(Integer theMaxResults) {
065                myMaxResults = theMaxResults;
066                return this;
067        }
068
069        /**
070         * If <code>true<</code>, adds the <code>no-cache</code> directive to the
071         * request. This directive indicates that the cache should not be used to
072         * serve this request.
073         */
074        public boolean isNoCache() {
075                return myNoCache;
076        }
077
078        /**
079         * If <code>true<</code>, adds the <code>no-cache</code> directive to the
080         * request. This directive indicates that the cache should not be used to
081         * serve this request.
082         */
083        public CacheControlDirective setNoCache(boolean theNoCache) {
084                myNoCache = theNoCache;
085                return this;
086        }
087
088        public boolean isNoStore() {
089                return myNoStore;
090        }
091
092        public CacheControlDirective setNoStore(boolean theNoStore) {
093                myNoStore = theNoStore;
094                return this;
095        }
096
097        /**
098         * Parses a list of <code>Cache-Control</code> header values
099         *
100         * @param theValues The <code>Cache-Control</code> header values
101         */
102        public CacheControlDirective parse(List<String> theValues) {
103                if (theValues != null) {
104                        for (String nextValue : theValues) {
105                                StringTokenizer tok = new StringTokenizer(nextValue, ",");
106                                while (tok.hasMoreTokens()) {
107                                        String next = trim(tok.nextToken());
108                                        if (Constants.CACHE_CONTROL_NO_CACHE.equals(next)) {
109                                                myNoCache = true;
110                                        } else if (Constants.CACHE_CONTROL_NO_STORE.equals(next)) {
111                                                myNoStore = true;
112                                        } else if (next.startsWith(MAX_RESULTS_EQUALS)) {
113                                                String valueString = trim(next.substring(MAX_RESULTS_EQUALS.length()));
114                                                try {
115                                                        myMaxResults = Integer.parseInt(valueString);
116                                                } catch (NumberFormatException e) {
117                                                        ourLog.warn("Invalid {} value: {}", Constants.CACHE_CONTROL_MAX_RESULTS, valueString);
118                                                }
119                                        }
120                                }
121                        }
122                }
123
124                return this;
125        }
126
127        /**
128         * Convenience factory method for a no-cache directivel
129         */
130        public static CacheControlDirective noCache() {
131                return new CacheControlDirective().setNoCache(true);
132        }
133}