??? 前一段時(shí)間在公司一直不能夠登陸B(tài)logjava,所以沒有時(shí)間更新博客。今天周二休息所以就繼續(xù)我的OpenOffice.org之戀吧!:)
??? 這次應(yīng)該說Java調(diào)用OOo具體類的業(yè)務(wù)代碼了。
??? OOo的技術(shù)架構(gòu)設(shè)計(jì)是與平臺(tái)無關(guān)的,其構(gòu)建在操作系統(tǒng)層之上的模塊層次除了一部分VCL庫以外,都達(dá)到了平臺(tái)無關(guān),平臺(tái)無關(guān)是SUN的一貫作風(fēng)。這部分代碼占到了整個(gè)OOo的90%以上,而那部分VCL庫平臺(tái)有關(guān)的代碼是為了直接調(diào)用各個(gè)平臺(tái)之間與GUI有關(guān)的圖形圖像組件的最小公約數(shù)。這個(gè)就像jdk中的awt/swing一樣,他們對(duì)各個(gè)操作系統(tǒng)都有的GUI組件進(jìn)行了封裝,而對(duì)沒有的組件進(jìn)行了本地模擬。swt做的正好與之相反,當(dāng)然這個(gè)已經(jīng)離題了:)暫不討論這些。
??? OOo安裝完成以后,在${OOoPath}/program/classes目錄之下會(huì)有一些jar包存在,這些主要用于其自定義UNO組件擴(kuò)展的內(nèi)部類庫。我們會(huì)主要使用到如下四個(gè)類包: jurt.jar、unoil.jar、ridl.jar 與
juh.jar將其加入到我們項(xiàng)目的classpath之中。接下來我們就可以引用其類苦中的類來自定義我們需要的具體功能了。
??? ??? 服務(wù)管理器
??? UNO 引入了服務(wù)管理器的概念。服務(wù)管理器可以被視為創(chuàng)建服務(wù)的“工廠”。現(xiàn)在,只需將服務(wù)看
作可用于執(zhí)行特定任務(wù)的 UNO 對(duì)象即可。稍后我們將更精確地定義術(shù)語“服務(wù)”。
例如,可以使用以下服務(wù):
??? ??? com.sun.star.frame.Desktop
維護(hù)加載的文檔:用于加載文檔,獲得當(dāng)前文檔以及訪問所有加載的文檔
??? ??? com.sun.star.configuration.ConfigurationProvider
生成對(duì) OOo 配置(例如工具 – 選項(xiàng)對(duì)話框中的設(shè)置)的訪問權(quán)限
??? ??? com.sun.star.sdb.DatabaseContext
維護(hù)與 OOo 一起注冊(cè)的數(shù)據(jù)庫
??? ??? com.sun.star.system.SystemShellExecute
在當(dāng)前平臺(tái)上執(zhí)行為應(yīng)用程序注冊(cè)的系統(tǒng)命令或文檔
??? ??? com.sun.star.text.GlobalSettings
管理文本文檔的全局視圖和打印設(shè)置
??? 這些類是以后我們能夠使用到的比較主要的類。服務(wù)的功能是其始終存在于組件上下文中。組件上下文包括創(chuàng)建了服務(wù)以及服務(wù)使用的其他數(shù)據(jù)的服務(wù)管理器。
我們自定義的類被視為 OOo 進(jìn)程的客戶機(jī),而此時(shí)的 OOo 是服務(wù)器。該服務(wù)器有自己的組件上下文和服務(wù)管理器,可從客戶機(jī)程序進(jìn)行訪問以使用辦公軟件功能。該客戶機(jī)程序初始化 UNO,并從 OOo 進(jìn)程獲得組件上下文。在內(nèi)部,此初始化進(jìn)程創(chuàng)建一個(gè)本地服務(wù)管理器,建立與一個(gè)正在運(yùn)行的OOo 進(jìn)程的管道連接(如有必要,則啟動(dòng)一個(gè)新進(jìn)程)并返回遠(yuǎn)程組件上下文。
public?class HelloWorld {
????
public?static?void?main(String[]?args)?{
????????
try?{
????????????
//?get?the?remote?office?component?context
????????????com.sun.star.uno.XComponentContext?xContext?=
????????????????com.sun.star.comp.helper.Bootstrap.bootstrap();
????????????System.out.println(
"HelloWorld? OOo?");
????????????????
????????????com.sun.star.lang.XMultiComponentFactory?xMCF?
=
????????????????xContext.getServiceManager();
????????????String?available?
=?(xMCF?!=?null???"available"?:?"not?available");
????????????System.out.println(?
"remote?ServiceManager?is?"?+?available?);?????????
????????}
????????
catch?(java.lang.Exception?e){
????????????e.printStackTrace();
????????}
????????
finally?{
????????????System.exit(
0);
????????}
????}
}
?? com.sun.star.comp.helper.Bootstrap.bootstrap() 方法初始化 UNO,并返回一個(gè)正在運(yùn)行的 OOo 進(jìn)程的遠(yuǎn)程組件上下文。而由腳本調(diào)用的UNO的方法就不是這樣初始化的啦:)
??? 第一個(gè)初始化步驟完成后,您可以使用組件上下文的方法?? getServiceManager() 獲得OOo 進(jìn)程的遠(yuǎn)程服務(wù)管理器,這就使您可以通過 API 訪問可用的完整辦公軟件功能。
??? 在OOo's sdk的doc中描述各個(gè)類用的說明語言是c++,而且其使用的名稱是service而非class,這個(gè)大家注意一下。
??? 我們的上下文中的對(duì)象是一個(gè)軟件工件,具有您可調(diào)用的方法。使用 OOo 完成某些操作時(shí)需要對(duì)象。但從哪里獲得這些對(duì)象呢?
??? 新對(duì)象
??? 通常情況下,新對(duì)象或第一次訪問所需的對(duì)象是由 OOo 中的服務(wù)管理器創(chuàng)建的。在如下示例中,遠(yuǎn)程服務(wù)管理器創(chuàng)建遠(yuǎn)程 Desktop 對(duì)象,該對(duì)象用于處理 OOo 中的應(yīng)用程序窗口和已加載的文檔:

