<このシリーズの、前の記事 | このシリーズの目次 | このシリーズの、次の記事>
UNOの基本概念を学んだので、我々は、我々のサンプルUNO拡張機能の詳細を理解できるになった。サンプルUNO拡張機能をよく理解しておかないと、将来のUNOの拡張機能を開発する目的にサンプルを使えないだろう。
それはそうだろう。
作成過程を追体験することで、サンプルUNO拡張機能を理解することにしよう。
分かった。
プロジェクトを作ろう。
共通Gradleビルドスクリプト群または共通Antビルドファイル群が格納されたディレクトリの下に、ディレクトリ、'hiUnoExtensionsUnoExtension'を作る。これが、プロジェクトのルートディレクトリだ。ディレクトリ名は任意だ。
長い名前だな . . .
ああ、この機会に言っておくが、私は、長い名前を使うことにほとんどためらいがない。それは、長い名前が好きだからではなく、省略があまり好きでないからだ。何かに名付けるときは省略は便利に思えるが、少し時間がたってだいぶそれについて忘れた後に見ると、わかりにくいことになりかねない。例えば、先ほどのものを'hiExtExt'と名付けたとして、'Ext'は何を意味するのだろうか?Extended?Exterior?External?Extinct?Extra?Extract?Extreme?Extinguisher?仮に'Extension'として正しく理解したとして、一体何の拡張機能なのか?Firefoxの拡張機能か?Eclipseの拡張機能か?Javaの拡張機能か?. . . もし誰かが、省略をそれぞれ、しばらく時間がたった後でも思い出せる優れた記憶力を持っているならば、省略すればよい。残念なことに、私の記憶力はお粗末なものであり、そのため、可能な限り、省略を避けなければならなくなっている。だから、私が付ける長い名前を気にする必要はない。短い名前が好きな人は自分で短くすればよい。
いいだろう。
次に、このプロジェクトのGradleビルドスクリプトまたはAntビルドファイルを作る。
Gradleビルドスクリプトの方は、以下のように書く。
// # Change the target name
ext.TARGET_NAME = "thebiasplanet.hiunoextensionsunoextension.uno"
apply ("from": "../commonBuild01.gradle")
// # Change the default task
defaultTasks ("registerUnoExtension")
ext ({
// Add this if necessary
//CHECKSTYLE = "ON"
// Add this if necessary
//JAR_DEPLOY_DIRECTORY_NAME = "?"
// Add this if necessary
//WAR_DEPLOY_DIRECTORY_NAME = "?"
// # Change this if necessary
INCLUDED_JAR_FILE_NAMES = ["../unoUtilitiesToDisclose/target/thebiasplanet.unoutilities.jar"]
// # Change this if necessary
OTHER_CLASSES_PATHS = [JAVA_FILES_BASE_DIRECTORY_NAME, CLASSES_BASE_DIRECTORY_NAME, LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME + "/unoil.jar", LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME + "/jurt.jar", LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME + "/ridl.jar", LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME + "/juh.jar"]
REFERENCED_PROJECT_DIRECTORY_NAMES = ["../unoUtilitiesToDisclose"]
})
apply ("from": "../commonBuild02.gradle")
ターゲット名(ここでは、'thebiasplanet.hiunoextensionsunoextension.uno')とデフォルトタスク('registerUnoExtension')を指定する。そして、'INCLUDED_JAR_FILE_NAMES'配列に、UNOユーティリティプロジェクトのJarファイル名を含めるが、これによって、このJarファイルの中身が、このサンプルUNO拡張機能プロジェクトのJarファイルに含まれるようになる。
ターゲット名は何に使用されるのか?
UNOデータタイプ「マージされた」レジストリファイルの名前、Jarファイルの名前、UNO拡張機能ファイルの名前、UNOコンポーネント設定ファイルの名前に使われる。
ふーむ、これらのファイルの説明は後で行なわれるのだろうな。
'INCLUDED_JAR_FILE_NAMES'配列にUNOユーティリティプロジェクトのJarファイル名を含めるというのは、UNOユーティリティプロジェクトのJarファイルが、このサンプルUNO拡張機能プロジェクトのJarファイル内に展開されるという意味か?
そうだ。
そうすると、他のUNO拡張機能を登録する際、UNOユーティリティプロジェクトのJarファイルの中身が重複してしまうと思うが。
そう。実際には、それで特に問題は起きないが、正直なところ、美しくはない。複数のUNO拡張機能からJarファイルが共有されるようにできるが、それには、LibreOfficeの設定が必要になる。こうした設定は、将来の記事で行なうことにする。
オーケー。
ところで、'OTHER_CLASSES_PATHS'配列に含まれる、'LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME'ディレクトリ配下のJarファイル群に注目してくれ。これらのJarファイルは、UNOのライブラリだ。これらは、我々のJavaソースをコンパイルするのに必要だが、我々のJarファイルには含まれない。というのは、これらはデフォルトで実行時にロードされるからだ。
なるほど。
Antビルドファイルの方は、以下のように書く。
<?xml version="1.0" encoding="UTF-8"?>
<!-- # Change the project name and the default target -->
<project basedir="." name="thebiasplanet.hiunoextensionsunoextension.uno" default="registerUnoExtension">
<import file="../commonBuild01.xml"/>
<!-- Add this if necessary
<property name="CHECKSTYLE" value="ON"/>
-->
<!-- Add this if necessary
<property name="JAR_DEPLOY_DIRECTORY_NAME" value="?"/>
-->
<!-- Add this if necessary
<property name="WAR_DEPLOY_DIRECTORY_NAME" value="?"/>
-->
<path id="INCLUDED_JAR_FILE_NAMES">
<!-- # Add the pathelement if necessary
<pathelement path="?"/>
-->
<pathelement path="../unoUtilitiesToDisclose/target/thebiasplanet.unoutilities.jar"/>
</path>
<path id="OTHER_CLASSES_PATHS">
<!-- # Change the path if necessary -->
<pathelement path="${JAVA_FILES_BASE_DIRECTORY_NAME}:${CLASSES_BASE_DIRECTORY_NAME}:${LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME}/unoil.jar:${LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME}/jurt.jar:${LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME}/ridl.jar:${LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME}/juh.jar"/>
</path>
<import file="../commonBuild02.xml"/>
</project>
プロジェクト名(ここでは、'thebiasplanet.hiunoextensionsunoextension.uno')とデフォルトターゲット('registerUnoExtension')を指定する。そして、'INCLUDED_JAR_FILE_NAMES'パスに、UNOユーティリティプロジェクトのJarファイル名を含めるが、これによって、このJarファイルの中身が、このサンプルUNO拡張機能プロジェクトのJarファイルに含まれるようになる。
ところで、'OTHER_CLASSES_PATHS'パスに含まれる、'LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME'ディレクトリ配下のJarファイル群に注目してくれ。Those Jar files are UNO libraries. これらは、我々のJavaソースをコンパイルするのに必要だが、我々のJarファイルには含まれない。というのは、これらはデフォルトで実行時にロードされるからだ。
オーケー。
次に、プロジェクトディレクトリの下に以下のディレクトリ構造を作る。
/source
/java
/resource
/unoIdl
分かった。
特定のUNOインターフェースを実装するUNOコンポーネントを作りたいので、そのUNOインターフェースを作ろう。UNOコンポーネントが既存のUNOインターフェースのみを実装すればよいのであれば、これは必要ないが、多くの場合、独自のUNOインターフェースを作りたいということになるだろう。
我々のUNOインターフェースを'thebiasplanet.uno.hiunoextensionsunoextension.XHiUnoExtensions'と名付けるが、これは、'unoIdl'ディレクトリ配下にUNOIDLファイル、'thebiasplanet/uno/hiunoextensionsunoextension/XHiUnoExtensions.idl'を作ることを意味する。
そして、この'XHiUnoExtensions.idl'ファイルに以下を書く。
// # Change the defined variable name START
#ifndef __thebiasplanet_uno_hiunoextensionsunoextension_XHiUnoExtensions_idl__
#define __thebiasplanet_uno_hiunoextensionsunoextension_XHiUnoExtensions_idl__
// # Change the defined variable name END
#include <com/sun/star/uno/XInterface.idl>
// # Add necessary idls START
#include <com/sun/star/lang/IllegalArgumentException.idl>
// # Add necessary idls END
// # Change the module name
module thebiasplanet { module uno { module hiunoextensionsunoextension {
// # Change the interface name and the parent interface
interface XHiUnoExtensions: com::sun::star::uno::XInterface
{
// # Add methods START
string sayHi( [in] string p_name)
raises (com::sun::star::lang::IllegalArgumentException);
// # Add methods END
};
}; }; };
#endif
ふーむ、 . . .
'#ifndef' ~ '#endif'ブロックは、その中のコードが複数回実行されないようにするためのものだ。定義する名前は、他の定義名の間で一意であればなんでもよい。
'#include'命令において、インクルードされるファイルがシステムインクルードディレクトリ配下にある場合には<>を使い、インクルードされるファイルがユーザー独自のディレクトリ配下にある場合には""を使う。
'com::sun::star::uno::XInterface'は、我々のUNOインターフェースの基底UNOインターフェースだ。我々のUNOインターフェースは一つのUNOインターフェースしか継承しないが、複数のUNOインターフェースを継承することもできる。'::'という表記に気をつけてくれ。UNOIDLでは、モジュールは'::'で区切られる。
'sayHi'メソッドが、我々のUNOインターフェースのメソッドだ。もちろん、必要であれば、我々のUNOインターフェースに複数のメソッドを持たせることもできる。
'[in]'指定は、この引数がメソッドの中に渡され、メソッド内からのこの引数への変更はメソッドの外からは見えないことを意味する。
それはわかるが、'[out]'と指定したらどうなるのか?Javaは'[out]'引数を取り扱えないと思うが。
実をいうと、'[out]'か'[inout]'の引数は、Javaでは配列にマッピングされる。配列が'[out] string p_argument1'ならば、'String [] p_argument1'にマッピングされる。
ああ、それでは、メソッド内で値を'p_argument1 [0]'に設定するわけだ。
そうだ。
データタイプ、'string'は、Javaでは'java.lang.String'にマッピングされるのだな?
そうだ。データタイプのマッピングについては、参考文書のここを参照してくれ。
おう、UNOの文字列にはnullが許されないのか。
そのようだ。
UNOインターフェースのUNOコンポーネントがスローするかもしれない'RuntimeException'を除く例外は、'raises'句に宣言しなければならない。'RuntimeException'は、'com.sun.star.uno.RuntimeException'またはその子孫のインスタンスだ。
なるほど。
- Apache OpenOffice Wiki. (2014/01/02). Apache OpenOffice Developer's Guide. Retrieved from https://wiki.openoffice.org/wiki/Documentation/DevGuide/OpenOffice.org_Developers_Guide