/** * Copyright 2005-2014 Restlet * * The contents of this file are subject to the terms of one of the following * open source licenses: Apache 2.0 or or EPL 1.0 (the "Licenses"). You can * select the license that you prefer but you may not use this file except in * compliance with one of these Licenses. * * You can obtain a copy of the Apache 2.0 license at * http://www.opensource.org/licenses/apache-2.0 * * You can obtain a copy of the EPL 1.0 license at * http://www.opensource.org/licenses/eclipse-1.0 * * See the Licenses for the specific language governing permissions and * limitations under the Licenses. * * Alternatively, you can obtain a royalty free commercial license with less * limitations, transferable or non-transferable, directly at * http://restlet.com/products/restlet-framework * * Restlet is a registered trademark of Restlet S.A.S. */ package org.restlet.data; import java.util.List; import org.restlet.engine.header.HeaderConstants; import org.restlet.engine.util.SystemUtils; import org.restlet.util.NamedValue; /** * Directive for caching mechanisms along the call chain. This overrides the * default behavior of those caches and proxies.<br> * <br> * Note that when used with HTTP connectors, this class maps to the * "Cache-Control" header. * * @author Jerome Louvel */ public final class CacheDirective implements NamedValue<String> { /** * Creates a "max-age" directive. Indicates that the client is willing to * accept a response whose age is no greater than the specified time in * seconds. Unless "max-stale" directive is also included, the client is not * willing to accept a stale response.<br> * <br> * Note that this directive can be used on requests or responses. * * @param maxAge * Maximum age in seconds. * @return A new "max-age" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP * 1.1 - Modifications of the Basic Expiration Mechanism</a> * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP * 1.1 - Cache Revalidation and Reload Controls</a> */ public static CacheDirective maxAge(int maxAge) { return new CacheDirective(HeaderConstants.CACHE_MAX_AGE, Integer.toString(maxAge), true); } /** * Creates a "max-stale" directive. Indicates that the client is willing to * accept a response that has exceeded its expiration time by any amount of * time.<br> * <br> * Note that this directive can be used on requests only. * * @return A new "max-stale" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP * 1.1 - Modifications of the Basic Expiration Mechanism</a> */ public static CacheDirective maxStale() { return new CacheDirective(HeaderConstants.CACHE_MAX_STALE); } /** * Creates a "max-stale" directive. Indicates that the client is willing to * accept a response that has exceeded its expiration time by a given amount * of time.<br> * <br> * Note that this directive can be used on requests only. * * @param maxStale * Maximum stale age in seconds. * @return A new "max-stale" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP * 1.1 - Modifications of the Basic Expiration Mechanism</a> */ public static CacheDirective maxStale(int maxStale) { return new CacheDirective(HeaderConstants.CACHE_MAX_STALE, Integer.toString(maxStale), true); } /** * Creates a "min-fresh" directive. Indicates that the client is willing to * accept a response whose freshness lifetime is no less than its current * age plus the specified time in seconds. That is, the client wants a * response that will still be fresh for at least the specified number of * seconds.<br> * <br> * Note that this directive can be used on requests only. * * @param minFresh * Minimum freshness lifetime in seconds. * @return A new "min-fresh" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP * 1.1 - Modifications of the Basic Expiration Mechanism</a> */ public static CacheDirective minFresh(int minFresh) { return new CacheDirective(HeaderConstants.CACHE_MIN_FRESH, Integer.toString(minFresh), true); } /** * Creates a "must-revalidate" directive. Indicates that the origin server * requires revalidation of a cache entry on any subsequent use.<br> * <br> * Note that this directive can be used on responses only. * * @return A new "must-revalidate" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP * 1.1 - Cache Revalidation and Reload Controls</a> */ public static CacheDirective mustRevalidate() { return new CacheDirective(HeaderConstants.CACHE_MUST_REVALIDATE); } /** * Creates a "no-cache" directive. Indicates that a cache must not use the * response to satisfy subsequent requests without successful revalidation * with the origin server.<br> * <br> * Note that this directive can be used on requests or responses. * * @return A new "no-cache" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP * 1.1 - What is Cacheable</a> */ public static CacheDirective noCache() { return new CacheDirective(HeaderConstants.CACHE_NO_CACHE); } /** * Creates a "no-cache" directive. Indicates that a cache must not use the * response to satisfy subsequent requests without successful revalidation * with the origin server.<br> * <br> * Note that this directive can be used on requests or responses. * * @param fieldNames * Field names, typically a HTTP header name, that must not be * sent by caches. * @return A new "no-cache" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP * 1.1 - What is Cacheable</a> */ public static CacheDirective noCache(List<String> fieldNames) { StringBuilder sb = new StringBuilder(); if (fieldNames != null) { for (int i = 0; i < fieldNames.size(); i++) { sb.append("\"" + fieldNames.get(i) + "\""); if (i < fieldNames.size() - 1) { sb.append(','); } } } return new CacheDirective(HeaderConstants.CACHE_NO_CACHE, sb.toString()); } /** * Creates a "no-cache" directive. Indicates that a cache must not use the * response to satisfy subsequent requests without successful revalidation * with the origin server.<br> * <br> * Note that this directive can be used on requests or responses. * * @param fieldName * A field name, typically a HTTP header name, that must not be * sent by caches. * @return A new "no-cache" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP * 1.1 - What is Cacheable</a> */ public static CacheDirective noCache(String fieldName) { return new CacheDirective(HeaderConstants.CACHE_NO_CACHE, "\"" + fieldName + "\""); } /** * Creates a "no-store" directive. Indicates that a cache must not release * or retain any information about the call. This applies to both private * and shared caches.<br> * <br> * Note that this directive can be used on requests or responses. * * @return A new "no-store" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.2">HTTP * 1.1 - What May be Stored by Caches</a> */ public static CacheDirective noStore() { return new CacheDirective(HeaderConstants.CACHE_NO_STORE); } /** * Creates a "no-transform" directive. Indicates that a cache or * intermediary proxy must not transform the response entity.<br> * <br> * Note that this directive can be used on requests or responses. * * @return A new "no-transform" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5">HTTP * 1.1 - No-Transform Directive</a> */ public static CacheDirective noTransform() { return new CacheDirective(HeaderConstants.CACHE_NO_TRANSFORM); } /** * Creates a "onlyIfCached" directive. Indicates that only cached responses * should be returned to the client.<br> * <br> * Note that this directive can be used on requests only. * * @return A new "only-if-cached" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP * 1.1 - Cache Revalidation and Reload Controls</a> */ public static CacheDirective onlyIfCached() { return new CacheDirective(HeaderConstants.CACHE_ONLY_IF_CACHED); } /** * Creates a "private" directive. Indicates that all or part of the response * message is intended for a single user and must not be cached by a shared * cache.<br> * <br> * Note that this directive can be used on responses only. * * @return A new "private" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP * 1.1 - What is Cacheable</a> */ public static CacheDirective privateInfo() { return new CacheDirective(HeaderConstants.CACHE_PRIVATE); } /** * Creates a "private" directive. Indicates that all or part of the response * message is intended for a single user and must not be cached by a shared * cache.<br> * <br> * Note that this directive can be used on responses only. * * @param fieldNames * Field names, typically a HTTP header name, that must be * private. * @return A new "private" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP * 1.1 - What is Cacheable</a> */ public static CacheDirective privateInfo(List<String> fieldNames) { StringBuilder sb = new StringBuilder(); if (fieldNames != null) { for (int i = 0; i < fieldNames.size(); i++) { sb.append("\"" + fieldNames.get(i) + "\""); if (i < fieldNames.size() - 1) { sb.append(','); } } } return new CacheDirective(HeaderConstants.CACHE_PRIVATE, sb.toString()); } /** * Creates a "private" directive. Indicates that all or part of the response * message is intended for a single user and must not be cached by a shared * cache.<br> * <br> * Note that this directive can be used on responses only. * * @param fieldName * A field name, typically a HTTP header name, that is private. * @return A new "private" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP * 1.1 - What is Cacheable</a> */ public static CacheDirective privateInfo(String fieldName) { return new CacheDirective(HeaderConstants.CACHE_PRIVATE, "\"" + fieldName + "\""); } /** * Creates a "proxy-revalidate" directive. Indicates that the origin server * requires revalidation of a cache entry on any subsequent use, except that * it does not apply to non-shared user agent caches<br> * <br> * Note that this directive can be used on responses only. * * @return A new "proxy-revalidate" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP * 1.1 - Cache Revalidation and Reload Controls</a> */ public static CacheDirective proxyMustRevalidate() { return new CacheDirective(HeaderConstants.CACHE_PROXY_MUST_REVALIDATE); } /** * Creates a "public" directive. Indicates that the response may be cached * by any cache, even if it would normally be non-cacheable or cacheable * only within a non-shared cache.<br> * <br> * Note that this directive can be used on responses only. * * @return A new "public" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP * 1.1 - What is Cacheable</a> */ public static CacheDirective publicInfo() { return new CacheDirective(HeaderConstants.CACHE_PUBLIC); } /** * Creates a "s-maxage" directive. Indicates that the client is willing to * accept a response from a shared cache (but not a private cache) whose age * is no greater than the specified time in seconds.<br> * <br> * Note that this directive can be used on responses only. * * @param sharedMaxAge * Maximum age in seconds. * @return A new "s-maxage" directive. * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP * 1.1 - Modifications of the Basic Expiration Mechanism</a> */ public static CacheDirective sharedMaxAge(int sharedMaxAge) { return new CacheDirective(HeaderConstants.CACHE_SHARED_MAX_AGE, Integer.toString(sharedMaxAge), true); } /** Indicates if the directive is a digit value. */ private boolean digit; /** The name. */ private volatile String name; /** The value. */ private volatile String value; /** * Constructor for directives with no value. * * @param name * The directive name. */ public CacheDirective(String name) { this(name, null); } /** * Constructor for directives with a value. * * @param name * The directive name. * @param value * The directive value. */ public CacheDirective(String name, String value) { this(name, value, false); } /** * Constructor for directives with a value. * * @param name * The directive name. * @param value * The directive value. * @param digit * The kind of value (true for a digit value, false otherwise). */ public CacheDirective(String name, String value, boolean digit) { this.name = name; this.value = value; this.digit = digit; } /** {@inheritDoc} */ @Override public boolean equals(Object obj) { // if obj == this no need to go further boolean result = (obj == this); if (!result) { result = obj instanceof CacheDirective; // if obj isn't a cache directive or is null don't evaluate further if (result) { CacheDirective that = (CacheDirective) obj; result = (((that.getName() == null) && (getName() == null)) || ((getName() != null) && getName() .equals(that.getName()))); // if names are both null or equal continue if (result) { result = (((that.getValue() == null) && (getValue() == null)) || ((getValue() != null) && getValue() .equals(that.getValue()))); // if values are both null or equal continue if (result) { result = (this.digit == that.digit); } } } } return result; } /** * Returns the name. * * @return The name. */ public String getName() { return name; } /** * Returns the value. * * @return The value. */ public String getValue() { return value; } /** {@inheritDoc} */ @Override public int hashCode() { return SystemUtils.hashCode(getName(), getValue(), isDigit()); } /** * Returns true if the directive contains a digit value. * * @return True if the directive contains a digit value. */ public boolean isDigit() { return digit; } /** * Indicates if the directive is a digit value. * * @param digit * True if the directive contains a digit value. */ public void setDigit(boolean digit) { this.digit = digit; } /** * Sets the name. * * @param name * The name. */ public void setName(String name) { this.name = name; } /** * Sets the value. * * @param value * The value. */ public void setValue(String value) { this.value = value; } @Override public String toString() { return "CacheDirective [digit=" + digit + ", name=" + name + ", value=" + value + "]"; } }