Common Template Engine 发布版本 | 每日构建 >>  English | 中文
下载 更新 论坛 关于我们
文档
首页概览
模板指南
表达式指南
语法外套指南
配置指南
扩展指南
API使用指南
常见问题
对比其它模板引擎
集成
MVC框架集成
JSP标签集成
缓存策略集成
日志框架集成
数据格式集成
脚本引擎集成
邮件发送组件集成
第三方集成依赖包
工具
调试器说明
查看器说明
模板生成器说明
模板转换器说明
编辑器插件说明
代码生成器说明
开发
架构设计
开发规范
项目计划
需求场景
资源
下载
许可协议
更新日志
UML图
Java Doc
测试覆盖率报告
社区
开发团队
论坛
知识库
邮件列表
问题列表
报告问题

 
CommonTemplate 扩展指南

一. 扩展总接口 整体设计...
org.commontemplate.config.Configuration
配置总接口,通过getXXX方式向引擎提供配置
org.commontemplate.standard.ConfigurationSettings
配置的setter实现,提供与Configuration的getter配对的setter,通常用于IoC注入方式,也可以编程调用setter
org.commontemplate.standard.StandardConfiguration
标准配置实现,内置了chain的封装,可以直接调用addXXX方法,简化编程设置方式。

二. 扩展点
说明:
“注册方法”均指:StandardConfiguration的设置函数。
“配置方法”均指:内置的properties配置方案,并且继承了标准配置。 配置...

1. 事件监听与扩展
相关接口:
com.commontemplate.core.EventListener
com.commontemplate.core.Event
注册方法:
addEventListener(EventListener)
addAsynchronousEventListener(EventListener)
配置方法:
eventListeners[100]=com.xxx.XxxListener() (注:下标号任意,只用于排序)
asynchronousEventListeners[100]=com.xxx.XxxListener()
参考实现:
引擎发布的事件:
com.commontemplate.core.event包下相关类

2. 模板资源加载器扩展
相关接口:
org.commontemplate.core.SourceLoader (模板源加载接口)
org.commontemplate.core.Source (模板源)
注册方法:
setSourceLoader(SourceLoader)
配置方法:
sourceLoader=com.xxx.YourSourceLoader()
参考实现:
org.commontemplate.standard.loader包下相关类

3. 上下文初始化器扩展
相关接口:
org.commontemplate.config.ContextInitializer
注册方法:
setContextInitializer(ContextInitializer)
配置方法:
contextInitializers[200]=com.xxx.XXXInitializer()
参考实现:
org.commontemplate.standard.context包下相关类

4. 缓存策略扩展
相关接口:
org.commontemplate.config.Cache
注册方法:
setTemplateCache(Cache)
setTemplatePersistentCache(Cache)
setStandardCache(String cacheStrategy, int cacheMaxSize) (注:标准cacheStrategy支持NONE, STRONG, SOFT, WEAK, FIFO, LRU, MRU, OSCACHE, EHCACHE)
配置方法:
templateCache=org.commontemplate.standard.cache.LRUCache()
templateCache.maxSize=1000
templatePersistentCache=org.commontemplate.standard.cache.DiskSerialCache()
templatePersistentCache.directory=C:/cache
参考实现:
org.commontemplate.standard.cache包下相关类

5. 热加载控制
引擎在每次从缓存中返回模板之前都会回调ReloadController.shouldReload(String templateName),
如果返回true,引擎将重新读取模板源,
并调用SourceComparator.isModified(Template template, Source source)进行比较,
若模板源已更改,则重新解析模板源并刷新缓存。
相关接口:
org.commontemplate.config.ReloadController
org.commontemplate.config.SourceComparator
注册方法:
setReloadController(ReloadController)
setModificationCheckInterval(long) (注:使用内置的org.commontemplate.standard.reload.IntervalReloadController)
setSourceComparator(SourceComparator)
配置方法:
reloadController.modificationCheckInterval=36000
参考实现:
org.commontemplate.standard.reload包下相关类

6. 模板名称过滤器扩展
在加载及缓存之前进行路径过滤,用于保证同一个模板的引用名称总是相同。
如:/xxx/yyy.mtl与/xxx/zzz/../yyy.mtl表示同一模板,但会被解析及缓存多次,所以应该用过滤器将其转换成相同的名称。
相关接口:
org.commontemplate.config.TemplateNameFilter
注册方法:
addTemplateNameFilter(TemplateNameFilter) (注:添加的TemplateNameFilter会按顺序组成过滤链)
配置方法:
templateNameFilters[200]=com.xxx.XxxFilter()
参考实现:
org.commontemplate.standard.filter.TemplateNameRelativer (注:此过滤器过滤 ../ 和 ./ 等相对路径)

