package org.cache2k.configuration;
/*
* #%L
* cache2k API
* %%
* Copyright (C) 2000 - 2017 headissue GmbH, Munich
* %%
* 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.
* #L%
*/
import org.cache2k.Cache2kBuilder;
import org.cache2k.expiry.*;
import org.cache2k.event.CacheEntryOperationListener;
import org.cache2k.integration.AdvancedCacheLoader;
import org.cache2k.integration.CacheWriter;
import org.cache2k.integration.ExceptionPropagator;
import org.cache2k.integration.FunctionalCacheLoader;
import org.cache2k.integration.ResiliencePolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
/**
* Configuration for a cache2k cache.
*
* <p>To create a cache, the {@link Cache2kBuilder} is used. All configuration properties
* are present on the builder and are documented in this place. Consequently all properties
* refer to the corresponding builder method.
*
* <p>The configuration bean is designed to be serializable. This is used for example to copy
* default configurations. The builder allows object references to customizations to be set.
* If this happens the configuration is not serializable. Such configuration is only used for
* immediate creation of one cache via the builder.
*
* <p>The configuration may contain additional beans, called configuration sections, that are
* used to configure extensions or sub modules.
*
* @author Jens Wilke
*/
@SuppressWarnings("unused")
public class Cache2kConfiguration<K, V> implements ConfigurationBean, ConfigurationWithSections {
public static final long EXPIRY_NOT_ETERNAL = Long.MAX_VALUE - 1;
private boolean storeByReference;
private String name;
private CacheType<K> keyType;
private CacheType<V> valueType;
private long entryCapacity = 2000;
private boolean strictEviction = false;
private boolean refreshAhead = false;
private long expireAfterWrite = -1;
private long retryInterval = -1;
private long maxRetryInterval = -1;
private long resilienceDuration = -1;
private boolean keepDataAfterExpired = false;
private boolean sharpExpiry = false;
private boolean suppressExceptions = true;
private int loaderThreadCount;
private boolean permitNullValues = false;
private boolean disableStatistics = false;
private boolean disableLastModificationTime = false;
private boolean externalConfigurationPresent = false;
private boolean boostConcurrency = false;
private CustomizationSupplier<Executor> loaderExecutor;
private CustomizationSupplier<Executor> prefetchExecutor;
private CustomizationSupplier<Executor> asyncListenerExecutor;
private CustomizationSupplier<ExpiryPolicy<K,V>> expiryPolicy;
private CustomizationSupplier<ResiliencePolicy<K,V>> resiliencePolicy;
private CustomizationSupplier<? extends FunctionalCacheLoader<K,V>> loader;
private CustomizationSupplier<CacheWriter<K,V>> writer;
private CustomizationSupplier<AdvancedCacheLoader<K,V>> advancedLoader;
private CustomizationSupplier<ExceptionPropagator<K>> exceptionPropagator;
private CustomizationCollection<CacheEntryOperationListener<K,V>> listeners;
private CustomizationCollection<CacheEntryOperationListener<K,V>> asyncListeners;
private ConfigurationSectionContainer sections;
/**
* Construct a config instance setting the type parameters and returning a
* proper generic type.
*
* @see Cache2kBuilder#keyType(Class)
* @see Cache2kBuilder#valueType(Class)
*/
public static <K,V> Cache2kConfiguration<K, V> of(Class<K> keyType, Class<V> valueType) {
Cache2kConfiguration c = new Cache2kConfiguration();
c.setKeyType(keyType);
c.setValueType(valueType);
return (Cache2kConfiguration<K, V>) c;
}
/**
* Construct a config instance setting the type parameters and returning a
* proper generic type.
*
* @see Cache2kBuilder#keyType(CacheType)
* @see Cache2kBuilder#valueType(CacheType)
*/
public static <K,V> Cache2kConfiguration<K, V> of(Class<K> keyType, CacheType<V> valueType) {
Cache2kConfiguration c = new Cache2kConfiguration();
c.setKeyType(keyType);
c.setValueType(valueType);
return (Cache2kConfiguration<K, V>) c;
}
/**
* Construct a config instance setting the type parameters and returning a
* proper generic type.
*
* @see Cache2kBuilder#keyType(Class)
* @see Cache2kBuilder#valueType(Class)
*/
public static <K,V> Cache2kConfiguration<K, V> of(CacheType<K> keyType, Class<V> valueType) {
Cache2kConfiguration c = new Cache2kConfiguration();
c.setKeyType(keyType);
c.setValueType(valueType);
return (Cache2kConfiguration<K, V>) c;
}
/**
* Construct a config instance setting the type parameters and returning a
* proper generic type.
*
* @see Cache2kBuilder#keyType(CacheType)
* @see Cache2kBuilder#valueType(CacheType)
*/
public static <K,V> Cache2kConfiguration<K, V> of(CacheType<K> keyType, CacheType<V> valueType) {
Cache2kConfiguration c = new Cache2kConfiguration();
c.setKeyType(keyType);
c.setValueType(valueType);
return (Cache2kConfiguration<K, V>) c;
}
/**
* @see Cache2kBuilder#name(String)
*/
public String getName() {
return name;
}
/**
*
* @see Cache2kBuilder#name(String)
*/
public void setName(String name) {
this.name = name;
}
/**
*
* @see Cache2kBuilder#entryCapacity
*/
public long getEntryCapacity() {
return entryCapacity;
}
public void setEntryCapacity(long v) {
this.entryCapacity = v;
}
/**
* @see Cache2kBuilder#refreshAhead(boolean)
*/
public boolean isRefreshAhead() {
return refreshAhead;
}
/**
* @see Cache2kBuilder#refreshAhead(boolean)
*/
public void setRefreshAhead(boolean v) {
this.refreshAhead = v;
}
public CacheType<K> getKeyType() {
return keyType;
}
private void checkNull(Object v) {
if (v == null) {
throw new NullPointerException("null value not allowed");
}
}
/**
* @see Cache2kBuilder#keyType(Class)
* @see CacheType for a general discussion on types
*/
public void setKeyType(Class<?> v) {
checkNull(v);
setKeyType(CacheTypeCapture.of(v));
}
/**
* @see Cache2kBuilder#keyType(CacheType)
* @see CacheType for a general discussion on types
*/
public void setKeyType(CacheType v) {
checkNull(v);
if (v.isArray()) {
throw new IllegalArgumentException("Arrays are not supported for keys");
}
keyType = v.getBeanRepresentation();
}
public CacheType<V> getValueType() {
return valueType;
}
/**
* @see Cache2kBuilder#valueType(Class)
* @see CacheType for a general discussion on types
*/
public void setValueType(Class<?> v) {
checkNull(v);
setValueType(CacheTypeCapture.of(v));
}
/**
* @see Cache2kBuilder#valueType(CacheType)
* @see CacheType for a general discussion on types
*/
public void setValueType(CacheType v) {
checkNull(v);
if (v.isArray()) {
throw new IllegalArgumentException("Arrays are not supported for values");
}
valueType = v.getBeanRepresentation();
}
public boolean isEternal() {
return expireAfterWrite == -1 || expireAfterWrite == ExpiryTimeValues.ETERNAL;
}
/**
* @see Cache2kBuilder#eternal(boolean)
*/
public void setEternal(boolean v) {
if (v) {
setExpireAfterWrite(ExpiryTimeValues.ETERNAL);
} else {
setExpireAfterWrite(EXPIRY_NOT_ETERNAL);
}
}
public long getExpireAfterWrite() {
return expireAfterWrite;
}
/**
* @see Cache2kBuilder#expireAfterWrite
*/
public void setExpireAfterWrite(long millis) {
if (millis == expireAfterWrite) {
return;
}
if (expireAfterWrite != -1) {
if (millis == Expiry.ETERNAL) {
throw new IllegalArgumentException("eternal disabled or expiry was set, refusing to reset back to eternal");
}
if (expireAfterWrite == Expiry.ETERNAL) {
throw new IllegalArgumentException("eternal enabled explicitly, refusing to enable expiry");
}
}
this.expireAfterWrite = millis;
}
/**
* @see Cache2kBuilder#retryInterval
*/
public long getRetryInterval() {
return retryInterval;
}
/**
* @see Cache2kBuilder#retryInterval
*/
public void setRetryInterval(long millis) {
retryInterval = millis;
}
/**
* @see Cache2kBuilder#maxRetryInterval
*/
public long getMaxRetryInterval() {
return maxRetryInterval;
}
/**
* @see Cache2kBuilder#maxRetryInterval
*/
public void setMaxRetryInterval(long millis) {
maxRetryInterval = millis;
}
/**
* @see Cache2kBuilder#resilienceDuration
*/
public long getResilienceDuration() {
return resilienceDuration;
}
/**
* @see Cache2kBuilder#resilienceDuration
*/
public void setResilienceDuration(long millis) {
resilienceDuration = millis;
}
public boolean isKeepDataAfterExpired() {
return keepDataAfterExpired;
}
/**
* @see Cache2kBuilder#keepDataAfterExpired(boolean)
*/
public void setKeepDataAfterExpired(boolean v) {
this.keepDataAfterExpired = v;
}
public boolean isSharpExpiry() {
return sharpExpiry;
}
/**
* @see Cache2kBuilder#sharpExpiry(boolean)
*/
public void setSharpExpiry(boolean v) {
this.sharpExpiry = v;
}
public boolean isSuppressExceptions() {
return suppressExceptions;
}
/**
* @see Cache2kBuilder#suppressExceptions(boolean)
*/
public void setSuppressExceptions(boolean v) {
this.suppressExceptions = v;
}
public boolean isExternalConfigurationPresent() {
return externalConfigurationPresent;
}
/**
* True, if an external configuration for the cache was found and is applied.
*/
public void setExternalConfigurationPresent(final boolean v) {
externalConfigurationPresent = v;
}
/**
* Mutable collection of additional configuration sections
*/
public ConfigurationSectionContainer getSections() {
if (sections == null) {
sections = new ConfigurationSectionContainer();
}
return sections;
}
public CustomizationSupplier<? extends FunctionalCacheLoader<K,V>> getLoader() {
return loader;
}
public void setLoader(final CustomizationSupplier<? extends FunctionalCacheLoader<K,V>> v) {
loader = v;
}
public CustomizationSupplier<AdvancedCacheLoader<K, V>> getAdvancedLoader() {
return advancedLoader;
}
public void setAdvancedLoader(final CustomizationSupplier<AdvancedCacheLoader<K, V>> v) {
advancedLoader = v;
}
public int getLoaderThreadCount() {
return loaderThreadCount;
}
/**
* @see Cache2kBuilder#loaderThreadCount(int)
*/
public void setLoaderThreadCount(final int v) {
loaderThreadCount = v;
}
public CustomizationSupplier<ExpiryPolicy<K, V>> getExpiryPolicy() {
return expiryPolicy;
}
public void setExpiryPolicy(final CustomizationSupplier<ExpiryPolicy<K, V>> _expiryPolicy) {
expiryPolicy = _expiryPolicy;
}
public CustomizationSupplier<CacheWriter<K, V>> getWriter() {
return writer;
}
/**
* @see Cache2kBuilder#writer(CacheWriter)
*/
public void setWriter(final CustomizationSupplier<CacheWriter<K, V>> v) {
writer = v;
}
public boolean isStoreByReference() {
return storeByReference;
}
/**
* @see Cache2kBuilder#storeByReference(boolean)
*/
public void setStoreByReference(final boolean v) {
storeByReference = v;
}
public CustomizationSupplier<ExceptionPropagator<K>> getExceptionPropagator() {
return exceptionPropagator;
}
/**
* @see Cache2kBuilder#exceptionPropagator(ExceptionPropagator)
*/
public void setExceptionPropagator(final CustomizationSupplier<ExceptionPropagator<K>> v) {
exceptionPropagator = v;
}
/**
* A set of listeners. Listeners added in this collection will be
* executed in a synchronous mode, meaning, further processing for
* an entry will stall until a registered listener is executed.
* The expiry will be always executed asynchronously.
*
* <p>A listener can be added by adding it to the collection.
* Duplicate (in terms of equal objects) listeners will be ignored.
*
* @return Mutable collection of listeners
*/
public CustomizationCollection<CacheEntryOperationListener<K,V>> getListeners() {
if (listeners == null) {
listeners = new DefaultCustomizationCollection<CacheEntryOperationListener<K, V>>();
}
return listeners;
}
/**
* @return True if listeners are added to this configuration.
*/
public boolean hasListeners() {
return listeners != null && !listeners.isEmpty();
}
/**
* A set of listeners. A listener can be added by adding it to the collection.
* Duplicate (in terms of equal objects) listeners will be ignored.
*
* @return Mutable collection of listeners
*/
public CustomizationCollection<CacheEntryOperationListener<K,V>> getAsyncListeners() {
if (asyncListeners == null) {
asyncListeners = new DefaultCustomizationCollection<CacheEntryOperationListener<K, V>>();
}
return asyncListeners;
}
/**
* @return True if listeners are added to this configuration.
*/
public boolean hasAsyncListeners() {
return asyncListeners != null && !asyncListeners.isEmpty();
}
public CustomizationSupplier<ResiliencePolicy<K, V>> getResiliencePolicy() {
return resiliencePolicy;
}
/**
* @see Cache2kBuilder#resiliencePolicy
*/
public void setResiliencePolicy(final CustomizationSupplier<ResiliencePolicy<K, V>> _resiliencePolicy) {
resiliencePolicy = _resiliencePolicy;
}
public boolean isStrictEviction() {
return strictEviction;
}
/**
* @see Cache2kBuilder#strictEviction(boolean)
*/
public void setStrictEviction(final boolean v) {
strictEviction = v;
}
public boolean isPermitNullValues() {
return permitNullValues;
}
/**
* @see Cache2kBuilder#permitNullValues(boolean)
*/
public void setPermitNullValues(final boolean v) {
permitNullValues = v;
}
public boolean isDisableStatistics() {
return disableStatistics;
}
/**
* @see Cache2kBuilder#disableStatistics
*/
public void setDisableStatistics(final boolean v) {
disableStatistics = v;
}
public CustomizationSupplier<Executor> getLoaderExecutor() {
return loaderExecutor;
}
public boolean isDisableLastModificationTime() {
return disableLastModificationTime;
}
/**
* @see Cache2kBuilder#disableLastModificationTime
*/
public void setDisableLastModificationTime(final boolean v) {
disableLastModificationTime = v;
}
/**
* @see Cache2kBuilder#loaderExecutor(Executor)
*/
public void setLoaderExecutor(final CustomizationSupplier<Executor> v) {
loaderExecutor = v;
}
public CustomizationSupplier<Executor> getPrefetchExecutor() {
return prefetchExecutor;
}
/**
* @see Cache2kBuilder#prefetchExecutor(Executor)
*/
public void setPrefetchExecutor(final CustomizationSupplier<Executor> v) {
prefetchExecutor = v;
}
public CustomizationSupplier<Executor> getAsyncListenerExecutor() {
return asyncListenerExecutor;
}
/**
* @see Cache2kBuilder#asyncListenerExecutor(Executor)
*/
public void setAsyncListenerExecutor(final CustomizationSupplier<Executor> v) {
asyncListenerExecutor = v;
}
public boolean isBoostConcurrency() {
return boostConcurrency;
}
/**
* @see Cache2kBuilder#boostConcurrency(boolean)
*/
public void setBoostConcurrency(final boolean v) {
boostConcurrency = v;
}
}