[英]exporting constructors into the FreeMarker data model
有什么方法可以將特定的類構造函數導出到FreeMarker數據模型中?
ObjectConstructor
提供了訪問任何可訪問的構造函數的能力:
Java的:
myDataModel.put("objectConstructor", new ObjectConstructor());
模板:
<#assign aList = objectConstructor("java.util.ArrayList", 100)>
但是我不想那樣做。 如果我有一個帶有兩個構造函數Foo(int x)
和Foo(String name, int x)
的類Foo
,我想以某種方式將一個對象導出為Foo
到數據模型中,以便可以在模板中執行此操作:
<#assign myfoo1 = Foo(1) >
<#assign myfoo2 = Foo("Buffalo Bill", 2) >
我可以使用TemplateMethodModelEx
手動執行此操作,但它需要我實現exec(List arguments)
並弄清楚如何拉出參數並將其推入Foo
類構造函數中。
我想要的是一個ClassConstructor
對象,該對象接受相關Class<T>
參數,並實現TemplateMethodModelEx
並自動進行強制轉換,就像FreeMarker自動處理Java對象方法調用一樣,我可以在Java中完成此操作:
myDataModel.put("Foo", new ClassConstructor(Foo.class));
有沒有辦法做到這一點?
從FTL調用Java方法和構造函數是BeansWrapper
的業務,它也是DefaultObjectWrapper
和您在那里找到的大多數自定義ObjectWrapper
的超類。 因此, ObjectWrapper.newInstance(Class clazz, List/*<TemplateModel>*/ arguments)
可以為您完成棘手的部分。 其他的則是一些瑣碎的工作(我在這里花了點時間來獲取ObjectWrapper
這是可選的):
package freemarker.adhoc;
import java.util.List;
import freemarker.core.Environment;
import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;
/**
* Creates an FTL method that calls the constructor of the given class. Supports overloading and varargs.
*/
public class ConstructorTemplateModel implements TemplateMethodModelEx {
private final Class constructorClass;
private final BeansWrapper objectWrapper;
/**
* @param objectWrapper
* The same {@link ObjectWrapper} used in the {@link Configuration}, or {@code null} if we should
* find the current {@link ObjectWrapper} for each constructor call (slower).
*/
public ConstructorTemplateModel(Class<?> constructorClass, BeansWrapper objectWrapper) {
this.constructorClass = constructorClass;
this.objectWrapper = objectWrapper;
}
@Override
public Object exec(List/*<TemplateModel>*/ arguments) throws TemplateModelException {
BeansWrapper objectWrapper = this.objectWrapper;
if (objectWrapper == null) {
objectWrapper = getCurrentBeansWrapper();
}
return objectWrapper.newInstance(constructorClass, arguments);
}
private BeansWrapper getCurrentBeansWrapper() {
Environment env = Environment.getCurrentEnvironment();
if (env == null) {
throw new IllegalStateException("No ongoing template processing");
}
ObjectWrapper objectWrapper = env.getObjectWrapper();
if (!(objectWrapper instanceof BeansWrapper)) {
throw new IllegalStateException("The object wrapper must be a BeansWrapper. Object wrapper class: "
+ objectWrapper.getClass().getName());
}
return (BeansWrapper) objectWrapper;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.