com.gitee.qdbp.staticize.task.TemplateCache Maven / Gradle / Ivy
package com.gitee.qdbp.staticize.task;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitee.qdbp.staticize.common.IMetaData;
import com.gitee.qdbp.staticize.exception.TagException;
import com.gitee.qdbp.staticize.exception.TemplateException;
import com.gitee.qdbp.staticize.io.IReaderCreator;
import com.gitee.qdbp.staticize.parse.TagParser;
import com.gitee.qdbp.staticize.tags.base.Taglib;
/**
* 模板缓存
*
* @author zhaohuihua
* @version 140722
*/
class TemplateCache {
/** 日志对象 **/
private static final Logger log = LoggerFactory.getLogger(TemplateCache.class);
/** 解析次数, 失败次数超过该配置则不再解析 **/
private static final int TIMES = 3;
/** 模板缓存 **/
private final Map cache;
/** 模板更新时间 **/
private final Map time;
/** 失败次数 **/
private final Map fail;
private final Taglib taglib;
private final IReaderCreator input;
/** 私有构造函数 **/
protected TemplateCache(Taglib taglib, IReaderCreator input) {
this.cache = new HashMap();
this.time = new HashMap();
this.fail = new HashMap();
this.taglib = taglib;
this.input = input;
}
/**
* 获取模板标签元数据, 如果缓存中存在从缓存中获取, 否则解析模板
*
* @author zhaohuihua
* @param path 模板相对路径
* @return 模板标签元数据
* @throws TemplateException 模板不存在, 模板读取失败, 模板不可用(多次解析失败)
* @throws TagException 模板解析失败
*/
public IMetaData get(String path) throws TemplateException, TagException {
// 只有相同的模板才进入线程等待
synchronized (path.intern()) {
// 获取更新时间
Date update = null;
try {
update = input.getUpdateTime(path);
} catch (IOException e) {
log.warn("获取更新时间失败", e);
}
// 缓存中有, 且更新时间一致, 直接返回缓存中的数据
Long millisecond = update == null ? null : update.getTime();
if (cache.containsKey(path) && equals(millisecond, time.get(path))) {
return cache.get(path);
}
// 如果模板解析失败次数超过3次, 不再解析, 直接返回异常
Integer times = fail.get(path);
if (times != null && times >= TIMES) {
fail.put(path, times + 1);
throw new TemplateException("模板不可用, 多次解析失败: " + path);
}
IMetaData data;
try {
// 解析模板
data = new TagParser(taglib, input).parse(path);
} catch (TagException | TemplateException e) {
// 记录模板解析失败次数
fail.put(path, times == null ? 1 : times + 1);
throw e;
}
// 缓存模板解析生成的元数据
cache.put(path, data);
time.put(path, millisecond);
log.info("模板解析成功: " + path);
return data;
}
}
private boolean equals(Long one, Long two) {
if (one == two) {
return true;
} else if (one == null || two == null) {
return false;
} else {
return one.equals(two);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy