com.jfinal.template.EngineConfig Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of enjoy Show documentation
Show all versions of enjoy Show documentation
Enjoy is a simple, light, rapid, independent, extensible Java Template Engine.
/**
* Copyright (c) 2011-2019, James Zhan 詹波 ([email protected]).
*
* 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 com.jfinal.template;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.jfinal.kit.StrKit;
import com.jfinal.template.expr.ast.ExprList;
import com.jfinal.template.expr.ast.SharedMethodKit;
import com.jfinal.template.ext.directive.*;
import com.jfinal.template.ext.sharedmethod.SharedMethodLib;
import com.jfinal.template.io.EncoderFactory;
import com.jfinal.template.io.WriterBuffer;
import com.jfinal.template.source.FileSource;
import com.jfinal.template.source.FileSourceFactory;
import com.jfinal.template.source.ISource;
import com.jfinal.template.source.ISourceFactory;
import com.jfinal.template.source.StringSource;
import com.jfinal.template.stat.Location;
import com.jfinal.template.stat.OutputDirectiveFactory;
import com.jfinal.template.stat.Parser;
import com.jfinal.template.stat.ast.Define;
import com.jfinal.template.stat.ast.Output;
/**
* EngineConfig
*/
public class EngineConfig {
public static final String DEFAULT_ENCODING = "UTF-8";
WriterBuffer writerBuffer = new WriterBuffer();
private Map sharedFunctionMap = createSharedFunctionMap(); // new HashMap(512, 0.25F);
private List sharedFunctionSourceList = new ArrayList(); // for devMode only
Map sharedObjectMap = null;
private OutputDirectiveFactory outputDirectiveFactory = OutputDirectiveFactory.me;
private ISourceFactory sourceFactory = new FileSourceFactory();
private Map> directiveMap = new HashMap>(64, 0.5F);
private SharedMethodKit sharedMethodKit = new SharedMethodKit();
private boolean devMode = false;
private boolean reloadModifiedSharedFunctionInDevMode = true;
private String baseTemplatePath = null;
private String encoding = DEFAULT_ENCODING;
private String datePattern = "yyyy-MM-dd HH:mm";
public EngineConfig() {
// Add official directive of Template Engine
addDirective("render", RenderDirective.class);
addDirective("date", DateDirective.class);
addDirective("escape", EscapeDirective.class);
addDirective("string", StringDirective.class);
addDirective("random", RandomDirective.class);
addDirective("number", NumberDirective.class);
addDirective("call", CallDirective.class);
// Add official shared method of Template Engine
addSharedMethod(new SharedMethodLib());
}
/**
* Add shared function with file
*/
public void addSharedFunction(String fileName) {
fileName = fileName.replace("\\", "/");
// FileSource fileSource = new FileSource(baseTemplatePath, fileName, encoding);
ISource source = sourceFactory.getSource(baseTemplatePath, fileName, encoding);
doAddSharedFunction(source, fileName);
}
private synchronized void doAddSharedFunction(ISource source, String fileName) {
Env env = new Env(this);
new Parser(env, source.getContent(), fileName).parse();
addToSharedFunctionMap(sharedFunctionMap, env);
if (devMode) {
sharedFunctionSourceList.add(source);
env.addSource(source);
}
}
/**
* Add shared function with files
*/
public void addSharedFunction(String... fileNames) {
for (String fileName : fileNames) {
addSharedFunction(fileName);
}
}
/**
* Add shared function by string content
*/
public void addSharedFunctionByString(String content) {
// content 中的内容被解析后会存放在 Env 之中,而 StringSource 所对应的
// Template 对象 isModified() 始终返回 false,所以没有必要对其缓存
StringSource stringSource = new StringSource(content, false);
doAddSharedFunction(stringSource, null);
}
/**
* Add shared function by ISource
*/
public void addSharedFunction(ISource source) {
String fileName = source instanceof FileSource ? ((FileSource)source).getFileName() : null;
doAddSharedFunction(source, fileName);
}
private void addToSharedFunctionMap(Map sharedFunctionMap, Env env) {
Map funcMap = env.getFunctionMap();
for (Entry e : funcMap.entrySet()) {
if (sharedFunctionMap.containsKey(e.getKey())) {
throw new IllegalArgumentException("Template function already exists : " + e.getKey());
}
Define func = e.getValue();
if (devMode) {
func.setEnvForDevMode(env);
}
sharedFunctionMap.put(e.getKey(), func);
}
}
/**
* Get shared function by Env
*/
Define getSharedFunction(String functionName) {
Define func = sharedFunctionMap.get(functionName);
if (func == null) {
/**
* 如果 func 最初未定义,但后续在共享模板文件中又被添加进来
* 此时在本 if 分支中无法被感知,仍然返回了 null
*
* 但共享模板文件会在后续其它的 func 调用时被感知修改并 reload
* 所以本 if 分支不考虑处理模板文件中追加 #define 的情况
*
* 如果要处理,只能是每次在 func 为 null 时,判断 sharedFunctionSourceList
* 中的模板是否被修改过,再重新加载,不优雅
*/
return null;
}
if (devMode && reloadModifiedSharedFunctionInDevMode) {
if (func.isSourceModifiedForDevMode()) {
synchronized (this) {
func = sharedFunctionMap.get(functionName);
if (func.isSourceModifiedForDevMode()) {
reloadSharedFunctionSourceList();
func = sharedFunctionMap.get(functionName);
}
}
}
}
return func;
}
/**
* Reload shared function source list
*
* devMode 要照顾到 sharedFunctionFiles,所以暂不提供
* removeSharedFunction(String functionName) 功能
* 开发者可直接使用模板注释功能将不需要的 function 直接注释掉
*/
private synchronized void reloadSharedFunctionSourceList() {
Map newMap = createSharedFunctionMap();
for (int i = 0, size = sharedFunctionSourceList.size(); i < size; i++) {
ISource source = sharedFunctionSourceList.get(i);
String fileName = source instanceof FileSource ? ((FileSource)source).getFileName() : null;
Env env = new Env(this);
new Parser(env, source.getContent(), fileName).parse();
addToSharedFunctionMap(newMap, env);
if (devMode) {
env.addSource(source);
}
}
this.sharedFunctionMap = newMap;
}
private Map createSharedFunctionMap() {
return new HashMap(512, 0.25F);
}
public synchronized void addSharedObject(String name, Object object) {
if (sharedObjectMap == null) {
sharedObjectMap = new HashMap(64, 0.25F);
} else if (sharedObjectMap.containsKey(name)) {
throw new IllegalArgumentException("Shared object already exists: " + name);
}
sharedObjectMap.put(name, object);
}
Map getSharedObjectMap() {
return sharedObjectMap;
}
/**
* Set output directive factory
*/
public void setOutputDirectiveFactory(OutputDirectiveFactory outputDirectiveFactory) {
if (outputDirectiveFactory == null) {
throw new IllegalArgumentException("outputDirectiveFactory can not be null");
}
this.outputDirectiveFactory = outputDirectiveFactory;
}
public Output getOutputDirective(ExprList exprList, Location location) {
return outputDirectiveFactory.getOutputDirective(exprList, location);
}
/**
* Invoked by Engine only
*/
void setDevMode(boolean devMode) {
this.devMode = devMode;
}
public boolean isDevMode() {
return devMode;
}
/**
* Invoked by Engine only
*/
void setSourceFactory(ISourceFactory sourceFactory) {
if (sourceFactory == null) {
throw new IllegalArgumentException("sourceFactory can not be null");
}
this.sourceFactory = sourceFactory;
}
public ISourceFactory getSourceFactory() {
return sourceFactory;
}
public void setBaseTemplatePath(String baseTemplatePath) {
// 使用 ClassPathSourceFactory 时,允许 baseTemplatePath 为 null 值
if (baseTemplatePath == null) {
this.baseTemplatePath = null;
return ;
}
if (StrKit.isBlank(baseTemplatePath)) {
throw new IllegalArgumentException("baseTemplatePath can not be blank");
}
baseTemplatePath = baseTemplatePath.trim();
baseTemplatePath = baseTemplatePath.replace("\\", "/");
if (baseTemplatePath.length() > 1) {
if (baseTemplatePath.endsWith("/")) {
baseTemplatePath = baseTemplatePath.substring(0, baseTemplatePath.length() - 1);
}
}
this.baseTemplatePath = baseTemplatePath;
}
public String getBaseTemplatePath() {
return baseTemplatePath;
}
public void setEncoding(String encoding) {
if (StrKit.isBlank(encoding)) {
throw new IllegalArgumentException("encoding can not be blank");
}
this.encoding = encoding;
writerBuffer.setEncoding(encoding); // 间接设置 EncoderFactory.encoding
}
public void setEncoderFactory(EncoderFactory encoderFactory) {
writerBuffer.setEncoderFactory(encoderFactory);
writerBuffer.setEncoding(encoding); // 间接设置 EncoderFactory.encoding
}
public void setWriterBufferSize(int bufferSize) {
writerBuffer.setBufferSize(bufferSize);
}
public String getEncoding() {
return encoding;
}
public void setDatePattern(String datePattern) {
if (StrKit.isBlank(datePattern)) {
throw new IllegalArgumentException("datePattern can not be blank");
}
this.datePattern = datePattern;
}
public String getDatePattern() {
return datePattern;
}
public void setReloadModifiedSharedFunctionInDevMode(boolean reloadModifiedSharedFunctionInDevMode) {
this.reloadModifiedSharedFunctionInDevMode = reloadModifiedSharedFunctionInDevMode;
}
@Deprecated
public void addDirective(String directiveName, Directive directive) {
addDirective(directiveName, directive.getClass());
}
public synchronized void addDirective(String directiveName, Class extends Directive> directiveClass) {
if (StrKit.isBlank(directiveName)) {
throw new IllegalArgumentException("directive name can not be blank");
}
if (directiveClass == null) {
throw new IllegalArgumentException("directiveClass can not be null");
}
if (directiveMap.containsKey(directiveName)) {
throw new IllegalArgumentException("directive already exists : " + directiveName);
}
directiveMap.put(directiveName, directiveClass);
}
public Class extends Directive> getDirective(String directiveName) {
return directiveMap.get(directiveName);
}
public void removeDirective(String directiveName) {
directiveMap.remove(directiveName);
}
/**
* Add shared method from object
*/
public void addSharedMethod(Object sharedMethodFromObject) {
sharedMethodKit.addSharedMethod(sharedMethodFromObject);
}
/**
* Add shared method from class
*/
public void addSharedMethod(Class> sharedMethodFromClass) {
sharedMethodKit.addSharedMethod(sharedMethodFromClass);
}
/**
* Add shared static method of Class
*/
public void addSharedStaticMethod(Class> sharedStaticMethodFromClass) {
sharedMethodKit.addSharedStaticMethod(sharedStaticMethodFromClass);
}
/**
* Remove shared Method with method name
*/
public void removeSharedMethod(String methodName) {
sharedMethodKit.removeSharedMethod(methodName);
}
/**
* Remove shared Method of the Class
*/
public void removeSharedMethod(Class> sharedClass) {
sharedMethodKit.removeSharedMethod(sharedClass);
}
/**
* Remove shared Method
*/
public void removeSharedMethod(Method method) {
sharedMethodKit.removeSharedMethod(method);
}
public SharedMethodKit getSharedMethodKit() {
return sharedMethodKit;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy