1 /***
2 * Copyright 2003-2010 Terracotta, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package net.sf.ehcache.config;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24 import java.util.concurrent.CopyOnWriteArraySet;
25
26 import net.sf.ehcache.CacheException;
27 import net.sf.ehcache.Element;
28 import net.sf.ehcache.config.TerracottaConfiguration.Consistency;
29 import net.sf.ehcache.config.TerracottaConfiguration.StorageStrategy;
30 import net.sf.ehcache.event.NotificationScope;
31 import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
32 import net.sf.ehcache.store.compound.ReadWriteCopyStrategy;
33
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 /***
38 * A value object used to represent cache configuration.
39 * <h4>Construction Patterns</h4>
40 * The recommended way of creating a <code>Cache</code> in Ehcache 2.0 and above is to create a <code>CacheConfiguration</code> object
41 * and pass it to the <code>Cache</code> constructor. See {@link net.sf.ehcache.Cache#Cache(CacheConfiguration)}.
42 * <p/>
43 * This class supports setter injection and also the fluent builder pattern.
44 * e.g.
45 * <code>Cache cache = new Cache(new CacheConfiguration("test2", 1000).eternal(true).memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.FIFO));</code>
46 * <p/>
47 * Rather than proliferation of new constructors as new versions of Ehcache come out, it intended to add the new configuration to this
48 * class.
49 * <p/>
50 * Another way to set configuration is declaratively in the <code>ehcache.xml</code> configuration file.
51 * e.g.
52 * <pre>{@code
53 * <cache name="testCache1"
54 * maxElementsInMemory="10000"
55 * eternal="false"
56 * timeToIdleSeconds="3600"
57 * timeToLiveSeconds="10"
58 * overflowToDisk="true"
59 * diskPersistent="true"
60 * diskExpiryThreadIntervalSeconds="120"
61 * maxElementsOnDisk="10000"
62 * />
63 * }</pre>
64 * <p/>
65 * <h4>Dynamic Configuration</h4>
66 * CacheConfiguration instances retrieved from Cache instances allow the dynamic
67 * modification of certain configuration properties. Currently the dynamic
68 * properties are:
69 * <ul>
70 * <li>Time To Idle</li>
71 * <li>Time To Live</li>
72 * <li>Max Elements in Memory</li>
73 * <li>Max Elements on Disk</li>
74 * </ul>
75 * Dynamic changes are however not persistent across cache restarts. On restart
76 * the cache configuration will be reloaded from its original source, erasing any
77 * changes made previously at runtime.
78 *
79 * @author Greg Luck
80 * @author Chris Dennis
81 * @version $Id: CacheConfiguration.html 13146 2011-08-01 17:12:39Z oletizi $
82 */
83 public class CacheConfiguration implements Cloneable {
84
85 /***
86 * Default value for clearOnFlush
87 */
88 public static final boolean DEFAULT_CLEAR_ON_FLUSH = true;
89
90 /***
91 * The default interval between runs of the expiry thread.
92 */
93 public static final long DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS = 120;
94
95 /***
96 * Set a buffer size for the spool of approx 30MB.
97 */
98 public static final int DEFAULT_SPOOL_BUFFER_SIZE = 30;
99
100 /***
101 * Default number of diskAccessStripes.
102 */
103 public static final int DEFAULT_DISK_ACCESS_STRIPES = 1;
104
105 /***
106 * Logging is off by default.
107 */
108 public static final boolean DEFAULT_LOGGING = false;
109
110 /***
111 * The default memory store eviction policy is LRU.
112 */
113 public static final MemoryStoreEvictionPolicy DEFAULT_MEMORY_STORE_EVICTION_POLICY = MemoryStoreEvictionPolicy.LRU;
114
115 /***
116 * The default cacheWriterConfiguration
117 */
118 public static final CacheWriterConfiguration DEFAULT_CACHE_WRITER_CONFIGURATION = new CacheWriterConfiguration();
119
120 /***
121 * Default value for copyOnRead
122 */
123 public static final boolean DEFAULT_COPY_ON_READ = false;
124
125 /***
126 * Default value for copyOnRead
127 */
128 public static final boolean DEFAULT_COPY_ON_WRITE = false;
129
130 /***
131 * Default value for ttl
132 */
133 public static final long DEFAULT_TTL = 0;
134
135 /***
136 * Default value for tti
137 */
138 public static final long DEFAULT_TTI = 0;
139
140 /***
141 * Default value for maxElementsOnDisk
142 */
143 public static final int DEFAULT_MAX_ELEMENTS_ON_DISK = 0;
144
145 /***
146 * Default value for transactionalMode
147 */
148 public static final TransactionalMode DEFAULT_TRANSACTIONAL_MODE = TransactionalMode.OFF;
149
150 /***
151 * Default value for statistics
152 */
153 public static final boolean DEFAULT_STATISTICS = false;
154
155 /***
156 * Default value for diskPersistent
157 */
158 public static final boolean DEFAULT_DISK_PERSISTENT = false;
159
160 /***
161 * Default copyStrategyConfiguration
162 */
163 public static final CopyStrategyConfiguration DEFAULT_COPY_STRATEGY_CONFIGURATION = new CopyStrategyConfiguration();
164
165 /***
166 * Default elementComparatorConfiguration
167 */
168 public static final ElementValueComparatorConfiguration DEFAULT_ELEMENT_VALUE_COMPARATOR_CONFIGURATION =
169 new ElementValueComparatorConfiguration();
170
171 /***
172 * Default maxBytesOnHeap value
173 */
174 public static final long DEFAULT_MAX_BYTES_ON_HEAP = 0;
175
176 /***
177 * Default maxBytesOffHeap value
178 */
179 public static final long DEFAULT_MAX_BYTES_OFF_HEAP = 0;
180
181 /***
182 * Default maxBytesOnDisk value
183 */
184 public static final long DEFAULT_MAX_BYTES_ON_DISK = 0;
185
186
187 private static final Logger LOG = LoggerFactory.getLogger(CacheConfiguration.class.getName());
188 private static final int HUNDRED_PERCENT = 100;
189
190 /***
191 * the name of the cache.
192 */
193 protected volatile String name;
194
195 /***
196 * Timeout in milliseconds for CacheLoader related calls
197 */
198 protected volatile long cacheLoaderTimeoutMillis;
199
200 /***
201 * the maximum objects to be held in the {@link net.sf.ehcache.store.MemoryStore}.
202 * <p/>
203 * <code>0</code> translates to no-limit.
204 */
205 protected volatile int maxEntriesLocalHeap;
206
207 /***
208 * the maximum objects to be held in the {@link net.sf.ehcache.store.disk.DiskStore}.
209 * <p/>
210 * <code>0</code> translates to no-limit.
211 */
212 protected volatile int maxElementsOnDisk = DEFAULT_MAX_ELEMENTS_ON_DISK;
213
214 /***
215 * The policy used to evict elements from the {@link net.sf.ehcache.store.MemoryStore}.
216 * This can be one of:
217 * <ol>
218 * <li>LRU - least recently used
219 * <li>LFU - Less frequently used
220 * <li>FIFO - first in first out, the oldest element by creation time
221 * </ol>
222 * The default value is LRU
223 *
224 * @since 1.2
225 */
226 protected volatile MemoryStoreEvictionPolicy memoryStoreEvictionPolicy = DEFAULT_MEMORY_STORE_EVICTION_POLICY;
227
228 /***
229 * Sets whether the MemoryStore should be cleared when
230 * {@link net.sf.ehcache.Ehcache#flush flush()} is called on the cache - true by default.
231 */
232 protected volatile boolean clearOnFlush = DEFAULT_CLEAR_ON_FLUSH;
233
234 /***
235 * Sets whether elements are eternal. If eternal, timeouts are ignored and the element
236 * is never expired.
237 */
238 protected volatile boolean eternal;
239
240 /***
241 * the time to idle for an element before it expires. Is only used
242 * if the element is not eternal.A value of 0 means do not check for idling.
243 */
244 protected volatile long timeToIdleSeconds = DEFAULT_TTI;
245
246 /***
247 * Sets the time to idle for an element before it expires. Is only used
248 * if the element is not eternal. This attribute is optional in the configuration.
249 * A value of 0 means do not check time to live.
250 */
251 protected volatile long timeToLiveSeconds = DEFAULT_TTL;
252
253 /***
254 * whether elements can overflow to disk when the in-memory cache
255 * has reached the set limit.
256 */
257 protected volatile boolean overflowToDisk;
258
259 /***
260 * For caches that overflow to disk, whether the disk cache persists between CacheManager instances.
261 */
262 protected volatile boolean diskPersistent = DEFAULT_DISK_PERSISTENT;
263
264 /***
265 * The path where the disk store is located
266 */
267 protected volatile String diskStorePath;
268
269 /***
270 * The size of the disk spool used to buffer writes
271 */
272 protected volatile int diskSpoolBufferSizeMB = DEFAULT_SPOOL_BUFFER_SIZE;
273
274 /***
275 * The number of concurrent disk access stripes.
276 */
277 protected volatile int diskAccessStripes = DEFAULT_DISK_ACCESS_STRIPES;
278
279 /***
280 * The interval in seconds between runs of the disk expiry thread.
281 * <p/>
282 * 2 minutes is the default.
283 * This is not the same thing as time to live or time to idle. When the thread runs it checks
284 * these things. So this value is how often we check for expiry.
285 */
286 protected volatile long diskExpiryThreadIntervalSeconds = DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS;
287
288 /***
289 * Indicates whether logging is enabled or not. False by default.
290 * Only used when cache is clustered with Terracotta.
291 */
292 protected volatile boolean logging = DEFAULT_LOGGING;
293
294 /***
295 * whether elements can overflow to off heap memory when the in-memory cache
296 * has reached the set limit.
297 */
298 protected volatile boolean overflowToOffHeap;
299
300 /***
301 * The event listener factories added by BeanUtils.
302 */
303 protected volatile List<CacheEventListenerFactoryConfiguration> cacheEventListenerConfigurations =
304 new ArrayList<CacheEventListenerFactoryConfiguration>();
305
306 /***
307 * The cache extension factories added by BeanUtils.
308 */
309 protected volatile List<CacheExtensionFactoryConfiguration> cacheExtensionConfigurations =
310 new ArrayList<CacheExtensionFactoryConfiguration>();
311
312 /***
313 * The BootstrapCacheLoaderFactoryConfiguration.
314 */
315 protected BootstrapCacheLoaderFactoryConfiguration bootstrapCacheLoaderFactoryConfiguration;
316
317 /***
318 * The CacheExceptionHandlerFactoryConfiguration.
319 */
320 protected CacheExceptionHandlerFactoryConfiguration cacheExceptionHandlerFactoryConfiguration;
321
322 /***
323 * The TerracottaConfiguration.
324 */
325 protected TerracottaConfiguration terracottaConfiguration;
326
327 /***
328 * The PinningConfiguration.
329 */
330 protected volatile PinningConfiguration pinningConfiguration;
331
332 /***
333 * The CacheWriterConfiguration.
334 */
335 protected CacheWriterConfiguration cacheWriterConfiguration = DEFAULT_CACHE_WRITER_CONFIGURATION;
336
337 /***
338 * The cache loader factories added by BeanUtils.
339 */
340 protected volatile List<CacheLoaderFactoryConfiguration> cacheLoaderConfigurations = new ArrayList<CacheLoaderFactoryConfiguration>();
341
342 /***
343 * The cache decorator factories added by BeanUtils.
344 */
345 protected volatile List<CacheDecoratorFactoryConfiguration> cacheDecoratorConfigurations =
346 new ArrayList<CacheDecoratorFactoryConfiguration>();
347
348 /***
349 * The listeners for this configuration.
350 */
351 protected volatile Set<CacheConfigurationListener> listeners = new CopyOnWriteArraySet<CacheConfigurationListener>();
352
353 private volatile boolean frozen;
354 private TransactionalMode transactionalMode = DEFAULT_TRANSACTIONAL_MODE;
355 private volatile boolean statistics = DEFAULT_STATISTICS;
356 private volatile CopyStrategyConfiguration copyStrategyConfiguration = DEFAULT_COPY_STRATEGY_CONFIGURATION.copy();
357 private volatile ElementValueComparatorConfiguration elementValueComparatorConfiguration =
358 DEFAULT_ELEMENT_VALUE_COMPARATOR_CONFIGURATION;
359 private volatile Boolean copyOnRead;
360 private volatile Boolean copyOnWrite;
361 private volatile boolean conflictingEternalValuesWarningLogged;
362 private volatile Searchable searchable;
363 private Long maxBytesLocalHeap;
364 private Long maxBytesLocalOffHeap;
365 private Long maxBytesLocalDisk;
366 private Integer maxBytesLocalHeapPercentage;
367 private Integer maxBytesLocalOffHeapPercentage;
368 private Integer maxBytesLocalDiskPercentage;
369
370 /***
371 * Default constructor.
372 * <p/>
373 * Note that an empty Cache is not valid and must have extra configuration added which can be done
374 * through the fluent methods in this class. Call <code>validateConfiguration()</code> to check your configuration.
375 *
376 * @see #validateCompleteConfiguration
377 */
378 public CacheConfiguration() {
379
380 }
381
382 /***
383 * Create a new cache configuration.
384 * <p/>
385 * Extra configuration can added after construction via the fluent methods in this class.
386 * Call <code>validateConfiguration()</code> to check your configuration.
387 *
388 * @param name the name of the cache. Note that "default" is a reserved name for the defaultCache.
389 * @param maxEntriesLocalHeap the maximum number of elements in memory, before they are evicted (0 == no limit)
390 * @see #validateCompleteConfiguration()
391 */
392 public CacheConfiguration(String name, int maxEntriesLocalHeap) {
393 this.name = name;
394 this.maxEntriesLocalHeap = maxEntriesLocalHeap;
395 }
396
397 /***
398 * Clones this object, following the usual contract.
399 *
400 * @return a copy, which independent other than configurations than cannot change.
401 */
402 @Override
403 public CacheConfiguration clone() {
404 CacheConfiguration config;
405 try {
406 config = (CacheConfiguration) super.clone();
407 } catch (CloneNotSupportedException e) {
408 throw new RuntimeException(e);
409 }
410
411 cloneCacheEventListenerConfigurations(config);
412
413 cloneCacheExtensionConfigurations(config);
414
415 if (bootstrapCacheLoaderFactoryConfiguration != null) {
416 config.bootstrapCacheLoaderFactoryConfiguration = bootstrapCacheLoaderFactoryConfiguration.clone();
417 }
418
419 if (cacheExceptionHandlerFactoryConfiguration != null) {
420 config.cacheExceptionHandlerFactoryConfiguration = cacheExceptionHandlerFactoryConfiguration.clone();
421 }
422
423 if (terracottaConfiguration != null) {
424 config.terracottaConfiguration = terracottaConfiguration.clone();
425 }
426
427 if (cacheWriterConfiguration != null) {
428 config.cacheWriterConfiguration = cacheWriterConfiguration.clone();
429 }
430
431 cloneCacheLoaderConfigurations(config);
432
433 cloneCacheDecoratorConfigurations(config);
434
435 config.listeners = new CopyOnWriteArraySet<CacheConfigurationListener>();
436
437 return config;
438 }
439
440 private void cloneCacheEventListenerConfigurations(CacheConfiguration config) {
441 if (cacheEventListenerConfigurations.size() > 0) {
442 List<CacheEventListenerFactoryConfiguration> copy = new ArrayList<CacheEventListenerFactoryConfiguration>();
443 for (CacheEventListenerFactoryConfiguration item : cacheEventListenerConfigurations) {
444 copy.add(item.clone());
445 }
446 config.cacheEventListenerConfigurations = copy;
447 }
448 }
449
450 private void cloneCacheExtensionConfigurations(CacheConfiguration config) {
451 if (cacheExtensionConfigurations.size() > 0) {
452 List<CacheExtensionFactoryConfiguration> copy = new ArrayList<CacheExtensionFactoryConfiguration>();
453 for (CacheConfiguration.CacheExtensionFactoryConfiguration item : cacheExtensionConfigurations) {
454 copy.add(item.clone());
455 }
456 config.cacheExtensionConfigurations = copy;
457 }
458 }
459
460 private void cloneCacheLoaderConfigurations(CacheConfiguration config) {
461 if (cacheLoaderConfigurations.size() > 0) {
462 List<CacheLoaderFactoryConfiguration> copy = new ArrayList<CacheLoaderFactoryConfiguration>();
463 for (CacheConfiguration.CacheLoaderFactoryConfiguration item : cacheLoaderConfigurations) {
464 copy.add(item.clone());
465 }
466 config.cacheLoaderConfigurations = copy;
467 }
468 }
469
470 private void cloneCacheDecoratorConfigurations(CacheConfiguration config) {
471 if (cacheDecoratorConfigurations.size() > 0) {
472 List<CacheDecoratorFactoryConfiguration> copy = new ArrayList<CacheDecoratorFactoryConfiguration>();
473 for (CacheDecoratorFactoryConfiguration item : cacheDecoratorConfigurations) {
474 copy.add(item.clone());
475 }
476 config.cacheDecoratorConfigurations = copy;
477 }
478 }
479
480 /***
481 * Sets the name of the cache.
482 *
483 * @param name the cache name. This must be unique. The / character is illegal. The # character does not work with RMI replication.
484 */
485 public final void setName(String name) {
486 checkDynamicChange();
487 if (name == null) {
488 throw new IllegalArgumentException("Cache name cannot be null.");
489 }
490 this.name = name;
491 }
492
493 /***
494 * Builder to set the name of the cache.
495 *
496 * @param name the cache name. This must be unique. The / character is illegal. The # character does not work with RMI replication.
497 * @return this configuration instance
498 * @see #setName(String)
499 */
500 public final CacheConfiguration name(String name) {
501 setName(name);
502 return this;
503 }
504
505 /***
506 * Enables or disables logging for the cache
507 * <p/>
508 * This property can be modified dynamically while the cache is operating.
509 * Only used when cache is clustered with Terracotta
510 *
511 * @param enable If true, enables logging otherwise disables logging
512 */
513 public final void setLogging(boolean enable) {
514 checkDynamicChange();
515 boolean oldLoggingEnabled = this.logging;
516 this.logging = enable;
517 fireLoggingChanged(oldLoggingEnabled, enable);
518 }
519
520 /***
521 * Enables or disables offheap store for the cache.
522 *
523 * @param overflowToOffHeap If true, enables offheap store otherwise disables it.
524 */
525 public final void setOverflowToOffHeap(boolean overflowToOffHeap) {
526 checkDynamicChange();
527 this.overflowToOffHeap = overflowToOffHeap;
528 }
529
530 /***
531 * Builder to enable or disable offheap store for the cache.
532 *
533 * @param overflowToOffHeap If true, enables offheap store otherwise disables it.
534 * @return this configuration instance
535 * @see #setOverflowToOffHeap(boolean)
536 */
537 public CacheConfiguration overflowToOffHeap(boolean overflowToOffHeap) {
538 setOverflowToOffHeap(overflowToOffHeap);
539 return this;
540 }
541
542 /***
543 * Sets the max off heap memory size allocated for this cache.
544 *
545 * @param maxMemoryOffHeap the max off heap memory size allocated for this cache.
546 */
547 public final void setMaxMemoryOffHeap(String maxMemoryOffHeap) {
548 checkDynamicChange();
549 setMaxBytesLocalOffHeap(maxMemoryOffHeap);
550 }
551
552 /***
553 * Builder to set the max off heap memory size allocated for this cache.
554 *
555 * @param maxMemoryOffHeap the max off heap memory size allocated for this cache.
556 * @return this configuration instance
557 * @see #setMaxMemoryOffHeap(String)
558 */
559 public CacheConfiguration maxMemoryOffHeap(String maxMemoryOffHeap) {
560 setMaxMemoryOffHeap(maxMemoryOffHeap);
561 return this;
562 }
563
564 /***
565 * Builder to enable or disable logging for the cache
566 * <p/>
567 * This property can be modified dynamically while the cache is operating.
568 * Only used when cache is clustered with Terracotta
569 *
570 * @param enable If true, enables logging otherwise disables logging
571 * @return this configuration instance
572 * @see #setLogging(boolean)
573 */
574 public final CacheConfiguration logging(boolean enable) {
575 setLogging(enable);
576 return this;
577 }
578
579 /***
580 * Sets the maximum objects to be held in memory (0 = no limit).
581 * <p/>
582 * This property can be modified dynamically while the cache is operating.
583 *
584 * @param maxElementsInMemory The maximum number of elements in memory, before they are evicted (0 == no limit)
585 * @deprecated use {@link #setMaxEntriesLocalHeap(long)}
586 */
587 @Deprecated
588 public final void setMaxElementsInMemory(int maxElementsInMemory) {
589 setMaxEntriesLocalHeap(maxElementsInMemory);
590 }
591
592 /***
593 * Sets the maximum objects to be held in local heap memory (0 = no limit).
594 * <p/>
595 * This property can be modified dynamically while the cache is operating.
596 *
597 * @param maxEntriesInMemory The maximum number of elements in memory, before they are evicted (0 == no limit)
598 */
599 public final void setMaxEntriesLocalHeap(long maxEntriesInMemory) {
600 if (maxEntriesInMemory > Integer.MAX_VALUE) {
601 throw new IllegalArgumentException("Values larger than Integer.MAX_VALUE are not currently supported.");
602 }
603
604 checkDynamicChange();
605 int oldCapacity = this.maxEntriesLocalHeap;
606 int newCapacity = (int) maxEntriesInMemory;
607 this.maxEntriesLocalHeap = (int) maxEntriesInMemory;
608 fireMemoryCapacityChanged(oldCapacity, newCapacity);
609 }
610
611 /***
612 * Builder that sets the maximum objects to be held in memory (0 = no limit).
613 * <p/>
614 * This property can be modified dynamically while the cache is operating.
615 *
616 * @param maxElementsInMemory The maximum number of elements in memory, before they are evicted (0 == no limit)
617 * @return this configuration instance
618 * @deprecated use {@link #maxEntriesLocalHeap(int)}
619 */
620 @Deprecated
621 public final CacheConfiguration maxElementsInMemory(int maxElementsInMemory) {
622 setMaxElementsInMemory(maxElementsInMemory);
623 return this;
624 }
625
626 /***
627 * Builder that sets the maximum objects to be held in memory (0 = no limit).
628 * <p/>
629 * This property can be modified dynamically while the cache is operating.
630 *
631 * @param maxElementsInMemory The maximum number of elements in memory, before they are evicted (0 == no limit)
632 * @return this configuration instance
633 */
634 public final CacheConfiguration maxEntriesLocalHeap(int maxElementsInMemory) {
635 setMaxEntriesLocalHeap(maxElementsInMemory);
636 return this;
637 }
638
639 /***
640 * Sets the timeout for CacheLoader execution (0 = no timeout).
641 *
642 * @param cacheLoaderTimeoutMillis the timeout in milliseconds.
643 */
644 public final void setCacheLoaderTimeoutMillis(long cacheLoaderTimeoutMillis) {
645 checkDynamicChange();
646 this.cacheLoaderTimeoutMillis = cacheLoaderTimeoutMillis;
647 }
648
649 /***
650 * Builder that sets the timeout for CacheLoader execution (0 = no timeout).
651
652 * @param timeoutMillis the timeout in milliseconds.
653 * @return this configuration instance
654 */
655 public CacheConfiguration timeoutMillis(long timeoutMillis) {
656 setCacheLoaderTimeoutMillis(timeoutMillis);
657 return this;
658 }
659
660 /***
661 * Sets the eviction policy. An invalid argument will set it to null.
662 *
663 * @param memoryStoreEvictionPolicy a String representation of the policy. One of "LRU", "LFU" or "FIFO".
664 */
665 public final void setMemoryStoreEvictionPolicy(String memoryStoreEvictionPolicy) {
666 setMemoryStoreEvictionPolicyFromObject(MemoryStoreEvictionPolicy.fromString(memoryStoreEvictionPolicy));
667 }
668
669 /***
670 * Builder that sets the eviction policy. An invalid argument will set it to null.
671 *
672 * @param memoryStoreEvictionPolicy a String representation of the policy. One of "LRU", "LFU" or "FIFO".
673 * @return this configuration instance
674 * @see #setMemoryStoreEvictionPolicy(String)
675 */
676 public final CacheConfiguration memoryStoreEvictionPolicy(String memoryStoreEvictionPolicy) {
677 setMemoryStoreEvictionPolicy(memoryStoreEvictionPolicy);
678 return this;
679 }
680
681 /***
682 * Sets the eviction policy. This method has a strange name to workaround a problem with XML parsing.
683 */
684 public final void setMemoryStoreEvictionPolicyFromObject(MemoryStoreEvictionPolicy memoryStoreEvictionPolicy) {
685 checkDynamicChange();
686 if (null == memoryStoreEvictionPolicy) {
687 this.memoryStoreEvictionPolicy = DEFAULT_MEMORY_STORE_EVICTION_POLICY;
688 } else {
689 this.memoryStoreEvictionPolicy = memoryStoreEvictionPolicy;
690 }
691 }
692
693 /***
694 * Builder which Sets the eviction policy. An invalid argument will set it to null.
695 *
696 * @return this configuration instance
697 * @see #setMemoryStoreEvictionPolicyFromObject(MemoryStoreEvictionPolicy)
698 */
699 public final CacheConfiguration memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy memoryStoreEvictionPolicy) {
700 setMemoryStoreEvictionPolicyFromObject(memoryStoreEvictionPolicy);
701 return this;
702 }
703
704 /***
705 * Sets whether the MemoryStore should be cleared when
706 * {@link net.sf.ehcache.Ehcache#flush flush()} is called on the cache - true by default.
707 *
708 * @param clearOnFlush true to clear on flush
709 */
710 public final void setClearOnFlush(boolean clearOnFlush) {
711 checkDynamicChange();
712 this.clearOnFlush = clearOnFlush;
713 }
714
715 /***
716 * Builder which sets whether the MemoryStore should be cleared when
717 * {@link net.sf.ehcache.Ehcache#flush flush()} is called on the cache - true by default.
718 *
719 * @param clearOnFlush true to clear on flush
720 * @return this configuration instance
721 * @see #setClearOnFlush(boolean)
722 */
723 public final CacheConfiguration clearOnFlush(boolean clearOnFlush) {
724 setClearOnFlush(clearOnFlush);
725 return this;
726 }
727
728 /***
729 * Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. False by default.
730 *
731 * @param eternal true for eternal
732 */
733 public final void setEternal(boolean eternal) {
734 checkDynamicChange();
735 isEternalValueConflictingWithTTIOrTTL(eternal, getTimeToLiveSeconds(), getTimeToIdleSeconds());
736 this.eternal = eternal;
737 if (eternal) {
738 setTimeToIdleSeconds(0);
739 setTimeToLiveSeconds(0);
740 }
741 }
742
743 private boolean isEternalValueConflictingWithTTIOrTTL(boolean newEternalValue, long newTTLValue, long newTTIValue) {
744 boolean conflicting = false;
745
746 if (newEternalValue && (newTTLValue != 0 || newTTIValue != 0)) {
747 conflicting = true;
748 }
749
750 if (conflicting && !conflictingEternalValuesWarningLogged) {
751 conflictingEternalValuesWarningLogged = true;
752 LOG.warn("Cache '" + getName() + "' is set to eternal but also has TTI/TTL set. "
753 + " To avoid this warning, clean up the config " + "removing conflicting values of eternal,"
754 + " TTI and TTL. Effective configuration for Cache '" + getName() + "' will be eternal='" + newEternalValue
755 + "', timeToIdleSeconds='0', timeToLiveSeconds='0'.");
756 }
757 return conflicting;
758 }
759
760 /***
761 * Builder which sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. False by default.
762 *
763 * @param eternal true for eternal
764 * @return this configuration instance
765 * @see #setEternal(boolean)
766 */
767 public final CacheConfiguration eternal(boolean eternal) {
768 setEternal(eternal);
769 return this;
770 }
771
772 /***
773 * 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
774 * {@link net.sf.ehcache.Element}
775 * <p/>
776 * This property can be modified dynamically while the cache is operating.
777 *
778 * @param timeToIdleSeconds the default amount of time to live for an element from its last accessed or modified date
779 */
780 public final void setTimeToIdleSeconds(long timeToIdleSeconds) {
781 checkDynamicChange();
782 if (!isEternalValueConflictingWithTTIOrTTL(eternal, 0, timeToIdleSeconds)) {
783 long oldTti = this.timeToIdleSeconds;
784 long newTti = timeToIdleSeconds;
785 this.timeToIdleSeconds = timeToIdleSeconds;
786 fireTtiChanged(oldTti, newTti);
787 }
788 }
789
790 /***
791 * Builder which sets the time to idle for an element before it expires. Is only used if the element is not eternal.
792 * This default can be overridden in {@link net.sf.ehcache.Element}
793 * <p/>
794 * This property can be modified dynamically while the cache is operating.
795 *
796 * @param timeToIdleSeconds the default amount of time to live for an element from its last accessed or modified date
797 * @return this configuration instance
798 * @see #setTimeToIdleSeconds(long)
799 */
800 public final CacheConfiguration timeToIdleSeconds(long timeToIdleSeconds) {
801 setTimeToIdleSeconds(timeToIdleSeconds);
802 return this;
803 }
804
805 /***
806 * Sets the time to idle for an element before it expires. Is only used if the element is not eternal.
807 * This default can be overridden in {@link net.sf.ehcache.Element}
808 * <p/>
809 * This property can be modified dynamically while the cache is operating.
810 *
811 * @param timeToLiveSeconds the default amount of time to live for an element from its creation date
812 */
813 public final void setTimeToLiveSeconds(long timeToLiveSeconds) {
814 checkDynamicChange();
815 if (!isEternalValueConflictingWithTTIOrTTL(eternal, timeToLiveSeconds, 0)) {
816 long oldTtl = this.timeToLiveSeconds;
817 long newTtl = timeToLiveSeconds;
818 this.timeToLiveSeconds = timeToLiveSeconds;
819 fireTtlChanged(oldTtl, newTtl);
820 }
821 }
822
823 /***
824 * Builder which sets the time to idle for an element before it expires. Is only used if the element is not eternal.
825 * This default can be overridden in {@link net.sf.ehcache.Element}
826 * <p/>
827 * This property can be modified dynamically while the cache is operating.
828 *
829 * @param timeToLiveSeconds the default amount of time to live for an element from its creation date
830 * @return this configuration instance
831 * @see #setTimeToLiveSeconds(long)
832 */
833 public final CacheConfiguration timeToLiveSeconds(long timeToLiveSeconds) {
834 setTimeToLiveSeconds(timeToLiveSeconds);
835 return this;
836 }
837
838 /***
839 * Sets whether elements can overflow to disk when the in-memory cache has reached the set limit.
840 *
841 * @param overflowToDisk whether to use the disk store
842 */
843 public final void setOverflowToDisk(boolean overflowToDisk) {
844 checkDynamicChange();
845 this.overflowToDisk = overflowToDisk;
846 validateConfiguration();
847 }
848
849 /***
850 * Builder which sets whether elements can overflow to disk when the in-memory cache has reached the set limit.
851 *
852 * @param overflowToDisk whether to use the disk store
853 * @return this configuration instance
854 * @see #setOverflowToDisk(boolean)
855 */
856 public final CacheConfiguration overflowToDisk(boolean overflowToDisk) {
857 setOverflowToDisk(overflowToDisk);
858 return this;
859 }
860
861 /***
862 * Sets whether the disk store persists between CacheManager instances. Note that this operates independently of {@link #overflowToDisk}.
863 *
864 * @param diskPersistent whether to persist the cache to disk between JVM restarts
865 */
866 public final void setDiskPersistent(boolean diskPersistent) {
867 checkDynamicChange();
868 this.diskPersistent = diskPersistent;
869 validateConfiguration();
870 }
871
872 /***
873 * Builder which sets whether the disk store persists between CacheManager instances. Note that this operates independently of {@link #overflowToDisk}.
874 *
875 * @param diskPersistent whether to persist the cache to disk between JVM restarts.
876 * @return this configuration instance
877 * @see #setDiskPersistent(boolean)
878 */
879 public final CacheConfiguration diskPersistent(boolean diskPersistent) {
880 setDiskPersistent(diskPersistent);
881 return this;
882 }
883
884 /***
885 * Sets the path that will be used for the disk store.
886 * If you use this feature, beware of collisions with CacheManagers
887 * potentially have a Cache with the same name!
888 *
889 * @param diskStorePath if <code>null</code>, CacheManager sets it using setter injection.
890 */
891 public final void setDiskStorePath(String diskStorePath) {
892 checkDynamicChange();
893 if (null == diskStorePath) {
894 this.diskStorePath = DiskStoreConfiguration.getDefaultPath();
895 }
896 this.diskStorePath = diskStorePath;
897 validateConfiguration();
898 }
899
900 /***
901 * Builder which sets the path that will be used for the disk store.
902 * If you use this feature, beware of collisions with CacheManagers
903 * potentially have a Cache with the same name!
904 *
905 * @param diskStorePath if <code>null</code>, CacheManager sets it using setter injection.
906 * @return this configuration instance
907 * @see #setDiskStorePath(String)
908 */
909 public final CacheConfiguration diskStorePath(String diskStorePath) {
910 setDiskStorePath(diskStorePath);
911 return this;
912 }
913
914 /***
915 * Sets the disk spool size, which is used to buffer writes to the DiskStore.
916 * If not set it defaults to {@link #DEFAULT_SPOOL_BUFFER_SIZE}
917 *
918 * @param diskSpoolBufferSizeMB a positive number
919 */
920 public void setDiskSpoolBufferSizeMB(int diskSpoolBufferSizeMB) {
921 checkDynamicChange();
922 if (diskSpoolBufferSizeMB <= 0) {
923 this.diskSpoolBufferSizeMB = DEFAULT_SPOOL_BUFFER_SIZE;
924 } else {
925 this.diskSpoolBufferSizeMB = diskSpoolBufferSizeMB;
926 }
927 }
928
929 /***
930 * Builder which sets the disk spool size, which is used to buffer writes to the DiskStore.
931 * If not set it defaults to {@link #DEFAULT_SPOOL_BUFFER_SIZE}
932 *
933 * @param diskSpoolBufferSizeMB a positive number
934 * @return this configuration instance
935 * @see #setDiskSpoolBufferSizeMB(int)
936 */
937 public final CacheConfiguration diskSpoolBufferSizeMB(int diskSpoolBufferSizeMB) {
938 setDiskSpoolBufferSizeMB(diskSpoolBufferSizeMB);
939 return this;
940 }
941
942 /***
943 * Sets the number of disk stripes. RandomAccessFiles used to access the data file. By default there
944 * is one stripe.
945 *
946 * @param stripes number of stripes (rounded up to a power-of-2)
947 */
948 public void setDiskAccessStripes(int stripes) {
949 checkDynamicChange();
950 if (stripes <= 0) {
951 this.diskAccessStripes = DEFAULT_DISK_ACCESS_STRIPES;
952 } else {
953 this.diskAccessStripes = stripes;
954 }
955 }
956
957 /***
958 * Builder which sets the number of disk stripes. RandomAccessFiles used to access the data file. By default there
959 * is one stripe.
960 *
961 * @return this configuration instance
962 * @see #setDiskAccessStripes(int)
963 */
964 public final CacheConfiguration diskAccessStripes(int stripes) {
965 setDiskAccessStripes(stripes);
966 return this;
967 }
968
969 /***
970 * Sets the maximum number elements on Disk. 0 means unlimited.
971 * <p/>
972 * This property can be modified dynamically while the cache is operating.
973 *
974 * @param maxElementsOnDisk the maximum number of Elements to allow on the disk. 0 means unlimited.
975 * @deprecated use {@link #setMaxEntriesLocalDisk(long)}
976 */
977 @Deprecated
978 public void setMaxElementsOnDisk(int maxElementsOnDisk) {
979 setMaxEntriesLocalDisk(maxElementsOnDisk);
980 }
981
982 /***
983 * Sets the maximum number elements on Disk. 0 means unlimited.
984 * <p/>
985 * This property can be modified dynamically while the cache is operating.
986 *
987 * @param maxEntriesOnDisk the maximum number of Elements to allow on the disk. 0 means unlimited.
988 */
989 public void setMaxEntriesLocalDisk(long maxEntriesOnDisk) {
990 if (maxEntriesOnDisk > Integer.MAX_VALUE) {
991 throw new IllegalArgumentException("Values greater than Integer.MAX_VALUE are not currently supported.");
992 }
993
994 checkDynamicChange();
995 int oldCapacity = this.maxElementsOnDisk;
996 int newCapacity = (int) maxEntriesOnDisk;
997 this.maxElementsOnDisk = (int) maxEntriesOnDisk;
998 fireDiskCapacityChanged(oldCapacity, newCapacity);
999 }
1000
1001 /***
1002 * Builder which sets the maximum number elements on Disk. 0 means unlimited.
1003 * <p/>
1004 * This property can be modified dynamically while the cache is operating.
1005 *
1006 * @param maxElementsOnDisk the maximum number of Elements to allow on the disk. 0 means unlimited.
1007 * @return this configuration instance
1008 * @see #setMaxElementsOnDisk(int)
1009 * @deprecated use {@link #maxEntriesLocalDisk(int)}
1010 */
1011 @Deprecated
1012 public final CacheConfiguration maxElementsOnDisk(int maxElementsOnDisk) {
1013 setMaxElementsOnDisk(maxElementsOnDisk);
1014 return this;
1015 }
1016
1017 /***
1018 * Builder which sets the maximum number elements on Disk. 0 means unlimited.
1019 * <p/>
1020 * This property can be modified dynamically while the cache is operating.
1021 *
1022 * @param maxElementsOnDisk the maximum number of Elements to allow on the disk. 0 means unlimited.
1023 * @return this configuration instance
1024 * @see #setMaxElementsOnDisk(int)
1025 */
1026 public final CacheConfiguration maxEntriesLocalDisk(int maxElementsOnDisk) {
1027 setMaxEntriesLocalDisk(maxElementsOnDisk);
1028 return this;
1029 }
1030
1031 /***
1032 * Sets the interval in seconds between runs of the disk expiry thread.
1033 * <p/>
1034 * 2 minutes is the default.
1035 * This is not the same thing as time to live or time to idle. When the thread runs it checks
1036 * these things. So this value is how often we check for expiry.
1037 */
1038 public final void setDiskExpiryThreadIntervalSeconds(long diskExpiryThreadIntervalSeconds) {
1039 checkDynamicChange();
1040 if (diskExpiryThreadIntervalSeconds <= 0) {
1041 this.diskExpiryThreadIntervalSeconds = DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS;
1042 } else {
1043 this.diskExpiryThreadIntervalSeconds = diskExpiryThreadIntervalSeconds;
1044 }
1045 }
1046
1047 /***
1048 * Builder which sets the interval in seconds between runs of the disk expiry thread.
1049 * <p/>
1050 * 2 minutes is the default.
1051 * This is not the same thing as time to live or time to idle. When the thread runs it checks
1052 * these things. So this value is how often we check for expiry.
1053 *
1054 * @return this configuration instance
1055 * @see #setDiskExpiryThreadIntervalSeconds(long)
1056 */
1057 public final CacheConfiguration diskExpiryThreadIntervalSeconds(long diskExpiryThreadIntervalSeconds) {
1058 setDiskExpiryThreadIntervalSeconds(diskExpiryThreadIntervalSeconds);
1059 return this;
1060 }
1061
1062 /***
1063 * Freeze this configuration. Any subsequent changes will throw a CacheException
1064 */
1065 public void freezeConfiguration() {
1066 frozen = true;
1067 if (searchable != null) {
1068 searchable.freezeConfiguration();
1069 }
1070 }
1071
1072 /***
1073 * @return true is this configuration is frozen - it cannot be changed dynamically.
1074 */
1075 public boolean isFrozen() {
1076 return frozen;
1077 }
1078
1079 /***
1080 * Getter to the CopyStrategy set in the config (really? how?).
1081 * This will always return the same unique instance per cache
1082 *
1083 * @return the {@link ReadWriteCopyStrategy} for instance for this cache
1084 */
1085 public ReadWriteCopyStrategy<Element> getCopyStrategy() {
1086
1087 return copyStrategyConfiguration.getCopyStrategyInstance();
1088 }
1089
1090 /***
1091 * Whether the Cache should copy elements it returns
1092 *
1093 * @param copyOnRead true, if copyOnRead
1094 */
1095 public CacheConfiguration copyOnRead(boolean copyOnRead) {
1096 this.setCopyOnRead(copyOnRead);
1097 return this;
1098 }
1099
1100 /***
1101 * Whether the Cache should copy elements it returns
1102 *
1103 * @return true, is copyOnRead
1104 */
1105 public boolean isCopyOnRead() {
1106 validateTransactionalSettings();
1107 return copyOnRead;
1108 }
1109
1110 /***
1111 * Whether the Cache should copy elements it returns
1112 *
1113 * @param copyOnRead true, if copyOnRead
1114 */
1115 public void setCopyOnRead(final boolean copyOnRead) {
1116 this.copyOnRead = copyOnRead;
1117 }
1118
1119 /***
1120 * Whether the Cache should copy elements it gets
1121 *
1122 * @param copyOnWrite true, if copyOnWrite
1123 */
1124 public CacheConfiguration copyOnWrite(boolean copyOnWrite) {
1125 this.copyOnWrite = copyOnWrite;
1126 return this;
1127 }
1128
1129 /***
1130 * Whether the Cache should copy elements it gets
1131 *
1132 * @return true, if copyOnWrite
1133 */
1134 public boolean isCopyOnWrite() {
1135 validateTransactionalSettings();
1136 return copyOnWrite;
1137 }
1138
1139 /***
1140 * Whether the Cache should copy elements it gets
1141 *
1142 * @param copyOnWrite true, if copyOnWrite
1143 */
1144 public void setCopyOnWrite(final boolean copyOnWrite) {
1145 this.copyOnWrite = copyOnWrite;
1146 }
1147
1148 /***
1149 * Sets the CopyStrategyConfiguration for this cache
1150 *
1151 * @param copyStrategyConfiguration the CopyStrategy Configuration
1152 */
1153 public void addCopyStrategy(CopyStrategyConfiguration copyStrategyConfiguration) {
1154 this.copyStrategyConfiguration = copyStrategyConfiguration;
1155 }
1156
1157 /***
1158 * Sets the ElementValueComparatorConfiguration for this cache
1159 *
1160 * @param elementValueComparatorConfiguration the ElementComparator Configuration
1161 */
1162 public void addElementValueComparator(ElementValueComparatorConfiguration elementValueComparatorConfiguration) {
1163 this.elementValueComparatorConfiguration = elementValueComparatorConfiguration;
1164 }
1165
1166 /***
1167 * Add configuration to make this cache searchable
1168 *
1169 * @param searchable search config to add
1170 */
1171 public final void addSearchable(Searchable searchable) {
1172 checkDynamicChange();
1173 this.searchable = searchable;
1174 }
1175
1176 /***
1177 * The maximum amount of bytes the cache should occupy on heap
1178 * @return value in bytes, 0 if none set
1179 */
1180 public long getMaxBytesLocalHeap() {
1181 return maxBytesLocalHeap == null ? DEFAULT_MAX_BYTES_ON_HEAP : maxBytesLocalHeap;
1182 }
1183
1184 /***
1185 * Setter for maxBytesLocalHeap as a String. Value can have a one char unit suffix or be a percentage (ending in %)
1186 * @param maxBytesHeap String representation of the size, can be relative (in %)
1187 */
1188 public void setMaxBytesLocalHeap(final String maxBytesHeap) {
1189 if (isPercentage(maxBytesHeap)) {
1190 maxBytesLocalHeapPercentage = parsePercentage(maxBytesHeap);
1191 } else {
1192 setMaxBytesLocalHeap(MemoryUnit.parseSizeInBytes(maxBytesHeap));
1193 }
1194 }
1195
1196 /***
1197 * Setter for maxBytesLocalDisk in bytes
1198 * @param maxBytesHeap max bytes on disk in bytes
1199 */
1200 public void setMaxBytesLocalHeap(final Long maxBytesHeap) {
1201 verifyGreaterThanZero(maxBytesHeap, "maxBytesLocalHeap");
1202 this.maxBytesLocalHeap = maxBytesHeap;
1203 }
1204
1205 /***
1206 * Sets the maxOnHeap size
1207 * @param amount the amount of unit
1208 * @param memoryUnit the actual unit
1209 * @return this
1210 */
1211
1212 public CacheConfiguration maxBytesLocalHeap(final long amount, final MemoryUnit memoryUnit) {
1213 setMaxBytesLocalHeap(memoryUnit.toBytes(amount));
1214 return this;
1215 }
1216
1217 /***
1218 * The maximum amount of bytes the cache should occupy off heap
1219 * @return value in bytes, 0 if none set
1220 */
1221 public long getMaxBytesLocalOffHeap() {
1222 return maxBytesLocalOffHeap == null ? DEFAULT_MAX_BYTES_OFF_HEAP : maxBytesLocalOffHeap;
1223 }
1224
1225 /***
1226 * Setter for maximum bytes off heap as a String. Value can have a one char unit suffix or be a percentage (ending in %)
1227 * @param maxBytesOffHeap String representation of the size, can be relative (in %)
1228 */
1229 public void setMaxBytesLocalOffHeap(final String maxBytesOffHeap) {
1230 if (isPercentage(maxBytesOffHeap)) {
1231 maxBytesLocalOffHeapPercentage = parsePercentage(maxBytesOffHeap);
1232 } else {
1233 setMaxBytesLocalOffHeap(MemoryUnit.parseSizeInBytes(maxBytesOffHeap));
1234 }
1235 }
1236
1237 /***
1238 * Getter for maximum bytes off heap expressed as a percentage
1239 * @return percentage (between 0 and 100)
1240 */
1241 public Integer getMaxBytesLocalOffHeapPercentage() {
1242 return maxBytesLocalOffHeapPercentage;
1243 }
1244
1245 /***
1246 * Getter for maximum bytes on heap expressed as a percentage
1247 * @return percentage (between 0 and 100)
1248 */
1249 public Integer getMaxBytesLocalHeapPercentage() {
1250 return maxBytesLocalHeapPercentage;
1251 }
1252
1253 /***
1254 * Getter for maximum bytes on disk expressed as a percentage
1255 * @return percentage (between 0 and 100)
1256 */
1257 public Integer getMaxBytesLocalDiskPercentage() {
1258 return maxBytesLocalDiskPercentage;
1259 }
1260
1261 private int parsePercentage(final String stringValue) {
1262 String trimmed = stringValue.trim();
1263 int percentage = Integer.parseInt(trimmed.substring(0, trimmed.length() - 1));
1264 if (percentage > HUNDRED_PERCENT || percentage < 0) {
1265 throw new IllegalArgumentException("Percentage need values need to be between 0 and 100 inclusive, but got : " + percentage);
1266 }
1267 return percentage;
1268 }
1269
1270 private boolean isPercentage(final String stringValue) {
1271 String trimmed = stringValue.trim();
1272 return trimmed.charAt(trimmed.length() - 1) == '%';
1273 }
1274
1275 /***
1276 * Sets the maximum amount of bytes the cache being configured will use on the OffHeap tier
1277 * @param maxBytesOffHeap max bytes on disk in bytes
1278 */
1279 public void setMaxBytesLocalOffHeap(final Long maxBytesOffHeap) {
1280 verifyGreaterThanZero(maxBytesOffHeap, "maxBytesLocalOffHeap");
1281 this.maxBytesLocalOffHeap = maxBytesOffHeap;
1282 }
1283
1284 /***
1285 * Sets the maxOffHeap tier size
1286 * @param amount the amount of unit
1287 * @param memoryUnit the actual unit
1288 * @return this
1289 */
1290 public CacheConfiguration maxBytesLocalOffHeap(final long amount, final MemoryUnit memoryUnit) {
1291 setMaxBytesLocalOffHeap(memoryUnit.toBytes(amount));
1292 return this;
1293 }
1294
1295 /***
1296 * The maximum amount of bytes the cache should occupy on disk
1297 * @return value in bytes, 0 if none set
1298 */
1299 public long getMaxBytesLocalDisk() {
1300 return maxBytesLocalDisk == null ? DEFAULT_MAX_BYTES_ON_DISK : maxBytesLocalDisk;
1301 }
1302
1303 /***
1304 * Setter for maxBytesOnDisk as a String. Value can have a one char unit suffix or be a percentage (ending in %)
1305 * @param maxBytesDisk String representation of the size, can be relative (in %)
1306 */
1307 public void setMaxBytesLocalDisk(final String maxBytesDisk) {
1308 if (isPercentage(maxBytesDisk)) {
1309 maxBytesLocalDiskPercentage = parsePercentage(maxBytesDisk);
1310 } else {
1311 setMaxBytesLocalDisk(MemoryUnit.parseSizeInBytes(maxBytesDisk));
1312 }
1313 }
1314
1315 /***
1316 * Sets the maximum amount of bytes the cache being configured will use on the OnDisk tier
1317 * @param maxBytesDisk max bytes on disk in bytes
1318 */
1319 public void setMaxBytesLocalDisk(final Long maxBytesDisk) {
1320 verifyGreaterThanZero(maxBytesDisk, "maxBytesLocalDisk");
1321 this.maxBytesLocalDisk = maxBytesDisk;
1322 }
1323
1324 /***
1325 * Sets the maxOnDisk size
1326 * @param amount the amount of unit
1327 * @param memoryUnit the actual unit
1328 * @return this
1329 */
1330 public CacheConfiguration maxBytesLocalDisk(final long amount, final MemoryUnit memoryUnit) {
1331 setMaxBytesLocalDisk(memoryUnit.toBytes(amount));
1332 return this;
1333 }
1334
1335 private void verifyGreaterThanZero(final Long maxBytesOnHeap, final String field) {
1336 if (maxBytesOnHeap != null && maxBytesOnHeap < 1) {
1337 throw new IllegalArgumentException(field + " has to be larger than 0");
1338 }
1339 }
1340
1341 /***
1342 * Returns the copyStrategyConfiguration
1343 *
1344 * @return the copyStrategyConfiguration
1345 */
1346 public CopyStrategyConfiguration getCopyStrategyConfiguration() {
1347 return this.copyStrategyConfiguration;
1348 }
1349
1350 /***
1351 * Returns the elementComparatorConfiguration
1352 *
1353 * @return the elementComparatorConfiguration
1354 */
1355 public ElementValueComparatorConfiguration getElementValueComparatorConfiguration() {
1356 return elementValueComparatorConfiguration;
1357 }
1358
1359 /***
1360 * Checks whether the user explicitly set the maxBytesOnHeapPercentage
1361 * @return true if set by user, false otherwise
1362 * @see #setMaxBytesLocalHeap(String)
1363 */
1364 public boolean isMaxBytesLocalHeapPercentageSet() {
1365 return maxBytesLocalHeapPercentage != null;
1366 }
1367
1368 /***
1369 * Checks whether the user explicitly set the maxBytesOffHeapPercentage
1370 * @return true if set by user, false otherwise
1371 * @see #setMaxBytesLocalOffHeap(String)
1372 */
1373 public boolean isMaxBytesLocalOffHeapPercentageSet() {
1374 return maxBytesLocalOffHeapPercentage != null;
1375 }
1376
1377 /***
1378 * Checks whether the user explicitly set the maxBytesOnDiskPercentage
1379 * @return true if set by user, false otherwise
1380 * @see #setMaxBytesLocalDisk(String)
1381 */
1382 public boolean isMaxBytesLocalDiskPercentageSet() {
1383 return maxBytesLocalDiskPercentage != null;
1384 }
1385
1386 /***
1387 * Configuration for the CacheEventListenerFactory.
1388 */
1389 public static final class CacheEventListenerFactoryConfiguration extends FactoryConfiguration<CacheEventListenerFactoryConfiguration> {
1390 private NotificationScope notificationScope = NotificationScope.ALL;
1391
1392 /***
1393 * Used by BeanHandler to set the mode during parsing. Convert listenFor string to uppercase and
1394 * look up enum constant in NotificationScope.
1395 */
1396 public void setListenFor(String listenFor) {
1397 if (listenFor == null) {
1398 throw new IllegalArgumentException("listenFor must be non-null");
1399 }
1400 this.notificationScope = NotificationScope.valueOf(NotificationScope.class, listenFor.toUpperCase());
1401 }
1402
1403 /***
1404 * @return this factory configuration instance
1405 * @see #setListenFor(String)
1406 */
1407 public final CacheEventListenerFactoryConfiguration listenFor(String listenFor) {
1408 setListenFor(listenFor);
1409 return this;
1410 }
1411
1412 /***
1413 * Get the value mode in terms of the mode enum
1414 */
1415 public NotificationScope getListenFor() {
1416 return this.notificationScope;
1417 }
1418 }
1419
1420 /***
1421 * Used by BeanUtils to add cacheEventListenerFactory elements to the cache configuration.
1422 */
1423 public final void addCacheEventListenerFactory(CacheEventListenerFactoryConfiguration factory) {
1424 checkDynamicChange();
1425 cacheEventListenerConfigurations.add(factory);
1426 validateConfiguration();
1427 }
1428
1429 /***
1430 * @return this configuration instance
1431 * @see #addCacheEventListenerFactory(CacheEventListenerFactoryConfiguration)
1432 */
1433 public final CacheConfiguration cacheEventListenerFactory(CacheEventListenerFactoryConfiguration factory) {
1434 addCacheEventListenerFactory(factory);
1435 return this;
1436 }
1437
1438 /***
1439 * Configuration for the CacheExtensionFactoryConfiguration.
1440 */
1441 public static final class CacheExtensionFactoryConfiguration extends FactoryConfiguration<CacheExtensionFactoryConfiguration> {
1442 }
1443
1444 /***
1445 * Used by BeanUtils to add cacheExtensionFactory elements to the cache configuration.
1446 */
1447 public final void addCacheExtensionFactory(CacheExtensionFactoryConfiguration factory) {
1448 checkDynamicChange();
1449 cacheExtensionConfigurations.add(factory);
1450 }
1451
1452 /***
1453 * @return this configuration instance
1454 * @see #addCacheExtensionFactory(CacheExtensionFactoryConfiguration)
1455 */
1456 public final CacheConfiguration cacheExtensionFactory(CacheExtensionFactoryConfiguration factory) {
1457 /***
1458 * {@inheritDoc}
1459 */
1460 addCacheExtensionFactory(factory);
1461 return this;
1462 }
1463
1464 /***
1465 * Configuration for the BootstrapCacheLoaderFactoryConfiguration.
1466 */
1467 public static final class BootstrapCacheLoaderFactoryConfiguration extends
1468 FactoryConfiguration<BootstrapCacheLoaderFactoryConfiguration> {
1469 }
1470
1471 /***
1472 * Allows BeanHandler to add the CacheManagerEventListener to the configuration.
1473 */
1474 public final void addBootstrapCacheLoaderFactory(BootstrapCacheLoaderFactoryConfiguration factory) {
1475 checkDynamicChange();
1476 this.bootstrapCacheLoaderFactoryConfiguration = factory;
1477 }
1478
1479 /***
1480 * @return this configuration instance
1481 * @see #addBootstrapCacheLoaderFactory(BootstrapCacheLoaderFactoryConfiguration)
1482 */
1483 public final CacheConfiguration bootstrapCacheLoaderFactory(BootstrapCacheLoaderFactoryConfiguration factory) {
1484 addBootstrapCacheLoaderFactory(factory);
1485 return this;
1486 }
1487
1488 /***
1489 * Configuration for the BootstrapCacheLoaderFactoryConfiguration.
1490 */
1491 public static final class CacheExceptionHandlerFactoryConfiguration extends
1492 FactoryConfiguration<CacheExceptionHandlerFactoryConfiguration> {
1493 }
1494
1495 /***
1496 * Add the CacheExceptionHandlerFactory to the configuration.
1497 * <p/>
1498 * Note that this will not have any effect when creating a cache solely through its constructed. The exception
1499 * handler will only be taken into account when {@link ConfigurationHelper} is used, for example through
1500 * {@link net.sf.ehcache.CacheManager}.
1501 */
1502 public final void addCacheExceptionHandlerFactory(CacheExceptionHandlerFactoryConfiguration factory) {
1503 checkDynamicChange();
1504 this.cacheExceptionHandlerFactoryConfiguration = factory;
1505 }
1506
1507 /***
1508 * @return this configuration instance
1509 * @see #addCacheExceptionHandlerFactory(CacheExceptionHandlerFactoryConfiguration)
1510 */
1511 public final CacheConfiguration cacheExceptionHandlerFactory(CacheExceptionHandlerFactoryConfiguration factory) {
1512 addCacheExceptionHandlerFactory(factory);
1513 return this;
1514 }
1515
1516 /***
1517 * Configuration for the CacheLoaderFactoryConfiguration.
1518 */
1519 public static final class CacheLoaderFactoryConfiguration extends FactoryConfiguration<CacheLoaderFactoryConfiguration> {
1520 }
1521
1522 /***
1523 * Used by BeanUtils to add each cacheLoaderFactory to the cache configuration.
1524 *
1525 * @param factory
1526 */
1527 public final void addCacheLoaderFactory(CacheLoaderFactoryConfiguration factory) {
1528 checkDynamicChange();
1529 cacheLoaderConfigurations.add(factory);
1530 }
1531
1532 /***
1533 * Configuration for the CacheDecoratorFactoryConfiguration.
1534 */
1535 public static final class CacheDecoratorFactoryConfiguration extends FactoryConfiguration<CacheDecoratorFactoryConfiguration> {
1536 }
1537
1538 /***
1539 * Used by BeanUtils to add each cacheDecoratorFactory to the cache configuration.
1540 *
1541 * @param factory
1542 */
1543 public final void addCacheDecoratorFactory(CacheDecoratorFactoryConfiguration factory) {
1544 checkDynamicChange();
1545 cacheDecoratorConfigurations.add(factory);
1546 }
1547
1548 /***
1549 * @return this configuration instance
1550 * @see #addCacheLoaderFactory(CacheLoaderFactoryConfiguration)
1551 */
1552 public final CacheConfiguration cacheLoaderFactory(CacheLoaderFactoryConfiguration factory) {
1553 addCacheLoaderFactory(factory);
1554 return this;
1555 }
1556
1557 /***
1558 * Allows BeanHandler to add the TerracottaConfiguration to the configuration.
1559 */
1560 public final void addTerracotta(TerracottaConfiguration terracottaConfiguration) {
1561 this.terracottaConfiguration = terracottaConfiguration;
1562 validateConfiguration();
1563 }
1564
1565 /***
1566 * Allows BeanHandler to add the PinningConfiguration to the configuration.
1567 */
1568 public final void addPinning(PinningConfiguration pinningConfiguration) {
1569 this.pinningConfiguration = pinningConfiguration;
1570 validateConfiguration();
1571 }
1572
1573 /***
1574 * @return this configuration instance
1575 * @see #addPinning(PinningConfiguration)
1576 */
1577 public final CacheConfiguration pinning(PinningConfiguration pinningConfiguration) {
1578 addPinning(pinningConfiguration);
1579 return this;
1580 }
1581
1582 /***
1583 * @return this configuration instance
1584 * @see #addTerracotta(TerracottaConfiguration)
1585 */
1586 public final CacheConfiguration terracotta(TerracottaConfiguration terracottaConfiguration) {
1587 addTerracotta(terracottaConfiguration);
1588 return this;
1589 }
1590
1591 /***
1592 * @see #addSearchable(Searchable)
1593 * @param searchable
1594 * @return this
1595 */
1596 public final CacheConfiguration searchable(Searchable searchable) {
1597 addSearchable(searchable);
1598 return this;
1599 }
1600
1601 /***
1602 * Allows BeanHandler to add the CacheWriterConfiguration to the configuration.
1603 */
1604 public final void addCacheWriter(CacheWriterConfiguration cacheWriterConfiguration) {
1605 if (null == cacheWriterConfiguration) {
1606 this.cacheWriterConfiguration = new CacheWriterConfiguration();
1607 } else {
1608 this.cacheWriterConfiguration = cacheWriterConfiguration;
1609 }
1610 }
1611
1612 /***
1613 * @return this configuration instance
1614 * @see #addCacheWriter(CacheWriterConfiguration)
1615 */
1616 public final CacheConfiguration cacheWriter(CacheWriterConfiguration cacheWriterConfiguration) {
1617 addCacheWriter(cacheWriterConfiguration);
1618 return this;
1619 }
1620
1621 /***
1622 * Sets the transactionalMode
1623 *
1624 * @param transactionalMode one of OFF, LOCAL, XA, XA_STRICT
1625 */
1626 public final void setTransactionalMode(final String transactionalMode) {
1627 if (null == transactionalMode) {
1628 throw new IllegalArgumentException("TransactionalMode value must be non-null");
1629 }
1630 this.transactionalMode = TransactionalMode.valueOf(transactionalMode.toUpperCase());
1631 }
1632
1633 /***
1634 * Builder which sets the transactionalMode
1635 *
1636 * @param transactionalMode one of OFF, LOCAL, XA, XA_STRICT
1637 * @return this configuration instance
1638 * @see #setTransactionalMode(String)
1639 */
1640 public final CacheConfiguration transactionalMode(String transactionalMode) {
1641 setTransactionalMode(transactionalMode);
1642 return this;
1643 }
1644
1645 /***
1646 * Builder which sets the transactionalMode
1647 *
1648 * @param transactionalMode one of OFF, LOCAL, XA, XA_STRICT
1649 * @return this configuration instance
1650 * @see #setTransactionalMode(String)
1651 */
1652 public final CacheConfiguration transactionalMode(TransactionalMode transactionalMode) {
1653 if (null == transactionalMode) {
1654 throw new IllegalArgumentException("TransactionalMode value must be non-null");
1655 }
1656 this.transactionalMode = transactionalMode;
1657 return this;
1658 }
1659
1660 /***
1661 * Sets whether the cache's statistics are enabled. at startup
1662 */
1663 public final void setStatistics(boolean enabled) {
1664 this.statistics = enabled;
1665 }
1666
1667 /***
1668 * Builder which sets whether the cache's statistics are enabled.
1669 *
1670 * @return this configuration instance
1671 * @see #setStatistics(boolean)
1672 */
1673 public final CacheConfiguration statistics(boolean statistics) {
1674 setStatistics(statistics);
1675 return this;
1676 }
1677
1678 /***
1679 * Gets whether the cache's statistics will be enabled at startup
1680 */
1681 public final boolean getStatistics() {
1682 return statistics;
1683 }
1684
1685 /***
1686 * Used to validate what should be a complete Cache Configuration.
1687 */
1688 public void validateCompleteConfiguration() {
1689
1690 validateConfiguration();
1691
1692
1693
1694 if (name == null) {
1695 throw new InvalidConfigurationException("Caches must be named.");
1696 }
1697 }
1698
1699 /***
1700 * Used to validate a Cache Configuration.
1701 */
1702 public void validateConfiguration() {
1703 if (terracottaConfiguration != null && terracottaConfiguration.isClustered()) {
1704 if (overflowToDisk) {
1705 throw new InvalidConfigurationException("overflowToDisk isn't supported for a clustered Terracotta cache");
1706 }
1707 if (diskPersistent) {
1708 throw new InvalidConfigurationException("diskPersistent isn't supported for a clustered Terracotta cache");
1709 }
1710 if (cacheEventListenerConfigurations != null) {
1711 for (CacheEventListenerFactoryConfiguration listenerConfig : cacheEventListenerConfigurations) {
1712 if (null == listenerConfig.getFullyQualifiedClassPath()) {
1713 continue;
1714 }
1715 if (!listenerConfig.getFullyQualifiedClassPath().startsWith("net.sf.ehcache.") &&
1716 LOG.isWarnEnabled()) {
1717 LOG.warn("The non-standard CacheEventListenerFactory '" + listenerConfig.getFullyQualifiedClassPath() +
1718 "' is used with a clustered Terracotta cache, " +
1719 "if the purpose of this listener is replication it is not supported in a clustered context");
1720 }
1721 }
1722 }
1723 }
1724 }
1725
1726 private void validateTransactionalSettings() {
1727 boolean transactional = transactionalMode.isTransactional();
1728 if (copyOnRead == null) {
1729 if (terracottaConfiguration != null && terracottaConfiguration.isCopyOnReadSet()) {
1730 copyOnRead = terracottaConfiguration.isCopyOnRead();
1731 } else {
1732 copyOnRead = transactional;
1733 }
1734 }
1735 if (copyOnWrite == null) {
1736 copyOnWrite = transactional;
1737 }
1738
1739 if (transactional) {
1740 if (!copyOnRead || !copyOnWrite) {
1741 throw new InvalidConfigurationException("A transactional cache has to be copyOnRead and copyOnWrite!");
1742 }
1743 }
1744 }
1745
1746 /***
1747 * Accessor
1748 */
1749 public String getName() {
1750 return name;
1751 }
1752
1753 /***
1754 * Accessor
1755 *
1756 * @deprecated use {@link #getMaxEntriesLocalHeap()}
1757 */
1758 @Deprecated
1759 public int getMaxElementsInMemory() {
1760 return maxEntriesLocalHeap;
1761 }
1762
1763 /***
1764 * Accessor
1765 */
1766 public long getCacheLoaderTimeoutMillis() {
1767 return cacheLoaderTimeoutMillis;
1768 }
1769
1770 /***
1771 * Accessor
1772 *
1773 * @deprecated use {@link #getMaxEntriesLocalDisk()}
1774 */
1775 @Deprecated
1776 public int getMaxElementsOnDisk() {
1777 return maxElementsOnDisk;
1778 }
1779
1780 /***
1781 * Configured maximum number of entries for the local disk store.
1782 */
1783 public long getMaxEntriesLocalDisk() {
1784 return maxElementsOnDisk;
1785 }
1786
1787 /***
1788 * Configured maximum number of entries for the local memory heap.
1789 */
1790 public long getMaxEntriesLocalHeap() {
1791 return maxEntriesLocalHeap;
1792 }
1793
1794 /***
1795 * Accessor
1796 */
1797 public MemoryStoreEvictionPolicy getMemoryStoreEvictionPolicy() {
1798 return memoryStoreEvictionPolicy;
1799 }
1800
1801 /***
1802 * Accessor
1803 */
1804 public boolean isClearOnFlush() {
1805 return clearOnFlush;
1806 }
1807
1808 /***
1809 * Accessor
1810 */
1811 public boolean isEternal() {
1812 return eternal;
1813 }
1814
1815 /***
1816 * Accessor
1817 */
1818 public long getTimeToIdleSeconds() {
1819 return timeToIdleSeconds;
1820 }
1821
1822 /***
1823 * Accessor
1824 */
1825 public long getTimeToLiveSeconds() {
1826 return timeToLiveSeconds;
1827 }
1828
1829 /***
1830 * Accessor
1831 */
1832 public boolean isOverflowToDisk() {
1833 return overflowToDisk;
1834 }
1835
1836 /***
1837 * Accessor
1838 */
1839 public boolean isDiskPersistent() {
1840 return diskPersistent;
1841 }
1842
1843 /***
1844 * Accessor
1845 */
1846 public boolean isSearchable() {
1847 return searchable != null;
1848 }
1849
1850 /***
1851 * Accessor
1852 */
1853 public String getDiskStorePath() {
1854 return diskStorePath;
1855 }
1856
1857 /***
1858 * Accessor
1859 */
1860 public int getDiskSpoolBufferSizeMB() {
1861 return diskSpoolBufferSizeMB;
1862 }
1863
1864 /***
1865 * Accessor
1866 */
1867 public long getDiskExpiryThreadIntervalSeconds() {
1868 return diskExpiryThreadIntervalSeconds;
1869 }
1870
1871 /***
1872 * Accessor
1873 */
1874 public int getDiskAccessStripes() {
1875 return diskAccessStripes;
1876 }
1877
1878 /***
1879 * Only used when cache is clustered with Terracotta
1880 *
1881 * @return true if logging is enabled otherwise false
1882 */
1883 public boolean getLogging() {
1884 return logging;
1885 }
1886
1887 /***
1888 * Accessor
1889 *
1890 * @return true if offheap store is enabled, otherwise false.
1891 */
1892 public boolean isOverflowToOffHeap() {
1893 return overflowToOffHeap;
1894 }
1895
1896 /***
1897 * Accessor
1898 *
1899 * @return the max memory of the offheap store for this cache.
1900 */
1901 public String getMaxMemoryOffHeap() {
1902 return Long.toString(getMaxMemoryOffHeapInBytes());
1903 }
1904
1905 /***
1906 * Accessor
1907 *
1908 * @return the max memory of the offheap store for this cache, in bytes.
1909 * @see #getMaxMemoryOffHeap()
1910 */
1911 public long getMaxMemoryOffHeapInBytes() {
1912 return getMaxBytesLocalOffHeap();
1913 }
1914
1915 /***
1916 * Accessor
1917 */
1918 public List getCacheEventListenerConfigurations() {
1919 return cacheEventListenerConfigurations;
1920 }
1921
1922 /***
1923 * Accessor
1924 *
1925 * @return the configuration
1926 */
1927 public List getCacheExtensionConfigurations() {
1928 return cacheExtensionConfigurations;
1929 }
1930
1931 /***
1932 * Accessor
1933 *
1934 * @return the configuration
1935 */
1936 public List getCacheLoaderConfigurations() {
1937 return cacheLoaderConfigurations;
1938 }
1939
1940 /***
1941 * Accessor
1942 *
1943 * @return the configuration
1944 */
1945 public List<CacheDecoratorFactoryConfiguration> getCacheDecoratorConfigurations() {
1946 return cacheDecoratorConfigurations;
1947 }
1948
1949 /***
1950 * Accessor
1951 *
1952 * @return the configuration
1953 */
1954 public BootstrapCacheLoaderFactoryConfiguration getBootstrapCacheLoaderFactoryConfiguration() {
1955 return bootstrapCacheLoaderFactoryConfiguration;
1956 }
1957
1958 /***
1959 * Accessor
1960 *
1961 * @return the configuration
1962 */
1963 public CacheExceptionHandlerFactoryConfiguration getCacheExceptionHandlerFactoryConfiguration() {
1964 return cacheExceptionHandlerFactoryConfiguration;
1965 }
1966
1967 /***
1968 * Accessor
1969 *
1970 * @return the terracotta configuration
1971 */
1972 public TerracottaConfiguration getTerracottaConfiguration() {
1973 return terracottaConfiguration;
1974 }
1975
1976 /***
1977 * Accessor
1978 *
1979 * @return the pinning configuration
1980 */
1981 public PinningConfiguration getPinningConfiguration() {
1982 return pinningConfiguration;
1983 }
1984
1985 /***
1986 * Accessor
1987 *
1988 * @return the writer configuration
1989 */
1990 public CacheWriterConfiguration getCacheWriterConfiguration() {
1991 return cacheWriterConfiguration;
1992 }
1993
1994 /***
1995 * Helper method to compute whether the cache is clustered or not
1996 *
1997 * @return True if the <terracotta/> element exists with {@code clustered="true"}
1998 */
1999 public boolean isTerracottaClustered() {
2000 return terracottaConfiguration != null && terracottaConfiguration.isClustered();
2001 }
2002
2003 /***
2004 * Accessor
2005 *
2006 * @return the CoherenceMode if Terracotta-clustered or null
2007 */
2008 public Consistency getTerracottaConsistency() {
2009 return terracottaConfiguration != null ? terracottaConfiguration.getConsistency() : null;
2010 }
2011
2012 /***
2013 * Accessor
2014 *
2015 * @return the StorageStrategy if Terracotta-clustered or null
2016 */
2017 public StorageStrategy getTerracottaStorageStrategy() {
2018 return terracottaConfiguration != null ? terracottaConfiguration.getStorageStrategy() : null;
2019 }
2020
2021 /***
2022 * To what transactionalMode was the Cache set
2023 *
2024 * @return transactionaMode
2025 */
2026 public final TransactionalMode getTransactionalMode() {
2027 return transactionalMode;
2028 }
2029
2030 /***
2031 * Helper method to compute whether the cache is XA transactional or not
2032 *
2033 * @return true if transactionalMode="xa_strict"
2034 */
2035 public boolean isXaStrictTransactional() {
2036 validateTransactionalSettings();
2037 return transactionalMode.equals(TransactionalMode.XA_STRICT);
2038 }
2039
2040 /***
2041 * Helper method to compute whether the cache is local transactional or not
2042 *
2043 * @return true if transactionalMode="local"
2044 */
2045 public boolean isLocalTransactional() {
2046 validateTransactionalSettings();
2047 return transactionalMode.equals(TransactionalMode.LOCAL);
2048 }
2049
2050 /***
2051 * Helper method to compute whether the cache is local_jta transactional or not
2052 *
2053 * @return true if transactionalMode="xa"
2054 */
2055 public boolean isXaTransactional() {
2056 validateTransactionalSettings();
2057 return transactionalMode.equals(TransactionalMode.XA);
2058 }
2059
2060 /***
2061 * Represents whether the Cache is transactional or not.
2062 *
2063 * @author alexsnaps
2064 */
2065 public static enum TransactionalMode {
2066
2067 /***
2068 * No Transactions
2069 */
2070 OFF(false),
2071
2072 /***
2073 * Local Transactions
2074 */
2075 LOCAL(true),
2076
2077 /***
2078 * XA Transactions
2079 */
2080 XA(true),
2081
2082 /***
2083 * XA Strict (true 2PC) Transactions
2084 */
2085 XA_STRICT(true);
2086
2087 private final boolean transactional;
2088
2089 /***
2090 * @param transactional
2091 */
2092 TransactionalMode(final boolean transactional) {
2093 this.transactional = transactional;
2094 }
2095
2096 /***
2097 * @return transactional
2098 */
2099 public boolean isTransactional() {
2100 return transactional;
2101 }
2102 }
2103
2104 /***
2105 * Add a listener to this cache configuration
2106 *
2107 * @param listener listener instance to add
2108 * @return true if a listener was added
2109 */
2110 public boolean addConfigurationListener(CacheConfigurationListener listener) {
2111 boolean added = listeners.add(listener);
2112 if (added) {
2113 listener.registered(this);
2114 }
2115 return added;
2116 }
2117
2118 /***
2119 * Remove the supplied cache configuration listener.
2120 *
2121 * @param listener listener to remove
2122 * @return true if a listener was removed
2123 */
2124 public boolean removeConfigurationListener(CacheConfigurationListener listener) {
2125 boolean removed = listeners.remove(listener);
2126 if (removed) {
2127 listener.deregistered(this);
2128 }
2129 return removed;
2130 }
2131
2132 private void fireTtiChanged(long oldTti, long newTti) {
2133 if (oldTti != newTti) {
2134 for (CacheConfigurationListener l : listeners) {
2135 l.timeToIdleChanged(oldTti, newTti);
2136 }
2137 }
2138 }
2139
2140 private void fireTtlChanged(long oldTtl, long newTtl) {
2141 if (oldTtl != newTtl) {
2142 for (CacheConfigurationListener l : listeners) {
2143 l.timeToLiveChanged(oldTtl, newTtl);
2144 }
2145 }
2146 }
2147
2148 private void fireLoggingChanged(boolean oldValue, boolean newValue) {
2149 if (oldValue != newValue) {
2150 for (CacheConfigurationListener l : listeners) {
2151 l.loggingChanged(oldValue, newValue);
2152 }
2153 }
2154 }
2155
2156 private void fireDiskCapacityChanged(int oldCapacity, int newCapacity) {
2157 if (oldCapacity != newCapacity) {
2158 for (CacheConfigurationListener l : listeners) {
2159 l.diskCapacityChanged(oldCapacity, newCapacity);
2160 }
2161 }
2162 }
2163
2164 private void fireMemoryCapacityChanged(int oldCapacity, int newCapacity) {
2165 if (oldCapacity != newCapacity) {
2166 for (CacheConfigurationListener l : listeners) {
2167 l.memoryCapacityChanged(oldCapacity, newCapacity);
2168 }
2169 }
2170 }
2171
2172 private void checkDynamicChange() {
2173 if (frozen) {
2174 throw new CacheException("Dynamic configuration changes are disabled for this cache");
2175 }
2176 }
2177
2178 /***
2179 * Intended for internal use only, and subject to change.
2180 * This is required so that changes in store implementation's config
2181 * (probably from other nodes) can propagate up to here
2182 */
2183 public void internalSetTimeToIdle(long timeToIdle) {
2184 this.timeToIdleSeconds = timeToIdle;
2185 }
2186
2187 /***
2188 * Intended for internal use only, and subject to change.
2189 */
2190 public void internalSetTimeToLive(long timeToLive) {
2191 this.timeToLiveSeconds = timeToLive;
2192 }
2193
2194 /***
2195 * Intended for internal use only, and subject to change.
2196 */
2197 public void internalSetMemCapacity(int capacity) {
2198 this.maxEntriesLocalHeap = capacity;
2199 }
2200
2201 /***
2202 * Intended for internal use only, and subject to change.
2203 */
2204 public void internalSetDiskCapacity(int capacity) {
2205 this.maxElementsOnDisk = capacity;
2206 }
2207
2208 /***
2209 * Intended for internal use only, and subject to change.
2210 */
2211 public void internalSetLogging(boolean logging) {
2212 this.logging = logging;
2213 }
2214
2215 /***
2216 * Get the defined search attributes indexed by attribute name
2217 *
2218 * @return search attributes
2219 */
2220 public Map<String, SearchAttribute> getSearchAttributes() {
2221 if (searchable == null) {
2222 return Collections.EMPTY_MAP;
2223 }
2224 return searchable.getSearchAttributes();
2225 }
2226
2227 /***
2228 * Get the search configuration for this cache (if any)
2229 *
2230 * @return search config (may be null)
2231 */
2232 public Searchable getSearchable() {
2233 return searchable;
2234 }
2235 }