<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    精彩的人生

    好好工作,好好生活

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      147 Posts :: 0 Stories :: 250 Comments :: 0 Trackbacks

    #

    突然發現我認識的今年畢業的人工作都找的很好(除了我們學校的),一個去了上海思科,一個是本科生,也去了上海,一個去了甲骨文。

    不知道我畢業的時候會咋樣,每念及此,倍感憂心。
    posted @ 2006-04-19 10:19 hopeshared 閱讀(259) | 評論 (0)編輯 收藏

    譯者:gracepig

    E-mail & MSN : zhangchi_nwpu@hotmail.com


    版權聲明:可以任意轉載,轉載時請務必以超鏈接形式標明文章原始出處和作者信息及本聲明
    英文原文地址:
    http://www.javaworld.com/javaworld/jw-07-2005/jw-0704-jena.html

    中文地址
    http://www.matrix.org.cn/resource/article/43/43598_RDF_JAVA.html

    關鍵詞:Resource Description Framework models RDF XML Jena Protégé

    摘要
    資源描述框架(Resource Description Framework RDF)是一種以XML格式描述元數據的標準格式。Jena是一種用于將關系數據庫或是文本文件中所表示的數據建立為元數據模型的框架方法。Protégé 用用來創建RDF元數據文檔的編輯工具。 建立這種數據庫和文件的元數據模型需要由用戶自己定義腳本。本文介紹介紹了SemantiRDFUtils這種腳本,它擁有多個功能塊可以用于維護Jena RDF 元數據模型.(2200詞,2005-7-4) By Venkata N.VAsam

    與XML成為不同軟件廠商之間數據交互的標準過程相似,資源描述框架(RDF)也沿著這條道路前進,希望能夠成為描述與交互元數據的標準。XML 使用文件類型定義(DTD)和XML格式定義(XSD)來描述數據。RDF使用XML語法和RDF Schema(RFDS)來將元數據描述成為數據模型。

    本文介紹了一種使用Jena RDF API 編寫的用戶自定義工具,使用這種工具來管理存儲在關系數據庫或是文本文件的數據模型。這種工具是由HP實驗室開發的,Jena框架是一個RDF,RDFS以及OWL(Web Ontology Language)的開源實現, 它包含著一個基于規則的推論引擎。它提供了建立和操縱RDF模型的Java API。本文介紹的SemanticRDFUtils.bat是一種使用Jena開發的腳本。使用這種腳本,我們可以維護存儲在關系數據庫和文本文件中的元數據模型。本文還介紹了怎樣使用Protégé來將建RDF的語意描述文件(.rdfs)和數據文件(.rdf)。

    軟件安裝
    在使用SemanticRDFUtils.bat之前必須先安裝以下的軟件。關于以下工具的鏈接請參看文中所附的資源。
    ????????J2SE 1.3 或更高的版本
    ????????Jena 2.0
    ????????Oracle 9.2.0.1.0
    ????????Apache Ant 1.5.4 或更新的版本
    ????????Protégé 2.1


    RDF和RDFS 文件簡要介紹
    下面的XML格式的RDF和RDFS文件用于顯示一個字母順序的交叉引用模型。它們是使用Protégé 2.1 的圖形界面工具創建的。當執行腳本和RDF查詢工具的時候我們可以動態的引入RDF文件。RDFS文件則在我們使用Protégé 給RDF文件中加入更多數據時使用。


    列表1. RDFTest1.rdf

    <?xml version='1.0' encoding='UTF-8'?>
    <!DOCTYPE rdf:RDF [
    ?? <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
    ?? <!ENTITY rdfs 'http://www.w3.org/TR/1999/PR-rdf-schema-19990303#'>
    ?? <!ENTITY Maana 'http://www.vvasam.com/Maana#'>
    ]>
    <rdf:RDF xmlns:rdf="&rdf;"
    ?? xmlns:Maana="&Maana;"
    ?? xmlns:rdfs="&rdfs;">
    <Maana:ASCII rdf:about="&Maana;RDFTest_Instance_0"
    ?? Maana:Name="A"
    ?? Maana:value="65"
    ?? rdfs:label="A:65">
    ?? <Maana:system rdf:resource="&Maana;RDFTest_Instance_2"/>
    </Maana:ASCII>
    <Maana:System rdf:about="&Maana;RDFTest_Instance_1"
    ?? Maana:Name="lowercase"
    ?? rdfs:label="lowercase"/>
    <Maana:ASCII rdf:about="&Maana;RDFTest_Instance_10000"
    ?? Maana:Name="b"
    ?? Maana:value="98"
    ?? rdfs:label="b:98">
    ?? <Maana:system rdf:resource="&Maana;RDFTest_Instance_1"/>
    </Maana:ASCII>
    <Maana:ASCII rdf:about="&Maana;RDFTest_Instance_10001"
    ?? Maana:Name="B"
    ?? Maana:value="66"
    ?? rdfs:label="B:66">
    ?? <Maana:system rdf:resource="&Maana;RDFTest_Instance_2"/>
    </Maana:ASCII>
    <Maana:AscXRef rdf:about="&Maana;RDFTest_Instance_10002"
    ?? rdfs:label="b:98:B:66">
    ?? <Maana:keyName rdf:resource="&Maana;RDFTest_Instance_10000"/>
    ?? <Maana:keyValue rdf:resource="&Maana;RDFTest_Instance_10001"/>
    </Maana:AscXRef>
    <Maana:AscXRef rdf:about="&Maana;RDFTest_Instance_10005"
    ?? rdfs:label="a:97:A:65">
    ?? <Maana:keyValue rdf:resource="&Maana;RDFTest_Instance_0"/>
    ?? <Maana:keyName rdf:resource="&Maana;RDFTest_Instance_8"/>
    </Maana:AscXRef>
    <Maana:System rdf:about="&Maana;RDFTest_Instance_2"
    ?? Maana:Name="uppercase"
    ?? rdfs:label="uppercase"/>
    <Maana:ASCII rdf:about="&Maana;RDFTest_Instance_8"
    ?? Maana:Name="a"
    ?? Maana:value="97"
    ?? rdfs:label="a:97">
    ?? <Maana:system rdf:resource="&Maana;RDFTest_Instance_1"/>
    </Maana:ASCII>
    </rdf:RDF>


    列表 2. RDFTest1.rdfs

    <?xml version='1.0' encoding='UTF-8'?>
    <!DOCTYPE rdf:RDF [
    ?? <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
    ?? <!ENTITY system 'http://protege.stanford.edu/system#'>
    ?? <!ENTITY Maana 'http://www.vvasam.com/Maana#'>
    ?? <!ENTITY rdfs 'http://www.w3.org/TR/1999/PR-rdf-schema-19990303#'>
    ]>
    <rdf:RDF xmlns:rdf="&rdf;"
    ?? xmlns:system="&system;"
    ?? xmlns:rdfs="&rdfs;"
    ?? xmlns:Maana="&Maana;">
    <rdf:Property rdf:about="&system;maxCardinality"
    ?? rdfs:label="system:maxCardinality"/>
    <rdf:Property rdf:about="&system;minCardinality"
    ?? rdfs:label="system:minCardinality"/>
    <rdf:Property rdf:about="&system;range"
    ?? rdfs:label="system:range"/>
    <rdfs:Class rdf:about="&Maana;ASCII"
    ?? rdfs:label="ASCII">
    ?? <rdfs:subClassOf rdf:resource="&rdfs;Resource"/>
    </rdfs:Class>
    <rdfs:Class rdf:about="&Maana;AscXRef"
    ?? rdfs:label="AscXRef">
    ?? <rdfs:subClassOf rdf:resource="&rdfs;Resource"/>
    </rdfs:Class>
    <rdf:Property rdf:about="&Maana;Name"
    ?? rdfs:label="Name">
    ?? <rdfs:domain rdf:resource="&Maana;ASCII"/>
    ?? <rdfs:domain rdf:resource="&Maana;System"/>
    ?? <rdfs:range rdf:resource="&rdfs;Literal"/>
    </rdf:Property>
    <rdf:Property rdf:about="&Maana;RDFTest_Slot_10003"
    ?? rdfs:label="RDFTest_Slot_10003">
    ?? <rdfs:range rdf:resource="&rdfs;Literal"/>
    </rdf:Property>
    <rdfs:Class rdf:about="&Maana;System"
    ?? rdfs:label="System">
    ?? <rdfs:subClassOf rdf:resource="&rdfs;Resource"/>
    </rdfs:Class>
    <rdf:Property rdf:about="&Maana;keyName"
    ?? rdfs:label="keyName">
    ?? <rdfs:range rdf:resource="&Maana;ASCII"/>
    ?? <rdfs:domain rdf:resource="&Maana;AscXRef"/>
    </rdf:Property>
    <rdf:Property rdf:about="&Maana;keyValue"
    ?? rdfs:label="keyValue">
    ?? <rdfs:range rdf:resource="&Maana;ASCII"/>
    ?? <rdfs:domain rdf:resource="&Maana;AscXRef"/>
    </rdf:Property>
    <rdf:Property rdf:about="&Maana;system"
    ?? rdfs:label="system">
    ?? <rdfs:domain rdf:resource="&Maana;ASCII"/>
    ?? <rdfs:range rdf:resource="&Maana;System"/>

    </rdf:Property>
    <rdf:Property rdf:about="&Maana;value"
    ?? rdfs:label="value">
    ?? <rdfs:domain rdf:resource="&Maana;ASCII"/>
    ?? <rdfs:range rdf:resource="&rdfs;Literal"/>
    </rdf:Property>
    </rdf:RDF>


    Jena和Protégé概述
    本節在宏觀層面上介紹Jena和Protégé。用戶可以在附加資源中得到關于這兩個產品更多的信息。本文的目的是使您對Jena和Protégé有一個比較清晰的理解。

    Jena RDF 和RDQL

    RDF數據模型是一個聲明(statement)的集合,每一個聲明都包括三個部分:資源,屬性和值。 資源(resource)可以是任何使用URI標示的內容,它可以包含其它屬性。每一個屬性有一個值。
    Jena可以將RDF模型保存在關系數據庫或是文件當中。RDQL是用來查詢RDF模型的語言。RDF提供一種節點可以為資源或是文本的有向圖(有向圖的概念請參看《離散數學》)。RDQL則提供一種方式,由用戶定義一種圖模式,使用這種模式對目標圖集合進行匹配,獲得所有符合定義模式的結果。圖1 使用RDF圖來表示列表1和列表2中文件

    resized image

    圖1:范例RDF文件的RDF 圖表示


    上圖中,橢圓代表資源,長方形代表描述。資源通過箭頭連接到其它的資源或是描述值(一個對象或是一個值)上,這樣一組關系形成一個三元組,成為一個聲明(statement)。
    下面給我一個RDQL查詢的例子。三元組(?x <http://www.vvasam.com/Maana#value> "97")是一個聲明。X是一個綁定的變量用來代表一個資源;http://www.vvasam.com/Maana#value是一個叫做“value”的屬性;97是這個屬性的值。

    SELECT ?x WHERE (?x <http://www.vvasam.com/Maana#value> "97")

    Jena的toolkit提供了一個在命令行方式執行的Java類(jjena.rdfquery)來進行RDQL查詢。下面的例子演示了如果使用這個命令進行查詢并將查詢結果存入test1.rdql當中。
    java jena.rdfquery --data RDFTest1.rdf --query test1.rdql
    x
    ================================================
    http://www.vvasam.com/Maana#RDFTest_Instance_8

    注意:通過文后的資源鏈接來獲得關于RDF和RDQL更多的信息。


    RDF 中使用Protégé

    Protégé 是一個用來建立和編輯ontologies和知識庫的GUI工具。Protégé可以在RDF格式下創建和保存數據。在使用Protégé建立RDF模型時,需要在新建一個工程的時候選取RDF Schema,如圖2所示。


    圖2. RDF Schema工程


    在Protégé's工程菜單選擇新建工程時,選擇格式(Select Format)對話框會彈出。點擊OK按鈕,圖3的窗口會出現。


    圖3. 缺省Protégé工程視圖


    正如您在圖3中所看到的那樣,Protégé有一些標簽。本文主要介紹其中的Classes,Instances和Algernon標簽。
    圖4顯示了Protégé的保存對話框。在其中用戶可以填入工程,類文件,實例文件,和命名空間的名字。如圖4所示,類文件名中包括RDF Schema的信息,實例文件名中包括RDF的數據。命名空間中以唯一URI的方式標示出RDF模型。


    圖4: Protégé's保存對話框


    圖5和圖6顯示的是Protégé's類標簽和實例標簽,分別表示了列表1和列表2中的.rdf和.rdfs文件。這些文件使用Protégé's schema 格式創建。


    圖5: Protégé的類標簽



    圖6: Protégé的實例標簽


    Protégé中的Algeronon 查詢
    Protégé's的Algernon query標簽為進行Algernon查訊提供了一個圖形界面,用戶可以在這個UI當中進行查詢,并查看結果。Algernon是一種基于三元組的查詢語言,如圖7所示Algernon將資源以遍歷(traversal)路徑的方式返回給用戶。缺省的Algernon并不會如下圖那樣顯示。要看到這個標簽,用戶必須從工程菜單的設置子菜單中選擇。



    圖7. Algernon 標簽


    Jena和Protégé之間的命名(terminology)映射
    由于Jena和Protégé是兩個不同的開源技術,所以他們的RDF 命名(terminology)存在差別。下表中列出了這些命名規則,用戶可以更具這些命名規則來創建和處理RDF文件。


    表1. Jena 和 Protégé 命名比較



    Jena 的語義RDF工具

    一節講解了一些用于維護Jena數據庫和文件模型的有用的工具/腳本。這些腳本文件包含在SemanticRDFUtils-scripts-files.zip文件當中,您可以在資源當中找到。下面的列表中描述了這些腳本文件可以執行的任務。當用戶以沒有任務ID號作為參數的命令行方式執行SemanticRDFUtils批處理文件時,下面的內容將會出現在你的控制臺當中

    C:\RDF\SemanticRDFUtils
    Usage: SemanticRDFUtils taskid
    ?? Where taskid should be any one of the following:
    ????1 --> To create and initialize the Jena system tables with a system model name as JenaRDFSystem
    ????2 --> To create a database model
    ????3 --> To remove a database model.
    ????4 --> To list the contents of a given model.
    ????5 --> To import RDF/XML file to a database.
    ????6 --> To list existing database model names
    ????7 --> To export a database model to a RDF/XML file
    ????8 --> To delete all the contents of a database model
    ????9 --> To create a union(RDF/XML file) of RDF/XML file models
    ????10 --> To create an intersection(RDF/XML file) of RDF/XML file models
    ????11 --> To create a difference(RDF/XML file) of RDF/XML file models
    ????12 --> To get the size of the given model
    ????13 --> Export the RDF query results as RDF/XML file.
    ????14 --> Delete the resource(s) from a model based on RDF query



    以上各任務ID的意思分別為:
    1:建立并初始化一個Jena系統表,系統模型名為JenaRDFSystem
    2:建立數據庫模型
    3:刪除一個數據庫模型
    4:列出所給出模型當中的內容
    5:將RDF/XML文件導入數據庫
    6:列出存在數據庫模型的名字
    7:將數據庫模型導出到RDF/XML文件中
    8:刪除一個數據庫模型當中的所有內容
    9: 為不同RDF/XML文件模型建立一個合并的RDF/XML文件
    10:建立不同RDF/XML文件直接的交集文件。
    11: 建立不同RDF/XML文件直接的差集文件。
    12:得到給定模型的大小
    13:將RDF查詢結果保存在RDF/XML文件當中
    14:從RDF查詢結果模型當中刪除資源

    SemanticRDFUtils腳本使用SemanticRDFUtils.properties文件儲存配置信息。下表給出了配置信息中的所有屬性:

    表 2. 屬性設置


    resized image


    任務
    第一個任務是在數據庫中建立一個Jena 系統表并要求下列屬性的正確值:
    ????????rdf_sytem_model_name
    ????????db_user
    ????????db_password
    ????????isRDFInDB
    ????????url

    第二個任務是在數據庫建立一個新的RDF模型并要求下列屬性的正確值:
    ????????rdf_sytem_model_name
    ????????db_user
    ????????db_password
    ????????isRDFInDB
    ????????url
    ????????modelName (如果這個屬性為空,那么腳本會提示用戶從鍵盤輸入值)

    第三個任務是從數據庫中刪除RDF模型并要求以下屬性的正確值:
    ????????rdf_sytem_model_name
    ????????db_user
    ????????db_password
    ????????isRDFInDB
    ????????url
    ????????modelName (如果這個屬性為空,那么腳本會提示用戶從鍵盤輸入值)

    第四個任務是列出RDF數據庫中的內容并要求以下屬性的正確值:
    ????????rdf_sytem_model_name
    ????????db_user
    ????????db_password
    ????????isRDFInDB
    ????????url
    ????????modelName (如果這個屬性為空,那么腳本會提示用戶從鍵盤輸入值)

    第五個任務是將RDF導入到數據庫模型當中,并要求以下屬性的正確值:
    ????????rdf_sytem_model_name
    ????????db_user
    ????????db_password
    ????????isRDFInDB
    ????????url
    ????????modelName (如果這個屬性為空,那么腳本會提示用戶從鍵盤輸入值)
    ????????import_rdffile_abs_name
    屬性import_rdffile_abs_name值將被置為.rdf文件的絕對路徑(如下的例子所示)。如果這個值為空那么腳本會提示用戶從鍵盤輸入值。
    import_rdffile_abs_name=C:\temp\RDFTest1.rdf

    第六個任務是列出一個數據庫模型中所有的模型,需要以下的屬性的正確值:
    ????????rdf_sytem_model_name
    ????????db_user
    ????????db_password
    ????????isRDFInDB
    ????????url

    第七個任務是將指定數據庫模型的內容導出到一個RDF文件當中,需要以下的屬性的正確值:
    ????????rdf_sytem_model_name
    ????????db_user
    ????????db_password
    ????????isRDFInDB
    ????????url
    ????????modelName (如果這個屬性值為空,腳本將提示用戶從鍵盤輸入)
    ????????import_rdffile_abs_name
    屬性export_rdffile_abs_name值將被置為.rdf文件的絕對路徑(如下的例子所示)。如果這個值為空那么腳本會提示用戶從鍵盤輸入值。
    export_rdffile_abs_name=C:/temp/export.rdf

    第八個任務是從數據模型中刪除內容,需要以下正確的屬性值:
    ????????rdf_sytem_model_name
    ????????db_user
    ????????db_password
    ????????isRDFInDB
    ????????url
    The ninth task performs a union operation on two file models and requires appropriate values for the following properties:

    第九個任務是對兩個文檔模型進行并集操作,需要以下正確的屬性值:
    ????????isRDFInDB
    ????????url
    ?????????????? file_rdfmodel1_abs_name
    ????????file_rdfmodel2_abs_name
    ????????result_rdfmodel_abs_name
    下面是一個范例的屬性值:
    file_rdfmodel1_abs_name=C:/temp/RDFTest1.rdf

    file_rdfmodel2_abs_name=C:/temp/RDFTest2.rdf

    result_rdfmodel_abs_name=C:/temp/RDFTestUnion.rdf

    當使用SemanticRDFUtils執行任務9的時候,兩個.rdf文件會被合并。如果要在一個合并的.rdf文件上建立一個Protégé工程,.rdfs文件必須被手工生成。

    第10個任務是執行兩個文件模型的交集操作,需要以下屬性的正確值:
    ????????isRDFInDB
    ????????url
    ????????file_rdfmodel1_abs_name
    ????????file_rdfmodel2_abs_name
    ????????result_rdfmodel_abs_name
    下面是一個范例的屬性值:
    file_rdfmodel1_abs_name=C:/temp/RDFTest1.rdf
    file_rdfmodel2_abs_name=C:/temp/RDFTest2.rdf
    result_rdfmodel_abs_name=C:/temp/RDFTestInterSection.rdf


    第11個任務是執行兩個文件模型的差集操作,需要以下屬性的正確值:
    ????????isRDFInDB
    ????????url
    ????????file_rdfmodel1_abs_name
    ????????file_rdfmodel2_abs_name
    ????????result_rdfmodel_abs_name
    下面是一個范例的屬性值:
    file_rdfmodel1_abs_name=C:/temp/RDFTest1.rdf
    file_rdfmodel2_abs_name=C:/temp/RDFTest2.rdf
    result_rdfmodel_abs_name=C:/temp/ RDFTestDifference.rdf


    第12個任務是列出指定數據庫模型的大小,需要以下屬性的正確值:
    ????????rdf_sytem_model_name
    ????????db_user
    ????????db_password
    ????????isRDFInDB
    ????????url
    ????????modelName (如果這個值為空那么腳本會提示用戶從鍵盤輸入值)

    第13個任務將對數據庫模型的一個RDF查詢結果導出到一個RDF文件中,需要以下屬性的正確值:
    ????????rdf_sytem_model_name
    ????????db_user
    ????????db_password
    ????????isRDFInDB
    ????????url
    ????????modelName (如果這個屬性值為空,腳本會要求用戶從鍵盤輸入值)
    ????????rdf_query
    ????????bind_var_name
    ????????export_rdffile_abs_name
    下面是一個范例的屬性值:
    rdf_query=SELECT ?x WHERE (?x????"65")
    bind_var_name=x
    export_rdffile_abs_name=C:/temp/exportquery.rdf


    第14個任務是將一個將數據庫模型的RDF查詢結果刪除,需要以下屬性的正確值:
    ????????rdf_sytem_model_name
    ????????db_user
    ????????db_password
    ????????isRDFInDB
    ????????url
    ????????modelName (如果這個屬性值為空,腳本會要求用戶從鍵盤輸入值)
    ????????rdf_query
    ????????bind_var_name
    下面是一個范例的屬性值:
    rdf_query=SELECT ?x WHERE (?x????"65")
    bind_var_name=x


    結論
    這篇文章介紹了怎么樣使用Jena和Protégé來創建RDF源數據模型。并描述了怎樣使用SemanticRDFUtils在命令行腳本方式下維護RDF模型。在這篇文章的資源中的SemanticRDFUtils-source-files.zip文件包含了能夠用來創建基于Web接口或是Protégé的插件的源文件,使用它們可以管理RDF模型。針對每一個RDF模型所加載的腳文會有所不同,所以需要區別對待,每一種情況都要獨立處理。

    關于作者:
    Venkata N. Vasam 主要工作領域是J2EE/Web services/EAI 架構。目前他使用SeeBeyond集成工具包(eGate和ICAN)為A2A和B2B集成需求提供Web服務/J2EE/EAI 架構。他獲得了J.N.T University,Hyderabad, India的計算機科學與工程學位。業余時間Vasam喜歡打網球看喜劇和運動電影。

    gracepig是(Matrix.org.cn)的會員,可以通過zhangchi_nwpu@hotmail.com和他聯系。


    資源
    文中的源碼下載地址
    http://www.javaworld.com/javaworld/jw-07-2005/jena/jw-0704-jena.zip
    "What is RDF?" 作者 Tim Bray (XML.com, 一月 2001): http://www.xml.com/pub/a/2001/01/24/rdf.html
    ????????RDF 規范
    http://www.w3.org/RDF/
    ????????Jena下載地址
    http://jena.sourceforge.net/downloads.html
    ????????RDF和Jena RDF API簡介
    http://jena.sourceforge.net/tutorial/RDF_API/index.html
    ????????Jena2: 一種語意Web框架
    http://www.hpl.hp.com/semweb/jena2.htm
    ????????RDQL:
    http://jena.sourceforge.net/tutorial/RDQL/index.html
    ????????RDF 入門
    http://www710.univ-lyon1.fr/~champin/rdf-tutorial/
    ????????Protégé 入門
    http://protege.stanford.edu/doc/tutorial/get_started/index.html
    ????????Protégé 下載
    http://protege.stanford.edu/download/download.html
    ????????Algernon標簽
    http://algernon-j.sourceforge.net/doc/algernon-protege.html
    ????????ava 下載地址
    http://java.sun.com/
    ????????Oracle下載地址
    http://www.oracle.com/technology/software/index.html
    ????????????????Matrix java門戶
    http://www.matrix.org.cn
    posted @ 2006-04-17 13:06 hopeshared 閱讀(2513) | 評論 (0)編輯 收藏

    進公司已經5個月了,這五個月過的還真是不輕松。

    在以前的公司,就算剛進去的時候什么都不會,2個月下來也會變成一個熟手,任務分配下來剩下的問題只是時間問題

    但是現在,經常會覺得無從下手,經常會覺得很無助,經常會覺得自卑:怎么自己什么都不會呢?為什么自己的知識面那么窄呢?怎么看了那么多資料什么都記不住呢?

    于是,就會想到放棄,就會很想休息。

    然后再網上四處閑逛,然后發現沒有什么值得去的網站。于是反思自己的工作,于是告訴自己:加油!不會就學習吧。

    于是開始放下急功近利的心,于是放下帶著目標的眼鏡,拿出最原始的、最基本的文檔,仔細地研讀。現在,我是學生,我在學習,我不是工人。

    posted @ 2006-04-12 13:28 hopeshared 閱讀(303) | 評論 (0)編輯 收藏

    老板讓我分析wildfire的結構,這個軟件是開源的,能拿到代碼,但是文檔太少了。我需要掌握它的體系結構,但是我已經看了n天的資料+文檔了,還是沒有理清,有沒有很好的辦法能快速掌握一個軟件的結構呢?偶比較笨,學習起來比較慢。。。
    posted @ 2006-04-11 13:05 hopeshared 閱讀(920) | 評論 (4)編輯 收藏

    版權聲明:本文可以自由轉載,轉載時請務必以超鏈接形式標明文章原始出處和作者信息及本聲明
    作者:cleverpig(作者的Blog:http://blog.matrix.org.cn/page/cleverpig)
    原文:http://www.matrix.org.cn/resource/article/44/44062_Java+Annotation+Apt.html
    關鍵字:java,annotation,apt

    前言:
    前不久在matrix上先后發表了《java annotation 入門》《java annotation 手冊》兩篇文章,比較全面的對java annotation的語法、原理、使用三方面進行了闡述。由于《入門》中的簡單例程雖然簡單明了的說明了annotation用法,但給大家的感覺可能是意猶未見,所以在此行文《java annotation高級應用》,具體實例化解釋annotation和annotation processing tool(APT)的使用。望能對各位的有所幫助。

    一、摘要:
    《java annotation高級應用》具體實例化解釋annotation和annotation processing tool(APT)的使用。望能對各位的有所幫助。本文列舉了用于演示annotation的BRFW演示框架、演示APT的apt代碼實例,并對其進行較為深度的分析,希望大家多多提意見。

    二、annotation實例分析
    1.BRFW(Beaninfo Runtime FrameWork)定義:
    本人編寫的一個annotation功能演示框架。顧名思義,BRFW就是在運行時取得bean信息的框架。

    2.BRFW的功能:
    A.源代碼級annotation:在bean的源代碼中使用annotation定義bean的信息;
    B.運行時獲取bean數據:在運行時分析bean class中的annotation,并將當前bean class中field信息取出,功能類似xdoclet;
    C.運行時bean數據的xml綁定:將獲得的bean數據構造為xml文件格式展現。熟悉j2ee的朋友知道,這個功能類似jaxb。

    3.BRFW框架:
    BRFW主要包含以下幾個類:
    A.Persistent類:定義了用于修飾類的固有類型成員變量的annotation。
    B.Exportable類:定義了用于修飾Class的類型的annotation。
    C.ExportToXml類:核心類,用于完成BRFW的主要功能:將具有Exportable Annotation的bean對象轉換為xml格式文本。
    D.AddressForTest類:被A和B修飾過的用于測試目的的地址bean類。其中包含了地址定義所必需的信息:國家、省級、城市、街道、門牌等。
    E.AddressListForTest類:被A和B修飾過的友人通訊錄bean類。其中包含了通訊錄所必備的信息:友人姓名、年齡、電話、住址(成員為AddressForTest類型的ArrayList)、備注。需要說明的是電話這個bean成員變量是由字符串類型組成的ArrayList類型。由于朋友的住址可能不唯一,故這里的住址為由AddressForTest類型組成的ArrayList。
    從上面的列表中,可以發現A、B用于修飾bean類和其類成員;C主要用于取出bean類的數據并將其作xml綁定,代碼中使用了E作為測試類;E中可能包含著多個D。
    在了解了這個簡單框架后,我們來看一下BRFW的代碼吧!

    4.BRFW源代碼分析:
    A.Persistent類:
    清單1:

    package com.bjinfotech.practice.annotation.runtimeframework;

    import java.lang.annotation.*;

    /**
    * 用于修飾類的固有類型成員變量的annotation
    * @author cleverpig
    *
    */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface Persistent {
    ????????String value() default "";
    }


    B.Exportable類:
    清單2:

    package com.bjinfotech.practice.annotation.runtimeframework;

    import java.lang.annotation.*;

    /**
    * 用于修飾類的類型的annotation
    * @author cleverpig
    *
    */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface Exportable {
    ????????//名稱
    ????????String name() default "";
    ????????//描述
    ????????String description() default "";
    ????????//省略name和description后,用來保存name值
    ????????String value() default "";
    ????????
    }


    C.AddressForTest類:
    清單3:

    package com.bjinfotech.practice.annotation.runtimeframework;

    /**
    * 用于測試的地址類
    * @author cleverpig
    *
    */
    @Exportable("address")
    public class AddressForTest {
    ????????//國家
    ????????@Persistent
    ????????private String country=null;
    ????????
    ????????//省級
    ????????@Persistent
    ????????private String province=null;
    ????????
    ????????//城市
    ????????@Persistent
    ????????private String city=null;
    ????????
    ????????//街道
    ????????@Persistent
    ????????private String street=null;

    ????????//門牌
    ????????@Persistent
    ????????private String doorplate=null;
    ????????
    ????????public AddressForTest(String country,String province,
    ????????????????????????String city,String street,String doorplate){
    ????????????????this.country=country;
    ????????????????this.province=province;
    ????????????????this.city=city;
    ????????????????this.street=street;
    ????????????????this.doorplate=doorplate;
    ????????}
    ????????
    }


    D.AddressListForTest類:
    清單4:

    package com.bjinfotech.practice.annotation.runtimeframework;

    import java.util.*;

    /**
    * 友人通訊錄
    * 包含:姓名、年齡、電話、住址(多個)、備注
    * @author cleverpig
    *
    */
    @Exportable(name="addresslist",description="address list")
    public class AddressListForTest {
    ????????//友人姓名
    ????????@Persistent
    ????????private String friendName=null;
    ????????
    ????????//友人年齡
    ????????@Persistent
    ????????private int age=0;
    ????????
    ????????//友人電話
    ????????@Persistent
    ????????private ArrayList<String> telephone=null;
    ????????
    ????????//友人住址:家庭、單位
    ????????@Persistent
    ????????private ArrayList<AddressForTest> AddressForText=null;
    ????????
    ????????//備注
    ????????@Persistent
    ????????private String note=null;
    ????????
    ????????public AddressListForTest(String name,int age,
    ????????????????????????ArrayList<String> telephoneList,
    ????????????????????????ArrayList<AddressForTest> addressList,
    ????????????????????????String note){
    ????????????????this.friendName=name;
    ????????????????this.age=age;
    ????????????????this.telephone=new ArrayList<String>(telephoneList);
    ????????????????this.AddressForText=new ArrayList<AddressForTest>(addressList);
    ????????????????this.note=note;
    ????????????????
    ????????}
    }


    E.ExportToXml類:
    清單5:

    package com.bjinfotech.practice.annotation.runtimeframework;

    import java.lang.reflect.Field;
    import java.util.Collection;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.ArrayList;

    /**
    * 將具有Exportable Annotation的對象轉換為xml格式文本
    * @author cleverpig
    *
    */
    public class ExportToXml {
    ????????/**
    ???????? * 返回對象的成員變量的值(字符串類型)
    ???????? * @param field 對象的成員變量
    ???????? * @param fieldTypeClass 對象的類型
    ???????? * @param obj 對象
    ???????? * @return 對象的成員變量的值(字符串類型)
    ???????? */
    ????????private String getFieldValue(Field field,Class fieldTypeClass,Object obj){
    ????????????????String value=null;
    ????????????????
    ????????????????try{
    ????????????????????????if (fieldTypeClass==String.class){
    ????????????????????????????????value=(String)field.get(obj);
    ????????????????????????}
    ????????????????????????else if (fieldTypeClass==int.class){
    ????????????????????????????????value=Integer.toString(field.getInt(obj));
    ????????????????????????}
    ????????????????????????else if (fieldTypeClass==long.class){
    ????????????????????????????????value=Long.toString(field.getLong(obj));
    ????????????????????????}
    ????????????????????????else if (fieldTypeClass==short.class){
    ????????????????????????????????value=Short.toString(field.getShort(obj));
    ????????????????????????}
    ????????????????????????else if (fieldTypeClass==float.class){
    ????????????????????????????????value=Float.toString(field.getFloat(obj));
    ????????????????????????}
    ????????????????????????else if (fieldTypeClass==double.class){
    ????????????????????????????????value=Double.toString(field.getDouble(obj));
    ????????????????????????}
    ????????????????????????else if (fieldTypeClass==byte.class){
    ????????????????????????????????value=Byte.toString(field.getByte(obj));
    ????????????????????????}
    ????????????????????????else if (fieldTypeClass==char.class){
    ????????????????????????????????value=Character.toString(field.getChar(obj));
    ????????????????????????}
    ????????????????????????else if (fieldTypeClass==boolean.class){
    ????????????????????????????????value=Boolean.toString(field.getBoolean(obj));
    ????????????????????????}
    ????????????????}
    ????????????????catch(Exception ex){
    ????????????????????????ex.printStackTrace();
    ????????????????????????value=null;
    ????????????????}
    ????????????????return value;
    ????????}
    ????????
    ????????/**
    ???????? * 輸出對象的字段,當對象的字段為Collection或者Map類型時,要調用exportObject方法繼續處理
    ???????? * @param obj 被處理的對象
    ???????? * @throws Exception
    ???????? */
    ????????public void exportFields(Object obj) throws Exception{
    ????????????????Exportable exportable=obj.getClass().getAnnotation(Exportable.class);????????
    ????????????????if (exportable!=null){
    ????????????????????????if (exportable.value().length()>0){
    //????????????????????????????????System.out.println("Class annotation Name:"+exportable.value());
    ????????????????????????}
    ????????????????????????else{
    //????????????????????????????????System.out.println("Class annotation Name:"+exportable.name());
    ????????????????????????}
    ????????????????}
    ????????????????else{
    //????????????????????????System.out.println(obj.getClass()+"類不是使用Exportable標注過的");
    ????????????????}
    ????????????????
    ????????????????//取出對象的成員變量
    ????????????????Field[] fields=obj.getClass().getDeclaredFields();
    ????????????????
    ????????????????for(Field field:fields){
    ????????????????????????//獲得成員變量的標注
    ????????????????????????Persistent fieldAnnotation=field.getAnnotation(Persistent.class);
    ????????????????????????if (fieldAnnotation==null){
    ????????????????????????????????continue;
    ????????????????????????}
    ????????????????????????//重要:避免java虛擬機檢查對私有成員的訪問權限
    ????????????????????????field.setAccessible(true);
    ????????????????????????Class typeClass=field.getType();
    ????????????????????????String name=field.getName();
    ????????????????????????String value=getFieldValue(field,typeClass,obj);
    ????????????????????????
    ????????????????????????//如果獲得成員變量的值,則輸出
    ????????????????????????if (value!=null){
    ????????????????????????????????System.out.println(getIndent()+"<"+name+">\n"
    ????????????????????????????????????????????????+getIndent()+"\t"+value+"\n"+getIndent()+"</"+name+">");
    ????????????????????????}
    ????????????????????????//處理成員變量中類型為Collection或Map
    ????????????????????????else if ((field.get(obj) instanceof Collection)||
    ????????????????????????????????????????(field.get(obj) instanceof Map)){
    ????????????????????????????????exportObject(field.get(obj));
    ????????????????????????}
    ????????????????????????else{
    ????????????????????????????????exportObject(field.get(obj));
    ????????????????????????}
    ????????????????????????
    ????????????????}
    ????????}
    ????????
    ????????//縮進深度
    ????????int levelDepth=0;
    ????????//防止循環引用的檢查者,循環引用現象如:a包含b,而b又包含a
    ????????Collection<Object> cyclicChecker=new ArrayList<Object>();
    ????????
    ????????/**
    ???????? * 返回縮進字符串
    ???????? * @return
    ???????? */
    ????????private String getIndent(){
    ????????????????String s="";
    ????????????????for(int i=0;i<levelDepth;i++){
    ????????????????????????s+="\t";
    ????????????????}
    ????????????????return s;
    ????????}
    ????????/**
    ???????? * 輸出對象,如果對象類型為Collection和Map類型,則需要遞歸調用exportObject進行處理
    ???????? * @param obj
    ???????? * @throws Exception
    ???????? */
    ????????public void exportObject(Object obj) throws Exception{
    ????????????????Exportable exportable=null;
    ????????????????String elementName=null;
    ????????????????
    ????????????????//循環引用現象處理
    ????????????????if (cyclicChecker.contains(obj)){
    ????????????????????????return;
    ????????????????}
    ????????????????
    ????????????????cyclicChecker.add(obj);
    ????????????????
    ????????????????//首先處理Collection和Map類型
    ????????????????if (obj instanceof Collection){
    ????????????????????????for(Iterator i=((Collection)obj).iterator();i.hasNext();){
    ????????????????????????????????exportObject(i.next());
    ????????????????????????}
    ????????????????}
    ????????????????else if (obj instanceof Map){
    ????????????????????????for(Iterator i=((Map)obj).keySet().iterator();i.hasNext();){
    ????????????????????????????????exportObject(i.next());
    ????????????????????????}
    ????????????????}
    ????????????????else{

    ????????????????????????exportable=obj.getClass().getAnnotation(Exportable.class);
    ????????????????????????//如果obj已經被Exportable Annotation修飾過了(注意annotation是具有繼承性的),
    ????????????????????????//則使用其name作為輸出xml的元素name
    ????????????????????????if (exportable!=null){
    ????????????????????????????????if (exportable.value().length()>0){
    ????????????????????????????????????????elementName=exportable.value();
    ????????????????????????????????}
    ????????????????????????????????else{
    ????????????????????????????????????????elementName=exportable.name();
    ????????????????????????????????}
    ????????????????????????}
    ????????????????????????//未被修飾或者Exportable Annotation的值為空字符串,
    ????????????????????????//則使用類名作為輸出xml的元素name
    ????????????????????????if (exportable==null||elementName.length()==0){
    ????????????????????????????????elementName=obj.getClass().getSimpleName();
    ????????????????????????}
    ????????????????????????//輸出xml元素頭
    ????????????????????????System.out.println(getIndent()+"<"+elementName+">");
    ????????????????????????levelDepth++;
    ????????????????????????//如果沒有被修飾,則直接輸出其toString()作為元素值
    ????????????????????????if (exportable==null){
    ????????????????????????????????System.out.println(getIndent()+obj.toString());
    ????????????????????????}
    ????????????????????????//否則將對象的成員變量導出為xml
    ????????????????????????else{
    ????????????????????????????????exportFields(obj);
    ????????????????????????}
    ????????????????????????levelDepth--;
    ????????????????????????//輸出xml元素結尾
    ????????????????????????System.out.println(getIndent()+"</"+elementName+">");
    ????????????????????????
    ????????????????}
    ????????????????cyclicChecker.remove(obj);
    ????????}
    ????????
    ????????public static void main(String[] argv){
    ????????????????try{
    ????????????????????????AddressForTest ad=new AddressForTest("China","Beijing",
    ????????????????????????????????????????"Beijing","winnerStreet","10");
    ????????????????????????
    ????????????????????????ExportToXml test=new ExportToXml();
    ????????????????????????
    ????????????????????????ArrayList<String> telephoneList=new ArrayList<String>();
    ????????????????????????telephoneList.add("66608888");
    ????????????????????????telephoneList.add("66608889");
    ????????????????????????
    ????????????????????????ArrayList<AddressForTest> adList=new ArrayList<AddressForTest>();
    ????????????????????????adList.add(ad);
    ????????????????????????
    ????????????????????????AddressListForTest adl=new AddressListForTest("coolBoy",
    ????????????????????????????????????????18,telephoneList,adList,"some words");
    ????????????????????????
    ????????????????????????test.exportObject(adl);
    ????????????????}
    ????????????????catch(Exception ex){
    ????????????????????????ex.printStackTrace();
    ????????????????}
    ????????}
    }


    在ExportToXml類之前的類比較簡單,這里必須說明一下ExportToXml類:此類的核心函數是exportObject和exportFields方法,前者輸出對象的xml信息,后者輸出對象成員變量的信息。由于對象類型和成員類型的多樣性,所以采取了以下的邏輯:

    在exportObject方法中,當對象類型為Collection和Map類型時,則需要遞歸調用exportObject進行處理;
    而如果對象類型不是Collection和Map類型的話,將判斷對象類是否被Exportable annotation修飾過:
    如果沒有被修飾,則直接輸出<對象類名>對象.toString()</對象類名>作為xml綁定結果的一部分;
    如果被修飾過,則需要調用exportFields方法對對象的成員變量進行xml綁定。

    在exportFields方法中,首先取出對象的所有成員,然后獲得被Persisitent annotation修飾的成員。在其后的一句:field.setAccessible(true)是很重要的,因為bean類定義中的成員訪問修飾都是private,所以為了避免java虛擬機檢查對私有成員的訪問權限,加上這一句是必需的。接著后面的語句便是輸出<成員名>成員值</成員名>這樣的xml結構。像在exportObject方法中一般,仍然需要判斷成員類型是否為Collection和Map類型,如果為上述兩種類型之一,則要在exportFields中再次調用exportObject來處理這個成員。

    在main方法中,本人編寫了一段演示代碼:建立了一個由單個友人地址類(AddressForTest)組成的ArrayList作為通訊錄類(AddressForTest)的成員的通訊錄對象,并且輸出這個對象的xml綁定,運行結果如下:

    清單6:

    <addresslist>
    ????????<friendName>
    ????????????????coolBoy
    ????????</friendName>
    ????????<age>
    ????????????????18
    ????????</age>
    ????????<String>
    ????????????????66608888
    ????????</String>
    ????????<String>
    ????????????????66608889
    ????????</String>
    ????????<address>
    ????????????????<country>
    ????????????????????????China
    ????????????????</country>
    ????????????????<province>
    ????????????????????????Beijing
    ????????????????</province>
    ????????????????<city>
    ????????????????????????Beijing
    ????????????????</city>
    ????????????????<street>
    ????????????????????????winnerStreet
    ????????????????</street>
    ????????????????<doorplate>
    ????????????????????????10
    ????????????????</doorplate>
    ????????</address>
    ????????<note>
    ????????????????some words
    ????????</note>
    </addresslist>


    三、APT實例分析:
    1.何謂APT?
    根據sun官方的解釋,APT(annotation processing tool)是一個命令行工具,它對源代碼文件進行檢測找出其中的annotation后,使用annotation processors來處理annotation。而annotation processors使用了一套反射API并具備對JSR175規范的支持。
    annotation processors處理annotation的基本過程如下:首先,APT運行annotation processors根據提供的源文件中的annotation生成源代碼文件和其它的文件(文件具體內容由annotation processors的編寫者決定),接著APT將生成的源代碼文件和提供的源文件進行編譯生成類文件。
    簡單的和前面所講的annotation實例BRFW相比,APT就像一個在編譯時處理annotation的javac。而且從sun開發者的blog中看到,java1.6 beta版中已將APT的功能寫入到了javac中,這樣只要執行帶有特定參數的javac就能達到APT的功能。

    2.為何使用APT?
    使用APT主要目的是簡化開發者的工作量,因為APT可以在編譯程序源代碼的同時,生成一些附屬文件(比如源文件、類文件、程序發布描述文字等),這些附屬文件的內容也都是與源代碼相關的。換句話說,使用APT就是代替了傳統的對代碼信息和附屬文件的維護工作。使用過hibernate或者beehive等軟件的朋友可能深有體會。APT可以在編譯生成代碼類的同時將相關的文件寫好,比如在使用beehive時,在代碼中使用annotation聲明了許多struct要用到的配置信息,而在編譯后,這些信息會被APT以struct配置文件的方式存放。

    3.如何定義processor?
    A.APT工作過程:
    從整個過程來講,首先APT檢測在源代碼文件中哪些annotation存在。然后APT將查找我們編寫的annotation processor factories類,并且要求factories類提供處理源文件中所涉及的annotation的annotation processor。接下來,一個合適的annotation processors將被執行,如果在processors生成源代碼文件時,該文件中含有annotation,則APT將重復上面的過程直到沒有新文件生成。

    B.編寫annotation processors:
    編寫一個annotation processors需要使用java1.5 lib目錄中的tools.jar提供的以下4個包:
    com.sun.mirror.apt: 和APT交互的接口;
    com.sun.mirror.declaration: 用于模式化類成員、類方法、類聲明的接口;
    com.sun.mirror.type: 用于模式化源代碼中類型的接口;
    com.sun.mirror.util: 提供了用于處理類型和聲明的一些工具。

    每個processor實現了在com.sun.mirror.apt包中的AnnotationProcessor接口,這個接口有一個名為“process”的方法,該方法是在APT調用processor時將被用到的。一個processor可以處理一種或者多種annotation類型。
    一個processor實例被其相應的工廠返回,此工廠為AnnotationProcessorFactory接口的實現。APT將調用工廠類的getProcessorFor方法來獲得processor。在調用過程中,APT將提供給工廠類一個AnnotationProcessorEnvironment 類型的processor環境類對象,在這個環境對象中,processor將找到其執行所需要的每件東西,包括對所操作的程序結構的參考,與APT通訊并合作一同完成新文件的建立和警告/錯誤信息的傳輸。

    提供工廠類有兩個方式:通過APT的“-factory”命令行參數提供,或者讓工廠類在APT的發現過程中被自動定位(關于發現過程詳細介紹請看http://java.sun.com/j2se/1.5.0/docs/guide/apt/GettingStarted.html)。前者對于一個已知的factory來講是一種主動而又簡單的方式;而后者則是需要在jar文件的META-INF/services目錄中提供一個特定的發現路徑:
    在包含factory類的jar文件中作以下的操作:在META-INF/services目錄中建立一個名為com.sun.mirror.apt.AnnotationProcessorFactory 的UTF-8編碼文件,在文件中寫入所有要使用到的factory類全名,每個類為一個單獨行。

    4.一個簡單的APT實例分析:
    A.實例構成:
    Review類:定義Review Annotation;
    ReviewProcessorFactory類:生成ReviewProcessor的工廠類;
    ReviewProcessor類:定義處理Review annotation的Processor;
    ReviewDeclarationVisitor類:定義Review annotation聲明訪問者,ReviewProcessor將要使用之對Class進行訪問。
    runapt.bat:定義了使用自定義的ReviewProcessor對Review類源代碼文件進行處理的APT命令行。

    B.Review類:
    清單7:

    package com.bjinfotech.practice.annotation.apt;

    /**
    * 定義Review Annotation
    * @author cleverpig
    *
    */
    public @interface Review {
    ????????public static enum TypeEnum{EXCELLENT,NICE,NORMAL,BAD};
    ????????TypeEnum type();
    ????????String name() default "Review";
    }


    C.ReviewProcessorFactory類:
    清單8:

    package com.bjinfotech.practice.annotation.apt;

    import java.util.Collection;
    import java.util.Set;
    import java.util.Arrays;
    import com.sun.mirror.apt.*;
    import com.sun.mirror.declaration.AnnotationTypeDeclaration;
    import com.sun.mirror.apt.AnnotationProcessorEnvironment;
    //請注意為了方便,使用了靜態import
    import static java.util.Collections.unmodifiableCollection;
    import static java.util.Collections.emptySet;

    /**
    * 生成ReviewProcessor的工廠類
    * @author cleverpig
    *
    */
    public class ReviewProcessorFactory implements AnnotationProcessorFactory{
    ????????/**
    ???????? * 獲得針對某個(些)類型聲明定義的Processor
    ???????? * @param atds 類型聲明集合
    ???????? * @param env processor環境
    ???????? */
    ????????public AnnotationProcessor getProcessorFor(
    ????????????????????????Set<AnnotationTypeDeclaration> atds,
    ????????????????????????AnnotationProcessorEnvironment env){
    ????????????????return new ReviewProcessor(env);
    ????????}
    ????????/**
    ???????? * 定義processor所支持的annotation類型
    ???????? * @return processor所支持的annotation類型的集合
    ???????? */
    ????????public Collection<String> ????????supportedAnnotationTypes(){
    ????????????????//“*”表示支持所有的annotation類型
    ????????????????//當然也可以修改為“foo.bar.*”、“foo.bar.Baz”,來對所支持的類型進行修飾
    ????????????return unmodifiableCollection(Arrays.asList("*"));
    ????}
    ????????
    ????????/**
    ???????? * 定義processor支持的選項
    ???????? * @return processor支持選項的集合
    ???????? */
    ????????public Collection<String> ????????supportedOptions(){
    ????????????????//返回空集合
    ????????????return emptySet();
    ????}
    ????????
    ????????public static void main(String[] argv){
    ????????????????System.out.println("ok");
    ????????}
    }


    D.ReviewProcessor類:
    清單9:

    package com.bjinfotech.practice.annotation.apt;

    import com.sun.mirror.apt.AnnotationProcessor;
    import com.sun.mirror.apt.AnnotationProcessorEnvironment;
    import com.sun.mirror.declaration.TypeDeclaration;
    import com.sun.mirror.util.DeclarationVisitors;
    import com.sun.mirror.util.DeclarationVisitor;

    /**
    * 定義Review annotation的Processor
    * @author cleverpig
    *
    */
    public class ReviewProcessor implements AnnotationProcessor{
    ????????//Processor所工作的環境
    ????????AnnotationProcessorEnvironment env=null;
    ????????
    ????????/**
    ???????? * 構造方法
    ???????? * @param env 傳入processor環境
    ???????? */
    ????????public ReviewProcessor(AnnotationProcessorEnvironment env){
    ????????????????this.env=env;
    ????????}
    ????????
    ????????/**
    ???????? * 處理方法:查詢processor環境中的類型聲明,
    ???????? */
    ????????public void process(){
    ????????????????//查詢processor環境中的類型聲明
    ????????????????for(TypeDeclaration type:env.getSpecifiedTypeDeclarations()){
    ????????????????????????//返回對類進行掃描、訪問其聲明時使用的DeclarationVisitor,
    ????????????????????????//傳入參數:new ReviewDeclarationVisitor(),為掃描開始前進行的對類聲明的處理
    ????????????????????????//????????DeclarationVisitors.NO_OP,表示在掃描完成時進行的對類聲明不做任何處理
    ????????????????????????DeclarationVisitor visitor=DeclarationVisitors.getDeclarationScanner(
    ????????????????????????????????????????new ReviewDeclarationVisitor(),DeclarationVisitors.NO_OP);
    ????????????????????????//應用DeclarationVisitor到類型
    ????????????????????????type.accept(visitor);
    ????????????????}
    ????????}
    }


    E.ReviewDeclarationVisitor類:
    清單10:

    package com.bjinfotech.practice.annotation.apt;

    import com.sun.mirror.util.*;
    import com.sun.mirror.declaration.*;

    /**
    * 定義Review annotation聲明訪問者
    * @author cleverpig
    *
    */
    public class ReviewDeclarationVisitor extends SimpleDeclarationVisitor{
    ????????/**
    ???????? * 定義訪問類聲明的方法:打印類聲明的全名
    ???????? * @param cd 類聲明對象
    ???????? */
    ????????public void visitClassDeclaration(ClassDeclaration cd){
    ????????????????System.out.println("獲取Class聲明:"+cd.getQualifiedName());
    ????????}
    ????????
    ????????public void visitAnnotationTypeDeclaration(AnnotationTypeDeclaration atd){
    ????????????????System.out.println("獲取Annotation類型聲明:"+atd.getSimpleName());
    ????????}
    ????????
    ????????public void visitAnnotationTypeElementDeclaration(AnnotationTypeElementDeclaration aed){
    ????????????????System.out.println("獲取Annotation類型元素聲明:"+aed.getSimpleName());
    ????????}
    }


    F.runapt.bat文件內容如下:
    清單11:

    E:
    rem 項目根目錄
    set PROJECT_ROOT=E:\eclipse3.1RC3\workspace\tigerFeaturePractice
    rem 包目錄路徑
    set PACKAGEPATH=com\bjinfotech\practice\annotation\apt
    rem 運行根路徑
    set RUN_ROOT=%PROJECT_ROOT%\build
    rem 源文件所在目錄路徑
    set SRC_ROOT=%PROJECT_ROOT%\test
    rem 設置Classpath
    set CLASSPATH=.;%JAVA_HOME%;%JAVA_HOME%/lib/tools.jar;%RUN_ROOT%

    cd %SRC_ROOT%\%PACKAGEPATH%
    apt -nocompile -factory com.bjinfotech.practice.annotation.apt.ReviewProcessorFactory??./*.java


    四、參考資源:
    http://java.sun.com/j2se/1.5.0/docs/guide/apt/GettingStarted.html
    作者的Blog:http://blog.matrix.org.cn/page/cleverpig


    五、源代碼下載:
    [下載文件]
    posted @ 2006-04-03 13:36 hopeshared 閱讀(2246) | 評論 (0)編輯 收藏

    僅列出標題
    共30頁: First 上一頁 12 13 14 15 16 17 18 19 20 下一頁 Last 
    主站蜘蛛池模板: 亚洲日韩在线中文字幕综合 | 亚洲午夜一区二区电影院| 久久精品亚洲一区二区三区浴池| 亚洲黄页网在线观看| 97在线免费视频| 四虎影院免费在线播放| 亚洲国产精品无码久久一线 | 国产乱辈通伦影片在线播放亚洲 | 亚洲av无码一区二区三区天堂古代 | 亚洲综合区小说区激情区 | 国产尤物在线视精品在亚洲| 一级做a爰全过程免费视频| 四虎永久免费地址在线观看| 综合自拍亚洲综合图不卡区| 一个人晚上在线观看的免费视频 | 亚洲成在人天堂一区二区| 免费一级毛suv好看的国产网站| 91久久成人免费| 亚洲无码黄色网址| 免费国产午夜高清在线视频| 亚洲国产一级在线观看| 亚洲国产精品美女久久久久| 免费黄色网址网站| 亚洲色偷偷色噜噜狠狠99| 182tv免费视视频线路一二三 | 噼里啪啦电影在线观看免费高清| 亚洲国产精品无码成人片久久| 国产无遮挡无码视频免费软件| 亚洲酒色1314狠狠做| 国产精品成人免费一区二区| 色费女人18女人毛片免费视频| 免费看大黄高清网站视频在线| 亚洲图片在线观看| 久久久久成人片免费观看蜜芽 | 久久受www免费人成_看片中文| 亚洲黄色免费网站| 最近中文字幕无吗高清免费视频| 亚洲精品二三区伊人久久| 曰批全过程免费视频网址| 亚洲成AV人影片在线观看| 国产亚洲一区二区三区在线|