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