/*
* =============================================================================
*
* Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* =============================================================================
*/
package org.thymeleaf.cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.engine.TemplateModel;
/**
* <p>
* Standard implementation of {@link ICacheManager}, returning
* configurable instances of {@link StandardCache} for each of
* the default caches defined at the cache manager interface.
* </p>
* <p>
* Each cache allows the configuration of the following parameters:
* </p>
* <ul>
* <li>Its <i>name</i> (will be displayed in logs).</li>
* <li>Its <i>initial size</i>: the size the cache will be initialized with.</li>
* <li>Its <i>maximum size</i>: the maximum size the cache will be allowed to reach.
* Some special values:
* <ul>
* <li><tt>-1</tt> means no limit in size.</li>
* <li><tt>0</tt> means this cache will not be used at
* all (<tt>getXCache()</tt> will return <tt>null</tt>).</li>
* </ul>
* </li>
* <li>Whether the cache should use <i>soft references</i> or not
* (<tt>java.lang.ref.SoftReference</tt>). Using Soft References
* allows the cache to be <i>memory-sensitive</i>, allowing the garbage collector
* to dispose cache entries if memory is critical, before raising an
* <tt>OutOfMemoryError</tt>.</li>
* <li>The <i>name of the logger</i> that will output trace information for the
* cache object. Configuring this allows a finer-grained log configuration that
* allows the more effective inspection of cache behaviour. If not specifically
* set, <tt>org.thymeleaf.TemplateEngine.cache.${cacheName}</tt> will be used.</li>
* <li>An (optional) <i>validity checker</i> implementing {@link ICacheEntryValidityChecker},
* which will be applied on each entry upon retrieval from cache in order to ensure
* it is still valid and can be used.
* </ul>
* <p>
* Note a class with this name existed since 2.0.0, but it was completely reimplemented
* in Thymeleaf 3.0
* </p>
*
* @author Daniel Fernández
*
* @since 3.0.0
*
*/
public class StandardCacheManager extends AbstractCacheManager {
/**
* Default template cache name: {@value}
*/
public static final String DEFAULT_TEMPLATE_CACHE_NAME = "TEMPLATE_CACHE";
/**
* Default template cache initial size: {@value}
*/
public static final int DEFAULT_TEMPLATE_CACHE_INITIAL_SIZE = 20;
/**
* Default template cache maximum size: {@value}
*/
public static final int DEFAULT_TEMPLATE_CACHE_MAX_SIZE = 200;
/**
* Default template cache "enable counters" flag: {@value}
*/
public static final boolean DEFAULT_TEMPLATE_CACHE_ENABLE_COUNTERS = false;
/**
* Default template cache "use soft references" flag: {@value}
*/
public static final boolean DEFAULT_TEMPLATE_CACHE_USE_SOFT_REFERENCES = true;
/**
* Default template cache logger name: null (default behaviour = org.thymeleaf.TemplateEngine.cache.TEMPLATE_CACHE)
*/
public static final String DEFAULT_TEMPLATE_CACHE_LOGGER_NAME = null;
/**
* Default template cache validity checker: an instance of {@link StandardParsedTemplateEntryValidator}.
*/
public static final ICacheEntryValidityChecker<TemplateCacheKey,TemplateModel> DEFAULT_TEMPLATE_CACHE_VALIDITY_CHECKER = new StandardParsedTemplateEntryValidator();
/**
* Default expression cache name: {@value}
*/
public static final String DEFAULT_EXPRESSION_CACHE_NAME = "EXPRESSION_CACHE";
/**
* Default expression cache initial size: {@value}
*/
public static final int DEFAULT_EXPRESSION_CACHE_INITIAL_SIZE = 100;
/**
* Default expression cache maximum size: {@value}
*/
public static final int DEFAULT_EXPRESSION_CACHE_MAX_SIZE = 500;
/**
* Default expression cache "enable counters" flag: {@value}
*/
public static final boolean DEFAULT_EXPRESSION_CACHE_ENABLE_COUNTERS = false;
/**
* Default expression cache "use soft references" flag: {@value}
*/
public static final boolean DEFAULT_EXPRESSION_CACHE_USE_SOFT_REFERENCES = true;
/**
* Default expression cache logger name: null (default behaviour = org.thymeleaf.TemplateEngine.cache.EXPRESSION_CACHE)
*/
public static final String DEFAULT_EXPRESSION_CACHE_LOGGER_NAME = null;
/**
* Default expression cache validity checker: null
*/
public static final ICacheEntryValidityChecker<ExpressionCacheKey,Object> DEFAULT_EXPRESSION_CACHE_VALIDITY_CHECKER = null;
private String templateCacheName = DEFAULT_TEMPLATE_CACHE_NAME;
private int templateCacheInitialSize = DEFAULT_TEMPLATE_CACHE_INITIAL_SIZE;
private int templateCacheMaxSize = DEFAULT_TEMPLATE_CACHE_MAX_SIZE;
private boolean templateCacheEnableCounters = DEFAULT_TEMPLATE_CACHE_ENABLE_COUNTERS;
private boolean templateCacheUseSoftReferences = DEFAULT_TEMPLATE_CACHE_USE_SOFT_REFERENCES;
private String templateCacheLoggerName = DEFAULT_TEMPLATE_CACHE_LOGGER_NAME;
private ICacheEntryValidityChecker<TemplateCacheKey,TemplateModel> templateCacheValidityChecker = DEFAULT_TEMPLATE_CACHE_VALIDITY_CHECKER;
private String expressionCacheName = DEFAULT_EXPRESSION_CACHE_NAME;
private int expressionCacheInitialSize = DEFAULT_EXPRESSION_CACHE_INITIAL_SIZE;
private int expressionCacheMaxSize = DEFAULT_EXPRESSION_CACHE_MAX_SIZE;
private boolean expressionCacheEnableCounters = DEFAULT_EXPRESSION_CACHE_ENABLE_COUNTERS;
private boolean expressionCacheUseSoftReferences = DEFAULT_EXPRESSION_CACHE_USE_SOFT_REFERENCES;
private String expressionCacheLoggerName = DEFAULT_EXPRESSION_CACHE_LOGGER_NAME;
private ICacheEntryValidityChecker<ExpressionCacheKey,Object> expressionCacheValidityChecker = DEFAULT_EXPRESSION_CACHE_VALIDITY_CHECKER;
public StandardCacheManager() {
super();
}
@Override
protected final ICache<TemplateCacheKey, TemplateModel> initializeTemplateCache() {
final int maxSize = getTemplateCacheMaxSize();
if (maxSize == 0) {
return null;
}
return new StandardCache<TemplateCacheKey, TemplateModel>(
getTemplateCacheName(), getTemplateCacheUseSoftReferences(),
getTemplateCacheInitialSize(), maxSize,
getTemplateCacheValidityChecker(), getTemplateCacheLogger(), getTemplateCacheEnableCounters());
}
@Override
protected final ICache<ExpressionCacheKey, Object> initializeExpressionCache() {
final int maxSize = getExpressionCacheMaxSize();
if (maxSize == 0) {
return null;
}
return new StandardCache<ExpressionCacheKey, Object>(
getExpressionCacheName(), getExpressionCacheUseSoftReferences(),
getExpressionCacheInitialSize(), maxSize,
getExpressionCacheValidityChecker(), getExpressionCacheLogger(), getExpressionCacheEnableCounters());
}
public String getTemplateCacheName() {
return this.templateCacheName;
}
public boolean getTemplateCacheUseSoftReferences() {
return this.templateCacheUseSoftReferences;
}
private boolean getTemplateCacheEnableCounters() {
return this.templateCacheEnableCounters;
}
public int getTemplateCacheInitialSize() {
return this.templateCacheInitialSize;
}
public int getTemplateCacheMaxSize() {
return this.templateCacheMaxSize;
}
public String getTemplateCacheLoggerName() {
return this.templateCacheLoggerName;
}
public ICacheEntryValidityChecker<TemplateCacheKey,TemplateModel> getTemplateCacheValidityChecker() {
return this.templateCacheValidityChecker;
}
public final Logger getTemplateCacheLogger() {
final String loggerName = getTemplateCacheLoggerName();
if (loggerName != null) {
return LoggerFactory.getLogger(loggerName);
}
return LoggerFactory.getLogger(TemplateEngine.class.getName() + ".cache." + getTemplateCacheName());
}
public String getExpressionCacheName() {
return this.expressionCacheName;
}
public boolean getExpressionCacheUseSoftReferences() {
return this.expressionCacheUseSoftReferences;
}
private boolean getExpressionCacheEnableCounters() {
return this.expressionCacheEnableCounters;
}
public int getExpressionCacheInitialSize() {
return this.expressionCacheInitialSize;
}
public int getExpressionCacheMaxSize() {
return this.expressionCacheMaxSize;
}
public String getExpressionCacheLoggerName() {
return this.expressionCacheLoggerName;
}
public ICacheEntryValidityChecker<ExpressionCacheKey,Object> getExpressionCacheValidityChecker() {
return this.expressionCacheValidityChecker;
}
public final Logger getExpressionCacheLogger() {
final String loggerName = getExpressionCacheLoggerName();
if (loggerName != null) {
return LoggerFactory.getLogger(loggerName);
}
return LoggerFactory.getLogger(TemplateEngine.class.getName() + ".cache." + getExpressionCacheName());
}
public void setTemplateCacheName(final String templateCacheName) {
this.templateCacheName = templateCacheName;
}
public void setTemplateCacheInitialSize(final int templateCacheInitialSize) {
this.templateCacheInitialSize = templateCacheInitialSize;
}
public void setTemplateCacheMaxSize(final int templateCacheMaxSize) {
this.templateCacheMaxSize = templateCacheMaxSize;
}
public void setTemplateCacheUseSoftReferences(final boolean templateCacheUseSoftReferences) {
this.templateCacheUseSoftReferences = templateCacheUseSoftReferences;
}
public void setTemplateCacheLoggerName(final String templateCacheLoggerName) {
this.templateCacheLoggerName = templateCacheLoggerName;
}
public void setTemplateCacheValidityChecker(final ICacheEntryValidityChecker<TemplateCacheKey, TemplateModel> templateCacheValidityChecker) {
this.templateCacheValidityChecker = templateCacheValidityChecker;
}
public void setTemplateCacheEnableCounters(boolean templateCacheEnableCounters) {
this.templateCacheEnableCounters = templateCacheEnableCounters;
}
public void setExpressionCacheName(final String expressionCacheName) {
this.expressionCacheName = expressionCacheName;
}
public void setExpressionCacheInitialSize(final int expressionCacheInitialSize) {
this.expressionCacheInitialSize = expressionCacheInitialSize;
}
public void setExpressionCacheMaxSize(final int expressionCacheMaxSize) {
this.expressionCacheMaxSize = expressionCacheMaxSize;
}
public void setExpressionCacheUseSoftReferences(final boolean expressionCacheUseSoftReferences) {
this.expressionCacheUseSoftReferences = expressionCacheUseSoftReferences;
}
public void setExpressionCacheLoggerName(final String expressionCacheLoggerName) {
this.expressionCacheLoggerName = expressionCacheLoggerName;
}
public void setExpressionCacheValidityChecker(final ICacheEntryValidityChecker<ExpressionCacheKey, Object> expressionCacheValidityChecker) {
this.expressionCacheValidityChecker = expressionCacheValidityChecker;
}
public void setExpressionCacheEnableCounters(boolean expressionCacheEnableCounters) {
this.expressionCacheEnableCounters = expressionCacheEnableCounters;
}
}