com.phloc.web.http.CacheControlBuilder Maven / Gradle / Ivy
/**
* Copyright (C) 2006-2015 phloc systems
* http://www.phloc.com
* office[at]phloc[dot]com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.phloc.web.http;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.phloc.commons.CGlobal;
import com.phloc.commons.ICloneable;
import com.phloc.commons.ValueEnforcer;
import com.phloc.commons.annotations.Nonempty;
import com.phloc.commons.annotations.ReturnsMutableCopy;
import com.phloc.commons.collections.ContainerHelper;
import com.phloc.commons.string.StringHelper;
import com.phloc.commons.string.ToStringGenerator;
/**
* This class is used to build the response HTTP header field Cache-Control
* value in a structured way. This header field is only applicable for HTTP/1.1
*
* @author Philip Helger
*/
public class CacheControlBuilder implements ICloneable
{
private Long m_aMaxAgeSeconds;
private Long m_aSharedMaxAgeSeconds;
private boolean m_bPublic = false;
private boolean m_bPrivate = false;
private boolean m_bNoCache = false;
private boolean m_bNoStore = false;
private boolean m_bNoTransform = false;
private boolean m_bMustRevalidate = false;
private boolean m_bProxyRevalidate = false;
private final List m_aExtensions = new ArrayList ();
public CacheControlBuilder ()
{}
public CacheControlBuilder (@Nonnull final CacheControlBuilder aBase)
{
ValueEnforcer.notNull (aBase, "Base");
m_aMaxAgeSeconds = aBase.m_aMaxAgeSeconds;
m_aSharedMaxAgeSeconds = aBase.m_aSharedMaxAgeSeconds;
m_bPublic = aBase.m_bPublic;
m_bPrivate = aBase.m_bPrivate;
m_bNoCache = aBase.m_bNoCache;
m_bNoStore = aBase.m_bNoStore;
m_bNoTransform = aBase.m_bNoTransform;
m_bMustRevalidate = aBase.m_bMustRevalidate;
m_bProxyRevalidate = aBase.m_bProxyRevalidate;
m_aExtensions.addAll (aBase.m_aExtensions);
}
/**
* Set the maximum age relative to the request time
*
* @param eTimeUnit
* {@link TimeUnit} to use
* @param nDuration
* The duration in the passed unit
* @return this
*/
@Nonnull
public CacheControlBuilder setMaxAge (@Nonnull final TimeUnit eTimeUnit, final long nDuration)
{
return setMaxAgeSeconds (eTimeUnit.toSeconds (nDuration));
}
/**
* Set the maximum age in days relative to the request time
*
* @param nDays
* Days to keep it
* @return this
*/
@Nonnull
public CacheControlBuilder setMaxAgeDays (@Nonnegative final long nDays)
{
return setMaxAgeSeconds (nDays * CGlobal.SECONDS_PER_DAY);
}
/**
* Set the maximum age in hours relative to the request time
*
* @param nHours
* Hours to keep it
* @return this
*/
@Nonnull
public CacheControlBuilder setMaxAgeHours (@Nonnegative final long nHours)
{
return setMaxAgeSeconds (nHours * CGlobal.SECONDS_PER_HOUR);
}
/**
* Set the maximum age in minutes relative to the request time
*
* @param nMinutes
* Minutes to keep it
* @return this
*/
@Nonnull
public CacheControlBuilder setMaxAgeMinutes (@Nonnegative final long nMinutes)
{
return setMaxAgeSeconds (nMinutes * CGlobal.SECONDS_PER_MINUTE);
}
/**
* Set the maximum age in seconds relative to the request time. Specifies the
* maximum amount of time that a representation will be considered fresh.
* Similar to Expires, this directive is relative to the time of the request,
* rather than absolute. [seconds] is the number of seconds from the time of
* the request you wish the representation to be fresh for.
*
* @param nSeconds
* Seconds to keep it
* @return this
*/
@Nonnull
public CacheControlBuilder setMaxAgeSeconds (@Nonnegative final long nSeconds)
{
ValueEnforcer.isGE0 (nSeconds, "Seconds");
m_aMaxAgeSeconds = Long.valueOf (nSeconds);
return this;
}
public boolean hasMaxAgeSeconds ()
{
return m_aMaxAgeSeconds != null;
}
@Nullable
public Long getMaxAgeSeconds ()
{
return m_aMaxAgeSeconds;
}
/**
* Set the maximum age for shared caches relative to the request time. Similar
* to max-age, except that it only applies to shared (e.g., proxy) caches.
*
* @param eTimeUnit
* {@link TimeUnit} to use
* @param nDuration
* The duration in the passed unit
* @return this
*/
@Nonnull
public CacheControlBuilder setSharedMaxAge (@Nonnull final TimeUnit eTimeUnit, final long nDuration)
{
return setSharedMaxAgeSeconds (eTimeUnit.toSeconds (nDuration));
}
/**
* Set the maximum age for shared caches in days relative to the request time.
* Similar to max-age, except that it only applies to shared (e.g., proxy)
* caches.
*
* @param nDays
* Days to keep it
* @return this
*/
@Nonnull
public CacheControlBuilder setSharedMaxAgeDays (@Nonnegative final long nDays)
{
return setSharedMaxAgeSeconds (nDays * CGlobal.SECONDS_PER_DAY);
}
/**
* Set the maximum age for shared caches in hours relative to the request
* time. Similar to max-age, except that it only applies to shared (e.g.,
* proxy) caches.
*
* @param nHours
* Hours to keep it
* @return this
*/
@Nonnull
public CacheControlBuilder setSharedMaxAgeHours (@Nonnegative final long nHours)
{
return setSharedMaxAgeSeconds (nHours * CGlobal.SECONDS_PER_HOUR);
}
/**
* Set the maximum age for shared caches in minutes relative to the request
* time. Similar to max-age, except that it only applies to shared (e.g.,
* proxy) caches.
*
* @param nMinutes
* Minutes to keep it
* @return this
*/
@Nonnull
public CacheControlBuilder setSharedMaxAgeMinutes (@Nonnegative final long nMinutes)
{
return setSharedMaxAgeSeconds (nMinutes * CGlobal.SECONDS_PER_MINUTE);
}
/**
* Set the maximum age for shared caches in seconds relative to the request
* time. Similar to max-age, except that it only applies to shared (e.g.,
* proxy) caches.
*
* @param nSeconds
* Seconds to keep it
* @return this
*/
@Nonnull
public CacheControlBuilder setSharedMaxAgeSeconds (@Nonnegative final long nSeconds)
{
ValueEnforcer.isGE0 (nSeconds, "Seconds");
m_aSharedMaxAgeSeconds = Long.valueOf (nSeconds);
return this;
}
public boolean hasSharedMaxAgeSeconds ()
{
return m_aSharedMaxAgeSeconds != null;
}
@Nullable
public Long getSharedMaxAgeSeconds ()
{
return m_aSharedMaxAgeSeconds;
}
/**
* Set the public value. marks authenticated responses as cacheable;
* normally, if HTTP authentication is required, responses are automatically
* private.
*
* @param bPublic
* true
to enable public
* @return this
*/
@Nonnull
public CacheControlBuilder setPublic (final boolean bPublic)
{
m_bPublic = bPublic;
return this;
}
public boolean isPublic ()
{
return m_bPublic;
}
/**
* Set the private value. allows caches that are specific to one user
* (e.g., in a browser) to store the response; shared caches (e.g., in a
* proxy) may not.
*
* @param bPrivate
* true
to enable private
* @return this
*/
@Nonnull
public CacheControlBuilder setPrivate (final boolean bPrivate)
{
m_bPrivate = bPrivate;
return this;
}
public boolean isPrivate ()
{
return m_bPrivate;
}
/**
* Set the no-cache value. Forces caches to submit the request to the
* origin server for validation before releasing a cached copy, every time.
* This is useful to assure that authentication is respected (in combination
* with public), or to maintain rigid freshness, without sacrificing all of
* the benefits of caching.
*
* @param bNoCache
* true
to enable no-cache
* @return this
*/
@Nonnull
public CacheControlBuilder setNoCache (final boolean bNoCache)
{
m_bNoCache = bNoCache;
return this;
}
public boolean isNoCache ()
{
return m_bNoCache;
}
/**
* Set the no-store value. Instructs caches not to keep a copy of the
* representation under any conditions.
*
* @param bNoStore
* true
to enable no-store
* @return this
*/
@Nonnull
public CacheControlBuilder setNoStore (final boolean bNoStore)
{
m_bNoStore = bNoStore;
return this;
}
public boolean isNoStore ()
{
return m_bNoStore;
}
/**
* Set the no-transform value. Implementors of intermediate caches
* (proxies) have found it useful to convert the media type of certain entity
* bodies. A non- transparent proxy might, for example, convert between image
* formats in order to save cache space or to reduce the amount of traffic on
* a slow link. If a message includes the no-transform directive, an
* intermediate cache or proxy MUST NOT change those headers that are listed
* in section 13.5.2 as being subject to the no-transform directive. This
* implies that the cache or proxy MUST NOT change any aspect of the
* entity-body that is specified by these headers, including the value of the
* entity-body itself.
*
* @param bNoTransform
* true
to enable no-transform
* @return this
*/
@Nonnull
public CacheControlBuilder setNoTransform (final boolean bNoTransform)
{
m_bNoTransform = bNoTransform;
return this;
}
public boolean isNoTransform ()
{
return m_bNoTransform;
}
/**
* Set the must-revalidate value. Tells caches that they must obey any
* freshness information you give them about a representation. HTTP allows
* caches to serve stale representations under special conditions; by
* specifying this header, you’re telling the cache that you want it to
* strictly follow your rules.
*
* @param bMustRevalidate
* true
to enable must-revalidate
* @return this
*/
@Nonnull
public CacheControlBuilder setMustRevalidate (final boolean bMustRevalidate)
{
m_bMustRevalidate = bMustRevalidate;
return this;
}
public boolean isMustRevalidate ()
{
return m_bMustRevalidate;
}
/**
* Set the proxy-revalidate value. Similar to must-revalidate, except
* that it only applies to proxy caches.
*
* @param bProxyRevalidate
* true
to enable proxy-revalidate
* @return this
*/
@Nonnull
public CacheControlBuilder setProxyRevalidate (final boolean bProxyRevalidate)
{
m_bProxyRevalidate = bProxyRevalidate;
return this;
}
public boolean isProxyRevalidate ()
{
return m_bProxyRevalidate;
}
@Nonnull
public CacheControlBuilder addExtension (@Nonnull @Nonempty final String sExtension)
{
ValueEnforcer.notEmpty (sExtension, "Extension");
if (sExtension.indexOf (',') >= 0)
throw new IllegalArgumentException ("Each extension must be added separately: '" + sExtension + "'");
m_aExtensions.add (sExtension);
return this;
}
@Nonnull
@ReturnsMutableCopy
public List getAllExtensions ()
{
return ContainerHelper.newList (m_aExtensions);
}
@Nonnull
public String getAsHTTPHeaderValue ()
{
final List aItems = new ArrayList ();
if (m_aMaxAgeSeconds != null)
aItems.add ("max-age=" + m_aMaxAgeSeconds.toString ());
if (m_aSharedMaxAgeSeconds != null)
aItems.add ("s-maxage=" + m_aSharedMaxAgeSeconds.toString ());
if (m_bPublic)
aItems.add ("public");
if (m_bPrivate)
aItems.add ("private");
if (m_bNoCache)
aItems.add ("no-cache");
if (m_bNoStore)
aItems.add ("no-store");
if (m_bNoTransform)
aItems.add ("no-transform");
if (m_bMustRevalidate)
aItems.add ("must-revalidate");
if (m_bProxyRevalidate)
aItems.add ("proxy-revalidate");
aItems.addAll (m_aExtensions);
return StringHelper.getImploded (", ", aItems);
}
@Nonnull
public CacheControlBuilder getClone ()
{
return new CacheControlBuilder (this);
}
@Override
public String toString ()
{
return new ToStringGenerator (this).appendIfNotNull ("maxAgeSecs", m_aMaxAgeSeconds)
.appendIfNotNull ("sharedMaxAgeSecs", m_aSharedMaxAgeSeconds)
.append ("public", m_bPublic)
.append ("private", m_bPrivate)
.append ("noCache", m_bNoCache)
.append ("noStore", m_bNoStore)
.append ("noTransform", m_bNoTransform)
.append ("mustRevalidate", m_bMustRevalidate)
.append ("proxyRevalidate", m_bProxyRevalidate)
.append ("extensions", m_aExtensions)
.toString ();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy