XDoclet


XDoclet 學習筆記

©原作者:Rick Hightower   北漂男人整理

•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 編程語言中的 if 和 for 語句之類的流。內容標記打印當前解析樹上下文的片段,如類名稱、方法名稱和參數,等等。

•模板示例:

    這裏有一個簡單的模板,它尋找所有的實體 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:forAllClassestype="javax.ejb.EntityBean">
   
Classname=<XDtClass:className/>


    <XDtProperty:forAllPropertiesWithTagtagName="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。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章