7. 模板源过滤器扩展
相关接口:
org.commontemplate.config.SourceFilter
注册方法:
addSourceFilter(SourceFilter)
配置方法:
sourceFilters[200]=com.xxx.XxxFilter()
参考实现:
org.commontemplate.standard.coat.AttributeSyntaxCoatFilter

8. 非指令文本块过滤器扩展
编译期过滤非指令文本块.
相关接口:
org.commontemplate.config.TextFilter
注册方法:
addTextFilter(TextFilter)
配置方法:
textFilters[200]=com.xxx.XxxFilter()
参考实现:
org.commontemplate.standard.coat.CommentSyntaxCoatFilter

9. 表达式过滤器扩展
在表达式编译之前过滤表达式文本串.
相关接口:
org.commontemplate.config.ExpressionFilter
注册方法:
addExpressionFilter(ExpressionFilter)
配置方法:
expressionFilters[200]=com.xxx.XxxFilter()
expressionReplacement{&lt;}=< (注:使用内置的ExpressionReplacementFilter)
参考实现:
org.commontemplate.standard.filter.ExpressionReplacementFilter

10. 模板元素渲染过程拦截器扩展
拦截render()过程.
相关接口:
org.commontemplate.config.RenderInterceptor
注册方法:
addRenderInterceptor(RenderInterceptor)
配置方法:
renderInterceptors[200]=com.xxx.XxxInterceptor()
参考实现:
org.commontemplate.standard.debug.DebugInterceptor

11. 表达式求值过程拦截器扩展
拦截evaluate()过程.
相关接口:
org.commontemplate.config.EvaluateInterceptor
注册方法:
addEvaluateInterceptor(EvaluateInterceptor)
配置方法:
evaluateInterceptors[200]=com.xxx.XxxInterceptor()
参考实现:


12. 语法扩展
相关类:
org.commontemplate.config.Syntax (指令语法及特殊指令设置)
注册方法:
setSyntax(Syntax)
配置方法:
syntax.directiveLeader='$'
syntax.expressionBegin='{'
syntax.expressionEnd='}'
syntax.lineComment='#'
syntax.blockComment='*'
syntax.noParse='!'
syntax.endDirectiveName=end
注意事项:
各符号不能重复
默认使用:
Syntax.DEFAULT

13. 关键字扩展
相关类:
org.commontemplate.config.Keywords (表达式关键字设置)
注册方法:
setKeywords(Keywords)
配置方法:
keywords.null="null"
keywords.true="true"
keywords.false="false"
keywords.current="this"
keywords.parent="super"
注意事项:
各关键字不能重复
默认使用:
Keywords.DEFAULT

14. 区域变量扩展
相关接口:
org.commontemplate.config.ScopeHandler
注册方法:
addScopeHandler(name, ScopeHandler)
配置方法:
scopeHandler{xxx}=com.xxx.XXXScopeHandler()
参考实现:
org.commontemplate.standard.scope包下相关类

15. 指令扩展
相关接口和基类:
org.commontemplate.config.DirectiveHandler
org.commontemplate.config.BlockDirectiveHandler
org.commontemplate.config.MiddleDirectiveHandler
org.commontemplate.standard.directive.DirectiveHandlerSupport
org.commontemplate.standard.directive.BlockDirectiveHandlerSupport
org.commontemplate.standard.directive.MiddleDirectiveHandlerSupport
注册方法:
addDirectiveHandler(String name, DirectiveHandler)
配置方法:
directive{xxx}=com.xxx.XXXDirective()
参考实现:
org.commontemplate.standard.directive及其子包下相关类
注意事项:
DirectiveHandler应该保证线程安全,最简单的保证方式是:
(1) 若DirectiveHandler实现类中没有任何属性,则该实现类一定是线程安全的。
(2) 若DirectiveHandler实现类中所有属性都是final的(或只在构造函数中赋值),则该实现类也是线程安全的。
(3) 若DirectiveHandler实现类中所有属性状态都是正确同步的,则该实现类也是线程安全的。
表达式状态:
(a) 表达式名称化:
如果处理类的isExpressionNamed()方法返回true,表示当表达式为变量名时,作为名称串处理,
如:$macro{button}等价于$macro{"button"}
如果特殊情况需要使用变量,可使用反斜线处理:$macro{\name}
(b) 表达式是否必需:
如果处理类的isExpressionRequired()方法返回true,表示当指令必需有表达式,否则报错。

