XDoclet 学习笔记

来源:互联网 发布:程序员看不懂英文文档 编辑:程序博客网 时间:2024/06/05 20:31

•XDoclet概要:

    XDoclet 是一个通用的代码生成实用程序,是一个扩展的Javadoc Doclet引擎(现已与Javadoc Doclet独立),XDoclet是EJBDoclet的后继者,而EJBDoclet是由Rickard Oberg发起的。(http://xdoclet.sourceforge.net/xdoclet/index.html),它允许您使用象 JavaDoc 标记之类的东西来向诸如类、方法和字段之类的语言特征添加元数据。随后,它利用这些额外的元数据来生成诸如部署描述符和源代码之类的相关文件。可以让你创建自己的javadoc @tags进而利用XDoclet中的Templet enging基于这些@tags生成源代码或其他文件(例如xml的deployment descriptors)。

    XDoclet 继承了 JavaDoc 引擎的思想,允许根据定制 JavaDoc 标记生成代码和其他文件。当然,XDoclet 也可以访问整个解析树。这样,它就可以访问类、类的包结构和类的方法。

    人类发明了计算机来让它做那些枯燥无味的事情,而将自己解脱出来,去做有创造性的事情。使用 XDoclet 模板将使开发人员从单调无味的代码中解脱出来。

    XDoclet 提供了自己的模板引擎。该模板引擎在概念上类似于 JavaServer Pages(JSP)技术。它实质上包含两类标记:块标记(block tag)和内容标记(content tag)。块标记控制如 Java 编程语言中的 iffor 语句之类的流。内容标记打印当前解析树上下文的片段,如类名称、方法名称和参数,等等。

•模板示例:

    这里有一个简单的模板,它寻找所有的实体 Bean(EntityBean),然后打印出它们的类名称及其所有 cmp 字段的名称:

  <XDtClass:forAllClasses type="javax.ejb.EntityBean">
   Classname=<XDtClass:className/>
   <XDtProperty:forAllPropertiesWithTag tagName="ejb.persistence">
        CMP Field = <XDtMethod:propertyName/>
   </XDtProperty:forAllPropertiesWithTag>
</XDtClass:forAllClasses>

     这个模板同时演示了块标记和内容标记。

     —forAllClasses 是一个块标记示例,它遍历传递给模板引擎的所有类,这些类是通过调用 XDoclet 的 ant 构建文件中的 fileset 传递的。forAllClasses 使用 type 属性(type="javax.ejb.EntityBean")过滤掉不属于类型 javax.ejb.EntityBean 的那些类。

     —className 是内容标记的一个示例,它打印出当前类的名称。

     forAllProperitesWithTag 是另一个块标记示例。它遍历实现类中所有具有 XDoclet 标记 @ejb.persistence 的特性(这些特性与该 bean 的 cmp 字段相关)。最后,propertyName 是内容标记的另外一个示例,因为它在遍历过程中显示当前特性名称。

    下面用黑色粗体字体显示了块标记,用红色粗体字体显示了内容标记。另外,这些块还用圆矩形框来演示其范围。

 

  <XDtClass:forAllClasses type="javax.ejb.EntityBean">
   Classname=<XDtClass:className/>

    <XDtProperty:forAllPropertiesWithTag tagName="ejb.persistence">
        CMP Field = <XDtMethod:propertyName/>
   </XDtProperty:forAllPropertiesWithTag>

</XDtClass:forAllClasses>

       这个代码模板的输出如下:

 Classname=EmployeeBean
        CMP Field = id
        CMP Field = firstName
        CMP Field = lastName
        CMP Field = phone

Classname=DeptBean
        CMP Field = id
        CMP Field = name

      要运行该模板,您的 ant 构建文件中将需要下列代码:

 <target name="templatedoclet" >
   <taskdef
      name="templatedoclet"
      classname="xdoclet.DocletTask"
      classpathref="xdocpath"
   />
   <templatedoclet destdir="test">
      <fileset dir="${src}">
         <include name="**/*Bean.java"/>
      </fileset>
      <template
         templateFile="template/template.xdt"
         destinationfile="test.txt"/>
   </templatedoclet>
</target>

    templatedoclet 任务用来执行模板。fileset 子元素用于指定:您只想要 src 目录中以“Bean.java”结尾的文件。模板子任务用于指定被使用的模板文件以及目标文件。

•XDoclet 体系结构:

  XDoclet 由三个主要组件组成:

  1. XJavaDoc 引擎
  2. XDoclet 引擎
  3. 模块

模块由几个部分组成:

  1. 任务
  2. 子任务
  3. 标记处理程序
  4. 模板

     —XJavaDoc 引擎:XJavaDoc 解析 Java 源文件,然后构建有关类和语言特征(包、方法和字段)以及元数据的信息树。XJavaDoc 引擎通过一个易于使用的 API 提供访问。该 API 提供了与带有一些额外特征的 JavaDoc API 相同的类信息,这些额外特征与存储及读取元数据以及其他结构相关联。XJavaDoc 增加了在运行时修改 JavaDoc 标记的能力。这样就可以推断元数据,并可以将其缺省值设为比较合理的值。

    —XDoclet 引擎:XJavaDoc 引擎读取标记,这些标记组成了类的元数据和结构。XDoclet 引擎使用来自 XJavaDoc 引擎的信息,来生成支持文件(源代码和部署描述符)。XDoclet 提供了一个优秀的模板生成引擎,该引擎将模板转换成一个或多个支持文件。XDoclet 有一个模块装入程序,它动态地装入用 xdoclet.xml 文件(包含在模块的 jar 文件中)指定的 XDoclet 模块。

    您无需创建模块就可创建模板。每个顶级 XDoclet Ant 任务都有执行任意模板的能力,以此替换随模块一起提供的模板。

    —模块引擎:模块由任务、子任务、标记处理程序和模板组成。

 子任务:子任务指定要调用的缺省模板,它允许您向该模板传递配置参数。在编写了一些模板之后,您将编写一个子任务。子任务的示例如下所示:

 <ejbdoclet ...>
     <localinterface/>
</ejbdoclet>

上面的 localinterface 是 ejbdoclet 下的一个子任务。我将描述如何在 ejbdoclet 下面编写另外一个子任务来处理将 EJB 组件作为 Web 服务公开。在我讨论子任务时,您将了解如何实现子任务并指定其结构,以及如何指定它们同其父任务之间的关系。

模板:XDoclet 模板生成部署描述符和源代码文件。实际上,XDoclet 模板可以生成任何类型的文件。正是这种能力为组件开发提供了帮助,生成了组件的各种配置文件和部署描述符。实际上,您甚至可以编写自己的组件框架,然后使用 XDoclet 来生成另外的部署类型文件。

标记处理程序:标记处理程序对于 XDoclet 标记,就如同定制标记(Custom Tag)处理程序对于 JSP 定制标记。XDoclet 引擎根据标记的名称将标记映射到与该标记对应的标记处理程序。标记处理程序类必须生成 xdoclet.TagHandler 的子类。XDoclet 使用反射来根据标记名称调用标记处理程序的方法。因此,XDtProperty:forAllPropertiesWithTag 在 Property 标记处理程序中寻找方法 forAllPropertiesWithTag。

模板引擎通过在与标记一起提供的 xdoclet.xml 文件中查找标记处理程序,来了解要使用哪个标记处理程序。以下是核心 xdoclet.xml 文件中用于 Property 标记处理程序入口的代码片段:

  <taghandler
    <taghandler namespace="Property"      
     class="xdoclet.tagshandler.PropertyTagsHandler"/>
...
/>

当 XDoclet 碰到 XDtProperty:forAllPropertiesWithTag 标记时,它便在 xdoclet.tagshandler.PropertyTagsHandler 类中寻找 forAllPropertiesWithTag 方法。其实现方法如下:首先将 XDt 前缀从 XDtProperty 剥离,然后查找在 xdoclet.xml 文件中定义的映射。

以下是 Property 标记处理程序的部分清单:

  public class PropertyTagsHandler extends AbstractProgramElementTagsHandler
{
...
     public void forAllPropertiesWithTag(String template, Properties attributes)
                                                          throws XDocletException
     {
         ...
         String requiredTag = attributes.getProperty("tagName");
         if (requiredTag == null) {
             throw new XDocletException(
             "missing required tag parameter in forAllPropertiesHavingTag");
         }
         XClass oldClass = getCurrentClass();
         XClass superclass = null;
         Collection already = new ArrayList();
         // loop over superclasses
         do {
             XMethod oldCurrentMethod = getCurrentMethod();
             Collection methods = getCurrentClass().getMethods();
             for (Iterator j = methods.iterator(); j.hasNext(); ) {
                 XMethod currentMethod = (XMethod) j.next();
                 log.debug("looking at method " + currentMethod.getName());
                 if (currentMethod.getDoc().hasTag(requiredTag)) {
                     setCurrentMethod(currentMethod);
                     String propertyName = currentMethod.getPropertyName();
                     log.debug("property identified " + propertyName);
                     if (!already.contains(propertyName)) {
                         generate(template);
                         already.add(propertyName);
                     }
                 }
                 setCurrentMethod(oldCurrentMethod);
             }
             // Add super class info
             superclass = getCurrentClass().getSuperclass();
             if (superclass != null) {
                 pushCurrentClass(superclass);
             }
         } while (superclass != null);
         setCurrentClass(oldClass);
     }
...

•查找模板块和内容标记:

    要开发自己的定制模板,最好的方法是参考 XDoclet 在其模块中提供的类似模板。您可以这样做:解压缩(unjar)那些模块,寻找以 xdt 结尾的文件,或者下载 XDoclet 源代码并寻找那些模板。此外,还有一种方法,借助类似于 JavaDoc 的文档来查找与 XDoclet 一起提供的所有可用的模板标记。

    幸运的是,XDoclet 提供了整个模板语言的参考大全。可以在 [XDoclet Install Dir]/docs/templates/index.html 中找到该参考大全。它是您开发真正属于自己的定制模板的指南。

    如果您熟悉 JavaDoc,那么该模板语言参考大全使用起来就很简单。XDoclet 标记处理程序对应于那些标记的名称空间,它们显示在左上面板中。特定处理程序的实际标记显示在左下方,而该标记的文档则显示在右边的面板中。如果您想查找一个标记(例如,XDtClass:forAllClasses),那么请从名称空间剥离掉 Xdt(例如,XdtClass 变成 class),然后查找该标记(如,forAllClasses)。请参阅上图以便搞清楚如何查找 XDtClass:forAllClasses。

 
原创粉丝点击