xDoclet是一种通过读取Java源文件中的特定标签,然后生成指定文件的工具。xDoclet标签本身已经提供了一些常用的标签,例如@ejb,@hibernate,@web等等,但是仍然不能满足我们的需求。
例如我们最新的项目中引用了一个javascript验证框架,通过配置特定的XML配置文件,即可完成客户端表单验证,但是不想开发人员再去学习一套框架,于是想让开发人员在源代码中写@javascript这样的标签,然后生成其配置文件。
Javascript客户端验证一直是web开发中一个比较头疼的问题,经常是每一个页面中充斥着许多类似甚至相同的验证代码,如何统一有效的治理这些代码,以及如何做到代码页面的分离一直没有太好的解决方法。
运用这个验证框架那么客户端开发就变成了配置validation-config.xml这个文件如此轻松了,本文并不打算具体讲述如何使用JSValidation框架,有爱好的朋友可以去http://www.cosoft.org.cn/projects/jsvalidation JSValidation的官方网站自己去学习。
虽然运用这框架已经可以很好的完成客户端验证代码的编写,并且提供了dtd文件进行xml文件的,但是手动编写xml文件还是很轻易出错,效率比较低,而且新的开发人员还要把握一个全新的框架,不宜于开发人员入门。
像Struts或JSF这样的框架大都需要为表单写一个类似FormBean的东西,以JSF为例,假如表单内有一文本框<input type=”text” name=”txtUsername” /,那么对应的Page类或叫FormBean类就应有如下代码:
private HtmlInputText txtUsername = new HtmlInputText();
/**
* @return 用户名
*/
public HtmlInputText getTxtUsername ()
{
return txtUsername;
}
/**
* @param text
*/
public void setTxtTeaName(HtmlInputText text)
{
txtTeaName = text;
}
假如可以利用xDoclet,那么,就可以自动生成JSValidation的配置文件了,而且还利于培训新的开发人员,再加入ant task还可以形成每日构建。想象的代码应该是下面这个样子:
/**
* @javascript.field
* name="frmZBAddGlobalPage:txtTeaName"
* display-name="用户名"
*
* @javascript.depend
* name="required"
*
* @return用户名
*/
public HtmlInputText getTxtUsername()
{
return txtUsername;
}
通过分析xDoclet自带的一些标签包,发现只需要提供三个文件即可实现自定义xDoclet标签:一个继续于XmlSuBTask的类,一个继续于DocletTask的类(用于ant),一个xdt的模板语言文件即可。
在XmlSubTask类中,首先,定义模板文件名:
private static String DEFAULT_TEMPLATE_FILE =
"resources/validation-config.xdt";
定义dtd文件名:
private final static String DTD_FILE_NAME_20 =
"resources/validation-config.dtd";
定义要生成的配置文件名:
private static String GENERATED_FILE_NAME = "validation-config.xml";
然后只需将三个文件组合起来既可,具体代码如下:
public JavascriptSubTask()
{
setTemplateURL(getClass().getResource(DEFAULT_TEMPLATE_FILE));
setDestinationFile(GENERATED_FILE_NAME);
}
public void execute() throws XDocletException
{
setDtdURL(getClass().getResource(DTD_FILE_NAME_20));
startProcess();
}
protected void engineStarted() throws XDocletException
{
System.out.println(
Translator.getString(
XDocletMessages.class,
XDocletMessages.GENERATING_SOMETHING,
new String[] { getDestinationFile()}));
}
要想ant可以使用,只需要以下简单的代码:
/*
* 创建日期 2004-4-26
*/
package paradise.xdoclet.modules.javascript;
import xdoclet.DocletTask;
/**
* @author 清风
*/
public class JavascriptDocletTask extends DocletTask
{
public JavascriptDocletTask()
{
addSubTask(new JavascriptSubTask());
}
}
在ant中按如下方式定义:
<target name="javascript" depends="jxdoc_init" description="Generate javascript validation-config"
<javascriptdoclet destdir="${jsp}/javascript"
<fileset dir="${src}"
<include name="**/zaibian/*.java"/
</fileset
</javascriptdoclet
</target
接下来,也是最核心的部分,就是有关xdt模板语言,xdt文件可以说是自定义xDoclet标签的最重要的文件之一,以JavaScriptxDoclet为例,简单介绍一下xdt模板语言:
<XDtClass:forAllClasses遍历所有含有标签的类(在ant中指定)
<XDtMethod:forAllMethods遍历当前类的所有方法
<XDtMethod:ifHasMethodTag tagName="javascript.form"假如遍历到的方法中含有指定的标签
<XDtMethod:forAllMethodTags tagName="javascript.depend"遍历当前方法的所有标签
更多的模板语言,参考xDoclet的.XDT文档,都是很好理解的模板语言。
接下来,开始自定义自己的标签,新建一个xtags.xml文件,加上开头
<?xml version="1.0" encoding="UTF-8"?
<!DOCTYPE xdoclet PUBLIC "-//XDoclet Team//DTD XDoclet Tags 1.1//EN" "http://xdoclet.sourceforge.net/dtds/xtags_1_1.dtd"
然后写下所有自定义的标签,例如:
<xdoclet
<namespace
<namejavascript</name
<tags
<tag
<levelmethod</level
<namejavascript.form</name
<usage-descriptionForm</usage-description
<condition type="method"/
<parameter type="text"
<nameid</name
<usage-descriptionForm id</usage-description
<mandatorytrue</mandatory
</parameter
<parameter type="text"
<nameshow-error</name
<usage-descriptionForm Error Display</usage-description
<mandatorytrue</mandatory
</parameter
<parameter type="text"
<nameonfail</name
<usage-descriptionForm Error Run Custom Javascript Function</usage-description
<mandatoryfalse</mandatory
</parameter
</tag
</tags
</namespace
</xdoclet
注重几个地方:
“<level method </level”代表该标签出现在方法上而不是类之上。例如
/**
*@javascript.form
*name=”test”
*/
public String getXXX()
{
}
a
最后就是将这些文件打成jar,其放置目录分别是:
根目录
--META-INF/xtags.xml
--源代码
----
------resources/*.xdt,*.dtd