All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gitee.qdbp.staticize.task.TemplateCache Maven / Gradle / Ivy

There is a newer version: 3.5.18
Show newest version
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