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}