001package org.cache2k.configuration; 002 003/* 004 * #%L 005 * cache2k API 006 * %% 007 * Copyright (C) 2000 - 2016 headissue GmbH, Munich 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import org.cache2k.Cache2kBuilder; 024import org.cache2k.expiry.*; 025import org.cache2k.event.CacheEntryOperationListener; 026import org.cache2k.integration.AdvancedCacheLoader; 027import org.cache2k.integration.CacheLoader; 028import org.cache2k.integration.CacheWriter; 029import org.cache2k.integration.ExceptionPropagator; 030import org.cache2k.integration.ResiliencePolicy; 031 032import java.util.ArrayList; 033import java.util.Collections; 034import java.util.List; 035import java.util.concurrent.Executor; 036 037/** 038 * Configuration for a cache2k cache. 039 * 040 * <p>To create a cache, the {@link Cache2kBuilder} is used. All configuration properties 041 * are present on the builder and are documented in this place. Consequently all properties 042 * refer to the corresponding builder method. 043 * 044 * <p>The configuration bean is designed to be serializable. This is used for example to copy 045 * default configurations. The builder allows object references to customizations to be set. 046 * If this happens the configuration is not serializable. Such configuration is only used for 047 * immediate creation of one cache via the builder. 048 * 049 * <p>The configuration may contain additional beans, called configuration sections, that are 050 * used to configure extensions or sub modules. 051 * 052 * @author Jens Wilke 053 */ 054@SuppressWarnings("unused") 055public class Cache2kConfiguration<K, V> implements ConfigurationBean, ConfigurationWithSections { 056 057 public static final long EXPIRY_NOT_ETERNAL = Long.MAX_VALUE - 1; 058 059 private boolean storeByReference; 060 private String name; 061 private CacheType<K> keyType; 062 private CacheType<V> valueType; 063 private long entryCapacity = 2000; 064 private boolean strictEviction = false; 065 private boolean refreshAhead = false; 066 private long expireAfterWrite = -1; 067 private long retryInterval = -1; 068 private long maxRetryInterval = -1; 069 private long resilienceDuration = -1; 070 private boolean keepDataAfterExpired = false; 071 private boolean sharpExpiry = false; 072 private boolean suppressExceptions = true; 073 private int loaderThreadCount; 074 private boolean permitNullValues = false; 075 private boolean disableStatistics = false; 076 private int evictionSegmentCount = -1; 077 private boolean externalConfigurationPresent = false; 078 079 private CustomizationSupplier<Executor> loaderExecutor; 080 private CustomizationSupplier<Executor> prefetchExecutor; 081 private CustomizationSupplier<ExpiryPolicy<K,V>> expiryPolicy; 082 private CustomizationSupplier<ResiliencePolicy<K,V>> resiliencePolicy; 083 private CustomizationSupplier<CacheLoader<K,V>> loader; 084 private CustomizationSupplier<CacheWriter<K,V>> writer; 085 private CustomizationSupplier<AdvancedCacheLoader<K,V>> advancedLoader; 086 private CustomizationSupplier<ExceptionPropagator<K>> exceptionPropagator; 087 088 private CustomizationCollection<CacheEntryOperationListener<K,V>> listeners; 089 private CustomizationCollection<CacheEntryOperationListener<K,V>> asyncListeners; 090 091 private ConfigurationSectionContainer sections; 092 093 /** 094 * Construct a config instance setting the type parameters and returning a 095 * proper generic type. 096 * 097 * @see Cache2kBuilder#keyType(Class) 098 * @see Cache2kBuilder#valueType(Class) 099 */ 100 public static <K,V> Cache2kConfiguration<K, V> of(Class<K> keyType, Class<V> valueType) { 101 Cache2kConfiguration c = new Cache2kConfiguration(); 102 c.setKeyType(keyType); 103 c.setValueType(valueType); 104 return (Cache2kConfiguration<K, V>) c; 105 } 106 107 /** 108 * Construct a config instance setting the type parameters and returning a 109 * proper generic type. 110 * 111 * @see Cache2kBuilder#keyType(CacheType) 112 * @see Cache2kBuilder#valueType(CacheType) 113 */ 114 public static <K,V> Cache2kConfiguration<K, V> of(Class<K> keyType, CacheType<V> valueType) { 115 Cache2kConfiguration c = new Cache2kConfiguration(); 116 c.setKeyType(keyType); 117 c.setValueType(valueType); 118 return (Cache2kConfiguration<K, V>) c; 119 } 120 121 /** 122 * Construct a config instance setting the type parameters and returning a 123 * proper generic type. 124 * 125 * @see Cache2kBuilder#keyType(Class) 126 * @see Cache2kBuilder#valueType(Class) 127 */ 128 public static <K,V> Cache2kConfiguration<K, V> of(CacheType<K> keyType, Class<V> valueType) { 129 Cache2kConfiguration c = new Cache2kConfiguration(); 130 c.setKeyType(keyType); 131 c.setValueType(valueType); 132 return (Cache2kConfiguration<K, V>) c; 133 } 134 135 /** 136 * Construct a config instance setting the type parameters and returning a 137 * proper generic type. 138 * 139 * @see Cache2kBuilder#keyType(CacheType) 140 * @see Cache2kBuilder#valueType(CacheType) 141 */ 142 public static <K,V> Cache2kConfiguration<K, V> of(CacheType<K> keyType, CacheType<V> valueType) { 143 Cache2kConfiguration c = new Cache2kConfiguration(); 144 c.setKeyType(keyType); 145 c.setValueType(valueType); 146 return (Cache2kConfiguration<K, V>) c; 147 } 148 149 /** 150 * @see Cache2kBuilder#name(String) 151 */ 152 public String getName() { 153 return name; 154 } 155 156 /** 157 * 158 * @see Cache2kBuilder#name(String) 159 */ 160 public void setName(String name) { 161 this.name = name; 162 } 163 164 /** 165 * 166 * @see Cache2kBuilder#entryCapacity 167 */ 168 public long getEntryCapacity() { 169 return entryCapacity; 170 } 171 172 public void setEntryCapacity(long v) { 173 this.entryCapacity = v; 174 } 175 176 /** 177 * @see Cache2kBuilder#refreshAhead(boolean) 178 */ 179 public boolean isRefreshAhead() { 180 return refreshAhead; 181 } 182 183 /** 184 * @see Cache2kBuilder#refreshAhead(boolean) 185 */ 186 public void setRefreshAhead(boolean v) { 187 this.refreshAhead = v; 188 } 189 190 /** 191 * @deprecated use {@link #isRefreshAhead()} 192 * 193 * @see Cache2kBuilder#refreshAhead(boolean) 194 */ 195 public boolean isBackgroundRefresh() { 196 return refreshAhead; 197 } 198 199 /** 200 * @deprecated use {@link #setRefreshAhead(boolean)} 201 * 202 * @see Cache2kBuilder#refreshAhead(boolean) 203 */ 204 public void setBackgroundRefresh(boolean v) { 205 refreshAhead = v; 206 } 207 208 public CacheType<K> getKeyType() { 209 return keyType; 210 } 211 212 private void checkNull(Object v) { 213 if (v == null) { 214 throw new NullPointerException("null value not allowed"); 215 } 216 } 217 218 /** 219 * @see Cache2kBuilder#keyType(Class) 220 * @see CacheType for a general discussion on types 221 */ 222 public void setKeyType(Class<?> v) { 223 checkNull(v); 224 setKeyType(CacheTypeCapture.of(v)); 225 } 226 227 /** 228 * @see Cache2kBuilder#keyType(CacheType) 229 * @see CacheType for a general discussion on types 230 */ 231 public void setKeyType(CacheType v) { 232 checkNull(v); 233 if (v.isArray()) { 234 throw new IllegalArgumentException("Arrays are not supported for keys"); 235 } 236 keyType = v.getBeanRepresentation(); 237 } 238 239 public CacheType<V> getValueType() { 240 return valueType; 241 } 242 243 /** 244 * @see Cache2kBuilder#valueType(Class) 245 * @see CacheType for a general discussion on types 246 */ 247 public void setValueType(Class<?> v) { 248 checkNull(v); 249 setValueType(CacheTypeCapture.of(v)); 250 } 251 252 /** 253 * @see Cache2kBuilder#valueType(CacheType) 254 * @see CacheType for a general discussion on types 255 */ 256 public void setValueType(CacheType v) { 257 checkNull(v); 258 if (v.isArray()) { 259 throw new IllegalArgumentException("Arrays are not supported for values"); 260 } 261 valueType = v.getBeanRepresentation(); 262 } 263 264 public boolean isEternal() { 265 return expireAfterWrite == -1 || expireAfterWrite == ExpiryTimeValues.ETERNAL; 266 } 267 268 /** 269 * @see Cache2kBuilder#eternal(boolean) 270 */ 271 public void setEternal(boolean v) { 272 if (v) { 273 setExpireAfterWrite(ExpiryTimeValues.ETERNAL); 274 } else { 275 setExpireAfterWrite(EXPIRY_NOT_ETERNAL); 276 } 277 } 278 279 /** 280 * @deprecated use {@link #setExpireAfterWrite} 281 */ 282 public void setExpirySeconds(int v) { 283 if (v == -1 || v == Integer.MAX_VALUE) { 284 expireAfterWrite = -1; 285 } 286 expireAfterWrite = v * 1000L; 287 } 288 289 /** 290 * @deprecated use {@link #getExpireAfterWrite} 291 */ 292 public int getExpirySeconds() { 293 if (isEternal()) { 294 return -1; 295 } 296 return (int) (expireAfterWrite / 1000); 297 } 298 299 public long getExpireAfterWrite() { 300 return expireAfterWrite; 301 } 302 303 /** 304 * @see Cache2kBuilder#expireAfterWrite 305 */ 306 public void setExpireAfterWrite(long millis) { 307 if (millis == expireAfterWrite) { 308 return; 309 } 310 if (expireAfterWrite != -1) { 311 if (millis == Expiry.ETERNAL) { 312 throw new IllegalArgumentException("not eternal or expiry was set, refusing to reset back to eternal"); 313 } 314 if (expireAfterWrite == Expiry.ETERNAL) { 315 throw new IllegalArgumentException("eternal was set, refusing to reset to expire time span"); 316 } 317 } 318 this.expireAfterWrite = millis; 319 } 320 321 /** 322 * @see Cache2kBuilder#retryInterval 323 */ 324 public long getRetryInterval() { 325 return retryInterval; 326 } 327 328 /** 329 * @see Cache2kBuilder#retryInterval 330 */ 331 public void setRetryInterval(long millis) { 332 retryInterval = millis; 333 } 334 335 /** 336 * @see Cache2kBuilder#maxRetryInterval 337 */ 338 public long getMaxRetryInterval() { 339 return maxRetryInterval; 340 } 341 342 /** 343 * @see Cache2kBuilder#maxRetryInterval 344 */ 345 public void setMaxRetryInterval(long millis) { 346 maxRetryInterval = millis; 347 } 348 349 /** 350 * @see Cache2kBuilder#resilienceDuration 351 */ 352 public long getResilienceDuration() { 353 return resilienceDuration; 354 } 355 356 /** 357 * @see Cache2kBuilder#resilienceDuration 358 */ 359 public void setResilienceDuration(long millis) { 360 resilienceDuration = millis; 361 } 362 363 public boolean isKeepDataAfterExpired() { 364 return keepDataAfterExpired; 365 } 366 367 /** 368 * @see Cache2kBuilder#keepDataAfterExpired(boolean) 369 */ 370 public void setKeepDataAfterExpired(boolean v) { 371 this.keepDataAfterExpired = v; 372 } 373 374 public boolean isSharpExpiry() { 375 return sharpExpiry; 376 } 377 378 /** 379 * @see Cache2kBuilder#sharpExpiry(boolean) 380 */ 381 public void setSharpExpiry(boolean v) { 382 this.sharpExpiry = v; 383 } 384 385 public boolean isSuppressExceptions() { 386 return suppressExceptions; 387 } 388 389 /** 390 * @see Cache2kBuilder#suppressExceptions(boolean) 391 */ 392 public void setSuppressExceptions(boolean v) { 393 this.suppressExceptions = v; 394 } 395 396 public boolean isExternalConfigurationPresent() { 397 return externalConfigurationPresent; 398 } 399 400 /** 401 * True, if an external configuration for the cache was found and is applied. 402 */ 403 public void setExternalConfigurationPresent(final boolean v) { 404 externalConfigurationPresent = v; 405 } 406 407 /** 408 * Mutable collection of additional configuration sections 409 */ 410 public ConfigurationSectionContainer getSections() { 411 if (sections == null) { 412 sections = new ConfigurationSectionContainer(); 413 } 414 return sections; 415 } 416 417 public CustomizationSupplier<CacheLoader<K,V>> getLoader() { 418 return loader; 419 } 420 421 public void setLoader(final CustomizationSupplier<CacheLoader<K,V>> v) { 422 loader = v; 423 } 424 425 public CustomizationSupplier<AdvancedCacheLoader<K, V>> getAdvancedLoader() { 426 return advancedLoader; 427 } 428 429 public void setAdvancedLoader(final CustomizationSupplier<AdvancedCacheLoader<K, V>> v) { 430 advancedLoader = v; 431 } 432 433 public int getLoaderThreadCount() { 434 return loaderThreadCount; 435 } 436 437 /** 438 * @see Cache2kBuilder#loaderThreadCount(int) 439 */ 440 public void setLoaderThreadCount(final int v) { 441 loaderThreadCount = v; 442 } 443 444 public CustomizationSupplier<ExpiryPolicy<K, V>> getExpiryPolicy() { 445 return expiryPolicy; 446 } 447 448 public void setExpiryPolicy(final CustomizationSupplier<ExpiryPolicy<K, V>> _expiryPolicy) { 449 expiryPolicy = _expiryPolicy; 450 } 451 452 public CustomizationSupplier<CacheWriter<K, V>> getWriter() { 453 return writer; 454 } 455 456 /** 457 * @see Cache2kBuilder#writer(CacheWriter) 458 */ 459 public void setWriter(final CustomizationSupplier<CacheWriter<K, V>> v) { 460 writer = v; 461 } 462 463 public boolean isStoreByReference() { 464 return storeByReference; 465 } 466 467 /** 468 * @see Cache2kBuilder#storeByReference(boolean) 469 */ 470 public void setStoreByReference(final boolean v) { 471 storeByReference = v; 472 } 473 474 public CustomizationSupplier<ExceptionPropagator<K>> getExceptionPropagator() { 475 return exceptionPropagator; 476 } 477 478 /** 479 * @see Cache2kBuilder#exceptionPropagator(ExceptionPropagator) 480 */ 481 public void setExceptionPropagator(final CustomizationSupplier<ExceptionPropagator<K>> v) { 482 exceptionPropagator = v; 483 } 484 485 /** 486 * A set of listeners. Listeners added in this collection will be 487 * executed in a synchronous mode, meaning, further processing for 488 * an entry will stall until a registered listener is executed. 489 * The expiry will be always executed asynchronously. 490 * 491 * <p>A listener can be added by adding it to the collection. 492 * Duplicate (in terms of equal objects) listeners will be ignored. 493 * 494 * @return Mutable collection of listeners 495 */ 496 public CustomizationCollection<CacheEntryOperationListener<K,V>> getListeners() { 497 if (listeners == null) { 498 listeners = new DefaultCustomizationCollection<CacheEntryOperationListener<K, V>>(); 499 } 500 return listeners; 501 } 502 503 /** 504 * @return True if listeners are added to this configuration. 505 */ 506 public boolean hasListeners() { 507 return listeners != null && !listeners.isEmpty(); 508 } 509 510 /** 511 * A set of listeners. A listener can be added by adding it to the collection. 512 * Duplicate (in terms of equal objects) listeners will be ignored. 513 * 514 * @return Mutable collection of listeners 515 */ 516 public CustomizationCollection<CacheEntryOperationListener<K,V>> getAsyncListeners() { 517 if (asyncListeners == null) { 518 asyncListeners = new DefaultCustomizationCollection<CacheEntryOperationListener<K, V>>(); 519 } 520 return asyncListeners; 521 } 522 523 /** 524 * @return True if listeners are added to this configuration. 525 */ 526 public boolean hasAsyncListeners() { 527 return asyncListeners != null && !asyncListeners.isEmpty(); 528 } 529 530 public CustomizationSupplier<ResiliencePolicy<K, V>> getResiliencePolicy() { 531 return resiliencePolicy; 532 } 533 534 /** 535 * @see Cache2kBuilder#resiliencePolicy 536 */ 537 public void setResiliencePolicy(final CustomizationSupplier<ResiliencePolicy<K, V>> _resiliencePolicy) { 538 resiliencePolicy = _resiliencePolicy; 539 } 540 541 public boolean isStrictEviction() { 542 return strictEviction; 543 } 544 545 /** 546 * @see Cache2kBuilder#strictEviction(boolean) 547 */ 548 public void setStrictEviction(final boolean v) { 549 strictEviction = v; 550 } 551 552 public boolean isPermitNullValues() { 553 return permitNullValues; 554 } 555 556 /** 557 * @see Cache2kBuilder#permitNullValues(boolean) 558 */ 559 public void setPermitNullValues(final boolean v) { 560 permitNullValues = v; 561 } 562 563 public boolean isDisableStatistics() { 564 return disableStatistics; 565 } 566 567 /** 568 * @see Cache2kBuilder#disableStatistics 569 */ 570 public void setDisableStatistics(final boolean v) { 571 disableStatistics = v; 572 } 573 574 public int getEvictionSegmentCount() { 575 return evictionSegmentCount; 576 } 577 578 /** 579 * 580 * @see Cache2kBuilder#evictionSegmentCount(int) 581 */ 582 public void setEvictionSegmentCount(final int v) { 583 evictionSegmentCount = v; 584 } 585 586 public CustomizationSupplier<Executor> getLoaderExecutor() { 587 return loaderExecutor; 588 } 589 590 /** 591 * @see Cache2kBuilder#loaderExecutor(Executor) 592 */ 593 public void setLoaderExecutor(final CustomizationSupplier<Executor> v) { 594 loaderExecutor = v; 595 } 596 597 public CustomizationSupplier<Executor> getPrefetchExecutor() { 598 return prefetchExecutor; 599 } 600 601 /** 602 * @see Cache2kBuilder#prefetchExecutor(Executor) 603 */ 604 public void setPrefetchExecutor(final CustomizationSupplier<Executor> v) { 605 prefetchExecutor = v; 606 } 607 608 609}