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