16. 操作符扩展
相关接口和基类:
org.commontemplate.config.BinaryOperatorHandler
org.commontemplate.config.UnaryOperatorHandler
org.commontemplate.standard.operator.BinaryOperatorHandlerSupport
org.commontemplate.standard.operator.UnaryOperatorHandlerSupport
注册方法:
addBinaryOperatorHandler(String name, BinaryOperatorHandler)
addUnaryOperatorHandler(String name, UnaryOperatorHandler)
addBinaryOperatorPriority(String name, int priority) (注:不设置将默认为0)
addUnaryOperatorPriority(String name, int priority) (注:不设置,符号型默认为0,名称型默认为functionPriority)
setFunctionPriority(int priority)
配置方法:
binaryOperator{*}=com.xxx.XXXBinaryOperatorHandler()
unaryOperator{-}=com.xxx.XXXUnaryOperatorHandler()
如果一个操作符针对不同的操作数类型有不同的处理类,可以使用Chain封装:
binaryOperator{*}=org.commontemplate.standard.operator.BinaryOperatorHandlerChain()
binaryOperator{*}.binaryOperatorHandlers=multiplyBinaryOperator[]
multiplyBinaryOperator[100]=com.xxx.NumberMultiplyOperatorHandler()
multiplyBinaryOperator[200]=com.xxx.StringRepeatOperatorHandler()
参考实现:
org.commontemplate.standard.operator及其子包下相关类
注意事项:
OperatorHandler应该保证线程安全,方式同上面的DirectiveHandler
OperatorHandler不应该改变操作数的状态,如:两个集合相加,应将两个集合的项添加到一个新的集合中,而不是将其中一个集合的项添加到另一个集合中。
特殊操作数:
(a) 操作数延迟求值:
用于短路情况,声明Lazy后,参数将以LazyOperand的实例传入,需使用operand = ((LazyOperand)operand).evaluate()方式取其真实值。
如:Boolean的And/Or操作,左操作数决定右操作数是否需要求值,就要用到RightOperandLazy。
相关标识:BinaryOperatorHandler.isLeftOperandLazy(), BinaryOperatorHandler.isRightOperandLazy(), UnaryOperatorHandler.isOperandLazy()
(b) 操作数名称化:
如果操作数为无引号字符串时,不将其作为变量取值,而作为字符串,
如:对象的属性${bean.property},键值对的键${key:value}等,
与加号对比:bean + property,property将作为变量,而不是名称,
相关标识:BinaryOperatorHandler.isLeftOperandNamed(), BinaryOperatorHandler.isRightOperandNamed(), UnaryOperatorHandler.isOperandNamed()
(c) 操作数函数化:
如果操作数为函数时,不将其作为函数一元操作符运算,而作为org.commontemplate.util.Funtion封装,
如:对象的属性${bean.function()}
与加号对比:bean + function(),bean将与function()的返回值相加,
相关标识:BinaryOperatorHandler.isRightOperandFunctioned(), UnaryOperatorHandler.isOperandFunctioned()
(d) 关于函数:
函数其实就是非符号(与变量名规则相同)的一元操作符,注册及使用方式与一元操作符一致,
非符号一元操作符UnaryOperatorHandler.isKeyword()的返回值:
为true时,该操作符名称将不可作为变量名。
为false时,操作符的操作数必需有括号,否则将视为变量。
如:注册“abs”一元操作符,则必需用abs(operand), 而不能用abs operand,否则在复杂表达式中与变量引起歧义,
如果abs的isKeyword()为true, 则可以用abs operand, 但abs将不能再作为变量名。
对比:符号一元操作符“!”,可以用“! operand”,也可以用“!(operand)”
(e) 编译器优化:
当操作数都为常量时,编译器会在编译期求值,并保存到表达式树,操符符应保证传入相同的参数,总是得到相同的结果
如果不希望被优化,覆写isOptimize()方法,使其返回false

