Enjoy 3.2 release ^_^
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.directive;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.text.SimpleDateFormat;
|
||||
import com.jfinal.template.Directive;
|
||||
import com.jfinal.template.Env;
|
||||
import com.jfinal.template.TemplateException;
|
||||
import com.jfinal.template.expr.ast.Expr;
|
||||
import com.jfinal.template.expr.ast.ExprList;
|
||||
import com.jfinal.template.stat.ParseException;
|
||||
import com.jfinal.template.stat.Scope;
|
||||
|
||||
/**
|
||||
* 不带参时,按默认 pattern 输出当前日期
|
||||
*
|
||||
* #date() 指令支持无参时获取当前指令,第一个参数 string 当成是 pattern
|
||||
*
|
||||
* 日期输出指令,第一个参数是被输出的 java.util.Date 对象或其子类对象
|
||||
* 无第二个参数时按默认 patter 输出,第二个参数为 expr 表达式,表示 pattern
|
||||
* 第二个为 date 时,表示当第一个为 null 时的默认值
|
||||
*/
|
||||
public class DateDirective extends Directive {
|
||||
|
||||
private Expr valueExpr;
|
||||
private Expr datePatternExpr;
|
||||
private int paraNum;
|
||||
|
||||
public void setExprList(ExprList exprList) {
|
||||
this.paraNum = exprList.length();
|
||||
if (paraNum > 2) {
|
||||
throw new ParseException("Wrong number parameter of #date directive, two parameters allowed at most", location);
|
||||
}
|
||||
|
||||
if (paraNum == 0) {
|
||||
this.valueExpr = null;
|
||||
this.datePatternExpr = null;
|
||||
} else if (paraNum == 1) {
|
||||
this.valueExpr = exprList.getExprArray()[0];
|
||||
this.datePatternExpr = null;
|
||||
} else if (paraNum == 2) {
|
||||
this.valueExpr = exprList.getExprArray()[0];
|
||||
this.datePatternExpr = exprList.getExprArray()[1];
|
||||
}
|
||||
}
|
||||
|
||||
public void exec(Env env, Scope scope, Writer writer) {
|
||||
if (paraNum == 0) {
|
||||
outputToday(env, writer);
|
||||
} else if (paraNum == 1) {
|
||||
outputWithoutDatePattern(env, scope, writer);
|
||||
} else if (paraNum == 2) {
|
||||
outputWithDatePattern(env, scope, writer);
|
||||
}
|
||||
}
|
||||
|
||||
private void outputToday(Env env, Writer writer) {
|
||||
Object value = format(new java.util.Date(), env.getEngineConfig().getDatePattern());
|
||||
write(writer, value.toString());
|
||||
}
|
||||
|
||||
private void outputWithoutDatePattern(Env env, Scope scope, Writer writer) {
|
||||
Object value = valueExpr.eval(scope);
|
||||
if (value != null) {
|
||||
value = format(value, env.getEngineConfig().getDatePattern());
|
||||
write(writer, value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void outputWithDatePattern(Env env, Scope scope, Writer writer) {
|
||||
Object value = valueExpr.eval(scope);
|
||||
if (value == null) {
|
||||
return ;
|
||||
}
|
||||
|
||||
Object dp = this.datePatternExpr.eval(scope);
|
||||
if ( !(dp instanceof String) ) {
|
||||
throw new TemplateException("The sencond parameter dataPattern of #date directive must be String", location);
|
||||
}
|
||||
value = format(value, (String)dp);
|
||||
write(writer, value.toString());
|
||||
}
|
||||
|
||||
private String format(Object value, String datePattern) {
|
||||
try {
|
||||
return new SimpleDateFormat(datePattern).format(value);
|
||||
} catch (Exception e) {
|
||||
throw new TemplateException(e.getMessage(), location, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.directive;
|
||||
|
||||
import java.io.Writer;
|
||||
import com.jfinal.template.Directive;
|
||||
import com.jfinal.template.Env;
|
||||
import com.jfinal.template.stat.Scope;
|
||||
|
||||
/**
|
||||
* Escape 对字符串进行转义
|
||||
* 用法:
|
||||
* #escape(value)
|
||||
*/
|
||||
public class EscapeDirective extends Directive {
|
||||
|
||||
public void exec(Env env, Scope scope, Writer writer) {
|
||||
Object value = exprList.eval(scope);
|
||||
if (value != null) {
|
||||
write(writer, escape(value.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 挪到 StrKit 中
|
||||
private String escape(String str) {
|
||||
if (str == null || str.length() == 0) {
|
||||
return str;
|
||||
}
|
||||
|
||||
int len = str.length();
|
||||
StringBuilder ret = new StringBuilder(len * 2);
|
||||
for (int i = 0; i < len; i++) {
|
||||
char cur = str.charAt(i);
|
||||
switch (cur) {
|
||||
case '<':
|
||||
ret.append("<");
|
||||
break;
|
||||
case '>':
|
||||
ret.append(">");
|
||||
break;
|
||||
case '\"':
|
||||
ret.append(""");
|
||||
break;
|
||||
case '\'':
|
||||
ret.append("'"); // IE 不支持 ' 考虑 '
|
||||
break;
|
||||
case '&':
|
||||
ret.append("&");
|
||||
break;
|
||||
default:
|
||||
ret.append(cur);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.directive;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.text.SimpleDateFormat;
|
||||
import com.jfinal.template.Directive;
|
||||
import com.jfinal.template.Env;
|
||||
import com.jfinal.template.TemplateException;
|
||||
import com.jfinal.template.expr.ast.ExprList;
|
||||
import com.jfinal.template.stat.ParseException;
|
||||
import com.jfinal.template.stat.Scope;
|
||||
|
||||
/**
|
||||
* 输出当前时间,默认考虑是输出时间,给 pattern 输出可能是 Date、DateTime、Timestamp
|
||||
* 带 String 参数,表示 pattern
|
||||
*/
|
||||
public class NowDirective extends Directive {
|
||||
|
||||
public void setExrpList(ExprList exprList) {
|
||||
if (exprList.length() > 1) {
|
||||
throw new ParseException("#now directive support one parameter only", location);
|
||||
}
|
||||
super.setExprList(exprList);
|
||||
}
|
||||
|
||||
public void exec(Env env, Scope scope, Writer writer) {
|
||||
String dataPattern;
|
||||
if (exprList.length() == 0) {
|
||||
dataPattern = env.getEngineConfig().getDatePattern();
|
||||
} else {
|
||||
Object dp = exprList.eval(scope);
|
||||
if (dp instanceof String) {
|
||||
dataPattern = (String)dp;
|
||||
} else {
|
||||
throw new TemplateException("The parameter of #new directive must be String", location);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
String value = new SimpleDateFormat(dataPattern).format(new java.util.Date());
|
||||
write(writer, value);
|
||||
} catch (Exception e) {
|
||||
throw new TemplateException(e.getMessage(), location, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.directive;
|
||||
|
||||
import java.io.Writer;
|
||||
import com.jfinal.template.Directive;
|
||||
import com.jfinal.template.Env;
|
||||
import com.jfinal.template.stat.Scope;
|
||||
|
||||
/**
|
||||
* 输出随机数
|
||||
*/
|
||||
public class RandomDirective extends Directive {
|
||||
|
||||
private java.util.Random random = new java.util.Random();
|
||||
|
||||
public void exec(Env env, Scope scope, Writer writer) {
|
||||
write(writer, String.valueOf(random.nextInt()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.directive;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.jfinal.template.Directive;
|
||||
import com.jfinal.template.EngineConfig;
|
||||
import com.jfinal.template.Env;
|
||||
import com.jfinal.template.TemplateException;
|
||||
import com.jfinal.template.expr.ast.Assign;
|
||||
import com.jfinal.template.expr.ast.ExprList;
|
||||
import com.jfinal.template.source.ISource;
|
||||
import com.jfinal.template.stat.Ctrl;
|
||||
import com.jfinal.template.stat.ParseException;
|
||||
import com.jfinal.template.stat.Parser;
|
||||
import com.jfinal.template.stat.Scope;
|
||||
import com.jfinal.template.stat.ast.Define;
|
||||
import com.jfinal.template.stat.ast.Include;
|
||||
import com.jfinal.template.stat.ast.Stat;
|
||||
|
||||
/**
|
||||
* #render 指令用于动态渲染子模板,作为 include 指令的补充
|
||||
*
|
||||
* <pre>
|
||||
* 两种用法:
|
||||
* 1:只传入一个参数,参数可以是 String 常量,也可以是任意表达式
|
||||
* #render("_hot.html")
|
||||
* #render(subFile)
|
||||
*
|
||||
* 2:传入任意多个参数,除第一个参数以外的所有参数必须是赋值表达式,用于实现参数传递功能
|
||||
* #render("_hot.html", title = "热门新闻", list = newsList)
|
||||
*
|
||||
* 上例中传递了 title、list 两个参数,可以代替父模板中的 #set 指令传参方式
|
||||
* 并且此方式传入的参数只在子模板作用域有效,不会污染父模板作用域
|
||||
*
|
||||
* 这种传参方式有利于将子模板模块化,例如上例的调用改成如下的参数:
|
||||
* #render("_hot.html", title = "热门项目", list = projectList)
|
||||
* 通过这种传参方式在子模板 _hot.html 之中,完全不需要修改对于 title 与 list
|
||||
* 这两个变量的处理代码,就实现了对 “热门项目” 数据的渲染
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public class RenderDirective extends Directive {
|
||||
|
||||
private String parentFileName;
|
||||
private Map<String, StatInfo> statInfoCache = new HashMap<String,StatInfo>();
|
||||
|
||||
public void setExprList(ExprList exprList) {
|
||||
int len = exprList.length();
|
||||
if (len == 0) {
|
||||
throw new ParseException("The parameter of #render directive can not be blank", location);
|
||||
}
|
||||
if (len > 1) {
|
||||
for (int i = 1; i < len; i++) {
|
||||
if (!(exprList.getExpr(i) instanceof Assign)) {
|
||||
throw new ParseException("The " + i + "th parameter of #render directive must be an assignment expression", location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 location 中获取父模板的 fileName,用于生成 subFileName
|
||||
* 如果是孙子模板,那么 parentFileName 为最顶层的模板,而非直接上层的模板
|
||||
*/
|
||||
this.parentFileName = location.getTemplateFile();
|
||||
this.exprList = exprList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对 exprList 进行求值,并将第一个表达式的值作为模板名称返回,
|
||||
* 开启 local assignment 保障 #render 指令参数表达式列表
|
||||
* 中的赋值表达式在当前 scope 中进行,有利于模块化
|
||||
*/
|
||||
private Object evalAssignExpressionAndGetFileName(Scope scope) {
|
||||
Ctrl ctrl = scope.getCtrl();
|
||||
try {
|
||||
ctrl.setLocalAssignment();
|
||||
return exprList.evalExprList(scope)[0];
|
||||
} finally {
|
||||
ctrl.setWisdomAssignment();
|
||||
}
|
||||
}
|
||||
|
||||
public void exec(Env env, Scope scope, Writer writer) {
|
||||
// 在 exprList.eval(scope) 之前创建,使赋值表达式在本作用域内进行
|
||||
scope = new Scope(scope);
|
||||
|
||||
Object value = evalAssignExpressionAndGetFileName(scope);
|
||||
if (!(value instanceof String)) {
|
||||
throw new TemplateException("The parameter value of #render directive must be String", location);
|
||||
}
|
||||
|
||||
String subFileName = Include.getSubFileName((String)value, parentFileName);
|
||||
StatInfo statInfo = statInfoCache.get(subFileName);
|
||||
if (statInfo == null) {
|
||||
statInfo = parseStatInfo(env, subFileName);
|
||||
statInfoCache.put(subFileName, statInfo);
|
||||
} else if (env.getEngineConfig().isDevMode()) {
|
||||
// statInfo.env.isSourceListModified() 逻辑可以支持 #render 子模板中的 #include 过来的子模板在 devMode 下在修改后可被重加载
|
||||
if (statInfo.source.isModified() || statInfo.env.isSourceListModified()) {
|
||||
statInfo = parseStatInfo(env, subFileName);
|
||||
statInfoCache.put(subFileName, statInfo);
|
||||
}
|
||||
}
|
||||
|
||||
statInfo.stat.exec(statInfo.env, scope, writer);
|
||||
scope.getCtrl().setJumpNone();
|
||||
}
|
||||
|
||||
private StatInfo parseStatInfo(Env env, String subFileName) {
|
||||
EngineConfig config = env.getEngineConfig();
|
||||
// FileSource fileSource = new FileSource(config.getBaseTemplatePath(), subFileName, config.getEncoding());
|
||||
ISource fileSource = config.getSourceFactory().getSource(config.getBaseTemplatePath(), subFileName, config.getEncoding());
|
||||
|
||||
try {
|
||||
EnvSub envSub = new EnvSub(env);
|
||||
Stat stat = new Parser(envSub, fileSource.getContent(), subFileName).parse();
|
||||
return new StatInfo(envSub, stat, fileSource);
|
||||
} catch (Exception e) {
|
||||
throw new ParseException(e.getMessage(), location, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class StatInfo {
|
||||
EnvSub env;
|
||||
Stat stat;
|
||||
ISource source;
|
||||
|
||||
StatInfo(EnvSub env, Stat stat, ISource source) {
|
||||
this.env = env;
|
||||
this.stat = stat;
|
||||
this.source = source;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* EnvSub 用于将子模板与父模板中的模板函数隔离开来,
|
||||
* 否则在子模板被修改并被重新解析时会再次添加子模板中的
|
||||
* 模板函数,从而抛出异常
|
||||
*
|
||||
* EnvSub 也可以使子模板中定义的模板函数不与上层产生冲突,
|
||||
* 有利于动态型模板渲染的模块化
|
||||
*
|
||||
* 注意: #render 子模板中定义的模板函数无法被上层调用
|
||||
*/
|
||||
private static class EnvSub extends Env {
|
||||
Env parentEnv;
|
||||
|
||||
public EnvSub(Env parentEnv) {
|
||||
super(parentEnv.getEngineConfig());
|
||||
this.parentEnv = parentEnv;
|
||||
}
|
||||
|
||||
/**
|
||||
* 接管父类 getFunction(),先从子模板中找模板函数,找不到再去父模板中找
|
||||
*/
|
||||
public Define getFunction(String functionName) {
|
||||
Define func = functionMap.get(functionName);
|
||||
return func != null ? func : parentEnv.getFunction(functionName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.directive;
|
||||
|
||||
import java.io.Writer;
|
||||
import com.jfinal.template.Directive;
|
||||
import com.jfinal.template.Env;
|
||||
import com.jfinal.template.FastStringWriter;
|
||||
import com.jfinal.template.expr.ast.Const;
|
||||
import com.jfinal.template.expr.ast.Expr;
|
||||
import com.jfinal.template.expr.ast.ExprList;
|
||||
import com.jfinal.template.expr.ast.Id;
|
||||
import com.jfinal.template.stat.ParseException;
|
||||
import com.jfinal.template.stat.Scope;
|
||||
|
||||
/**
|
||||
* #string 指令方便定义大量的多行文本变量,这个是 java 语言中极为需要的功能
|
||||
*
|
||||
* 定义:
|
||||
* #string(name)
|
||||
* 在此是大量的字符串
|
||||
* #end
|
||||
*
|
||||
* 使用:
|
||||
* #(name)
|
||||
*/
|
||||
public class StringDirective extends Directive {
|
||||
|
||||
private String name;
|
||||
private boolean isLocalAssignment = false;
|
||||
|
||||
public void setExprList(ExprList exprList) {
|
||||
Expr[] exprArray = exprList.getExprArray();
|
||||
if (exprArray.length == 0) {
|
||||
throw new ParseException("#string directive parameter cant not be null", location);
|
||||
}
|
||||
if (exprArray.length > 2) {
|
||||
throw new ParseException("wrong number of #string directive parameter, two parameters allowed at most", location);
|
||||
}
|
||||
|
||||
if (!(exprArray[0] instanceof Id)) {
|
||||
throw new ParseException("#string first parameter must be identifier", location);
|
||||
}
|
||||
this.name = ((Id)exprArray[0]).getId();
|
||||
if (exprArray.length == 2) {
|
||||
if (exprArray[1] instanceof Const) {
|
||||
if (((Const)exprArray[1]).isBoolean()) {
|
||||
this.isLocalAssignment = ((Const)exprArray[1]).getBoolean();
|
||||
} else {
|
||||
throw new ParseException("#string sencond parameter must be boolean", location);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void exec(Env env, Scope scope, Writer writer) {
|
||||
FastStringWriter fsw = new FastStringWriter();
|
||||
stat.exec(env, scope, fsw);
|
||||
|
||||
if (this.isLocalAssignment) {
|
||||
scope.setLocal(name, fsw.toString());
|
||||
} else {
|
||||
scope.set(name, fsw.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hasEnd() 方法返回 true 时,表示该指令拥有指令体以及 #end 结束块
|
||||
* 模板引擎在解析时会将 "指令体" 赋值到 stat 属性中,在 exec(...) 方法中
|
||||
* 可通过 stat.exec(...) 执行 "指令体" 内部的所有指令
|
||||
*/
|
||||
public boolean hasEnd() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.extensionmethod;
|
||||
|
||||
/**
|
||||
* 针对 java.lang.Byte 的扩展方法
|
||||
*
|
||||
* 用法:
|
||||
* #if(value.toInt() == 123)
|
||||
*/
|
||||
public class ByteExt {
|
||||
|
||||
public Boolean toBoolean(Byte self) {
|
||||
return self != 0;
|
||||
}
|
||||
|
||||
public Integer toInt(Byte self) {
|
||||
return self.intValue();
|
||||
}
|
||||
|
||||
public Long toLong(Byte self) {
|
||||
return self.longValue();
|
||||
}
|
||||
|
||||
public Float toFloat(Byte self) {
|
||||
return self.floatValue();
|
||||
}
|
||||
|
||||
public Double toDouble(Byte self) {
|
||||
return self.doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.extensionmethod;
|
||||
|
||||
/**
|
||||
* 针对 java.lang.Double 的扩展方法
|
||||
*
|
||||
* 用法:
|
||||
* #if(value.toInt() == 123)
|
||||
*/
|
||||
public class DoubleExt {
|
||||
|
||||
public Boolean toBoolean(Double self) {
|
||||
return self != 0;
|
||||
}
|
||||
|
||||
public Integer toInt(Double self) {
|
||||
return self.intValue();
|
||||
}
|
||||
|
||||
public Long toLong(Double self) {
|
||||
return self.longValue();
|
||||
}
|
||||
|
||||
public Float toFloat(Double self) {
|
||||
return self.floatValue();
|
||||
}
|
||||
|
||||
public Double toDouble(Double self) {
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.extensionmethod;
|
||||
|
||||
/**
|
||||
* 针对 java.lang.Float 的扩展方法
|
||||
*
|
||||
* 用法:
|
||||
* #if(value.toInt() == 123)
|
||||
*/
|
||||
public class FloatExt {
|
||||
|
||||
public Boolean toBoolean(Float self) {
|
||||
return self != 0;
|
||||
}
|
||||
|
||||
public Integer toInt(Float self) {
|
||||
return self.intValue();
|
||||
}
|
||||
|
||||
public Long toLong(Float self) {
|
||||
return self.longValue();
|
||||
}
|
||||
|
||||
public Float toFloat(Float self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
public Double toDouble(Float self) {
|
||||
return self.doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.extensionmethod;
|
||||
|
||||
/**
|
||||
* 针对 java.lang.Integer 的扩展方法
|
||||
*
|
||||
* 重要用途:
|
||||
* Controller.keepPara() 方法会将所有类型的数据当成 String 并传回到
|
||||
* 到模板中,所以模板中的如下代码将无法工作:
|
||||
* #if(age > 18)
|
||||
* ....
|
||||
* #end
|
||||
*
|
||||
* 以上代码,第一次渲染模板时,由于 age 为 int 类型,那么 if 语句中是正确的表达式,
|
||||
* 当提交表单后在后端调用 keepPara() 以后 age 变成了 String 类型,表达式错误,
|
||||
* 在有了扩展方法以后,解决办法如下:
|
||||
* #if(age.toInt() > 18)
|
||||
* ...
|
||||
* #end
|
||||
* 如上所示,无论 age 是 String 还是 int 型,调用其 toInt() 方法将一直确保
|
||||
* age 为 int 类型
|
||||
*
|
||||
* 以上用法,必须针对 String 与 Integer 同时扩展一个 toInt() 方法,模板表达式中的
|
||||
* 变量为 String 或为 Integer 时都存在 toInt() 方法可供调用
|
||||
*
|
||||
*
|
||||
* 用法:
|
||||
* #if(age.toInt() > 18)
|
||||
*/
|
||||
public class IntegerExt {
|
||||
|
||||
public Boolean toBoolean(Integer self) {
|
||||
return self != 0;
|
||||
}
|
||||
|
||||
public Integer toInt(Integer self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
public Long toLong(Integer self) {
|
||||
return self.longValue();
|
||||
}
|
||||
|
||||
public Float toFloat(Integer self) {
|
||||
return self.floatValue();
|
||||
}
|
||||
|
||||
public Double toDouble(Integer self) {
|
||||
return self.doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.extensionmethod;
|
||||
|
||||
/**
|
||||
* 针对 java.lang.Long 的扩展方法
|
||||
*
|
||||
* 用法:
|
||||
* #if(value.toInt() == 123)
|
||||
*/
|
||||
public class LongExt {
|
||||
|
||||
public Boolean toBoolean(Long self) {
|
||||
return self != 0;
|
||||
}
|
||||
|
||||
public Integer toInt(Long self) {
|
||||
return self.intValue();
|
||||
}
|
||||
|
||||
public Long toLong(Long self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
public Float toFloat(Long self) {
|
||||
return self.floatValue();
|
||||
}
|
||||
|
||||
public Double toDouble(Long self) {
|
||||
return self.doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.extensionmethod;
|
||||
|
||||
/**
|
||||
* 针对 java.lang.Short 的扩展方法
|
||||
*
|
||||
* 用法:
|
||||
* #if(value.toInt() == 123)
|
||||
*/
|
||||
public class ShortExt {
|
||||
|
||||
public Boolean toBoolean(Short self) {
|
||||
return self != 0;
|
||||
}
|
||||
|
||||
public Integer toInt(Short self) {
|
||||
return self.intValue();
|
||||
}
|
||||
|
||||
public Long toLong(Short self) {
|
||||
return self.longValue();
|
||||
}
|
||||
|
||||
public Float toFloat(Short self) {
|
||||
return self.floatValue();
|
||||
}
|
||||
|
||||
public Double toDouble(Short self) {
|
||||
return self.doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.extensionmethod;
|
||||
|
||||
import com.jfinal.kit.StrKit;
|
||||
|
||||
/**
|
||||
* 针对 java.lang.String 的扩展方法
|
||||
*
|
||||
* 重要用途:
|
||||
* Controller.keepPara() 方法会将所有类型的数据当成 String 并传回到
|
||||
* 到模板中,所以模板中的如下代码将无法工作:
|
||||
* #if(age > 18)
|
||||
* ....
|
||||
* #end
|
||||
*
|
||||
* 以上代码,第一次渲染模板时,由于 age 为 int 类型,那么 if 语句中是正确的表达式,
|
||||
* 当提交表单后在后端调用 keepPara() 以后 age 变成了 String 类型,表达式错误,
|
||||
* 在有了扩展方法以后,解决办法如下:
|
||||
* #if(age.toInt() > 18)
|
||||
* ...
|
||||
* #end
|
||||
* 如上所示,无论 age 是 String 还是 int 型,调用其 toInt() 方法将一直确保
|
||||
* age 为 int 类型
|
||||
*
|
||||
* 以上用法,必须针对 String 与 Integer 同时扩展一个 toInt() 方法,模板表达式中的
|
||||
* 变量为 String 或为 Integer 时都存在 toInt() 方法可供调用
|
||||
*
|
||||
* 用法:
|
||||
* #if(age.toInt() > 18)
|
||||
*/
|
||||
public class StringExt {
|
||||
|
||||
/**
|
||||
* StringExt.toBoolean() 是数据类型转换,所以与 Logic.isTrue(String)
|
||||
* 中的逻辑不同,后者只要 String 值非 null 并且 length() > 0 即返回 true
|
||||
*/
|
||||
public Boolean toBoolean(String self) {
|
||||
if (StrKit.isBlank(self)) {
|
||||
return null; // return Boolean.FALSE;
|
||||
}
|
||||
|
||||
String value = self.trim().toLowerCase();
|
||||
if ("true".equals(value) || "1".equals(value)) { // 未来考虑 "yes"、"on"
|
||||
return Boolean.TRUE;
|
||||
} else if ("false".equals(value) || "0".equals(value)) {
|
||||
return Boolean.FALSE;
|
||||
} else {
|
||||
throw new RuntimeException("Can not parse to boolean type of value: \"" + self + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
public Integer toInt(String self) {
|
||||
return StrKit.isBlank(self) ? null : Integer.parseInt(self);
|
||||
}
|
||||
|
||||
public Long toLong(String self) {
|
||||
return StrKit.isBlank(self) ? null : Long.parseLong(self);
|
||||
}
|
||||
|
||||
public Float toFloat(String self) {
|
||||
return StrKit.isBlank(self) ? null : Float.parseFloat(self);
|
||||
}
|
||||
|
||||
public Double toDouble(String self) {
|
||||
return StrKit.isBlank(self) ? null : Double.parseDouble(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
166
src/main/java/com/jfinal/template/ext/spring/JFinalView.java
Normal file
166
src/main/java/com/jfinal/template/ext/spring/JFinalView.java
Normal file
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.spring;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import org.springframework.web.servlet.view.AbstractTemplateView;
|
||||
|
||||
/**
|
||||
* JFinalView
|
||||
*
|
||||
* <pre>
|
||||
* 关键设置:
|
||||
* 1:setContentType("text/html;charset=UTF-8") 设置 content type 字符集为 UTF-8
|
||||
*
|
||||
* 2:setExposeRequestAttributes(true) 设置将 request 中的属性值注入到 model 中去
|
||||
* 便于在模板中使用 #(value) 访问 request.setAttribute(...) 进去的值
|
||||
*
|
||||
* 3: setExposeSessionAttributes(true) 设置将 session 中的属性值注入到 model 中去
|
||||
* 使用在模板中使用 #(value) 访问 session.setAttribute(...) 进去的值
|
||||
*
|
||||
* 注意:JFinalViewResolver.setSessionInView(true) 中的配置与
|
||||
* JFinalView.setExposeSessionAttributes(true) 可实现
|
||||
* 相似的功能,区别在于前者访问方式为 #(session.value) 而后者为
|
||||
* #(value),两种配置只选其一
|
||||
* </pre>
|
||||
*/
|
||||
public class JFinalView extends AbstractTemplateView {
|
||||
|
||||
@Override
|
||||
protected void renderMergedTemplateModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
if (JFinalViewResolver.sessionInView) {
|
||||
HttpSession hs = request.getSession(JFinalViewResolver.createSession);
|
||||
if (hs != null) {
|
||||
model.put("session", new InnerSession(hs));
|
||||
}
|
||||
}
|
||||
|
||||
Writer writer = response.getWriter();
|
||||
JFinalViewResolver.engine.getTemplate(getUrl()).render(model, writer);
|
||||
writer.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
|
||||
class InnerSession extends HashMap<Object, Object> implements HttpSession {
|
||||
|
||||
private static final long serialVersionUID = -8679493647540628009L;
|
||||
private HttpSession session;
|
||||
|
||||
public InnerSession(HttpSession session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
// HashMap 相关方法处理 ----------------------------------------------------
|
||||
/**
|
||||
* 覆盖 HashMap 的 put
|
||||
*/
|
||||
public Object put(Object name, Object value) {
|
||||
session.setAttribute((String)name, value);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 覆盖 HashMap 的 get
|
||||
*/
|
||||
public Object get(Object name) {
|
||||
return session.getAttribute((String)name);
|
||||
}
|
||||
|
||||
// Session 相关方法处理 ----------------------------------------------------
|
||||
public Object getAttribute(String key) {
|
||||
return session.getAttribute(key);
|
||||
}
|
||||
|
||||
public Enumeration getAttributeNames() {
|
||||
return session.getAttributeNames();
|
||||
}
|
||||
|
||||
public long getCreationTime() {
|
||||
return session.getCreationTime();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return session.getId();
|
||||
}
|
||||
|
||||
public long getLastAccessedTime() {
|
||||
return session.getLastAccessedTime();
|
||||
}
|
||||
|
||||
public int getMaxInactiveInterval() {
|
||||
return session.getMaxInactiveInterval();
|
||||
}
|
||||
|
||||
public ServletContext getServletContext() {
|
||||
return session.getServletContext();
|
||||
}
|
||||
|
||||
public javax.servlet.http.HttpSessionContext getSessionContext() {
|
||||
return session.getSessionContext();
|
||||
}
|
||||
|
||||
public Object getValue(String key) {
|
||||
return session.getValue(key);
|
||||
}
|
||||
|
||||
public String[] getValueNames() {
|
||||
return session.getValueNames();
|
||||
}
|
||||
|
||||
public void invalidate() {
|
||||
session.invalidate();
|
||||
}
|
||||
|
||||
public boolean isNew() {
|
||||
return session.isNew();
|
||||
}
|
||||
|
||||
public void putValue(String key, Object value) {
|
||||
session.putValue(key, value);
|
||||
}
|
||||
|
||||
public void removeAttribute(String key) {
|
||||
session.removeAttribute(key);
|
||||
}
|
||||
|
||||
public void removeValue(String key) {
|
||||
session.removeValue(key);
|
||||
}
|
||||
|
||||
public void setAttribute(String key, Object value) {
|
||||
session.setAttribute(key, value);
|
||||
}
|
||||
|
||||
public void setMaxInactiveInterval(int maxInactiveInterval) {
|
||||
session.setMaxInactiveInterval(maxInactiveInterval);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -0,0 +1,254 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* 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.ext.spring;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.servlet.ServletContext;
|
||||
import org.springframework.web.servlet.view.AbstractTemplateViewResolver;
|
||||
import com.jfinal.kit.StrKit;
|
||||
import com.jfinal.template.Directive;
|
||||
import com.jfinal.template.Engine;
|
||||
import com.jfinal.template.source.ClassPathSourceFactory;
|
||||
import com.jfinal.template.source.ISourceFactory;
|
||||
|
||||
/**
|
||||
* JFinalViewResolver
|
||||
*
|
||||
* <pre>
|
||||
* 关键配置:
|
||||
* 1:setDevMode(true) 设置支持热加载模板文件
|
||||
*
|
||||
* 2:addSharedFunction(file) 添加共享函数文件
|
||||
*
|
||||
* 3:setSourceFactory(new ClassPathSourceFactory()),从 class path 与 jar 包中加载模板文件
|
||||
* 一般用于 sprint boot
|
||||
*
|
||||
* 4:setSessionInView(true) 设置在模板中可通过 #(session.value) 访问 session 中的数据
|
||||
*
|
||||
* 5:setCreateSession(boolean) 用来设置 request.getSession(boolean) 调时的参数
|
||||
*
|
||||
* 6:setBaseTemplatePath(path) 设置模板文件所在的基础路径,通常用于 spring mvc
|
||||
* 默认值为 web 根路径,一般不需要设置
|
||||
* </pre>
|
||||
*/
|
||||
public class JFinalViewResolver extends AbstractTemplateViewResolver {
|
||||
|
||||
public static final Engine engine = new Engine();
|
||||
|
||||
static List<String> sharedFunctionFiles = new ArrayList<String>();
|
||||
static boolean sessionInView = false;
|
||||
static boolean createSession = true;
|
||||
|
||||
public Engine getEngine() {
|
||||
return engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置开发模式,值为 true 时支持模板文件热加载
|
||||
*/
|
||||
public void setDevMode(boolean devMode) {
|
||||
engine.setDevMode(devMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 shared function 文件,多个文件用逗号分隔
|
||||
*
|
||||
* 主要用于 Spring MVC 的 xml 配置方式
|
||||
*
|
||||
* Spring Boot 的代码配置方式可使用 addSharedFunction(...) 进行配置
|
||||
*/
|
||||
public void setSharedFunction(String sharedFunctionFiles) {
|
||||
if (StrKit.isBlank(sharedFunctionFiles)) {
|
||||
throw new IllegalArgumentException("sharedFunctionFiles can not be blank");
|
||||
}
|
||||
|
||||
String[] fileArray = sharedFunctionFiles.split(",");
|
||||
for (String fileName : fileArray) {
|
||||
JFinalViewResolver.sharedFunctionFiles.add(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加 shared function 文件,可调用多次添加多个文件
|
||||
*/
|
||||
public void addSharedFunction(String fileName) {
|
||||
// 等待 SourceFactory、baseTemplatePath 配置到位,利用 sharedFunctionFiles 实现延迟加载
|
||||
sharedFunctionFiles.add(fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加自定义指令
|
||||
*/
|
||||
public void addDirective(String directiveName, Directive directive) {
|
||||
engine.addDirective(directiveName, directive);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加共享对象
|
||||
*/
|
||||
public void addSharedObject(String name, Object object) {
|
||||
engine.addSharedObject(name, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加共享方法
|
||||
*/
|
||||
public void addSharedMethod(Object sharedMethodFromObject) {
|
||||
engine.addSharedMethod(sharedMethodFromObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加共享方法
|
||||
*/
|
||||
public void addSharedMethod(Class<?> sharedMethodFromClass) {
|
||||
engine.addSharedMethod(sharedMethodFromClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加扩展方法
|
||||
*/
|
||||
public static void addExtensionMethod(Class<?> targetClass, Object objectOfExtensionClass) {
|
||||
Engine.addExtensionMethod(targetClass, objectOfExtensionClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加扩展方法
|
||||
*/
|
||||
public static void addExtensionMethod(Class<?> targetClass, Class<?> extensionClass) {
|
||||
Engine.addExtensionMethod(targetClass, extensionClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 ISourceFactory 用于为 engine 切换不同的 ISource 实现类
|
||||
*
|
||||
* <pre>
|
||||
* 配置为 ClassPathSourceFactory 时特别注意:
|
||||
* 由于在 initServletContext() 通过如下方法中已设置了 baseTemplatePath 值:
|
||||
* setBaseTemplatePath(servletContext.getRealPath("/"))
|
||||
*
|
||||
* 而 ClassPathSourceFactory 在 initServletContext() 方法中设置的
|
||||
* 值之下不能工作,所以在本方法中通过如下方法清掉了该值:
|
||||
* setBaseTemplatePath(null)
|
||||
*
|
||||
* 这种处理方式适用于绝大部分场景,如果在使用 ClassPathSourceFactory 的同时
|
||||
* 仍然需要设置 baseTemplatePath,则在调用该方法 “之后” 通过如下代码再次配置:
|
||||
* setBaseTemplatePath(value)
|
||||
* </pre>
|
||||
*/
|
||||
public void setSourceFactory(ISourceFactory sourceFactory) {
|
||||
if (sourceFactory instanceof ClassPathSourceFactory) {
|
||||
engine.setBaseTemplatePath(null);
|
||||
}
|
||||
engine.setSourceFactory(sourceFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模板基础路径
|
||||
*/
|
||||
public void setBaseTemplatePath(String baseTemplatePath) {
|
||||
engine.setBaseTemplatePath(baseTemplatePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置为 true 时支持在模板中使用 #(session.value) 形式访问 session 中的数据
|
||||
*/
|
||||
public void setSessionInView(boolean sessionInView) {
|
||||
JFinalViewResolver.sessionInView = sessionInView;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在使用 request.getSession(createSession) 时传入
|
||||
* 用来指示 session 不存在时是否立即创建
|
||||
*/
|
||||
public void setCreateSession(boolean createSession) {
|
||||
JFinalViewResolver.createSession = createSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 encoding
|
||||
*/
|
||||
public void setEncoding(String encoding) {
|
||||
engine.setEncoding(encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 #date(...) 指令,对于 Date、Timestamp、Time 的输出格式
|
||||
*/
|
||||
public void setDatePattern(String datePattern) {
|
||||
engine.setDatePattern(datePattern);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
public JFinalViewResolver() {
|
||||
setViewClass(requiredViewClass());
|
||||
setOrder(0);
|
||||
setContentType("text/html;charset=UTF-8");
|
||||
// setPrefix("/view/");
|
||||
// setSuffix(".html");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> requiredViewClass() {
|
||||
return JFinalView.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* spring 回调,利用 ServletContext 做必要的初始化工作
|
||||
*/
|
||||
@Override
|
||||
protected void initServletContext(ServletContext servletContext) {
|
||||
super.initServletContext(servletContext);
|
||||
|
||||
initBaseTemplatePath(servletContext);
|
||||
initSharedFunction();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 baseTemplatePath 值,启用 ClassPathSourceFactory 时
|
||||
* 无需设置 baseTemplatePath 为 web 根路径
|
||||
*/
|
||||
private void initBaseTemplatePath(ServletContext servletContext) {
|
||||
if (engine.getSourceFactory() instanceof ClassPathSourceFactory) {
|
||||
// do nothing
|
||||
} else {
|
||||
if (StrKit.isBlank(engine.getBaseTemplatePath())) {
|
||||
String path = servletContext.getRealPath("/");
|
||||
engine.setBaseTemplatePath(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 利用 sharedFunctionFiles 延迟调用 addSharedFunction
|
||||
* 因为需要等待 baseTemplatePath 以及 ISourceFactory 设置完毕以后
|
||||
* 才能正常工作
|
||||
*/
|
||||
private void initSharedFunction() {
|
||||
for (String file : sharedFunctionFiles) {
|
||||
engine.addSharedFunction(file.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user