|
|
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{<}=< (注:使用内置的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包下相关类
|
|
|