All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ehcache.config.builders.CacheConfigurationBuilder Maven / Gradle / Ivy

There is a newer version: 3.10.8
Show newest version
/*
 * 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.config.builders;

import org.ehcache.config.Builder;
import org.ehcache.config.CacheConfiguration;
import org.ehcache.config.EvictionAdvisor;
import org.ehcache.config.ResourcePools;
import org.ehcache.config.units.MemoryUnit;
import org.ehcache.core.config.BaseCacheConfiguration;
import org.ehcache.core.config.store.StoreEventSourceConfiguration;
import org.ehcache.core.spi.store.heap.SizeOfEngine;
import org.ehcache.expiry.ExpiryPolicy;
import org.ehcache.impl.config.copy.DefaultCopierConfiguration;
import org.ehcache.impl.config.event.DefaultCacheEventDispatcherConfiguration;
import org.ehcache.impl.config.event.DefaultCacheEventListenerConfiguration;
import org.ehcache.impl.config.event.DefaultEventSourceConfiguration;
import org.ehcache.impl.config.loaderwriter.DefaultCacheLoaderWriterConfiguration;
import org.ehcache.impl.config.resilience.DefaultResilienceStrategyConfiguration;
import org.ehcache.impl.config.serializer.DefaultSerializerConfiguration;
import org.ehcache.impl.config.store.disk.OffHeapDiskStoreConfiguration;
import org.ehcache.impl.copy.SerializingCopier;
import org.ehcache.impl.config.store.heap.DefaultSizeOfEngineConfiguration;
import org.ehcache.spi.copy.Copier;
import org.ehcache.spi.loaderwriter.CacheLoaderWriter;
import org.ehcache.spi.resilience.ResilienceStrategy;
import org.ehcache.spi.serialization.Serializer;
import org.ehcache.spi.service.ServiceConfiguration;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.function.UnaryOperator;

import static java.util.Objects.requireNonNull;
import static java.util.Optional.ofNullable;
import static org.ehcache.core.config.ExpiryUtils.convertToExpiryPolicy;
import static org.ehcache.impl.config.store.heap.DefaultSizeOfEngineConfiguration.DEFAULT_MAX_OBJECT_SIZE;
import static org.ehcache.impl.config.store.heap.DefaultSizeOfEngineConfiguration.DEFAULT_OBJECT_GRAPH_SIZE;
import static org.ehcache.impl.config.store.heap.DefaultSizeOfEngineConfiguration.DEFAULT_UNIT;


/**
 * The {@code CacheConfigurationBuilder} enables building {@link CacheConfiguration}s using a fluent style.
 * 

* As with all Ehcache builders, all instances are immutable and calling any method on the builder will return a new * instance without modifying the one on which the method was called. * This enables the sharing of builder instances without any risk of seeing them modified by code elsewhere. */ public class CacheConfigurationBuilder implements Builder> { private final Collection> serviceConfigurations = new HashSet<>(); private ExpiryPolicy expiry; private ClassLoader classLoader = null; private EvictionAdvisor evictionAdvisor; private ResourcePools resourcePools; private final Class keyType; private final Class valueType; /** * Creates a new instance ready to produce a {@link CacheConfiguration} with key type {@code } and with value type * {@code } and which will use the {@link ResourcePools configured resources}. * * @param keyType the key type * @param valueType the value type * @param resourcePools the resources to use * @param the key type * @param the value type * @return a {@code CacheConfigurationBuilder} */ public static CacheConfigurationBuilder newCacheConfigurationBuilder(Class keyType, Class valueType, ResourcePools resourcePools) { return new CacheConfigurationBuilder<>(keyType, valueType, resourcePools); } /** * Creates a new instance ready to produce a {@link CacheConfiguration} with key type {@code } and with value type * {@code } and which will use the {@link ResourcePools configured resources}, passed as a {@link ResourcePoolsBuilder}. * * @param keyType the key type * @param valueType the value type * @param resourcePoolsBuilder the resources to use, as a builder * @param the key type * @param the value type * @return a {@code CacheConfigurationBuilder} */ public static CacheConfigurationBuilder newCacheConfigurationBuilder(Class keyType, Class valueType, Builder resourcePoolsBuilder) { return new CacheConfigurationBuilder<>(keyType, valueType, resourcePoolsBuilder.build()); } /** * Creates a new instance ready to produce a {@link CacheConfiguration} functionally equivalent to the supplied configuration. * * @param configuration seed configuration * @param the key type * @param the value type * @return a {@code CacheConfigurationBuilder} */ public static CacheConfigurationBuilder newCacheConfigurationBuilder(CacheConfiguration configuration) { CacheConfigurationBuilder builder = newCacheConfigurationBuilder(configuration.getKeyType(), configuration.getValueType(), configuration.getResourcePools()) .withClassLoader(configuration.getClassLoader()) .withEvictionAdvisor(configuration.getEvictionAdvisor()) .withExpiry(configuration.getExpiryPolicy()); for (ServiceConfiguration serviceConfig : configuration.getServiceConfigurations()) { builder = builder.add(serviceConfig); } return builder; } private CacheConfigurationBuilder(Class keyType, Class valueType, ResourcePools resourcePools) { this.keyType = keyType; this.valueType = valueType; this.resourcePools = resourcePools; } private CacheConfigurationBuilder(CacheConfigurationBuilder other) { this.keyType = other.keyType; this.valueType = other.valueType; this.expiry = other.expiry; this.classLoader = other.classLoader; this.evictionAdvisor = other.evictionAdvisor; this.resourcePools = other.resourcePools; this.serviceConfigurations.addAll(other.serviceConfigurations); } /** * Adds a {@link ServiceConfiguration} to the returned builder. * * @param configuration the service configuration to add * @return a new builder with the added service configuration */ public CacheConfigurationBuilder add(ServiceConfiguration configuration) { CacheConfigurationBuilder otherBuilder = new CacheConfigurationBuilder<>(this); if (getExistingServiceConfiguration(configuration.getClass()) != null) { if (configuration instanceof DefaultCopierConfiguration) { DefaultCopierConfiguration copierConfiguration = (DefaultCopierConfiguration) configuration; otherBuilder.removeExistingCopierConfigFor(copierConfiguration.getType()); } else if (configuration instanceof DefaultSerializerConfiguration) { DefaultSerializerConfiguration serializerConfiguration = (DefaultSerializerConfiguration) configuration; otherBuilder.removeExistingSerializerConfigFor(serializerConfiguration.getType()); } else if (!(configuration instanceof DefaultCacheEventListenerConfiguration)) { throw new IllegalStateException("Cannot add a generic service configuration when another one already exists. " + "Rely on specific with* methods or make sure your remove other configuration first."); } } otherBuilder.serviceConfigurations.add(configuration); return otherBuilder; } /** * Convenience method to add a {@link ServiceConfiguration} that is produced by a {@link Builder}. * * @param configurationBuilder the service configuration to add, {@link Builder#build()} will be called on it * @return a new builder with the added service configuration * * @see #add(ServiceConfiguration) */ public CacheConfigurationBuilder add(Builder> configurationBuilder) { return add(configurationBuilder.build()); } /** * Adds an {@link EvictionAdvisor} to the returned builder. * * @param evictionAdvisor the eviction advisor to be used * @return a new builder with the added eviction advisor */ public CacheConfigurationBuilder withEvictionAdvisor(final EvictionAdvisor evictionAdvisor) { CacheConfigurationBuilder otherBuilder = new CacheConfigurationBuilder<>(this); otherBuilder.evictionAdvisor = evictionAdvisor; return otherBuilder; } /** * Removes a {@link ServiceConfiguration} from the returned builder. * * @param configuration the service configuration to remove * @return a new builder without the specified configuration */ public CacheConfigurationBuilder remove(ServiceConfiguration configuration) { CacheConfigurationBuilder otherBuilder = new CacheConfigurationBuilder<>(this); otherBuilder.serviceConfigurations.remove(configuration); return otherBuilder; } /** * Clears all {@link ServiceConfiguration}s from the returned builder. * * @return a new builder with no service configurations left */ public CacheConfigurationBuilder clearAllServiceConfig() { CacheConfigurationBuilder otherBuilder = new CacheConfigurationBuilder<>(this); otherBuilder.serviceConfigurations.clear(); return otherBuilder; } /** * Returns the first {@link ServiceConfiguration} with type matching the class passed in. * * @param clazz the service configuration class * @param the type of the service configuration * @return a matching service configuration, or {@code null} if none can be found */ public > T getExistingServiceConfiguration(Class clazz) { for (ServiceConfiguration serviceConfiguration : serviceConfigurations) { if (clazz.equals(serviceConfiguration.getClass())) { return clazz.cast(serviceConfiguration); } } return null; } /** * Returns all {@link ServiceConfiguration}s of type matching the class passed in. * * @param clazz the service configuration class * @param the type of the service configuration * @return a list with service configurations */ public > List getExistingServiceConfigurations(Class clazz) { ArrayList results = new ArrayList<>(); for (ServiceConfiguration serviceConfiguration : serviceConfigurations) { if (clazz.equals(serviceConfiguration.getClass())) { results.add(clazz.cast(serviceConfiguration)); } } return results; } /** * Adds a {@link ClassLoader} to the returned builder. *

* The {@link ClassLoader} will be used for resolving all non Ehcache types. * * @param classLoader the class loader to use * @return a new builder with the added class loader */ public CacheConfigurationBuilder withClassLoader(ClassLoader classLoader) { CacheConfigurationBuilder otherBuilder = new CacheConfigurationBuilder<>(this); otherBuilder.classLoader = classLoader; return otherBuilder; } /** * Adds the {@link ResourcePools} to the returned builder. *

* {@link ResourcePools} is what determines the tiering of a cache. * * @param resourcePools the resource pools to use * @return a new builder with the added resource pools */ public CacheConfigurationBuilder withResourcePools(ResourcePools resourcePools) { if (resourcePools == null) { throw new NullPointerException("Null resource pools"); } CacheConfigurationBuilder otherBuilder = new CacheConfigurationBuilder<>(this); otherBuilder.resourcePools = resourcePools; return otherBuilder; } /** * Convenience method to add a {@link ResourcePools} through a {@link ResourcePoolsBuilder} to the returned builder. * * @param resourcePoolsBuilder the builder providing the resource pool * @return a new builder with the added resource pools * * @see #withResourcePools(ResourcePools) */ public CacheConfigurationBuilder withResourcePools(ResourcePoolsBuilder resourcePoolsBuilder) { return withResourcePools(requireNonNull(resourcePoolsBuilder, "Null resource pools builder").build()); } /** * Adds {@link org.ehcache.expiry.Expiry} configuration to the returned builder. *

* {@code Expiry} is what controls data freshness in a cache. * * @param expiry the expiry to use * @return a new builder with the added expiry * * @deprecated Use {@link #withExpiry(ExpiryPolicy)} instead */ @Deprecated public CacheConfigurationBuilder withExpiry(org.ehcache.expiry.Expiry expiry) { return withExpiry(convertToExpiryPolicy(requireNonNull(expiry, "Null expiry"))); } /** * Adds {@link ExpiryPolicy} configuration to the returned builder. *

* {@code ExpiryPolicy} is what controls data freshness in a cache. * * @param expiry the expiry to use * @return a new builder with the added expiry */ public CacheConfigurationBuilder withExpiry(ExpiryPolicy expiry) { if (expiry == null) { throw new NullPointerException("Null expiry"); } CacheConfigurationBuilder otherBuilder = new CacheConfigurationBuilder<>(this); otherBuilder.expiry = expiry; return otherBuilder; } /** * Indicates whether this builder has configured expiry or not. * * @return {@code true} if expiry configured, {@code false} otherwise */ public boolean hasConfiguredExpiry() { return expiry != null; } /** * Adds a {@link CacheLoaderWriter} to the configured builder. *

* Configuration of a {@link CacheLoaderWriter} is what enables cache-through patterns. * * @param loaderWriter the loaderwriter to use * @return a new builder with the added loaderwriter configuration */ public CacheConfigurationBuilder withLoaderWriter(CacheLoaderWriter loaderWriter) { return addOrReplaceConfiguration(new DefaultCacheLoaderWriterConfiguration(requireNonNull(loaderWriter, "Null loaderWriter"))); } /** * Adds a {@link CacheLoaderWriter} configured through a class and optional constructor arguments to the configured * builder. *

* Configuration of a {@link CacheLoaderWriter} is what enables cache-through patterns. * * @param loaderWriterClass the loaderwrite class * @param arguments optional constructor arguments * @return a new builder with the added loaderwriter configuration */ public CacheConfigurationBuilder withLoaderWriter(Class> loaderWriterClass, Object... arguments) { return addOrReplaceConfiguration(new DefaultCacheLoaderWriterConfiguration(requireNonNull(loaderWriterClass, "Null loaderWriterClass"), arguments)); } /** * Adds a {@link ResilienceStrategy} to the configured builder. * * @param resilienceStrategy the resilience strategy to use * @return a new builder with the added resilience strategy configuration */ public CacheConfigurationBuilder withResilienceStrategy(ResilienceStrategy resilienceStrategy) { return addOrReplaceConfiguration(new DefaultResilienceStrategyConfiguration(requireNonNull(resilienceStrategy, "Null resilienceStrategy"))); } /** * Adds a {@link ResilienceStrategy} configured through a class and optional constructor arguments to the configured * builder. * * @param resilienceStrategyClass the resilience strategy class * @param arguments optional constructor arguments * @return a new builder with the added resilience strategy configuration */ @SuppressWarnings("rawtypes") public CacheConfigurationBuilder withResilienceStrategy(Class resilienceStrategyClass, Object... arguments) { return addOrReplaceConfiguration(new DefaultResilienceStrategyConfiguration(requireNonNull(resilienceStrategyClass, "Null resilienceStrategyClass"), arguments)); } /** * Adds by-value semantic using the cache key serializer for the key on heap. *

* {@link Copier}s are what enable control of by-reference / by-value semantics for on-heap tier. * * @return a new builder with the added key copier */ public CacheConfigurationBuilder withKeySerializingCopier() { return withKeyCopier(SerializingCopier.asCopierClass()); } /** * Adds by-value semantic using the cache value serializer for the value on heap. *

* {@link Copier}s are what enable control of by-reference / by-value semantics for on-heap tier. * * @return a new builder with the added value copier */ public CacheConfigurationBuilder withValueSerializingCopier() { return withValueCopier(SerializingCopier.asCopierClass()); } /** * Adds by-value semantic using the provided {@link Copier} for the key on heap. *

* {@link Copier}s are what enable control of by-reference / by-value semantics for on-heap tier. * * @param keyCopier the key copier to use * @return a new builder with the added key copier */ public CacheConfigurationBuilder withKeyCopier(Copier keyCopier) { return withCopier(new DefaultCopierConfiguration<>(requireNonNull(keyCopier, "Null key copier"), DefaultCopierConfiguration.Type.KEY)); } /** * Adds by-value semantic using the provided {@link Copier} class for the key on heap. *

* {@link Copier}s are what enable control of by-reference / by-value semantics for on-heap tier. * * @param keyCopierClass the key copier class to use * @return a new builder with the added key copier */ public CacheConfigurationBuilder withKeyCopier(Class> keyCopierClass) { return withCopier(new DefaultCopierConfiguration<>(requireNonNull(keyCopierClass, "Null key copier class"), DefaultCopierConfiguration.Type.KEY)); } /** * Adds by-value semantic using the provided {@link Copier} for the value on heap. *

* {@link Copier}s are what enable control of by-reference / by-value semantics for on-heap tier. * * @param valueCopier the value copier to use * @return a new builder with the added value copier */ public CacheConfigurationBuilder withValueCopier(Copier valueCopier) { return withCopier(new DefaultCopierConfiguration<>(requireNonNull(valueCopier, "Null value copier"), DefaultCopierConfiguration.Type.VALUE)); } /** * Adds by-value semantic using the provided {@link Copier} class for the value on heap. *

* {@link Copier}s are what enable control of by-reference / by-value semantics for on-heap tier. * * @param valueCopierClass the value copier class to use * @return a new builder with the added value copier */ public CacheConfigurationBuilder withValueCopier(Class> valueCopierClass) { return withCopier(new DefaultCopierConfiguration<>(requireNonNull(valueCopierClass, "Null value copier class"), DefaultCopierConfiguration.Type.VALUE)); } /** * Adds a {@link Serializer} for cache keys to the configured builder. *

* {@link Serializer}s are what enables cache storage beyond the heap tier. * * @param keySerializer the key serializer to use * @return a new builder with the added key serializer */ public CacheConfigurationBuilder withKeySerializer(Serializer keySerializer) { return withSerializer(new DefaultSerializerConfiguration<>(requireNonNull(keySerializer, "Null key serializer"), DefaultSerializerConfiguration.Type.KEY)); } /** * Adds a {@link Serializer} class for cache keys to the configured builder. *

* {@link Serializer}s are what enables cache storage beyond the heap tier. * * @param keySerializerClass the key serializer to use * @return a new builder with the added key serializer */ public CacheConfigurationBuilder withKeySerializer(Class> keySerializerClass) { return withSerializer(new DefaultSerializerConfiguration<>(requireNonNull(keySerializerClass, "Null key serializer class"), DefaultSerializerConfiguration.Type.KEY)); } /** * Adds a {@link Serializer} for cache values to the configured builder. *

* {@link Serializer}s are what enables cache storage beyond the heap tier. * * @param valueSerializer the key serializer to use * @return a new builder with the added value serializer */ public CacheConfigurationBuilder withValueSerializer(Serializer valueSerializer) { return withSerializer(new DefaultSerializerConfiguration<>(requireNonNull(valueSerializer, "Null value serializer"), DefaultSerializerConfiguration.Type.VALUE)); } /** * Adds a {@link Serializer} class for cache values to the configured builder. *

* {@link Serializer}s are what enables cache storage beyond the heap tier. * * @param valueSerializerClass the key serializer to use * @return a new builder with the added value serializer */ public CacheConfigurationBuilder withValueSerializer(Class> valueSerializerClass) { return withSerializer(new DefaultSerializerConfiguration<>(requireNonNull(valueSerializerClass, "Null value serializer class"), DefaultSerializerConfiguration.Type.VALUE)); } /** * Adds {@link StoreEventSourceConfiguration} with the specified dispatcher concurrency * to the configured builder. * * @param dispatcherConcurrency the level of concurrency in the dispatcher for ordered events * @return a new builder with the added configuration */ public CacheConfigurationBuilder withDispatcherConcurrency(int dispatcherConcurrency) { return addOrReplaceConfiguration(new DefaultEventSourceConfiguration(dispatcherConcurrency)); } /** * Adds a {@link ServiceConfiguration} for the {@link org.ehcache.core.events.CacheEventDispatcherFactory} specifying * the thread pool alias to use. * * @param threadPoolAlias the thread pool alias to use * @return a new builder with the added configuration */ public CacheConfigurationBuilder withEventListenersThreadPool(String threadPoolAlias) { return addOrReplaceConfiguration(new DefaultCacheEventDispatcherConfiguration(threadPoolAlias)); } /** * Adds a {@link ServiceConfiguration} for the {@link org.ehcache.impl.internal.store.disk.OffHeapDiskStore.Provider} * indicating thread pool alias and write concurrency. * * @param threadPoolAlias the thread pool alias * @param concurrency the write concurrency * @return a new builder with the added configuration */ public CacheConfigurationBuilder withDiskStoreThreadPool(String threadPoolAlias, int concurrency) { return addOrReplaceConfiguration(new OffHeapDiskStoreConfiguration(threadPoolAlias, concurrency)); } /** * Adds or updates the {@link DefaultSizeOfEngineConfiguration} with the specified object graph maximum size to the configured * builder. *

* {@link SizeOfEngine} is what enables the heap tier to be sized in {@link MemoryUnit}. * * @param size the maximum graph size * @return a new builder with the added / updated configuration */ public CacheConfigurationBuilder withSizeOfMaxObjectGraph(long size) { return mapServiceConfiguration(DefaultSizeOfEngineConfiguration.class, existing -> ofNullable(existing) .map(e -> new DefaultSizeOfEngineConfiguration(e.getMaxObjectSize(), e.getUnit(), size)) .orElse(new DefaultSizeOfEngineConfiguration(DEFAULT_MAX_OBJECT_SIZE, DEFAULT_UNIT, size))); } /** * Adds or updates the {@link DefaultSizeOfEngineConfiguration} with the specified maximum mapping size to the configured * builder. *

* {@link SizeOfEngine} is what enables the heap tier to be sized in {@link MemoryUnit}. * * @param size the maximum mapping size * @param unit the memory unit * @return a new builder with the added / updated configuration */ public CacheConfigurationBuilder withSizeOfMaxObjectSize(long size, MemoryUnit unit) { return mapServiceConfiguration(DefaultSizeOfEngineConfiguration.class, existing -> ofNullable(existing) .map(e -> new DefaultSizeOfEngineConfiguration(size, unit, e.getMaxObjectGraphSize())) .orElse(new DefaultSizeOfEngineConfiguration(size, unit, DEFAULT_OBJECT_GRAPH_SIZE))); } @Override public CacheConfiguration build() { return new BaseCacheConfiguration<>(keyType, valueType, evictionAdvisor, classLoader, expiry, resourcePools, serviceConfigurations.toArray(new ServiceConfiguration[serviceConfigurations.size()])); } private CacheConfigurationBuilder withSerializer(DefaultSerializerConfiguration configuration) { CacheConfigurationBuilder otherBuilder = new CacheConfigurationBuilder<>(this); otherBuilder.removeExistingSerializerConfigFor(configuration.getType()); otherBuilder.serviceConfigurations.add(configuration); return otherBuilder; } private void removeExistingSerializerConfigFor(DefaultSerializerConfiguration.Type type) { @SuppressWarnings({"unchecked","rawtypes"}) List> existingServiceConfigurations = (List) getExistingServiceConfigurations(DefaultSerializerConfiguration.class); for (DefaultSerializerConfiguration configuration : existingServiceConfigurations) { if (configuration.getType().equals(type)) { serviceConfigurations.remove(configuration); } } } private CacheConfigurationBuilder withCopier(DefaultCopierConfiguration configuration) { CacheConfigurationBuilder otherBuilder = new CacheConfigurationBuilder<>(this); otherBuilder.removeExistingCopierConfigFor(configuration.getType()); otherBuilder.serviceConfigurations.add(configuration); return otherBuilder; } private void removeExistingCopierConfigFor(DefaultCopierConfiguration.Type type) { @SuppressWarnings({"unchecked","rawtypes"}) List> existingServiceConfigurations = (List) getExistingServiceConfigurations(DefaultCopierConfiguration.class); for (DefaultCopierConfiguration configuration : existingServiceConfigurations) { if (configuration.getType().equals(type)) { serviceConfigurations.remove(configuration); } } } @SuppressWarnings("unchecked") private > CacheConfigurationBuilder addOrReplaceConfiguration(T configuration) { return addOrReplaceConfiguration((Class) configuration.getClass(), configuration); } private > CacheConfigurationBuilder addOrReplaceConfiguration(Class configurationType, T configuration) { return mapServiceConfiguration(configurationType, e -> configuration); } private > CacheConfigurationBuilder mapServiceConfiguration(Class configurationType, UnaryOperator mapper) { CacheConfigurationBuilder otherBuilder = new CacheConfigurationBuilder<>(this); T existingServiceConfiguration = otherBuilder.getExistingServiceConfiguration(configurationType); if (existingServiceConfiguration != null) { otherBuilder.serviceConfigurations.remove(existingServiceConfiguration); } otherBuilder.serviceConfigurations.add(mapper.apply(existingServiceConfiguration)); return otherBuilder; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy