前一段时间在公司一直不能够登陆Blogjava,所以没有时间更新博客。今天周二休息所以就继续我的OpenOffice.org之恋吧!:)
这次应该说Java调用OOo具体类的业务代码了。
OOo的技术架构设计是与平台无关的,其构建在操作系统层之上的模块层次除了一部分VCL库以外,都达到了平台无关,平台无关是SUN的一贯作风。这部分代码占到了整个OOo的90%以上,而那部分VCL库平台有关的代码是为了直接调用各个平台之间与GUI有关的图形图像组件的最小公约数。这个就像jdk中的awt/swing一样,他们对各个操作系统都有的GUI组件进行了封装,而对没有的组件进行了本地模拟。swt做的正好与之相反,当然这个已经离题了:)暂不讨论这些。
OOo安装完成以后,在${OOoPath}/program/classes目录之下会有一些jar包存在,这些主要用于其自定义UNO组件扩展的内部类库。我们会主要使用到如下四个类包: jurt.jar、unoil.jar、ridl.jar 与
juh.jar将其加入到我们项目的classpath之中。接下来我们就可以引用其类苦中的类来自定义我们需要的具体功能了。
服务管理器 UNO 引入了
服务管理器的概念。服务管理器可以被视为创建
服务的“工厂”。现在,只需将服务看
作可用于执行特定任务的 UNO 对象即可。稍后我们将更精确地定义术语“服务”。
例如,可以使用以下服务:
com.sun.star.frame.Desktop
维护加载的文档:用于加载文档,获得当前文档以及访问所有加载的文档
com.sun.star.configuration.ConfigurationProvider
生成对 OOo 配置(例如工具 – 选项对话框中的设置)的访问权限
com.sun.star.sdb.DatabaseContext
维护与 OOo 一起注册的数据库
com.sun.star.system.SystemShellExecute
在当前平台上执行为应用程序注册的系统命令或文档
com.sun.star.text.GlobalSettings
管理文本文档的全局视图和打印设置
这些类是以后我们能够使用到的比较主要的类。服务的功能是其始终存在于组件上下文中。组件上下文包括创建了服务以及服务使用的其他数据的服务管理器。
我们自定义的类被视为 OOo 进程的客户机,而此时的 OOo 是服务器。该服务器有自己的组件上下文和服务管理器,可从客户机程序进行访问以使用办公软件功能。该客户机程序初始化 UNO,并从 OOo 进程获得组件上下文。在内部,此初始化进程创建一个本地服务管理器,建立与一个正在运行的OOo 进程的管道连接(如有必要,则启动一个新进程)并返回远程组件上下文。
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,并返回一个正在运行的 OOo 进程的远程组件上下文。而由脚本调用的UNO的方法就不是这样初始化的啦:)
第一个初始化步骤完成后,您可以使用组件上下文的方法 getServiceManager() 获得OOo 进程的远程服务管理器,这就使您可以通过 API 访问可用的完整办公软件功能。
在OOo's sdk的doc中描述各个类用的说明语言是c++,而且其使用的名称是
service而非class,这个大家注意一下。
我们的上下文中的
对象是一个软件工件,具有您可调用的方法。使用 OOo 完成某些操作时需要对象。但从哪里获得这些对象呢?
新对象
通常情况下,新对象或第一次访问所需的对象是由 OOo 中的服务管理器创建的。在如下示例中,远程服务管理器创建远程 Desktop 对象,该对象用于处理 OOo 中的应用程序窗口和已加载的文档:
Object desktop = xRemoteServiceManager.createInstanceWithContext(
"com.sun.star.frame.Desktop", xRemoteContext);
OOo中还有和我们java中的接口类似概念的
interface:接口指定共同定义对象的一个方面的属性集和方法集。
OOo中引入接口和服务的概念是出于以下几个原因:
- 接口和服务将规范从实现中分离出来
接口或服务的规范是抽象的,也就是说,它没有定义支持某项功能的对象如何在内部实现此支持。通过 OOo API 的抽象规范,可以在 API 下分离出实现,并安装其他实现(如果需要)。
2. 服务名称允许按规范名称而不是类名称创建实例
在 Java 中,使用 new 运算符来创建类实例。此方法有所限制:获得的类为硬编码。以后您无法在不编辑代码的情况下将其更换为其他类。服务的概念解决了这个问题。OOo 中的中心对象工厂(即全局服务管理器)被请求创建一个对象,此对象不需要被定义内部实现就可以用于特定目的。这是可以实现的,因为通过服务名称可以从工厂定制服务,并且工厂决定返回的服务实现。获得哪种实现没有什么区别,因为您只使用明确定义的服务接口。
3. 多继承接口使细颗粒状接口便于管理
如果抽象接口是细颗粒状,即小型且仅描述对象的一个方面而不是多个方面,则可以更好的重复使用。但那样的话,就需要多个此类接口来描述一个有用的对象。一方面,多继承接口允许具有细颗粒状接口;另一方面,又允许通过将接口组织成集合来轻松地管理这些接口。由于在办公软件环境中对象很可能共享多个方面,因此,此细颗粒状可以使接口重复使用,从而获得行为一致的对象。例如,可以使用统一的方式来处理文字,无论处理的是正文、文字框、页眉或页脚文字、脚注、表格单元格还是绘图形状中的文字。不需要为这些不同的文字处理定义单独的接口。
使用接口 由于必须通过 UNO 对象的接口来访问它们,因此会对某些语言(例如 Java )造成影响。因为在这些语言中,只有编译器所需的对象引用类型正确时才能从中调用方法。在 Java 中,在访问对象实现的接口之前,通常就可以转换对象类型。但使用 UNO 对象时是不同的:必须, UNO环境在需要访问对象支持的接口的方法时获得相应的引用,但编译器对此不知情。只有这时才能安全地转换对象类型。
Java UNO 环境含有用于此目的的 queryInterface() 方法。它看起来似乎非常复杂,但当您了解了 queryInterface() 是与跨进程安全转换 UNO 类型相关的,就会很快习惯它。
1 XToolkit xToolkit = (XToolkit) UnoRuntime.queryInterface(
2 XToolkit.class, xMultiComponentFactory
3 .createInstanceWithContext("com.sun.star.awt.Toolkit",
4 xScriptContext.getComponentContext()));
本文依据《创作共用约定》之“署名-禁止派生-非商业用途”方式发布,即你可以免费拷贝、分发、呈现和表演当前作品,但是必须基于以下条款:
对于任何二次使用或分发,你必须让其他人明确当前作品的授权条款。
在得到作者的明确允许下,这里的某些条款可以放弃。