摘要:給出了J2EE應(yīng)用軟件靜態(tài)模型的詳細描述,并提出一種利用靜態(tài)分析技術(shù)自動重構(gòu)J2EE應(yīng)用軟件靜態(tài)模型的方法,實現(xiàn)了原型工具,有效地幫助用戶分析、理解、測試J2EE應(yīng)用軟件系統(tǒng)。最后通過一個實例描述模型的建立過程。
關(guān)鍵詞:J2EE靜態(tài)模型; J2EE構(gòu)件; 逆向工程
中圖分類號:TP311.5文獻標(biāo)志碼:A
文章編號:1001-3695(2007)11-0196-04
0引言
隨著J2EE技術(shù)的發(fā)展,J2EE應(yīng)用軟件使用范圍不斷擴大,有效地幫助企業(yè)、用戶完成較大規(guī)模的應(yīng)用。但是,隨著企業(yè)應(yīng)用的日益復(fù)雜和多元化,J2EE應(yīng)用軟件日益龐大,在軟件的維護和擴展過程中,對軟件的分析理解、測試都很復(fù)雜,甚至難以進行,特別是隨著時間的推移,應(yīng)用軟件相關(guān)文檔可能會發(fā)生遺失,使軟件的理解更加困難。因此需要一種針對J2EE應(yīng)用軟件的理解與建模工具,重構(gòu)J2EE應(yīng)用軟件的模型,幫助用戶分析、理解J2EE應(yīng)用軟件的組成和結(jié)構(gòu)。另外,生成的模型可以為利用模型驅(qū)動測試技術(shù)測試J2EE應(yīng)用系統(tǒng)提供測試模型建立依據(jù),甚至可以直接轉(zhuǎn)換為測試模型[1]。
從廣義上講,這屬于逆向工程[2]研究的范疇。目前,逆向工程的研究大都集中在通過對組成應(yīng)用軟件的類級代碼分析生成體系結(jié)構(gòu)模型,以UML類圖、活動圖等形式表現(xiàn),對J2EE應(yīng)用軟件的逆向工程研究比較少。文獻[3]提出利用北京航空航天大學(xué)軟件工程研究所QESat/Java軟件分析與測試工具通過對應(yīng)用系統(tǒng)進行分析,得到系統(tǒng)的類視圖、關(guān)系視圖等。文獻[4,5]給出了描述J2EE應(yīng)用軟件組成的四種視圖,即導(dǎo)航視圖、概念視圖、模塊視圖、執(zhí)行視圖,通過它們來顯示J2EE應(yīng)用系統(tǒng)的結(jié)構(gòu)。這些研究在一定程度上給出了建立J2EE應(yīng)用軟件模型以及對模型進行重構(gòu)的方法。但J2EE應(yīng)用軟件必須運行在特定的容器中,對其動態(tài)運行模型的捕捉不僅需要將完整的系統(tǒng)部署到容器中,還要在容器、系統(tǒng)中注入跟蹤方法。因此很難控制和捕捉,得到模型的正確性也受到容器和輸入的影響。靜態(tài)模型中記錄的軟件組成、結(jié)構(gòu)、功能信息為理解、分析軟件提供了充分的信息。本文主要考慮軟件靜態(tài)模型的重構(gòu)問題。目前已有的靜態(tài)模型,一般是從UML圖的角度出發(fā)考慮類及方法調(diào)用關(guān)系。在文獻[4,5]中雖然給出了四種視圖表現(xiàn)模型概念,但是在靜態(tài)模型方面只表現(xiàn)了類、構(gòu)件內(nèi)部的靜態(tài)關(guān)系,對于構(gòu)件中的耦合、軟件的整體組織都沒有完整地表示。另一方面,目前存在的重構(gòu)方法,一般是將對J2EE構(gòu)件的分析轉(zhuǎn)換成對類文件的分析,但是J2EE應(yīng)用軟件的組成單元內(nèi)部都有特定的組織形式,各個單元之間的耦合關(guān)系也不盡相同。因此這種方法會丟失部分信息,得到的模型并不完整。
針對以上問題,本文以J2EE規(guī)范和現(xiàn)有模型理論為基礎(chǔ),分析J2EE應(yīng)用軟件的編碼規(guī)則和結(jié)構(gòu)特點,給出了J2EE應(yīng)用軟件靜態(tài)模型的完整描述,并提出了自動重構(gòu)J2EE應(yīng)用軟件靜態(tài)模型的方法。本方法根據(jù)J2EE軟件靜態(tài)模型的特點,對目標(biāo)J2EE應(yīng)用軟件進行完整的靜態(tài)分析,識別J2EE應(yīng)用軟件的組成構(gòu)件,逐步生成J2EE應(yīng)用軟件的靜態(tài)模型,為理解程序和構(gòu)件的結(jié)構(gòu)提供幫助。
1J2EE應(yīng)用軟件靜態(tài)模型概述
1.1J2EE應(yīng)用軟件概述
J2EE是用于建立服務(wù)器方應(yīng)用程序的一種系統(tǒng)平臺[3],為企業(yè)應(yīng)用提供了一個多層結(jié)構(gòu)的分布式應(yīng)用程序模型。應(yīng)用程序邏輯根據(jù)其實現(xiàn)的不同功能被封裝到不同的構(gòu)件中。構(gòu)件是對外提供一組規(guī)約化接口的、符合一定標(biāo)準(zhǔn)的、可替換的軟件系統(tǒng)的程序模塊。J2EE規(guī)范中規(guī)定,J2EE構(gòu)件包含JSP、Servlet、EJB等。其中:JSP和Servlet構(gòu)件可以動態(tài)處理用戶的各種請求并作出響應(yīng),運行在Web容器中,屬于Web層構(gòu)件;EJB構(gòu)件負責(zé)處理各種業(yè)務(wù)邏輯,運行在業(yè)務(wù)層。每個EJB構(gòu)件都必須遵守EJB API的規(guī)定。按照EJB實現(xiàn)的模式不同,EJB又分為會話Bean、實體Bean和消息驅(qū)動Bean。
J2EE規(guī)范規(guī)定J2EE應(yīng)用軟件必須包含Java類文件和部署文件等。其中:Java類文件完成軟件的主要功能;部署文件則記錄構(gòu)件的各種信息,容器通過讀取部署文件運行構(gòu)件。
1.2J2EE應(yīng)用軟件靜態(tài)模型
為重構(gòu)J2EE應(yīng)用程序靜態(tài)模型,首先引入J2EE靜態(tài)模型的定義和基本的表現(xiàn)形式。靜態(tài)模型是在不需要運行軟件的情況下,對程序結(jié)構(gòu)、程序的組織等信息的描述,包括包、類、屬性、方法、類之間的各種相互關(guān)系、方法之間的調(diào)用關(guān)系、各種復(fù)雜度等;這些信息一般可通過分析軟件程序獲得。本文根據(jù)J2EE應(yīng)用程序的特點以及組成結(jié)構(gòu),根據(jù)文獻[4,5]中靜態(tài)模型相關(guān)的內(nèi)容并加以擴充,將J2EE應(yīng)用程序的靜態(tài)模型描述為文件視圖、構(gòu)件視圖、模塊視圖和體系結(jié)構(gòu)視圖。
1.2.1文件視圖
J2EE應(yīng)用程序由多種類型的文件組成。文件視圖用于表示J2EE應(yīng)用程序的目錄、包、類文件、配置文件、JSP文件等的組織形式。它以組成J2EE應(yīng)用程序最基本的文件作為元素,描述文件的物理位置、物理組織形式,記錄文件內(nèi)部的基本信息,如方法、屬性、各種復(fù)雜度信息,以及方法調(diào)用關(guān)系等。
1.2.2構(gòu)件視圖
構(gòu)件視圖構(gòu)建在文件視圖的基礎(chǔ)上。它以J2EE標(biāo)準(zhǔn)中定義的Servlet、EJB、JSP等基本構(gòu)件為單位組織J2EE應(yīng)用程序中的各種文件,描述其組成方面的細節(jié)信息、關(guān)系信息以及該構(gòu)件向外提供的接口等信息,如圖1所示。
在該視圖中,在構(gòu)件的主類中加入標(biāo)簽〈〈CType+SubType+CName〉〉,用于標(biāo)志構(gòu)件的具體類型。標(biāo)簽的具體含義如表1所示。
在靜態(tài)模型中,構(gòu)件視圖和組織結(jié)構(gòu)視圖中的元素存在著一對多的對應(yīng)關(guān)系。具體關(guān)系如表2所示(*代表必須存在)。
1.2.3模塊視圖和體系結(jié)構(gòu)視圖
這兩個視圖都關(guān)注應(yīng)用程序靜態(tài)關(guān)系,主要區(qū)別是模塊視圖關(guān)注J2EE應(yīng)用程序某一模塊的結(jié)構(gòu)以及關(guān)系;體系結(jié)構(gòu)視圖則是將所有的模塊組織起來,建立應(yīng)用軟件整體的結(jié)構(gòu)。這兩個視圖聯(lián)合起來反映了J2EE應(yīng)用程序整體的體系結(jié)構(gòu)整體模型。
J2EE應(yīng)用程序一般用來處理大規(guī)模的業(yè)務(wù)邏輯,不同的構(gòu)件聯(lián)合起來完成某一特定的功能。因此在本文中將J2EE應(yīng)用程序劃分為不同的模塊表示應(yīng)用程序功能的組織形式。但是構(gòu)件之間存在著復(fù)雜的關(guān)系,模塊如何劃分是一個重要的問題。文獻[6]中提供了一種通過判斷主動對象和被動對象的方法來劃分模塊。但是由于其中涉及到工作流以及動態(tài)運行方面的問題,比較復(fù)雜。下面將給出一種簡單的劃分方式。
在J2EE應(yīng)用軟件中,主要的功能邏輯由Servlet、會話Bean完成,JSP、實體Bean、消息驅(qū)動Bean以及其他的一些類文件只是充當(dāng)表現(xiàn)和提供業(yè)務(wù)服務(wù)特征和屬性的角色。基于這些分析,本文提出的模塊劃分方法如下:
a)獲取程序中所有的Servlet和會話Bean構(gòu)件,并建立這些構(gòu)件之間的關(guān)系,將完全沒有關(guān)系(與之關(guān)聯(lián)會話Bean也沒有關(guān)系)的構(gòu)件作為不同的模塊;
b)如果同一個Servlet關(guān)聯(lián)著不同的會話Bean并且之間完全沒有關(guān)系,則將會話Bean作為不同的模塊,并將Servlet分配到這兩個模塊中;
c)如果一個會話Bean只與會話Bean有關(guān),則將它加入與其有關(guān)的會話Bean模塊中;
d)建立JSP,實體Bean以及其他類與會話Bean、Servlet之間的關(guān)系;
e)將JSP、Servlet加入到表示層,EJB加入到邏輯層。
根據(jù)以上的模塊劃分標(biāo)準(zhǔn)即可將整個應(yīng)用軟件劃分為獨立的功能模塊,建立對應(yīng)的模塊視圖。將所有的模塊視圖,根據(jù)共同的訪問界面、調(diào)用關(guān)系,共同的數(shù)據(jù)資源、數(shù)據(jù)一致性等關(guān)系組合成整體的體系結(jié)構(gòu)視圖;將入口的JSP作為單獨的部分成為體系結(jié)構(gòu)的入口。
以上四個視圖從系統(tǒng)的結(jié)構(gòu)、組成單元的基本信息、構(gòu)件關(guān)系模型、模塊關(guān)系,以及系統(tǒng)的整體體系結(jié)構(gòu)方面等角度描述了J2EE應(yīng)用軟件完整的靜態(tài)模型,反映了J2EE應(yīng)用軟件的特點。
2靜態(tài)模型重構(gòu)技術(shù)
2.1靜態(tài)模型建立過程概述
利用靜態(tài)分析技術(shù)實現(xiàn)J2EE靜態(tài)模型重構(gòu)的具體過程如圖2所示。主要包括以下步驟:
a)獲取組織結(jié)構(gòu)信息。讀取J2EE應(yīng)用軟件的組成結(jié)構(gòu)信息,得到J2EE應(yīng)用程序的組織結(jié)構(gòu)信息。
b)靜態(tài)分析。對應(yīng)用程序進行靜態(tài)分析,包括類文件分析、JSP文件分析、XML文件分析,記錄其組成的各種基本信息,建立文件視圖。
c)構(gòu)件識別。根據(jù)從J2EE規(guī)范中對Servlet、EJB、JSP等構(gòu)件的定義中提取出的構(gòu)件識別規(guī)則,從靜態(tài)分析后得到的信息中識別出各種J2EE構(gòu)件,并得到構(gòu)件視圖。
d)模塊劃分。按照1.2.3節(jié)提供的模塊劃分標(biāo)準(zhǔn),根據(jù)b)c)中得到的信息,將組成J2EE應(yīng)用程序的構(gòu)件劃分到不同的模塊,得到模塊視圖。
e)建立體系結(jié)構(gòu)視圖。按照關(guān)聯(lián)關(guān)系,將模塊視圖組織成體系結(jié)構(gòu)視圖,完成整個靜態(tài)模型的建立過程。
2.2對應(yīng)用軟件進行靜態(tài)分析
自動重構(gòu)J2EE應(yīng)用軟件靜態(tài)模型過程中,首先要對其進行靜態(tài)分析,得到組成應(yīng)用軟件的基本單元、單元內(nèi)部信息、關(guān)系信息等。完整的J2EE應(yīng)用軟件一般包括類文件、XML文件、JSP文件。因此,靜態(tài)分析包括類文件分析器、XML文件分析器、JSP文件分析器。
對類文件的分析采用QESat/ Java軟件的靜態(tài)分析器對文件進行分析。該靜態(tài)分析器的主要部分是由JavaCC根據(jù)Java語法生成的一個分析器,通過詞法與語法匹配,得到代碼的各種基本信息以及調(diào)用關(guān)系信息。
該靜態(tài)分析器只能分析Java代碼,對XML文件和JSP文件無能為力。因此,在該靜態(tài)分析器后,提供了對XML和JSP文件的分析器。
XML分析器主要采用XPPXML文件讀取器為核心,將XML按照標(biāo)簽讀取;然后根據(jù)XML標(biāo)簽的具體內(nèi)容,獲取其屬性以及標(biāo)簽包含的內(nèi)容,記錄到靜態(tài)信息中。
JSP分析器則是封裝了一個HTML分析器,通過讀取JSP文件,根據(jù)JSP標(biāo)簽,記錄〈jsp:XX〉等標(biāo)簽信息,并分析〈%..%〉內(nèi)部的Java代碼,獲得JSP與其他文件的關(guān)系。
通過以上的分析過程,最終得到如下信息:
a)類的基本信息。包括包名、類名、類型、父類和實現(xiàn)的接口等信息。
b)類內(nèi)部的信息。包括類包含的屬性信息、方法名稱、參數(shù)、返回值。
c)類方法的內(nèi)部信息。
d)構(gòu)件基本信息。包括構(gòu)件名、類型、關(guān)系信息的記錄。
e)JSP基本信息。包括JSP名、內(nèi)部調(diào)用信息。
得到以上信息后,就可以建立J2EE應(yīng)用軟件靜態(tài)模型中的文件視圖。
2.3構(gòu)件識別
構(gòu)件識別主要是根據(jù)J2EE規(guī)范中對JSP、Servlet、EJB構(gòu)件的定義,總結(jié)構(gòu)件識別的基本規(guī)則,按照構(gòu)件識別規(guī)則,將屬于同一構(gòu)件的信息進行合并,建立完整的構(gòu)件信息。
2.3.1構(gòu)件識別規(guī)則
J2EE規(guī)范中為J2EE構(gòu)件(包括Servlet、EJB等)提供了完整的定義。根據(jù)對J2EE規(guī)范的提取,得到對J2EE構(gòu)件的識別規(guī)則。
1)Servlet構(gòu)件
父類為javax.servlet.HttpServlet或者javax.servlet.Gene ̄ricServlet[3],且在部署描述文件中由〈〈Servlet〉〉標(biāo)簽描述的public類型的Java類稱之為一個Servlet。
Servlet構(gòu)件包括一個Servlet主類和一個與之相關(guān)的部署文件。
2)EJB構(gòu)件
EJB可分為實體Bean、會話Bean和消息驅(qū)動Bean。對于會話Bean,將實現(xiàn)javax.ejb.SessionBean接口;對于實體Bean,將實現(xiàn)javax.ejb.EntityBean接口;對于消息驅(qū)動Bean,將實現(xiàn)javax.ejb.MessageBean接口[3]。每個EJB構(gòu)件都是由一個主類、本地接口、遠程接口以及一個與之相關(guān)的部署文件組成的。對于home接口繼承javax.ejb.EJBHome或者javax.ejb.EJBLocalHome接口;對于EJBObject接口繼承javax.ejb.EJBObject或者javax.ejb.EJBLocalObject接口。
2.3.2構(gòu)件識別方法
構(gòu)件識別過程就是依照上面的構(gòu)件識別規(guī)則,在得到的信息中找到構(gòu)件的特征,將相關(guān)聯(lián)的內(nèi)容組合在一起。
構(gòu)件的識別既可通過判斷類文件中類的繼承信息獲得,也可通過分析部署文件中對構(gòu)件結(jié)構(gòu)的描述獲得。為了能夠使構(gòu)件識別更加準(zhǔn)確,本文中將兩種方法結(jié)合在一起。具體過程如下:
a)讀取類文件中父類信息,按照構(gòu)件識別規(guī)則判斷該父類是否符合某一標(biāo)準(zhǔn)(如是否為HttpServlet);如果符合,則將該類記錄為特定的類型。
b)遍歷部署文件信息中對構(gòu)件結(jié)構(gòu)的記錄,按照構(gòu)件名在類文件信息中查找對應(yīng)的組成元素,并判斷類型是否正確;如果符合,則將該類加入到該構(gòu)件信息中。這樣就完成了J2EE構(gòu)件的識別過程。
2.4模塊劃分
在1.2.3節(jié)中已給出了模塊劃分的基本規(guī)則。在此簡單介紹模塊劃分的實現(xiàn)。在構(gòu)件識別過程中,各種構(gòu)件均已被識別。因此在模塊劃分階段:a)基于識別的構(gòu)件信息查找所有Servlet構(gòu)件、會話EJB構(gòu)件;b)在構(gòu)件主類的靜態(tài)信息中查找構(gòu)件間的相互關(guān)系,按照劃分規(guī)則將這些構(gòu)件劃分到不同的模塊中,并予以標(biāo)志;c)從靜態(tài)分析的文件中讀取其他的JSP、EJB與已建立的模塊中的構(gòu)件之間的關(guān)系,進行添加。
3實例分析
QESat/Java(Java軟件分析與測試工具)是北京航空航天大學(xué)軟件工程研究所“十一五預(yù)研項目”的課題,而對J2EE應(yīng)用程序的分析、理解與測試是其中一項關(guān)鍵技術(shù)。目前已基本實現(xiàn)分析和理解功能,并在一定程度上得到了應(yīng)用。本章以北航軟件所基于J2EE平臺開發(fā)的實驗室管理系統(tǒng)為例,實現(xiàn)其靜態(tài)模型的重構(gòu)過程。
3.1實例介紹
實驗室管理系統(tǒng)是依照J2EE應(yīng)用軟件模式開發(fā)的分布式管理平臺,包括實驗室人員管理、信息開放、設(shè)備管理、經(jīng)費管理、產(chǎn)品介紹等。該應(yīng)用軟件系統(tǒng)依照J2EE特點,采用三層體系架構(gòu),采用JSP、Servlet、EJB和數(shù)據(jù)庫技術(shù)實現(xiàn),有效地幫助實現(xiàn)實驗室的管理和對外開放的功能。
該系統(tǒng)規(guī)模較大,包含的各種類、構(gòu)件以及之間的關(guān)系比較復(fù)雜,因此在進行系統(tǒng)維護時,很難通過閱讀程序代碼和現(xiàn)有文檔了解系統(tǒng)的內(nèi)部結(jié)構(gòu)和組織關(guān)系。使用模型重構(gòu)工具可以迅速獲得該系統(tǒng)的靜態(tài)模型,了解程序內(nèi)部各部分的關(guān)系。
3.2模型重構(gòu)及結(jié)果說明
建立測試項目,并配置測試所需的環(huán)境。通過對項目進行完整的分析后得到系統(tǒng)的靜態(tài)模型(圖3)。在圖3(a)中給出了bookSession構(gòu)件的基本結(jié)構(gòu)。通過視圖不難看出,該構(gòu)件是一個會話EJB,名字為bookSession,它包括bookSessionBean類。其中bookSession、bookSessionLoca、bookSessionHome和bookSessionLocalHome分別是它的四個接口。它們共同完成該構(gòu)件的功能。在(b)中表現(xiàn)了以bookSession為主要構(gòu)件的模塊,該模塊通過viewBook、bookModify等與用戶交互,訪問該會話Bean,進而操作數(shù)據(jù)庫,實現(xiàn)對圖書操作的業(yè)務(wù)邏輯。(c)則是將全部模塊組織起來,形成整個系統(tǒng)完整的體系結(jié)構(gòu)。
3.3小結(jié)
以上實例自動實現(xiàn)了J2EE應(yīng)用軟件靜態(tài)模型重構(gòu)過程,并得到重構(gòu)模型,從系統(tǒng)的結(jié)構(gòu)、組成單元的基本信息、構(gòu)件關(guān)系模型、模塊關(guān)系,以及系統(tǒng)的整體體系結(jié)構(gòu)方面重構(gòu)了系統(tǒng)完整的靜態(tài)信息;充分體現(xiàn)了工具在模型重構(gòu)、輔助分析理解程序方面的作用;得到的靜態(tài)模型不僅為理解程序組成單元內(nèi)部信息,也為了解系統(tǒng)整體信息提供了幫助。程序分析理解人員可基于其了解軟件系統(tǒng)的細節(jié)信息、構(gòu)件的組織結(jié)構(gòu),以及獨立的單元如何組織完成業(yè)務(wù)邏輯。該模型同時為程序的分析、理解提供了可視化的方法,方便了對J2EE應(yīng)用軟件進行理解,并為程序測試人員提供了程序的基本信息,用于幫助測試人員在單元測試、構(gòu)件測試、模塊測試中選擇測試對象;與QESat/Java的代碼視圖配合還可以幫助用戶選取測試用例、分析測試結(jié)果等。同時,獲得的構(gòu)件模型、模塊關(guān)系模型以及體系結(jié)構(gòu)模型還可以為模型驅(qū)動測試提供幫助和模型基礎(chǔ)。
4結(jié)束語
J2EE技術(shù)的廣泛應(yīng)用以及J2EE應(yīng)用軟件規(guī)模的日益龐大使得對J2EE應(yīng)用軟件的分析、理解、測試變得越來越復(fù)雜和困難。本文通過分析J2EE規(guī)范和J2EE應(yīng)用軟件的特點,給出了J2EE應(yīng)用軟件靜態(tài)模型的詳細描述,并提出對J2EE應(yīng)用軟件進行完整靜態(tài)分析,得到了J2EE應(yīng)用軟件靜態(tài)模型的方法,概述了原型工具的實現(xiàn)技術(shù)。本方法實現(xiàn)了J2EE應(yīng)用軟件靜態(tài)模型重構(gòu),不僅幫助系統(tǒng)開發(fā)人員分析、理解J2EE應(yīng)用軟件,生成的靜態(tài)模型還可以作為J2EE應(yīng)用軟件幫助文檔,豐富逆向工程對J2EE構(gòu)件建模的研究領(lǐng)域;另一方面,生成的靜態(tài)模型可以為模型驅(qū)動測試J2EE應(yīng)用軟件提供模型依據(jù)。但是,在模型表現(xiàn)方面,它還存在著一定的不足,工具在模型的顯示還未涉及圖形排布問題。因此下一步工作將考慮使用何種排布算法以更好地顯示該模型。
參考文獻:
[1]劉冬懿,金茂忠,劉超,等.從UML設(shè)計模型到測試模型的研究[J].計算機應(yīng)用研究,2007,24(5):56-59.
[2]袁望洪,陳向葵.逆向工程研究與發(fā)展[J].計算機科學(xué),1999,26(2):50-55.
[3]沈艷芳.面向J2EE的分析和測試技術(shù)的研究和實現(xiàn)[D].北京:北京航空航天大學(xué),2004:40-48.
[4]CLEMENTS P, BACHMANN F, BASS L, et al. Documenting software architectures: views and beyond[M]. Boston: Addison-Wesley, 2002.
[5]HAN Min-min, HOFMEISTER C, NORD R L. Reconstructing software architecture for J2EE Web applications[C]//Proc ofthe 10th Working Conference on Reverse Engineering. 2003:30-34.
[6]蔣建民.基于組件的分析模型[J].重慶工商大學(xué)學(xué)報:自然科學(xué)版,2003,20(1):37-40.
“本文中所涉及到的圖表、注解、公式等內(nèi)容請以PDF格式閱讀原文”