2017年6月10日土曜日

16: サンプルUNO拡張機能(LibreOffice拡張機能またはApache OpenOffice拡張機能)を理解する、パート3

<このシリーズの、前の記事 | このシリーズの目次 | このシリーズの、次の記事>

Main body START

'グローバルUNOサービス'プロバイダーを作る

-Hypothesizer

それでは、'グローバルUNOサービス'プロバイダーを作ろう。'グローバルUNOサービス'プロバイダーは、グローバルUNOサービスを登録する場合に必要なクラスだ。その場合、UNO拡張機能の中に1つの'グローバルUNOサービス'プロバイダーを含める。

-Rebutter

それは何をするのだ、具体的に?

-Hypothesizer

'グローバルUNOサービス'プロバイダーは、2つのスタティックメソッドを持っている。スタティックメソッド、'__writeRegistryServiceInfo'は、グローバルUNOサービスをLibreOfficeに登録する。そして、もう一方のメソッド、'__getComponentFactory'は、指定されたUNOコンポーネント名の'シングルUNOコンポーネント'UNOオブジェクトファクトリを戻す。

-Rebutter

'シングルUNOコンポーネント'UNOオブジェクトファクトリというのは何だ?

-Hypothesizer

この用語は参考文書で使われている用語ではないが、理解可能な説明をしようとすると、そういった用語が必要になるようだ。

'シングルUNOコンポーネント'UNOオブジェクトファクトリというのは、1つのUNOコンポーネント専用のUNOオブジェクトファクトリだ。

-Rebutter

それでは、'シングルUNOコンポーネント'UNOオブジェクトファクトリは、特定1つのUNOコンポーネントのみのインスタンスを作るのか?

-Hypothesizer

そう。グローバルUNOサービスマネージャーからグローバルUNOサービスのUNOオブジェクトを得る時、まず、そのグローバルUNOサービスのUNOコンポーネントの'シングルUNOコンポーネント'UNOオブジェクトファクトリを得て、次に、その'シングルUNOコンポーネント'UNOオブジェクトファクトリからUNOオブジェクトを得る。

-Rebutter

ははあ。

-Hypothesizer

これらのスタティックメソッドを我々が明示的に呼ぶことは通常ない。これらはUNOランタイムによって呼ばれるものだ。

-Rebutter

なるほど。

-Hypothesizer

我々の'グローバルUNOサービス'プロバイダーは 'thebiasplanet.uno.hiunoextensionsunoextension.HiUnoExtensionsUnoExtensionGlobalServicesProvider'だから、我々は、'source'ディレクトリ配下に、Javaソースファイル、'java/thebiasplanet/uno/hiunoextensionsunoextension/HiUnoExtensionsUnoExtensionGlobalServicesProvider.java'を作り、このファイルに以下を書く。

// # Change the package name
package thebiasplanet.uno.hiunoextensionsunoextension;

import java.util.Map;
import java.util.HashMap;
import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.registry.XRegistryKey;
import thebiasplanet.unoutilities.serviceshandling.GlobalUnoServicesProviderUtility;

// # Change the class name
public class HiUnoExtensionsUnoExtensionGlobalServicesProvider {
 private static final Map <String, Object []> IMPLEMENTATION_CLASS_NAME_TO_IMPLEMENTATION_CLASS_AND_SERVICE_NAMES_ARRAY_MAP = new HashMap <String, Object []> ();
 static {
  // # Add implementation classes START
  HiUnoExtensionsImplementation.setThisClassToServicesProvider (IMPLEMENTATION_CLASS_NAME_TO_IMPLEMENTATION_CLASS_AND_SERVICE_NAMES_ARRAY_MAP);
  // # Add implementation classes END
 }
 
 public static XSingleComponentFactory __getComponentFactory (String p_implementationName) {
  return GlobalUnoServicesProviderUtility.getSingleComponentFactory (IMPLEMENTATION_CLASS_NAME_TO_IMPLEMENTATION_CLASS_AND_SERVICE_NAMES_ARRAY_MAP, p_implementationName);
 }
 
 public static boolean __writeRegistryServiceInfo (XRegistryKey p_registryKey) {
  return GlobalUnoServicesProviderUtility.writeServicesInformationToRegistry (IMPLEMENTATION_CLASS_NAME_TO_IMPLEMENTATION_CLASS_AND_SERVICE_NAMES_ARRAY_MAP, p_registryKey);
 }
}
-Rebutter

ふーむ、 . . .

-Hypothesizer

スタティックメンバー、'IMPLEMENTATION_CLASS_NAME_TO_IMPLEMENTATION_CLASS_AND_SERVICE_NAMES_ARRAY_MAP'は、'グローバルUNOサービス'プロバイダーがUNOサービスを登録するのに必要な情報を格納する。この情報は、対象とするUNOコンポーネント(ここでは、1つのUNOコンポーネント、'thebiasplanet.uno.hiunoextensionsunoextension.HiUnoExtensionsImplementation')から取り出される。