Object?desktop?=?xRemoteServiceManager.createInstanceWithContext(
?????????
"com.sun.star.frame.Desktop",?xRemoteContext);
??? OOo中還有和我們java中的接口類似概念的interface:接口指定共同定義對(duì)象的一個(gè)方面的屬性集和方法集。
??? OOo中引入接口和服務(wù)的概念是出于以下幾個(gè)原因:
  1. 接口和服務(wù)將規(guī)范從實(shí)現(xiàn)中分離出來
??? 接口或服務(wù)的規(guī)范是抽象的,也就是說,它沒有定義支持某項(xiàng)功能的對(duì)象如何在內(nèi)部實(shí)現(xiàn)此支持。通過 OOo API 的抽象規(guī)范,可以在 API 下分離出實(shí)現(xiàn),并安裝其他實(shí)現(xiàn)(如果需要)。
? 2. 服務(wù)名稱允許按規(guī)范名稱而不是類名稱創(chuàng)建實(shí)例
??? 在 Java? 中,使用 new 運(yùn)算符來創(chuàng)建類實(shí)例。此方法有所限制:獲得的類為硬編碼。以后您無法在不編輯代碼的情況下將其更換為其他類。服務(wù)的概念解決了這個(gè)問題。OOo 中的中心對(duì)象工廠(即全局服務(wù)管理器)被請(qǐng)求創(chuàng)建一個(gè)對(duì)象,此對(duì)象不需要被定義內(nèi)部實(shí)現(xiàn)就可以用于特定目的。這是可以實(shí)現(xiàn)的,因?yàn)橥ㄟ^服務(wù)名稱可以從工廠定制服務(wù),并且工廠決定返回的服務(wù)實(shí)現(xiàn)。獲得哪種實(shí)現(xiàn)沒有什么區(qū)別,因?yàn)槟皇褂妹鞔_定義的服務(wù)接口。

? 3. 多繼承接口使細(xì)顆粒狀接口便于管理
??? 如果抽象接口是細(xì)顆粒狀,即小型且僅描述對(duì)象的一個(gè)方面而不是多個(gè)方面,則可以更好的重復(fù)使用。但那樣的話,就需要多個(gè)此類接口來描述一個(gè)有用的對(duì)象。一方面,多繼承接口允許具有細(xì)顆粒狀接口;另一方面,又允許通過將接口組織成集合來輕松地管理這些接口。由于在辦公軟件環(huán)境中對(duì)象很可能共享多個(gè)方面,因此,此細(xì)顆粒狀可以使接口重復(fù)使用,從而獲得行為一致的對(duì)象。例如,可以使用統(tǒng)一的方式來處理文字,無論處理的是正文、文字框、頁眉或頁腳文字、腳注、表格單元格還是繪圖形狀中的文字。不需要為這些不同的文字處理定義單獨(dú)的接口。

使用接口
??? 由于必須通過 UNO 對(duì)象的接口來訪問它們,因此會(huì)對(duì)某些語言(例如 Java )造成影響。因?yàn)樵谶@些語言中,只有編譯器所需的對(duì)象引用類型正確時(shí)才能從中調(diào)用方法。在 Java 中,在訪問對(duì)象實(shí)現(xiàn)的接口之前,通常就可以轉(zhuǎn)換對(duì)象類型。但使用 UNO 對(duì)象時(shí)是不同的:必須, UNO環(huán)境在需要訪問對(duì)象支持的接口的方法時(shí)獲得相應(yīng)的引用,但編譯器對(duì)此不知情。只有這時(shí)才能安全地轉(zhuǎn)換對(duì)象類型。
Java UNO 環(huán)境含有用于此目的的 queryInterface() 方法。它看起來似乎非常復(fù)雜,但當(dāng)您了解了 queryInterface() 是與跨進(jìn)程安全轉(zhuǎn)換 UNO 類型相關(guān)的,就會(huì)很快習(xí)慣它。
1?XToolkit?xToolkit?=?(XToolkit)?UnoRuntime.queryInterface(
2?????????????????XToolkit.class,?xMultiComponentFactory
3?????????????????????????.createInstanceWithContext("com.sun.star.awt.Toolkit",
4?????????????????????????????????xScriptContext.getComponentContext()));


??? 本文依據(jù)《創(chuàng)作共用約定》之“署名-禁止派生-非商業(yè)用途”方式發(fā)布,即你可以免費(fèi)拷貝、分發(fā)、呈現(xiàn)和表演當(dāng)前作品,但是必須基于以下條款:

  • 署名:你必須明確標(biāo)明作者的名字。

  • 非商業(yè)用途:你不可將當(dāng)前作品用于商業(yè)目的。

  • 禁止派生:你不可更改、轉(zhuǎn)變或者基于此作品重新構(gòu)造為新作品。

對(duì)于任何二次使用或分發(fā),你必須讓其他人明確當(dāng)前作品的授權(quán)條款。

在得到作者的明確允許下,這里的某些條款可以放棄。