notes
Watson
ibmcloud
Language_Translator
IBM-Cloud

Watson Language Translator を Java で呼び出す。編集中の Notes 文書から使う。

More than 1 year has passed since last update.

Watson Language Translator は、IBMが提供する機械翻訳アプリケーションです。

今回は、編集中の Notes 文書から Java を使って呼び出し、翻訳結果を 編集中の Notes 文書の別フィールドに戻したいと思います。

Java からの呼び出しが API リファレンス 通りではなかったので、Notes を使わわない方にも参考になると思います。

なお、編集中の Notes 文書から呼び出すために LS2J を使いました。


Watson Language Translator は、IBMが提供する機械翻訳アプリケーションです。

Watson Language Translator は、IBM が提供する Watson サービスの一つです。

IBM Cloudライト・アカウント (Bluemix)無期限・無料で使えるようになりました。


Watson Language Translator を Java で呼び出す。


Java から Watson を使いたいときは watson-developer-cloud/java-sdk があります。

GitHub に watson-developer-cloud/java-sdk のページがあります。

この SDK を使えば低レベルの http リクエストや json のパースを、自分で処理する必要がなくなります。

中ほどにある下記の here のリンクからすべての Watson サービス用の SDK が依存先も含めたひとつの jar としてダンロードできます。

JAR

Download the jar with dependencies here.

現在のファイル名は java-sdk-4.0.0-jar-with-dependencies.jar と Ver 4.0 が提供されています。


API リファレンス通りに動きません。

Java から翻訳を呼びだす方法は、API リファレンスではここにあります。

このようなサンプルが示されています。

LanguageTranslator service = new LanguageTranslator();

service.setUsernameAndPassword("{username}","{password}");

TranslateOptions translateOptions = new TranslateOptions.Builder()
.text("hello")
.source(Language.ENGLISH)
.target(Language.SPANISH)
.build();

TranslationResult result = service.translate(translateOptions)
.execute();

System.out.println(result);

String を入力すれば toString を利用できる TranslationResult が返ってくることを期待させるコード例です。

しかし、実際は、こんなに単純ではありませんでした。


動くJava コードはこちら

色々調べて動くようになった Java コードはこちらです。翻訳前の文章は List で渡します。結果も TranslationResult から List で取り出します。

翻訳を実行するだけのユーティリティクラスなので翻訳を実行するメソッド doIt() はインスタンス化が不要な static にしました。日本語の文を String で渡すと、英語の文が String で返ってきます。

import com.ibm.watson.developer_cloud.language_translator.v2.*;

import com.ibm.watson.developer_cloud.language_translator.v2.model.*;
import com.ibm.watson.developer_cloud.language_translator.v2.util.*;
import java.util.*;

public class WatsonTran {

public static void main (String[] args) {
System.out.println(doIt(args[0]));
}

public static String doIt(String input) {
String output = "";
List<String> inputList = new ArrayList<String>(Arrays.asList(input));

LanguageTranslator service = new LanguageTranslator();
service.setUsernameAndPassword("{username}","{password}");

TranslateOptions translateOptions = new TranslateOptions.Builder()
.text(inputList)
.source(Language.JAPANESE)
.target(Language.ENGLISH)
.build();

TranslationResult outputTran = service.translate(translateOptions)
.execute();

List<Translation> translations = outputTran .getTranslations();

if (translations.size() > 0) {
for (Translation nextTranslation : translations) {
output += nextTranslation.getTranslation();
}
}

return output;
}
}

実行結果はこちら。「こんにちは世界」が「hello world」に翻訳されました。

C:\watson>java -cp java-sdk-4.0.0-jar-with-dependencies.jar;. WatsonTran こんにちは世界

12 05, 2017 10:17:28 午前 okhttp3.internal.platform.Platform log
情報: --> POST https://gateway.watsonplatform.net/language-translator/api/v2/translate http/1.1 (62-byte body)
12 05, 2017 10:17:28 午前 okhttp3.internal.platform.Platform log
情報: <-- 200 OK https://gateway.watsonplatform.net/language-translator/api/v2/translate (211ms, unknown-length body)
hello world