-Rebutter

それでは、別のUNOコンポーネントも含めたい場合は、このスタティックブロックの中で、そのUNOコンポーネントの'setThisClassToServicesProvider'メソッドを呼べばよいわけだ。

-Hypothesizer

そう。この情報は別に、このメンバーに格納しなければならないわけではない。2つのスタティックメソッドが適切に実装されればそれでよい。

スタティックメソッド内の処理はユーティリティクラス、'thebiasplanet.unoutilities.serviceshandling.GlobalUnoServicesProviderUtility'に移譲される。どの'グローバルUNOサービス'プロバイダーでも同じだからだ。

-Rebutter

なるほど。

Jarのマニフェストコンテンツファイルを作る

-Hypothesizer

'source'ディレクトリ配下にJarマニフェストコンテンツファイル、'resource/MANIFEST.MF.addition'を作り、このファイルに以下を書く。

Comment01: # Change the class name
RegistrationClassName: thebiasplanet.uno.hiunoextensionsunoextension.HiUnoExtensionsUnoExtensionGlobalServicesProvider
UNO-Type-Path: <>

'MANIFEST.MF.addition'は、Jarマニフェストファイルに追加されるコンテンツを格納するファイルだ。

-Rebutter

うーむ、 . . . 'グローバルUNOサービス'プロバイダーが指定されている理由は理解できる。UNOランタイムは、我々のUNO拡張機能の中のどれが'グローバルUNOサービス'プロバイダーかを知らなければならない。

"UNO-Type-Path: <>"という行は何をしているのか?

-Hypothesizer

'UNO-Type-Path'は、このマニフェストファイルが属するJarファイルから使用されるUNOデータタイプを表わすJavaクラスを格納しているJarファイルを指定する。'<>'は、このマニフェストファイルが属するJarファイルを意味している。

-Rebutter

そうした追加のJarファイルはどこにあればよいのか?それらのJarファイルを我々のUNO拡張機能ファイルの中に入れなければならないのか?

-Hypothesizer

正直なところ、私は知らない。実のところ、共通のJarファイルを読み込むのに別の方法を我々は使うので、我々は、常に'<>'または''を指定する。後者は、追加のUNOデータタイプのためのJarファイルを何も使わないことを意味する。標準UNOデータタイプを格納するJarファイルを指定する必要はないことに注意しよう。そうしたJarファイルはデフォルトで読み込まれる。

-Rebutter

「標準UNOデータタイプ」というのは、LibreOfficeに含まれているUNOデータタイプのことか?

-Hypothesizer

そう。

-Rebutter

オーケー。

UNOコンポーネント設定ファイルを作る

-Hypothesizer

UNOコンポーネント設定ファイルを作る。これは、UNO拡張機能にどのUNOコンポーネントが含まれるかを指定するものだ。このファイルではまた、グローバルUNOサービスとして登録されるUNOコンポーネントにグローバルUNOサービス名を関連付ける。

ファイルは、'source'ディレクトリ配下の'resource/thebiasplanet.hiunoextensionsunoextension.uno.components'で、このファイルに以下を書く。

<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://openoffice.org/2010/uno-components">
 <!-- # Change the jar file uri -->
 <component loader="com.sun.star.loader.Java2" uri="thebiasplanet.hiunoextensionsunoextension.uno.jar">
  <!-- # Add service implementation class names -->
  <implementation name="thebiasplanet.uno.hiunoextensionsunoextension.HiUnoExtensionsImplementation">
   <!-- # Add service names -->
   <service name="thebiasplanet.uno.hiunoextensionsunoextension.HiUnoExtensions"/>
  </implementation>
 </component>
</components>
-Rebutter

このXMLファイルの構造からすると、1つのUNO拡張機能に複数のJarファイルを含められるようだな。

-Hypothesizer

おそらく。しかし、その推測を確かめたことはない。今のところ、複数のJarファイルを含める必要性が全然ないから。

-Rebutter

ははあ。'component'の中には複数の'implementation'タグを含められる。

-Hypothesizer

そう。注意しておくが、このXMLファイルでは、タグ、'component'はJarファイルを指しているが、我々の用語では、「UNOコンポーネント」は常にUNOインターフェースの実装を指している。 参考文書とUNOのソフトウェアそのものが、「コンポーネント」という用語を複数の種類の実体に使用しているので、そうした不一致が避けられない。

-Rebutter

いいだろう。

Main body END

References

  • Apache OpenOffice Wiki. (2014/01/02). Apache OpenOffice Developer's Guide. Retrieved from https://wiki.openoffice.org/wiki/Documentation/DevGuide/OpenOffice.org_Developers_Guide

<このシリーズの、前の記事 | このシリーズの目次 | このシリーズの、次の記事>