Domino の Java プログラム 講座 (初級編 検索と XML 文書の生成)

ドミノの検索も Java で行うことが可能です。
今回はその例として、キーワードを指定してビューを検索し、検索結果の文書から XML を生成して、それを返り値とするクラスを作ってみました。

検索して返ってくるものとしては、一番最初に思いついたのは文書の collection とか配列だったのですが、それはまあそれとして、もうひとつの学習として文書からの XML の生成を試してみるのもいいかな、と思ってそうしてみました。ちなみにこの XML の生成は R5.0.3 からの機能ですね。

結局、以下のサンプルのテーマはこの 3つです。

では内容を見ていきましょう。


まず最初に検索を行なって XML を返すクラスの内容です。

String でキーワードを引き数にとり、String で結果をまとめた XML 文書を返す doSearch メソッドを一つだけ持っているユーティリティクラスになっています。
メソッドは static でもよかったのかな、このかたちだと。
// でコメントにしてあるのはスタンドアローンでテストするのに使った main メソッドです。

import java.util.*;
import lotus.domino.*;

public class SearchDominoKeyword {

// public static void main(String[] args) {

// if(args.length != 1) {
// System.out.println("Please specify just one word");
// System.exit(0);
// }

// SearchDominoKeyword sdk = new SearchDominoKeyword();
// String out = sdk.doSearch(args[0]);
// System.out.println(out);

// }

public String doSearch(String keyword) {

Session session = null;
String xml = null;

try {
System.out.println("Going to create ResourceBundle object");
ResourceBundle props = ResourceBundle.getBundle("server");
System.out.println("ResourceBundle object is created");

String server = props.getString("server");
String user = props.getString("user");
String password = props.getString("password");
System.out.println("All parameters set");

session = NotesFactory.createSession(server, user, password);
System.out.println("Session is created");

Database db = session.getDatabase("", "ExampleDisc.nsf");
View view = db.getView("By Category");
ViewEntryCollection collection = view.getAllEntries();
System.out.println("View Entry Collection is created");

collection.FTSearch(keyword);
// collection.FTSearch(keyword, 100);
// 100 は最大検索結果の指定
int count = collection.getCount();

StringBuffer xmlSB = new StringBuffer("<?xml version=\"1.0\"?>");
// ecoding を指定しても OK
// StringBuffer xmlSB = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
xmlSB.append("<pagedata>");
xmlSB.append("<count>" + count + "</count>");

for (int i = 1; i <= count; i++) {
ViewEntry ve = collection.getNthEntry(i);
int score = ve.getFTSearchScore();
Document doc = ve.getDocument();

xmlSB.append("<document_wrapper>");
xmlSB.append(doc.generateXML());
xmlSB.append("<score>" + score + "</score>");
xmlSB.append("</document_wrapper>");

ve.recycle();
doc.recycle();
}

xmlSB.append("</pagedata>");
xml = xmlSB.toString();

} catch (Exception e) {

e.printStackTrace();

} finally {

try { session.recycle(); } catch (Exception e) {}

}

return xml;

}

}

今回は ResourceBundle オブジェクトを使用して、プロパティファイルからサーバー名などの変動情報を取得することにしました。

ResourceBundle props = ResourceBundle.getBundle("server");

String server = props.getString("server");
String user = props.getString("user");
String password = props.getString("password");

これがリソースバンドルとして取得するプロパティファイルの内容 (server.properties) です。

server=asdomino
user=Admin
password=PASSWORD

セッションの取得、データベースの取得、ビューの取得までのながれはおなじみですね。
取得した ViewEntryCollection オブジェクトに対して FTSearch メソッドでキーワードを指定して検索を実行します。

Database db = session.getDatabase("", "ExampleDisc.nsf");
View view = db.getView("By Category");
ViewEntryCollection collection = view.getAllEntries();
collection.FTSearch(keyword);

後は検索結果の文書を逐次処理していきますが、今回のひとつのテーマでもある XML 文書の生成を行います。

文書に対して generateXML() とやるだけで XML 文書ができます。これはなかなかすごいことのような気がします。

Document doc = ve.getDocument();

xmlSB.append("<document_wrapper>");
xmlSB.append(doc.generateXML());
xmlSB.append("</document_wrapper>");

テスト用のクラスです。 (上の本体にもテスト用の main がありますが、こうやって別のテスト用のクラスを作る方が"らしい"ですよね)

public class TestSDK {

public static void main(String[] args) {

// if(args.length != 1) {
// System.out.println("Please specify just one word");
// System.exit(0);
// }

SearchDominoKeyword sdk = new SearchDominoKeyword();
String out = sdk.doSearch(args[0]);
System.out.println( out);

}

}

こちらが先の SearchDominoKeyword クラスを利用したサーブレットです。いたってシンプルになってますね。
結果をそのままブラウザに出力しています。生成される XML が UTF-8 なので指定しておかないと DBCS 文字が ? になってしまいます。

import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
import lotus.domino.*;

public class SearchDominoKeywordServlet extends HttpServlet {

public SearchDominoKeywordServlet() { }

public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
doService(req, res); }

public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
doService(req, res); }

public void init()
throws ServletException {
super.init();
// System.out.println("init");
}

public void doService(HttpServletRequest req, HttpServletResponse res)
{

try {

String keyword = req.getParameter("keyword");
SearchDominoKeyword sdk = new SearchDominoKeyword();
String out = sdk.doSearch(keyword);

PrintWriter pw = null;
res.setContentType("text/html; charset=UTF-8");
pw = res.getWriter();
pw.println(out);

}

catch (Throwable te) {
System.out.println("Exception (Non-Domino)");
te.printStackTrace();
}


}
}

こちらが今回検索対象のデータベースです。

結果はこんなかんじです。IE 6.0 での実行結果です。

キーワードに「ドミノ」を指定しての実行ですが、count は 2 で、ドミノのカテゴリーのものは両方ちゃんと検索されていますね。

generateXML には上の例で使用した String を返り値に待つ以下のものの他に、2つのオプションがあります。

public String generateXML()
throws NotesException

ひとつは Writer を引き数にとるものです。

public void generateXML(java.io.Writer w)
throws NotesException, java.io.IOException

それによって、ファイルに書き出すことも可能です。

BufferedWriter bw = new BufferedWriter( new FileWriter("c:\\temp\\document.xml"));
doc.generateXML(bw);
bw.close();

また、XML を変換するためのスタイルシートを指定し (Object style) 、変換済みの XML (XSLResultTarget result) を受け取ることも可能です。

public void generateXML(Object style, XSLTResultTarget result)
throws NotesException, java.io.IOException, org.xml.sax.SAXException

[Top Pageに戻る]

Ads by TOK2