編集中の Notes 文書から使う。

今回作りたいアプリケーションは、あるフィールドに日本語に入力してアクションすると、別のフィールドに翻訳文が自動的にはいるというものです。

image.png


どうやって Notes から Java を呼ぶか?

今回の悩みどころは、どうやって Notes から Java を呼ぶかという点です。

編集中文書のフィールドの値を渡し、編集中文書のフィールドに値を戻したいのです。


Java Agent では編集中の文書のアクセスできません。

Notes 内で Java を呼び出すもっとも一般的な方法は Java Agent を使うことです。しかし、Java Agent では編集中の文書のアクセスできませんので、今回の目的には使えません。

いつも参考にさせていただく まだプログラマーですが何か?ノーツでワトソンを体験! という記事があります。

何に関する文章かを分類する Natural Language Classifier(NLC) をNotesから使うことを例にしています。こちらでは Java Agent を利用しています。

トレーニング(これは、全文や特定の View の文書群が対象になるので Java Agent の利用が最適です)後の、実際の分類処理の呼び出しは文書の保存時に行われています。DB を確認したところ、Postsave の処理の中で、文書 ID と分類対象の文章を環境変数にセットし、Java Agent を呼び出していました。Java Agent は環境変数から分類対象の文章を取得し、NLC での分類を実行、その結果を 文書 ID を元に取得した文書に書き込むという処理になっていました。


Notes Client Java UI API ならできそうですが...

Notes 8 からスタンダード版 は Eclipse の上で動いています。Notes 内の Eclipse プラグインで Notes Client Java UI API を利用することで、編集中の文書を含む各種の UI にアクセスできます。

Notes Client Java UI API 概要 という記事があり、編集中の文書のフィールド値の取得や変更も記載されています。

ただ、ちょっと敷居が高そうなので、他の方法を考えてみました。


LS2J で LotusScript から呼び出します。

「Notes Java 連携」などで検索していたら Notes サポートのつぶやきLS2J : LotusScript でJavaのクラスを呼び出してみる を見つけました。

LotusScript から、直接 Java のメソッドが呼べるようです。これなら、編集中の文書のフィールドへのアクセスは、LotusScript に任せ、Watson 呼び出しだけ Java で行うことができそうです。


classpath を通します。

今回は「C:\watson」にファイルを置きました。

notes.ini に下記を追加して、Notes が、今回のクラスを見つけられるようにします。

JavaUserClasses=C:\watson\java-sdk-4.0.0-jar-with-dependencies.jar;C:\watson;


フォームにパーツを配置します。

日本語用の「input」、翻訳結果の英文用の「output」の二つのテキストフィールドと、翻訳の実行を行うボタンを配置します。

image.png


ボタンにコードを書きます。

LS2J : LotusScript でJavaのクラスを呼び出してみる を参考にコードを書きます。

Uselsx "*javacon"

Sub Click(Source As Button)
Dim ws As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim InputStr As String
Dim OutputStr As String

Set uidoc = ws.CurrentDocument
InputStr = uidoc.FieldGetText( "input" )
OutputStr = WatsonTran(InputStr)
Call uidoc.FieldSetText("output", OutputStr )
End Sub

Function WatsonTran( InputStr As String) As String
Dim j As JavaSession
Dim c As JavaClass
Dim e As JavaError
Set j = New JavaSession
Set c = j.GetClass("WatsonTran")
WatsonTran = c.doIt(InputStr)
End Function


Notes は 9.0.1 + FP8 以降 にしてください。

watson-developer-cloud/java-sdk は Java 7 でコンパイルされていました。

9.0.1 に FP8 を適用すると、Notes の Java 環境が Java 6 から Java 8 になります。FP9 が現在の最新のようです。

IBM Notes/Domino 9.0.1 の Feature Pack / Fix Pack のダウンロードについて