/*
* Copyright Terracotta, Inc.
*
* 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 org.ehcache.expiry;
import org.ehcache.
ValueSupplier;
/**
* Utility class for getting predefined {@link Expiry} instances.
*/
public final class
Expirations {
/**
* Get an {@link Expiry} instance for a non expiring (ie. "eternal") cache.
*
* @return the no expiry instance
*/
public static
Expiry<
Object,
Object>
noExpiration() {
return
NoExpiry.
INSTANCE;
}
/**
* Get a time-to-live (TTL) {@link Expiry} instance for the given {@link Duration}.
*
* @param timeToLive the TTL duration
* @return a TTL expiry
*/
public static
Expiry<
Object,
Object>
timeToLiveExpiration(
Duration timeToLive) {
if (
timeToLive == null) {
throw new
NullPointerException("Duration cannot be null");
}
return new
TimeToLiveExpiry(
timeToLive);
}
/**
* Get a time-to-idle (TTI) {@link Expiry} instance for the given {@link Duration}.
*
* @param timeToIdle the TTI duration
* @return a TTI expiry
*/
public static
Expiry<
Object,
Object>
timeToIdleExpiration(
Duration timeToIdle) {
if (
timeToIdle == null) {
throw new
NullPointerException("Duration cannot be null");
}
return new
TimeToIdleExpiry(
timeToIdle);
}
/**
* Fluent API for creating an Expiry instance where you can specify constant values for creation, access and update time.
* Unspecified values will be set to {@code Duration.INFINITE} for create and {@code null} for access and update, matching
* the {@link #noExpiration() no expiration} expiry.
*
* @param <K> the key type for the cache
* @param <V> the value type for the cache
* @return an {@link Expiry} builder
*/
public static <K, V>
ExpiryBuilder<K, V>
builder() {
return new
ExpiryBuilder<K, V>();
}
private
Expirations() {
//
}
/**
* Simple implementation of the {@link Expiry} interface allowing to set constants to each expiry types.
*/
private static class
BaseExpiry<K, V> implements
Expiry<K, V> {
private final
Duration create;
private final
Duration access;
private final
Duration update;
BaseExpiry(
Duration create,
Duration access,
Duration update) {
this.
create =
create;
this.
access =
access;
this.
update =
update;
}
@
Override
public
Duration getExpiryForCreation(K
key, V
value) {
return
create;
}
@
Override
public
Duration getExpiryForAccess(K
key,
ValueSupplier<? extends V>
value) {
return
access;
}
@
Override
public
Duration getExpiryForUpdate(K
key,
ValueSupplier<? extends V>
oldValue, V
newValue) {
return
update;
}
@
Override
public boolean
equals(final
Object o) {
if (this ==
o) return true;
if (
o == null ||
getClass() !=
o.
getClass()) return false;
final
BaseExpiry that = (
BaseExpiry)
o;
if (
access != null ? !
access.
equals(
that.
access) :
that.
access != null) return false;
if (
create != null ? !
create.
equals(
that.
create) :
that.
create != null) return false;
if (
update != null ? !
update.
equals(
that.
update) :
that.
update != null) return false;
return true;
}
@
Override
public int
hashCode() {
int
result =
create != null ?
create.
hashCode() : 0;
result = 31 *
result + (
access != null ?
access.
hashCode() : 0);
result = 31 *
result + (
update != null ?
update.
hashCode() : 0);
return
result;
}
@
Override
public
String toString() {
return this.
getClass().
getSimpleName() + "{" +
"create=" +
create +
", access=" +
access +
", update=" +
update +
'}';
}
}
private static class
TimeToLiveExpiry extends
BaseExpiry<
Object,
Object> {
TimeToLiveExpiry(
Duration ttl) {
super(
ttl, null,
ttl);
}
}
private static class
TimeToIdleExpiry extends
BaseExpiry<
Object,
Object> {
TimeToIdleExpiry(
Duration tti) {
super(
tti,
tti,
tti);
}
}
private static class
NoExpiry extends
BaseExpiry<
Object,
Object> {
private static final
Expiry<
Object,
Object>
INSTANCE = new
NoExpiry();
private
NoExpiry() {
super(
Duration.
INFINITE, null, null);
}
}
/**
* Builder to create a simple {@link Expiry}.
*
* @param <K> Key type of the cache entries
* @param <V> Value type of the cache entries
*/
public static final class
ExpiryBuilder<K, V> {
private
Duration create =
Duration.
INFINITE;
private
Duration access = null;
private
Duration update = null;
private
ExpiryBuilder() {}
/**
* Set TTL since creation
*
* @param create TTL since creation
* @return this builder
*/
public
ExpiryBuilder<K, V>
setCreate(
Duration create) {
this.
create =
create;
return this;
}
/**
* Set TTL since last access
*
* @param access TTL since last access
* @return this builder
*/
public
ExpiryBuilder<K, V>
setAccess(
Duration access) {
this.
access =
access;
return this;
}
/**
* Set TTL since last update
*
* @param update TTL since last update
* @return this builder
*/
public
ExpiryBuilder<K, V>
setUpdate(
Duration update) {
this.
update =
update;
return this;
}
/**
*
* @return an {@link Expiry}
*/
public
Expiry<K, V>
build() {
return new
BaseExpiry<K, V>(
create,
access,
update);
}
}
}