Freemark的模板文件从缓存加载(该实现使用的缓存服务器Memcached)
该加载器分为以下几个部分:
1.主加载器FreemarkerCacheTemplateLoader(实现了freemarker.cache.TemplateLoader)
2.缓存组件CacheComponent(该实现为Memcached,如需要实现附上留言)
3.缓存实体类封装CacheEntity(用于缓存实体存取)
4.自定义异常CacheException
5.配置文件TemplateConfigure.properties(模板加载器配置),JNDI_Configure.properties(缓存组件配置)
实现自定义模板加载器需要实现TemplateLoader以下方法
1.void closeTemplateSource(Object arg0) throws IOException //模板使用完关闭方法
2.long getLastModified(Object templateSource) //模板最后修改时间
3.Object findTemplateSource(String name) throws IOException //模板查找
4.Reader getReader(final Object templateSource, final String encoding) throws IOException //模板内容
以下为个类实现:
/*
* FreemarkerCacheTemplateLoader.java
* Copyright (C) 2009 <JustinLei@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
package org.lambdasoft.components.template.ejb;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Locale;
import org.lambdasoft.components.cache.CacheComponent;
import org.lambdasoft.components.cache.CacheEntity;
import org.lambdasoft.exception.CacheException;
import freemarker.cache.TemplateLoader;
/**
* Freemark Memcached模板加载器
*
* @author lei.tang (justinlei@gmail.com)
* @date
* @version
*/
public class FreemarkerCacheTemplateLoader implements TemplateLoader{
private CacheComponent cacheComponent;
public static String DEFAULT_CACHE_KEY_PREFIX = "CACHE.TEMPLATE.";
public static String TEMPLATE_PREFIX = ".ftl";
private String templatePath;
public FreemarkerCacheTemplateLoader(CacheComponent cacheComponent,String templatePath) throws Exception {
synchronized (FreemarkerCacheTemplateLoader.class) {
this.templatePath = templatePath;
this.cacheComponent = cacheComponent;
_addTemplateToCacheServer();
}
}
//内部类缓存实体
private static final class _cacheEntity implements CacheEntity{
private static final long serialVersionUID = 1L;
private String key;
private String entity;
public _cacheEntity(String key,String entity) {
this.key = key;
this.entity = entity;
}
public void setKey(String key) {
}
public void setEntity(Object obj) {
}
public String getKey() {
return key.toUpperCase();
}
public Object getEntity() {
return entity;
}
public void check() throws CacheException {}
}
private void _addTemplateToCacheServer() throws Exception {
File file = new File(templatePath);
if(file.isDirectory()) {
File[] templateFiles = file.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
if(name.endsWith(TEMPLATE_PREFIX))
return true;
return false;
}
});
String locale = "_" + Locale.getDefault();
for (File templateFile : templateFiles) {
final String key = DEFAULT_CACHE_KEY_PREFIX + templateFile.getName().substring(0,
templateFile.getName().length()- TEMPLATE_PREFIX.length()) + locale;
BufferedReader bufferedReader = new BufferedReader(new FileReader(templateFile));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
while((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
final String entity = stringBuilder.toString();
cacheComponent.add(new _cacheEntity(key.toUpperCase(),entity));
}
}
}
public void closeTemplateSource(Object arg0) throws IOException {}
public long getLastModified(Object templateSource) {
//没有最后修改标识只返回为0
return 0;
}
public Object findTemplateSource(String name) throws IOException {
CacheEntity cacheEntity = cacheComponent.get(DEFAULT_CACHE_KEY_PREFIX + name.toUpperCase());
return cacheEntity.getEntity();
}
public Reader getReader(final Object templateSource, final String encoding) throws IOException {
return new StringReader((String)templateSource);
}
public void setCacheComponent(CacheComponent cacheComponent) {
this.cacheComponent = cacheComponent;
}
public CacheComponent getCacheComponent() {
return cacheComponent;
}
}
/*
* CacheEntity.java
* Copyright (C) 2009 <JustinLei@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
package org.lambdasoft.components.cache;
import java.io.Serializable;
import org.lambdasoft.exception.CacheException;
/**
*
* @author lei.tang (justinlei@gmail.com)
* @date 2009-8-15
* @version 1.0
*/
public interface CacheEntity extends Serializable{
/**
* 获取缓存key
* @return
*/
String getKey();
/**
* 设置缓存key
*/
void setKey(String key);
/**
* 获取缓存对象
* @return
*/
Object getEntity();
/**
* 设置缓存对象
* @param obj
*/
void setEntity(Object obj);
/**
* 缓存对象检查
* @throws CacheException
*/
void check() throws CacheException;
}
/*
* CacheException.java
* Copyright (C) 2009 <JustinLei@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
package org.lambdasoft.exception;
/**
*
* @author lei.tang (justinlei@gmail.com)
* @date 2009-9-11
* @version 1.0
*/
public class CacheException extends BusinessException{
private static final long serialVersionUID = 1L;
public CacheException(String msg) {
super("缓存错误: " + msg);
}
}
TemplateConfigure.properties:
TEMPLATE.DIR.ROOT=E:/workspace/templates
TEMPLATE.CACHE=true
TEMPLATE.CACHE.PREFIX=CACHE.TEMPLATE