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

net.sf.ehcache.config.CacheConfiguration Maven / Gradle / Ivy

Go to download

This is the ehcache core module. Pair it with other modules for added functionality.

There is a newer version: 2.6.11
Show newest version
/**
 *  Copyright 2003-2010 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 net.sf.ehcache.config;

import net.sf.ehcache.CacheException;
import net.sf.ehcache.event.NotificationScope;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
import net.sf.ehcache.store.compound.CopyStrategy;
import net.sf.ehcache.util.MemorySizeParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * A value object used to represent cache configuration.
 * 

Construction Patterns

* The recommended way of creating a Cache in Ehcache 2.0 and above is to create a CacheConfiguration object * and pass it to the Cache constructor. See {@link net.sf.ehcache.Cache#Cache(CacheConfiguration)}. *

* This class supports setter injection and also the fluent builder pattern. * e.g. * Cache cache = new Cache(new CacheConfiguration("test2", 1000).eternal(true).memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.FIFO)); *

* Rather than proliferation of new constructors as new versions of Ehcache come out, it intended to add the new configuration to this * class. *

* Another way to set configuration is declaratively in the ehcache.xml configuration file. * e.g. *

{@code
 * 
 * }
*

*

Dynamic Configuration

* CacheConfiguration instances retrieved from Cache instances allow the dynamic * modification of certain configuration properties. Currently the dynamic * properties are: *
    *
  • Time To Idle
  • *
  • Time To Live
  • *
  • Max Elements in Memory
  • *
  • Max Elements on Disk
  • *
* Dynamic changes are however not persistent across cache restarts. On restart * the cache configuration will be reloaded from its original source, erasing any * changes made previously at runtime. * * @author Greg Luck * @author (); return config; } private void cloneCacheEventListenerConfigurations(CacheConfiguration config) { if (cacheEventListenerConfigurations.size() > 0) { List copy = new ArrayList(); for (CacheEventListenerFactoryConfiguration item : cacheEventListenerConfigurations) { copy.add(item.clone()); } config.cacheEventListenerConfigurations = copy; } } private void cloneCacheExtensionConfigurations(CacheConfiguration config) { if (cacheExtensionConfigurations.size() > 0) { List copy = new ArrayList(); for (CacheConfiguration.CacheExtensionFactoryConfiguration item : cacheExtensionConfigurations) { copy.add(item.clone()); } config.cacheExtensionConfigurations = copy; } } private void cloneCacheLoaderConfigurations(CacheConfiguration config) { if (cacheLoaderConfigurations.size() > 0) { List copy = new ArrayList(); for (CacheConfiguration.CacheLoaderFactoryConfiguration item : cacheLoaderConfigurations) { copy.add(item.clone()); } config.cacheLoaderConfigurations = copy; } } private void cloneCacheDecoratorConfigurations(CacheConfiguration config) { if (cacheDecoratorConfigurations.size() > 0) { List copy = new ArrayList(); for (CacheDecoratorFactoryConfiguration item : cacheDecoratorConfigurations) { copy.add(item.clone()); } config.cacheDecoratorConfigurations = copy; } } /** * Sets the name of the cache. * * @param name the cache name. This must be unique. The / character is illegal. The # character does not work with RMI replication. */ public final void setName(String name) { checkDynamicChange(); if (name == null) { throw new IllegalArgumentException("Cache name cannot be null."); } this.name = name; } /** * Builder to set the name of the cache. * * @param name the cache name. This must be unique. The / character is illegal. The # character does not work with RMI replication. * @return this configuration instance * @see #setName(String) */ public final CacheConfiguration name(String name) { setName(name); return this; } /** * Enables or disables logging for the cache *

* This property can be modified dynamically while the cache is operating. * Only used when cache is clustered with Terracotta * * @param enable If true, enables logging otherwise disables logging */ public final void setLogging(boolean enable) { checkDynamicChange(); boolean oldLoggingEnabled = this.logging; this.logging = enable; fireLoggingChanged(oldLoggingEnabled, enable); } /** * Enables or disables offheap store for the cache. * * @param overflowToOffHeap If true, enables offheap store otherwise disables it. */ public final void setOverflowToOffHeap(boolean overflowToOffHeap) { checkDynamicChange(); this.overflowToOffHeap = overflowToOffHeap; } /** * Builder to enable or disable offheap store for the cache. * * @param overflowToOffHeap If true, enables offheap store otherwise disables it. * @return this configuration instance * @see #setOverflowToOffHeap(boolean) */ public CacheConfiguration overflowToOffHeap(boolean overflowToOffHeap) { setOverflowToOffHeap(overflowToOffHeap); return this; } /** * Sets the max off heap memory size allocated for this cache. * * @param maxMemoryOffHeap the max off heap memory size allocated for this cache. */ public final void setMaxMemoryOffHeap(String maxMemoryOffHeap) { checkDynamicChange(); this.maxMemoryOffHeap = maxMemoryOffHeap; } /** * Builder to set the max off heap memory size allocated for this cache. * * @param maxMemoryOffHeap the max off heap memory size allocated for this cache. * @return this configuration instance * @see #setMaxMemoryOffHeap(String) */ public CacheConfiguration maxMemoryOffHeap(String maxMemoryOffHeap) { setMaxMemoryOffHeap(maxMemoryOffHeap); return this; } /** * Builder to enable or disable logging for the cache *

* This property can be modified dynamically while the cache is operating. * Only used when cache is clustered with Terracotta * * @param enable If true, enables logging otherwise disables logging * @return this configuration instance * @see #setLogging(boolean) */ public final CacheConfiguration logging(boolean enable) { setLogging(enable); return this; } /** * Sets the maximum objects to be held in memory (0 = no limit). *

* This property can be modified dynamically while the cache is operating. * * @param maxElementsInMemory The maximum number of elements in memory, before they are evicted (0 == no limit) */ public final void setMaxElementsInMemory(int maxElementsInMemory) { checkDynamicChange(); int oldCapacity = this.maxElementsInMemory; int newCapacity = maxElementsInMemory; this.maxElementsInMemory = maxElementsInMemory; fireMemoryCapacityChanged(oldCapacity, newCapacity); } /** * Builder that sets the maximum objects to be held in memory (0 = no limit). *

* This property can be modified dynamically while the cache is operating. * * @param maxElementsInMemory The maximum number of elements in memory, before they are evicted (0 == no limit) * @return this configuration instance */ public final CacheConfiguration maxElementsInMemory(int maxElementsInMemory) { setMaxElementsInMemory(maxElementsInMemory); return this; } /** * Sets the timeout for CacheLoader execution (0 = no timeout). * * @param cacheLoaderTimeoutMillis the timeout in milliseconds. */ public final void setCacheLoaderTimeoutMillis(long cacheLoaderTimeoutMillis) { checkDynamicChange(); this.cacheLoaderTimeoutMillis = cacheLoaderTimeoutMillis; } /** * Builder that sets the timeout for CacheLoader execution (0 = no timeout). * @param timeoutMillis the timeout in milliseconds. * @return this configuration instance */ public CacheConfiguration timeoutMillis(long timeoutMillis) { setCacheLoaderTimeoutMillis(timeoutMillis); return this; } /** * Sets the eviction policy. An invalid argument will set it to null. * * @param memoryStoreEvictionPolicy a String representation of the policy. One of "LRU", "LFU" or "FIFO". */ public final void setMemoryStoreEvictionPolicy(String memoryStoreEvictionPolicy) { setMemoryStoreEvictionPolicyFromObject(MemoryStoreEvictionPolicy.fromString(memoryStoreEvictionPolicy)); } /** * Builder that sets the eviction policy. An invalid argument will set it to null. * * @param memoryStoreEvictionPolicy a String representation of the policy. One of "LRU", "LFU" or "FIFO". * @return this configuration instance * @see #setMemoryStoreEvictionPolicy(String) */ public final CacheConfiguration memoryStoreEvictionPolicy(String memoryStoreEvictionPolicy) { setMemoryStoreEvictionPolicy(memoryStoreEvictionPolicy); return this; } /** * Sets the eviction policy. This method has a strange name to workaround a problem with XML parsing. */ public final void setMemoryStoreEvictionPolicyFromObject(MemoryStoreEvictionPolicy memoryStoreEvictionPolicy) { checkDynamicChange(); if (null == memoryStoreEvictionPolicy) { this.memoryStoreEvictionPolicy = DEFAULT_MEMORY_STORE_EVICTION_POLICY; } else { this.memoryStoreEvictionPolicy = memoryStoreEvictionPolicy; } } /** * Builder which Sets the eviction policy. An invalid argument will set it to null. * * @return this configuration instance * @see #setMemoryStoreEvictionPolicyFromObject(MemoryStoreEvictionPolicy) */ public final CacheConfiguration memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy memoryStoreEvictionPolicy) { setMemoryStoreEvictionPolicyFromObject(memoryStoreEvictionPolicy); return this; } /** * Sets whether the MemoryStore should be cleared when * {@link net.sf.ehcache.Ehcache#flush flush()} is called on the cache - true by default. * * @param clearOnFlush true to clear on flush */ public final void setClearOnFlush(boolean clearOnFlush) { checkDynamicChange(); this.clearOnFlush = clearOnFlush; } /** * Builder which sets whether the MemoryStore should be cleared when * {@link net.sf.ehcache.Ehcache#flush flush()} is called on the cache - true by default. * * @param clearOnFlush true to clear on flush * @return this configuration instance * @see #setClearOnFlush(boolean) */ public final CacheConfiguration clearOnFlush(boolean clearOnFlush) { setClearOnFlush(clearOnFlush); return this; } /** * Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. False by default. * * @param eternal true for eternal */ public final void setEternal(boolean eternal) { checkDynamicChange(); checkConflictingEternalValues(eternal, getTimeToLiveSeconds(), getTimeToIdleSeconds()); this.eternal = eternal; if (eternal) { setTimeToIdleSeconds(0); setTimeToLiveSeconds(0); } } private void checkConflictingEternalValues(boolean newEternalValue, long newTTLValue, long newTTIValue) { if (!conflictingValuesWarningLogged && newEternalValue && (newTTLValue != 0 || newTTIValue != 0)) { conflictingValuesWarningLogged = true; LOG .warn("Cache '" + getName() + "' is set to eternal but also has TTI/TTL set." + " To avoid this warning, clean up the config " + "removing conflicting values of eternal," + " TTI and TTL."); } } /** * Builder which sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. False by default. * * @param eternal true for eternal * @return this configuration instance * @see #setEternal(boolean) */ public final CacheConfiguration eternal(boolean eternal) { setEternal(eternal); return this; } /** * Sets the time to idle for an element before it expires. Is only used if the element is not eternal. This can be overidden in * {@link net.sf.ehcache.Element} *

* This property can be modified dynamically while the cache is operating. * * @param timeToIdleSeconds the default amount of time to live for an element from its last accessed or modified date */ public final void setTimeToIdleSeconds(long timeToIdleSeconds) { checkDynamicChange(); checkConflictingEternalValues(eternal, getTimeToLiveSeconds(), timeToIdleSeconds); long oldTti = this.timeToIdleSeconds; long newTti = timeToIdleSeconds; this.timeToIdleSeconds = timeToIdleSeconds; fireTtiChanged(oldTti, newTti); } /** * Builder which sets the time to idle for an element before it expires. Is only used if the element is not eternal. * This default can be overridden in {@link net.sf.ehcache.Element} *

* This property can be modified dynamically while the cache is operating. * * @param timeToIdleSeconds the default amount of time to live for an element from its last accessed or modified date * @return this configuration instance * @see #setTimeToIdleSeconds(long) */ public final CacheConfiguration timeToIdleSeconds(long timeToIdleSeconds) { setTimeToIdleSeconds(timeToIdleSeconds); return this; } /** * Sets the time to idle for an element before it expires. Is only used if the element is not eternal. * This default can be overridden in {@link net.sf.ehcache.Element} *

* This property can be modified dynamically while the cache is operating. * * @param timeToLiveSeconds the default amount of time to live for an element from its creation date */ public final void setTimeToLiveSeconds(long timeToLiveSeconds) { checkDynamicChange(); checkConflictingEternalValues(eternal, timeToLiveSeconds, getTimeToIdleSeconds()); long oldTtl = this.timeToLiveSeconds; long newTtl = timeToLiveSeconds; this.timeToLiveSeconds = timeToLiveSeconds; fireTtlChanged(oldTtl, newTtl); } /** * Builder which sets the time to idle for an element before it expires. Is only used if the element is not eternal. * This default can be overridden in {@link net.sf.ehcache.Element} *

* This property can be modified dynamically while the cache is operating. * * @param timeToLiveSeconds the default amount of time to live for an element from its creation date * @return this configuration instance * @see #setTimeToLiveSeconds(long) */ public final CacheConfiguration timeToLiveSeconds(long timeToLiveSeconds) { setTimeToLiveSeconds(timeToLiveSeconds); return this; } /** * Sets whether elements can overflow to disk when the in-memory cache has reached the set limit. * * @param overflowToDisk whether to use the disk store */ public final void setOverflowToDisk(boolean overflowToDisk) { checkDynamicChange(); this.overflowToDisk = overflowToDisk; validateConfiguration(); } /** * Builder which sets whether elements can overflow to disk when the in-memory cache has reached the set limit. * * @param overflowToDisk whether to use the disk store * @return this configuration instance * @see #setOverflowToDisk(boolean) */ public final CacheConfiguration overflowToDisk(boolean overflowToDisk) { setOverflowToDisk(overflowToDisk); return this; } /** * Sets whether the disk store persists between CacheManager instances. Note that this operates independently of {@link #overflowToDisk}. * * @param diskPersistent whether to persist the cache to disk between JVM restarts */ public final void setDiskPersistent(boolean diskPersistent) { checkDynamicChange(); this.diskPersistent = diskPersistent; validateConfiguration(); } /** * Builder which sets whether the disk store persists between CacheManager instances. Note that this operates independently of {@link #overflowToDisk}. * * @param diskPersistent whether to persist the cache to disk between JVM restarts. * @return this configuration instance * @see #setDiskPersistent(boolean) */ public final CacheConfiguration diskPersistent(boolean diskPersistent) { setDiskPersistent(diskPersistent); return this; } /** * Sets the path that will be used for the disk store. * * @param diskStorePath this parameter is ignored. CacheManager sets it using setter injection. */ public final void setDiskStorePath(String diskStorePath) { checkDynamicChange(); if (null == diskStorePath) { this.diskStorePath = DiskStoreConfiguration.getDefaultPath(); } this.diskStorePath = diskStorePath; validateConfiguration(); } /** * Builder which sets the path that will be used for the disk store. * * @param diskStorePath this parameter is ignored. CacheManager sets it using setter injection. * @return this configuration instance * @see #setDiskStorePath(String) */ public final CacheConfiguration diskStorePath(String diskStorePath) { setDiskStorePath(diskStorePath); return this; } /** * Sets the disk spool size, which is used to buffer writes to the DiskStore. * If not set it defaults to {@link #DEFAULT_SPOOL_BUFFER_SIZE} * * @param diskSpoolBufferSizeMB a positive number */ public void setDiskSpoolBufferSizeMB(int diskSpoolBufferSizeMB) { checkDynamicChange(); if (diskSpoolBufferSizeMB <= 0) { this.diskSpoolBufferSizeMB = DEFAULT_SPOOL_BUFFER_SIZE; } else { this.diskSpoolBufferSizeMB = diskSpoolBufferSizeMB; } } /** * Builder which sets the disk spool size, which is used to buffer writes to the DiskStore. * If not set it defaults to {@link #DEFAULT_SPOOL_BUFFER_SIZE} * * @param diskSpoolBufferSizeMB a positive number * @return this configuration instance * @see #setDiskSpoolBufferSizeMB(int) */ public final CacheConfiguration diskSpoolBufferSizeMB(int diskSpoolBufferSizeMB) { setDiskSpoolBufferSizeMB(diskSpoolBufferSizeMB); return this; } /** * Sets the number of disk stripes. RandomAccessFiles used to access the data file. By default there * is one stripe. * * @param stripes number of stripes (rounded up to a power-of-2) */ public void setDiskAccessStripes(int stripes) { checkDynamicChange(); if (stripes <= 0) { this.diskAccessStripes = DEFAULT_DISK_ACCESS_STRIPES; } else { this.diskAccessStripes = stripes; } } /** * Builder which sets the number of disk stripes. RandomAccessFiles used to access the data file. By default there * is one stripe. * * @return this configuration instance * @see #setDiskAccessStripes(int) */ public final CacheConfiguration diskAccessStripes(int stripes) { setDiskAccessStripes(stripes); return this; } /** * Sets the maximum number elements on Disk. 0 means unlimited. *

* This property can be modified dynamically while the cache is operating. * * @param maxElementsOnDisk the maximum number of Elements to allow on the disk. 0 means unlimited. */ public void setMaxElementsOnDisk(int maxElementsOnDisk) { checkDynamicChange(); int oldCapacity = this.maxElementsOnDisk; int newCapacity = maxElementsOnDisk; this.maxElementsOnDisk = maxElementsOnDisk; fireDiskCapacityChanged(oldCapacity, newCapacity); } /** * Builder which sets the maximum number elements on Disk. 0 means unlimited. *

* This property can be modified dynamically while the cache is operating. * * @param maxElementsOnDisk the maximum number of Elements to allow on the disk. 0 means unlimited. * @return this configuration instance * @see #setMaxElementsOnDisk(int) */ public final CacheConfiguration maxElementsOnDisk(int maxElementsOnDisk) { setMaxElementsOnDisk(maxElementsOnDisk); return this; } /** * Sets the interval in seconds between runs of the disk expiry thread. *

* 2 minutes is the default. * This is not the same thing as time to live or time to idle. When the thread runs it checks * these things. So this value is how often we check for expiry. */ public final void setDiskExpiryThreadIntervalSeconds(long diskExpiryThreadIntervalSeconds) { checkDynamicChange(); if (diskExpiryThreadIntervalSeconds <= 0) { this.diskExpiryThreadIntervalSeconds = DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS; } else { this.diskExpiryThreadIntervalSeconds = diskExpiryThreadIntervalSeconds; } } /** * Builder which sets the interval in seconds between runs of the disk expiry thread. *

* 2 minutes is the default. * This is not the same thing as time to live or time to idle. When the thread runs it checks * these things. So this value is how often we check for expiry. * * @return this configuration instance * @see #setDiskExpiryThreadIntervalSeconds(long) */ public final CacheConfiguration diskExpiryThreadIntervalSeconds(long diskExpiryThreadIntervalSeconds) { setDiskExpiryThreadIntervalSeconds(diskExpiryThreadIntervalSeconds); return this; } /** * Freeze this configuration. Any subsequent changes will throw a CacheException */ public void freezeConfiguration() { frozen = true; } /** * @return true is this configuration is frozen - it cannot be changed dynamically. */ public boolean isFrozen() { return frozen; } /** * Getter to the CopyStrategy set in the config (really? how?). * This will always return the same unique instance per cache * * @return the {@link CopyStrategy} for instance for this cache */ public CopyStrategy getCopyStrategy() { // todo really make this pluggable through config! return copyStrategyConfiguration.getCopyStrategyInstance(); } /** * Whether the Cache should copy elements it returns * * @param copyOnRead true, if copyOnRead */ public CacheConfiguration copyOnRead(boolean copyOnRead) { this.setCopyOnRead(copyOnRead); return this; } /** * Whether the Cache should copy elements it returns * * @return true, is copyOnRead */ public boolean isCopyOnRead() { validateTransactionalSettings(); return copyOnRead; } /** * Whether the Cache should copy elements it returns * * @param copyOnRead true, if copyOnRead */ public void setCopyOnRead(final boolean copyOnRead) { this.copyOnRead = copyOnRead; } /** * Whether the Cache should copy elements it gets * * @param copyOnWrite true, if copyOnWrite */ public CacheConfiguration copyOnWrite(boolean copyOnWrite) { this.copyOnWrite = copyOnWrite; return this; } /** * Whether the Cache should copy elements it gets * * @return true, if copyOnWrite */ public boolean isCopyOnWrite() { validateTransactionalSettings(); return copyOnWrite; } /** * Whether the Cache should copy elements it gets * * @param copyOnWrite true, if copyOnWrite */ public void setCopyOnWrite(final boolean copyOnWrite) { this.copyOnWrite = copyOnWrite; } /** * Sets the CopyStrategyConfiguration for this cache * * @param copyStrategyConfiguration the CopyStrategy Configuration */ public void addCopyStrategy(CopyStrategyConfiguration copyStrategyConfiguration) { this.copyStrategyConfiguration = copyStrategyConfiguration; } /** * Returns the copyStrategyConfiguration * * @return the copyStrategyConfiguration */ public CopyStrategyConfiguration getCopyStrategyConfiguration() { return this.copyStrategyConfiguration; } /** * Getter to the default TM to use * * @return the default one if set, or null */ public Object getDefaultTransactionManager() { return defaultTransactionManager; } /** * Setter to the default TM * * @param defaultTransactionManager the default TM, can be null to fall back to TMLookup */ public void setDefaultTransactionManager(final Object defaultTransactionManager) { this.defaultTransactionManager = defaultTransactionManager; } /** * Configuration for the CachePeerListenerFactoryConfiguration. */ public static final class CacheEventListenerFactoryConfiguration extends FactoryConfiguration { private NotificationScope notificationScope = NotificationScope.ALL; /** * Used by BeanHandler to set the mode during parsing. Convert listenFor string to uppercase and * look up enum constant in NotificationScope. */ public void setListenFor(String listenFor) { if (listenFor == null) { throw new IllegalArgumentException("listenFor must be non-null"); } this.notificationScope = NotificationScope.valueOf(NotificationScope.class, listenFor.toUpperCase()); } /** * @return this factory configuration instance * @see #setListenFor(String) */ public final CacheEventListenerFactoryConfiguration listenFor(String listenFor) { setListenFor(listenFor); return this; } /** * Get the value mode in terms of the mode enum */ public NotificationScope getListenFor() { return this.notificationScope; } } /** * Used by BeanUtils to add cacheEventListenerFactory elements to the cache configuration. */ public final void addCacheEventListenerFactory(CacheEventListenerFactoryConfiguration factory) { checkDynamicChange(); cacheEventListenerConfigurations.add(factory); validateConfiguration(); } /** * @return this configuration instance * @see #addCacheEventListenerFactory(CacheEventListenerFactoryConfiguration) */ public final CacheConfiguration cacheEventListenerFactory(CacheEventListenerFactoryConfiguration factory) { addCacheEventListenerFactory(factory); return this; } /** * Configuration for the CacheExtensionFactoryConfiguration. */ public static final class CacheExtensionFactoryConfiguration extends FactoryConfiguration { } /** * Used by BeanUtils to add cacheExtensionFactory elements to the cache configuration. */ public final void addCacheExtensionFactory(CacheExtensionFactoryConfiguration factory) { checkDynamicChange(); cacheExtensionConfigurations.add(factory); } /** * @return this configuration instance * @see #addCacheExtensionFactory(CacheExtensionFactoryConfiguration) */ public final CacheConfiguration cacheExtensionFactory(CacheExtensionFactoryConfiguration factory) { /** * {@inheritDoc} */ addCacheExtensionFactory(factory); return this; } /** * Configuration for the BootstrapCacheLoaderFactoryConfiguration. */ public static final class BootstrapCacheLoaderFactoryConfiguration extends FactoryConfiguration { } /** * Allows BeanHandler to add the CacheManagerEventListener to the configuration. */ public final void addBootstrapCacheLoaderFactory(BootstrapCacheLoaderFactoryConfiguration factory) { checkDynamicChange(); this.bootstrapCacheLoaderFactoryConfiguration = factory; } /** * @return this configuration instance * @see #addBootstrapCacheLoaderFactory(BootstrapCacheLoaderFactoryConfiguration) */ public final CacheConfiguration bootstrapCacheLoaderFactory(BootstrapCacheLoaderFactoryConfiguration factory) { addBootstrapCacheLoaderFactory(factory); return this; } /** * Configuration for the BootstrapCacheLoaderFactoryConfiguration. */ public static final class CacheExceptionHandlerFactoryConfiguration extends FactoryConfiguration { } /** * Add the CacheExceptionHandlerFactory to the configuration. *

* Note that this will not have any effect when creating a cache solely through its constructed. The exception * handler will only be taken into account when {@link ConfigurationHelper} is used, for example through * {@link net.sf.ehcache.CacheManager}. */ public final void addCacheExceptionHandlerFactory(CacheExceptionHandlerFactoryConfiguration factory) { checkDynamicChange(); this.cacheExceptionHandlerFactoryConfiguration = factory; } /** * @return this configuration instance * @see #addCacheExceptionHandlerFactory(CacheExceptionHandlerFactoryConfiguration) */ public final CacheConfiguration cacheExceptionHandlerFactory(CacheExceptionHandlerFactoryConfiguration factory) { addCacheExceptionHandlerFactory(factory); return this; } /** * Configuration for the CacheLoaderFactoryConfiguration. */ public static final class CacheLoaderFactoryConfiguration extends FactoryConfiguration { } /** * Used by BeanUtils to add each cacheLoaderFactory to the cache configuration. * * @param factory */ public final void addCacheLoaderFactory(CacheLoaderFactoryConfiguration factory) { checkDynamicChange(); cacheLoaderConfigurations.add(factory); } /** * Configuration for the CacheDecoratorFactoryConfiguration. */ public static final class CacheDecoratorFactoryConfiguration extends FactoryConfiguration { } /** * Used by BeanUtils to add each cacheDecoratorFactory to the cache configuration. * * @param factory */ public final void addCacheDecoratorFactory(CacheDecoratorFactoryConfiguration factory) { checkDynamicChange(); cacheDecoratorConfigurations.add(factory); } /** * @return this configuration instance * @see #addCacheLoaderFactory(CacheLoaderFactoryConfiguration) */ public final CacheConfiguration cacheLoaderFactory(CacheLoaderFactoryConfiguration factory) { addCacheLoaderFactory(factory); return this; } /** * Allows BeanHandler to add the TerracottaConfiguration to the configuration. */ public final void addTerracotta(TerracottaConfiguration terracottaConfiguration) { this.terracottaConfiguration = terracottaConfiguration; validateConfiguration(); } /** * @return this configuration instance * @see #addTerracotta(TerracottaConfiguration) */ public final CacheConfiguration terracotta(TerracottaConfiguration terracottaConfiguration) { addTerracotta(terracottaConfiguration); return this; } /** * Allows BeanHandler to add the CacheWriterConfiguration to the configuration. */ public final void addCacheWriter(CacheWriterConfiguration cacheWriterConfiguration) { if (null == cacheWriterConfiguration) { this.cacheWriterConfiguration = new CacheWriterConfiguration(); } else { this.cacheWriterConfiguration = cacheWriterConfiguration; } } /** * @return this configuration instance * @see #addCacheWriter(CacheWriterConfiguration) */ public final CacheConfiguration cacheWriter(CacheWriterConfiguration cacheWriterConfiguration) { addCacheWriter(cacheWriterConfiguration); return this; } /** * Sets the transactionalMode * * @param transactionalMode OFF or XA */ public final void setTransactionalMode(final String transactionalMode) { if (null == transactionalMode) { throw new IllegalArgumentException("TransactionalMode value must be non-null"); } this.transactionalMode = TransactionalMode.valueOf(transactionalMode.toUpperCase()); } /** * Builder which sets the transactionalMode * * @param transactionalMode one of OFF or XA * @return this configuration instance * @see #setTransactionalMode(String) */ public final CacheConfiguration transactionalMode(String transactionalMode) { setTransactionalMode(transactionalMode); return this; } /** * Builder which sets the transactionalMode * * @param transactionalMode one of OFF or XA enum values * @return this configuration instance * @see #setTransactionalMode(String) */ public final CacheConfiguration transactionalMode(TransactionalMode transactionalMode) { if (null == transactionalMode) { throw new IllegalArgumentException("TransactionalMode value must be non-null"); } this.transactionalMode = transactionalMode; return this; } /** * Sets whether the cache's statistics are enabled. at startup */ public final void setStatistics(boolean enabled) { this.statistics = enabled; } /** * Builder which sets whether the cache's statistics are enabled. * * @return this configuration instance * @see #setStatistics(boolean) */ public final CacheConfiguration statistics(boolean statistics) { setStatistics(statistics); return this; } /** * Gets whether the cache's statistics will be enabled at startup */ public final boolean getStatistics() { return statistics; } /** * Used to validate what should be a complete Cache Configuration. */ public void validateCompleteConfiguration() { validateConfiguration(); //Extra checks that a completed cache config should have if (name == null) { throw new InvalidConfigurationException("Caches must be named."); } } /** * Used to validate a Cache Configuration. */ public void validateConfiguration() { if (terracottaConfiguration != null && terracottaConfiguration.isClustered()) { if (overflowToDisk) { throw new InvalidConfigurationException("overflowToDisk isn't supported for a clustered Terracotta cache"); } if (diskPersistent) { throw new InvalidConfigurationException("diskPersistent isn't supported for a clustered Terracotta cache"); } if (cacheEventListenerConfigurations != null) { for (CacheEventListenerFactoryConfiguration listenerConfig : cacheEventListenerConfigurations) { if (null == listenerConfig.getFullyQualifiedClassPath()) { continue; } if (!listenerConfig.getFullyQualifiedClassPath().startsWith("net.sf.ehcache.") && LOG.isWarnEnabled()) { LOG.warn("The non-standard CacheEventListenerFactory '" + listenerConfig.getFullyQualifiedClassPath() + "' is used with a clustered Terracotta cache, " + "if the purpose of this listener is replication it is not supported in a clustered context"); } } } } } private void validateTransactionalSettings() { boolean transactional = transactionalMode.isTransactional(); if (copyOnRead == null) { if (terracottaConfiguration != null && terracottaConfiguration.isCopyOnReadSet()) { copyOnRead = terracottaConfiguration.isCopyOnRead(); } else { copyOnRead = transactional; } } if (copyOnWrite == null) { copyOnWrite = transactional; } if (transactional) { if (!copyOnRead || !copyOnWrite) { throw new InvalidConfigurationException("A transactional cache has to be copyOnRead and copyOnWrite!"); } } } /** * Accessor */ public String getName() { return name; } /** * Accessor */ public int getMaxElementsInMemory() { return maxElementsInMemory; } /** * Accessor */ public long getCacheLoaderTimeoutMillis() { return cacheLoaderTimeoutMillis; } /** * Accessor */ public int getMaxElementsOnDisk() { return maxElementsOnDisk; } /** * Accessor */ public MemoryStoreEvictionPolicy getMemoryStoreEvictionPolicy() { return memoryStoreEvictionPolicy; } /** * Accessor */ public boolean isClearOnFlush() { return clearOnFlush; } /** * Accessor */ public boolean isEternal() { return eternal; } /** * Accessor */ public long getTimeToIdleSeconds() { return timeToIdleSeconds; } /** * Accessor */ public long getTimeToLiveSeconds() { return timeToLiveSeconds; } /** * Accessor */ public boolean isOverflowToDisk() { return overflowToDisk; } /** * Accessor */ public boolean isDiskPersistent() { return diskPersistent; } /** * Accessor */ public String getDiskStorePath() { return diskStorePath; } /** * Accessor */ public int getDiskSpoolBufferSizeMB() { return diskSpoolBufferSizeMB; } /** * Accessor */ public long getDiskExpiryThreadIntervalSeconds() { return diskExpiryThreadIntervalSeconds; } /** * Accessor */ public int getDiskAccessStripes() { return diskAccessStripes; } /** * Only used when cache is clustered with Terracotta * * @return true if logging is enabled otherwise false */ public boolean getLogging() { return logging; } /** * Accessor * * @return true if offheap store is enabled, otherwise false. */ public boolean isOverflowToOffHeap() { return overflowToOffHeap; } /** * Accessor * * @return the max memory of the offheap store for this cache. */ public String getMaxMemoryOffHeap() { return maxMemoryOffHeap; } /** * Accessor * * @return the max memory of the offheap store for this cache, in bytes. * @see #getMaxMemoryOffHeap() */ public long getMaxMemoryOffHeapInBytes() { return MemorySizeParser.parse(maxMemoryOffHeap); } /** * Accessor */ public List getCacheEventListenerConfigurations() { return cacheEventListenerConfigurations; } /** * Accessor * * @return the configuration */ public List getCacheExtensionConfigurations() { return cacheExtensionConfigurations; } /** * Accessor * * @return the configuration */ public List getCacheLoaderConfigurations() { return cacheLoaderConfigurations; } /** * Accessor * * @return the configuration */ public List getCacheDecoratorConfigurations() { return cacheDecoratorConfigurations; } /** * Accessor * * @return the configuration */ public BootstrapCacheLoaderFactoryConfiguration getBootstrapCacheLoaderFactoryConfiguration() { return bootstrapCacheLoaderFactoryConfiguration; } /** * Accessor * * @return the configuration */ public CacheExceptionHandlerFactoryConfiguration getCacheExceptionHandlerFactoryConfiguration() { return cacheExceptionHandlerFactoryConfiguration; } /** * Accessor * * @return the terracotta configuration */ public TerracottaConfiguration getTerracottaConfiguration() { return terracottaConfiguration; } /** * Accessor * * @return the writer configuration */ public CacheWriterConfiguration getCacheWriterConfiguration() { return cacheWriterConfiguration; } /** * Helper method to compute whether the cache is clustered or not * * @return True if the <terracotta/> element exists with {@code clustered="true"} */ public boolean isTerracottaClustered() { return terracottaConfiguration != null && terracottaConfiguration.isClustered(); } /** * To what transactionalMode was the Cache set * * @return transactionaMode */ public final TransactionalMode getTransactionalMode() { return transactionalMode; } /** * Helper method to compute whether the cache is transactional or not * * @return true if transactionalMode="XA" */ public boolean isTransactional() { validateTransactionalSettings(); return transactionalMode.isTransactional(); } /** * Represents whether the Cache is transactional or not. * * @author alexsnaps */ public static enum TransactionalMode { /** * No Transactions */ OFF(false), /** * XA Transactions */ XA(true); private final boolean transactional; /** * @param transactional */ TransactionalMode(final boolean transactional) { this.transactional = transactional; } /** * @return transactional */ public boolean isTransactional() { return transactional; } } /** * Add a listener to this cache configuration * * @param listener listener instance to add * @return true if a listener was added */ public boolean addConfigurationListener(CacheConfigurationListener listener) { boolean added = listeners.add(listener); if (added) { listener.registered(this); } return added; } /** * Remove the supplied cache configuration listener. * * @param listener listener to remove * @return true if a listener was removed */ public boolean removeConfigurationListener(CacheConfigurationListener listener) { boolean removed = listeners.remove(listener); if (removed) { listener.deregistered(this); } return removed; } private void fireTtiChanged(long oldTti, long newTti) { if (oldTti != newTti) { for (CacheConfigurationListener l : listeners) { l.timeToIdleChanged(oldTti, newTti); } } } private void fireTtlChanged(long oldTtl, long newTtl) { if (oldTtl != newTtl) { for (CacheConfigurationListener l : listeners) { l.timeToLiveChanged(oldTtl, newTtl); } } } private void fireLoggingChanged(boolean oldValue, boolean newValue) { if (oldValue != newValue) { for (CacheConfigurationListener l : listeners) { l.loggingChanged(oldValue, newValue); } } } private void fireDiskCapacityChanged(int oldCapacity, int newCapacity) { if (oldCapacity != newCapacity) { for (CacheConfigurationListener l : listeners) { l.diskCapacityChanged(oldCapacity, newCapacity); } } } private void fireMemoryCapacityChanged(int oldCapacity, int newCapacity) { if (oldCapacity != newCapacity) { for (CacheConfigurationListener l : listeners) { l.memoryCapacityChanged(oldCapacity, newCapacity); } } } private void checkDynamicChange() { if (frozen) { throw new CacheException("Dynamic configuration changes are disabled for this cache"); } } /** * Intended for internal use only, and subject to change. * This is required so that changes in store implementation's config * (probably from other nodes) can propagate up to here */ public void internalSetTimeToIdle(long timeToIdle) { this.timeToIdleSeconds = timeToIdle; } /** * Intended for internal use only, and subject to change. */ public void internalSetTimeToLive(long timeToLive) { this.timeToLiveSeconds = timeToLive; } /** * Intended for internal use only, and subject to change. */ public void internalSetMemCapacity(int capacity) { this.maxElementsInMemory = capacity; } /** * Intended for internal use only, and subject to change. */ public void internalSetDiskCapacity(int capacity) { this.maxElementsOnDisk = capacity; } /** * Intended for internal use only, and subject to change. */ public void internalSetLogging(boolean logging) { this.logging = logging; } /** * Intended for internal use only, and subject to change. * This is called from the store implementations to reflect the new coherent value * * @param coherent true for coherent */ public void internalSetCoherent(boolean coherent) { if (isTerracottaClustered()) { this.getTerracottaConfiguration().setCoherent(coherent); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy