001 /*
002 * The contents of this file are subject to the terms
003 * of the Common Development and Distribution License
004 * (the "License"). You may not use this file except
005 * in compliance with the License.
006 *
007 * You can obtain a copy of the license at
008 * http://www.opensource.org/licenses/cddl1.php
009 * See the License for the specific language governing
010 * permissions and limitations under the License.
011 */
012
013 /*
014 * CacheControl.java
015 *
016 * Created on March 5, 2007, 3:36 PM
017 */
018
019 package javax.ws.rs.core;
020
021 import java.util.ArrayList;
022 import java.util.HashMap;
023 import java.util.List;
024 import java.util.Map;
025 import javax.ws.rs.ext.RuntimeDelegate;
026 import javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate;
027
028 /**
029 * An abstraction for the value of a HTTP Cache-Control response header.
030 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9">HTTP/1.1 section 14.9</a>
031 */
032 public class CacheControl {
033 private boolean _private;
034 private List<String> privateFields;
035 private boolean noCache;
036 private List<String> noCacheFields;
037 private boolean noStore;
038 private boolean noTransform;
039 private boolean mustRevalidate;
040 private boolean proxyRevalidate;
041 private int maxAge = -1;
042 private int sMaxAge = -1;
043 private Map<String, String> cacheExtension;
044
045 private static final HeaderDelegate<CacheControl> delegate =
046 RuntimeDelegate.getInstance().createHeaderDelegate(CacheControl.class);
047
048
049 /**
050 * Create a new instance of CacheControl. The new instance will have the
051 * following default settings:
052 *
053 * <ul>
054 * <li>private = false</li>
055 * <li>noCache = false</li>
056 * <li>noStore = false</li>
057 * <li>noTransform = true</li>
058 * <li>mustRevalidate = false</li>
059 * <li>proxyRevalidate = false</li>
060 * <li>An empty list of private fields</li>
061 * <li>An empty list of no-cache fields</li>
062 * <li>An empty map of cache extensions</li>
063 * </ul>
064 */
065 public CacheControl() {
066 _private = false;
067 noCache = false;
068 noStore = false;
069 noTransform = true;
070 mustRevalidate = false;
071 proxyRevalidate = false;
072 }
073
074 /**
075 * Creates a new instance of CacheControl by parsing the supplied string.
076 * @param value the cache control string
077 * @return the newly created CacheControl
078 * @throws IllegalArgumentException if the supplied string cannot be parsed
079 * or is null
080 */
081 public static CacheControl valueOf(String value) throws IllegalArgumentException {
082 return delegate.fromString(value);
083 }
084
085 /**
086 * Corresponds to the must-revalidate cache control directive.
087 * @return true if the must-revalidate cache control directive will be included in the
088 * response, false otherwise.
089 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP/1.1 section 14.9.4</a>
090 */
091 public boolean isMustRevalidate() {
092 return mustRevalidate;
093 }
094
095 /**
096 * Corresponds to the must-revalidate cache control directive.
097 * @param mustRevalidate true if the must-revalidate cache control directive should be included in the
098 * response, false otherwise.
099 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP/1.1 section 14.9.4</a>
100 */
101 public void setMustRevalidate(boolean mustRevalidate) {
102 this.mustRevalidate = mustRevalidate;
103 }
104
105 /**
106 * Corresponds to the proxy-revalidate cache control directive.
107 * @return true if the proxy-revalidate cache control directive will be included in the
108 * response, false otherwise.
109 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP/1.1 section 14.9.4</a>
110 */
111 public boolean isProxyRevalidate() {
112 return proxyRevalidate;
113 }
114
115 /**
116 * Corresponds to the must-revalidate cache control directive.
117 * @param proxyRevalidate true if the proxy-revalidate cache control directive should be included in the
118 * response, false otherwise.
119 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP/1.1 section 14.9.4</a>
120 */
121 public void setProxyRevalidate(boolean proxyRevalidate) {
122 this.proxyRevalidate = proxyRevalidate;
123 }
124
125 /**
126 * Corresponds to the max-age cache control directive.
127 * @return the value of the max-age cache control directive, -1 if the directive is disabled.
128 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP/1.1 section 14.9.3</a>
129 */
130 public int getMaxAge() {
131 return maxAge;
132 }
133
134 /**
135 * Corresponds to the max-age cache control directive.
136 * @param maxAge the value of the max-age cache control directive, a value of -1 will disable the directive.
137 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP/1.1 section 14.9.3</a>
138 */
139 public void setMaxAge(int maxAge) {
140 this.maxAge = maxAge;
141 }
142
143 /**
144 * Corresponds to the s-maxage cache control directive.
145 * @return the value of the s-maxage cache control directive, -1 if the directive is disabled.
146 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP/1.1 section 14.9.3</a>
147 */
148 public int getSMaxAge() {
149 return sMaxAge;
150 }
151
152 /**
153 * Corresponds to the s-maxage cache control directive.
154 * @param sMaxAge the value of the s-maxage cache control directive, a value of -1 will disable the directive.
155 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP/1.1 section 14.9.3</a>
156 */
157 public void setSMaxAge(int sMaxAge) {
158 this.sMaxAge = sMaxAge;
159 }
160
161 /**
162 * Corresponds to the value of the no-cache cache control directive.
163 * @return a mutable list of field-names that will form the value of the no-cache cache control directive.
164 * An empty list results in a bare no-cache directive.
165 * @see #isNoCache
166 * @see #setNoCache
167 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
168 */
169 public List<String> getNoCacheFields() {
170 if (noCacheFields == null)
171 noCacheFields = new ArrayList<String>();
172 return noCacheFields;
173 }
174
175 /**
176 * Corresponds to the no-cache cache control directive.
177 * @param noCache true if the no-cache cache control directive should be included in the
178 * response, false otherwise.
179 * @see #getNoCacheFields
180 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
181 */
182 public void setNoCache(boolean noCache) {
183 this.noCache = noCache;
184 }
185
186 /**
187 * Corresponds to the no-cache cache control directive.
188 * @return true if the no-cache cache control directive will be included in the
189 * response, false otherwise.
190 * @see #getNoCacheFields
191 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
192 */
193 public boolean isNoCache() {
194 return noCache;
195 }
196
197 /**
198 * Corresponds to the private cache control directive.
199 * @return true if the private cache control directive will be included in the
200 * response, false otherwise.
201 * @see #getPrivateFields
202 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
203 */
204 public boolean isPrivate() {
205 return _private;
206 }
207
208 /**
209 * Corresponds to the value of the private cache control directive.
210 * @return a mutable list of field-names that will form the value of the private cache control directive.
211 * An empty list results in a bare no-cache directive.
212 * @see #isPrivate
213 * @see #setPrivate
214 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
215 */
216 public List<String> getPrivateFields() {
217 if (privateFields == null)
218 privateFields = new ArrayList<String>();
219 return privateFields;
220 }
221
222 /**
223 * Corresponds to the private cache control directive.
224 * @param _private true if the private cache control directive should be included in the
225 * response, false otherwise.
226 * @see #getPrivateFields
227 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
228 */
229 public void setPrivate(boolean _private) {
230 this._private = _private;
231 }
232
233 /**
234 * Corresponds to the no-transform cache control directive.
235 * @return true if the no-transform cache control directive will be included in the
236 * response, false otherwise.
237 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5">HTTP/1.1 section 14.9.5</a>
238 */
239 public boolean isNoTransform() {
240 return noTransform;
241 }
242
243 /**
244 * Corresponds to the no-transform cache control directive.
245 * @param noTransform true if the no-transform cache control directive should be included in the
246 * response, false otherwise.
247 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5">HTTP/1.1 section 14.9.5</a>
248 */
249 public void setNoTransform(boolean noTransform) {
250 this.noTransform = noTransform;
251 }
252
253 /**
254 * Corresponds to the no-store cache control directive.
255 * @return true if the no-store cache control directive will be included in the
256 * response, false otherwise.
257 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.2">HTTP/1.1 section 14.9.2</a>
258 */
259 public boolean isNoStore() {
260 return noStore;
261 }
262
263 /**
264 * Corresponds to the no-store cache control directive.
265 * @param noStore true if the no-store cache control directive should be included in the
266 * response, false otherwise.
267 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.2">HTTP/1.1 section 14.9.2</a>
268 */
269 public void setNoStore(boolean noStore) {
270 this.noStore = noStore;
271 }
272
273 /**
274 * Corresponds to a set of extension cache control directives.
275 * @return a mutable map of cache control extension names and their values.
276 * If a key has a null value, it will appear as a bare directive. If a key has
277 * a value that contains no whitespace then the directive will appear as
278 * a simple name=value pair. If a key has a value that contains whitespace
279 * then the directive will appear as a quoted name="value" pair.
280 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.6">HTTP/1.1 section 14.9.6</a>
281 */
282 public Map<String, String> getCacheExtension() {
283 if (cacheExtension == null)
284 cacheExtension = new HashMap<String, String>();
285 return cacheExtension;
286 }
287
288 /**
289 * Convert the cache control to a string suitable for use as the value of the
290 * corresponding HTTP header.
291 * @return a stringified cache control
292 */
293 @Override
294 public String toString() {
295 return delegate.toString(this);
296 }
297
298 /**
299 * Generate hash code from cache control properties.
300 * @return the hashCode
301 */
302 @Override
303 public int hashCode() {
304 int hash = 7;
305 hash = 41 * hash + (this._private ? 1 : 0);
306 hash = 41 * hash + (this.privateFields != null ? this.privateFields.hashCode() : 0);
307 hash = 41 * hash + (this.noCache ? 1 : 0);
308 hash = 41 * hash + (this.noCacheFields != null ? this.noCacheFields.hashCode() : 0);
309 hash = 41 * hash + (this.noStore ? 1 : 0);
310 hash = 41 * hash + (this.noTransform ? 1 : 0);
311 hash = 41 * hash + (this.mustRevalidate ? 1 : 0);
312 hash = 41 * hash + (this.proxyRevalidate ? 1 : 0);
313 hash = 41 * hash + this.maxAge;
314 hash = 41 * hash + this.sMaxAge;
315 hash = 41 * hash + (this.cacheExtension != null ? this.cacheExtension.hashCode() : 0);
316 return hash;
317 }
318
319 /**
320 * Compares obj to this cache control to see if they are the same
321 * considering all property values.
322 * @param obj the object to compare to
323 * @return true if the two cache controls are the same, false otherwise.
324 */
325 @Override
326 public boolean equals(Object obj) {
327 if (obj == null) {
328 return false;
329 }
330 if (getClass() != obj.getClass()) {
331 return false;
332 }
333 final CacheControl other = (CacheControl) obj;
334 if (this._private != other._private) {
335 return false;
336 }
337 if (this.privateFields != other.privateFields && (this.privateFields == null || !this.privateFields.equals(other.privateFields))) {
338 return false;
339 }
340 if (this.noCache != other.noCache) {
341 return false;
342 }
343 if (this.noCacheFields != other.noCacheFields && (this.noCacheFields == null || !this.noCacheFields.equals(other.noCacheFields))) {
344 return false;
345 }
346 if (this.noStore != other.noStore) {
347 return false;
348 }
349 if (this.noTransform != other.noTransform) {
350 return false;
351 }
352 if (this.mustRevalidate != other.mustRevalidate) {
353 return false;
354 }
355 if (this.proxyRevalidate != other.proxyRevalidate) {
356 return false;
357 }
358 if (this.maxAge != other.maxAge) {
359 return false;
360 }
361 if (this.sMaxAge != other.sMaxAge) {
362 return false;
363 }
364 if (this.cacheExtension != other.cacheExtension && (this.cacheExtension == null || !this.cacheExtension.equals(other.cacheExtension))) {
365 return false;
366 }
367 return true;
368 }
369
370 }