17. 属性扩展
用于为"."点号操作符提供数据
属性调用方式如: ${bean.property}
静态属性调用方式如: ${cls.PROPERTY}
系统属性调用方式如: ${.now}
相关接口:
org.commontemplate.standard.property.PropertyHandler
org.commontemplate.standard.property.StaticPropertyHandler
org.commontemplate.standard.property.SystemPropertyHandler
org.commontemplate.standard.property.PropertyHandlerSupport
org.commontemplate.standard.property.StaticPropertyHandlerSupport
org.commontemplate.standard.property.SystemPropertyHandlerSupport
配置方法:
property{java.lang.String.xxx}=com.xxx.XXXPropertyHandler()
staticProperty{java.lang.String.xxx}=com.xxx.XXXPropertyHandler()
systemProperty{xxx}=com.xxx.XXXPropertyHandler()
参考实现:
org.commontemplate.standard.property包及其子包相关类

18. 方法扩展
用于为"."点号操作符提供数据,并且只有在配置functionAvailable=true时才有效
方法调用方式如: ${obj.func(arg1,arg2)}
静态方法调用方式如: ${cls.func(arg1,arg2)}
系统方法调用方式如: ${.func(arg1,arg2)}
相关接口:
org.commontemplate.standard.function.FunctionHandler
org.commontemplate.standard.function.StaticFunctionHandler
org.commontemplate.standard.function.SystemFunctionHandler
org.commontemplate.standard.function.FunctionHandlerSupport
org.commontemplate.standard.function.StaticFunctionHandlerSupport
org.commontemplate.standard.function.SystemFunctionHandlerSupport
配置方法:
function{java.lang.String.xxx}=com.xxx.XXXFunctionHandler()
staticFunction{java.lang.String.xxx}=com.xxx.XXXFunctionHandler()
systemFunction{xxx}=com.xxx.XXXFunctionHandler()
参考实现:
org.commontemplate.standard.function包及其子包相关类

19. 序列扩展
用于为".."双点号操作符提供数据
相关接口:
org.commontemplate.standard.operator.sequence.StringSequenceOperatorHandler
org.commontemplate.standard.operator.sequence.StringSequence
注册方法:
addStringSequence(String[] sequence)
addStringSequence(String[] sequence, boolean cycle, boolean ignoreCase)
配置方法:
sequence<weekDays>=Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday
参考实现:
org.commontemplate.standard.operator.sequence包下相关类

20. 国际化扩展
用于为$msg或$message指令提供国际化信息内容
相关接口:
org.commontemplate.standard.i18n.ResourceBundleProvider
注册方法:
setResourceBundleProvider(ResourceBundleProvider)
setMessageBaseName(String baseName) (注:使用内置的PropertiesResourceBundleProvider)
配置方法:
resourceBundleProvider=org.commontemplate.standard.i18n.PropertiesResourceBundleProvider()
resourceBundleProvider.baseName=messages
参考实现:
org.commontemplate.standard.i18n.PropertiesResourceBundleProvider

21. 日志扩展
用于$log指令的输出.
相关接口:
org.commontemplate.util.log.LoggerProvider
org.commontemplate.util.log.Logger
配置方法:
loggerProvider=org.commontemplate.standard.log.CommonsLoggerProvider()
参考实现:
org.commontemplate.util.log包下相关类

22. 迭代数据集合转换器扩展
用于为"$for"指令提供迭代数据
相关接口和基类:
org.commontemplate.standard.collection.CollectionConverter
配置方法:
collectionConverter{com.xxx.XXX}=com.xxx.XXXCollectionConverter()
参考实现:
org.commontemplate.standard.collection包下相关类

23. 数据加载类型扩展
用于为"$data"指令提供数据
相关接口和基类:
org.commontemplate.standard.data.DataProvider
org.commontemplate.standard.data.InputStreamDataProvider
org.commontemplate.standard.data.StringDataProvider
配置方法:
dataProvider{xxx}=com.xxx.XXXDataProvider()
参考实现:
org.commontemplate.standard.data包下相关类

24. 代码过滤扩展
用于为"$code"指令提供过滤器
相关接口和基类:
org.commontemplate.core.OutputFilter
配置方法:
codeFilter{xxx}=com.xxx.XXXCodeFilter()
参考实现:
org.commontemplate.standard.directive.filter.code包下相关类

25. 转义过滤扩展
用于为"$escape"指令提供过滤器
相关接口和基类:
org.commontemplate.core.OutputFilter
配置方法:
escapeFilter{xxx}=com.xxx.XXXEscapeFilter()
参考实现:
org.commontemplate.standard.directive.filter.escape包下相关类

 

版权所有 © 2007 - 2009 CommonTemplate 开发小组