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}