MailとRDF
Mozilla Mail は、その data 構造のほとんどを、いくつかの datasource を通して、RDF で表現します。これは、RDF Templateを使って、mailnews に特化した data を user interface で表現できるようにします。
このドキュメントを読む前に、RDFについて学ぶ必要があります。そうしないと、絶望的なほど混乱するでしょう。
Mail RDF graphの概要
全ての account, folder, message の root resource は、msgaccounts:/と名付けられたRDF Resourceです。 この resource から、server, folder, 最終的に message へと到達するいくつかの arc が続きます。最終的に、graph の中の node から mail filter, annotation などをおそらく見付けることができるでしょう。これがどうやって設定されるか1つの例をここで示します。:
1つの RDF graph のこの tree-style 表現において、arc はitalic、resources はboldで示します。
msgaccounts:/
+-- http://home.netscape.com/NC-rdf#child -->
| imap://alecf@imap.mywork.com
| +-- http://home.netscape.com/NC-rdf#IsServer --> "true"
| +-- http://home.netscape.com/NC-rdf#child -->
| imap://alecf@imap.mywork.com/INBOX
| +-- http://home.netscape.com/NC-rdf#TotalMessages --> "4"
| +-- http://home.netscape.com/NC-rdf#IsServer --> "false"
| +-- http://home.netscape.com/NC-rdf#MessageChild -->
| | imap_message://alecf@imap.mywork.com/INBOX#1
| +-- http://home.netscape.com/NC-rdf#MessageChild -->
| | imap_message://alecf@imap.mywork.com/INBOX#2
| +-- http://home.netscape.com/NC-rdf#MessageChild -->
| | imap_message://alecf@imap.mywork.com/INBOX#3
| +-- http://home.netscape.com/NC-rdf#MessageChild -->
| imap_message://alecf@imap.mywork.com/INBOX#4
| etc...
+-- http://home.netscape.com/NC-rdf#child -->
| mailbox://alecf@pop.mywork.com
| +-- http://home.netscape.com/NC-rdf#IsServer --> "true"
| +-- http://home.netscape.com/NC-rdf#child -->
| mailbox://alecf@pop.mywork.com/INBOX
| +-- http://home.netscape.com/NC-rdf#TotalMessages --> "2"
| +-- http://home.netscape.com/NC-rdf#IsServer --> "false"
| +-- http://home.netscape.com/NC-rdf#MessageChild -->
| | mailbox_message://alecf@pop.mywork.com/INBOX#1
| +-- http://home.netscape.com/NC-rdf#MessageChild -->
| mailbox_message://alecf@pop.mywork.com/INBOX#2
| etc...
もちろん、RDF で表現された property はもっと多くありますが、しかし、この例はその雰囲気を与えるでしょう。
Datasources
mail の中で使われるいくつか基本的な dataresource があります:- nsMsgAccountDataSource - は、msgaccounts:/ から出て来る arc について query に答えます。それを msgaccounts:/ の外の #child nodes のために尋ねるなら、account manager の全てのserver の root URI を返します。現在、返された URI の server については何も知らないことに注意しなさい。
- nsMsgFolderDataSource - は、 toplevel の server folder を含んでいる mail folder の query に答えます。 #child arc に沿った1つの folder について尋ねるなら、その folder の中の全ての subfolder の resource を返すでしょう。 #MessageChild arc に沿った1つの folder について尋ねるなら、1つの folder の全ての message のための resource を返すでしょう。 message の総数、この folder は現在は root server かどうかなど、folder の様々な property についての query に答えるでしょう。
- nsMsgMessageDataSource - は、folder の中の message についての query に答えます。 現在は、1つの message の全ての RDF property は、含んでいる folder を保存している database から来ます。
DatasourceとUI
Mail は、UI を datasource に"伝統的"な方法で接続していません。
全ての UI component に渡って共有された1つの singleton datasource を持つ代わりに、我々は per-view datasource を持ちます。 これは、それそれの datasource の view/window に特化した data を扱うために、それそれの template-base の widget を認めます。例えば,,,??? (sorting? そのほかに何かありましたっけ?)それぞれの window の JavaScript が、javascript の source の中で datasource の variables を宣言することによって global な variable として load されるときに、Datasource は作られます。 document の onload= handler で、datasource は、それそれのRDF templateの親の element で、database property の設定することによって、それらの関連した widget に付けられます。
RDFへdataの反映
依存している content が変化したとき更新される1つの dynamic な UI を持つために、1つの datasource は、data を RDF へ反映する2つの key となる方法を実現しなければなりません。- query への応答: RDF が1つの resource について情報を尋ねるとき、datasource は query の結果を答えます。
- RDF へ非同期に通知 data それ自身が変わるときに、RDF は通知される必要があります。
詳細
Queryの応答
Mail は、RDF Resource Factory を、mail に特化した情報を RDF resource に付加するために使います。(RDF Resource Factory の詳細は、現在、RDF documentation にあります。) RDF Resource から、QueryInterface()が、mail/news object に割り当てた後、それから情報にアクセスすることを可能にします。
例えば、folder の panel は INBOX の中の message の数を表示する必要があります。この column の情報は、tree のRDF Templateが、datasource の GetTarget() method を呼ぶときに、尋ねられます。この質問の target はmailbox://alecf@pop.myisp.com/INBOXと名付けられた resource でして、その property node は、http://home.netscape.com/NC-rdf#TotalMessagesと名付けられます。次は、舞台裏での基本的な振舞です。:
var target = RDF.GetResource("mailbox://alecf@pop.myisp.com/INBOX");
var property = RDF.GetResource("http://home.netscape.com/NC-rdf#TotalMessages");
var resultNode = dataSource.GetTarget(target, property, true);
folder datasource の GetTarget() の中で, targetはnsIMsgFolderへ QueryInterface 付けられます。 全てのmessages を得るために、datasource は nsIMsgFolder.GetTotalMessages()を呼ぶでしょう。最後に、この call の結果を1つのRDF Literalへ変換し、GetTarget() の戻り値として戻すでしょう。
これが datasource の内側でどのように働くか示す1つの例:
var msgCountArc = RDF.GetResource("http://home.netscape.com/NC-rdf#TotalMessages");
function GetTarget(target, property, unused) {
var folder = target.QueryInterface(Components.interfaces.nsIMsgFolder);
if (property == msgCountArc) {
var msgCount = folder.GetTotalMessages(false);
var result = RDF.GetLiteral(msgCount.toString());
return result;
}
}
RDF の非同期な通知
ある mail object の data が変化したとき、そのデータは、datasource に登録された RDF の全ての observer に通知されて、RDF の中で反映されます。
mail folder の例で、それぞれの folder datasource は、始めにそれ自身を、mail session と共に、1つの nsIFolderListener として、登録します。なぜなら、それは1つの folder が変化したという情報を欲しているからです。 それぞれの template は、自分自身を、1つの RDF observer として、登録します。 folder の content、または、property が変化したとき、mail session に、folder listener に data が変化したことを通知することを伝えます。 folder datasource は、それらの property の変化を、OnAssert() または OnUnassert() の observer の呼出へ observer のために変換します。
呼出の流れは品質的には次のようです。:
登録:
- Folder datasource は自分自身を mail sesstion に folder listener として登録します。
- RDF Template は自分自身を datasource に content observer として登録します。
- Folder data が変化します。
- Folder は、mail session へその data が変化したことを通知します。
- Mail session は、folder listener へ folder が変化したことを通知します。
- Folder datasource は、RDF Content observers へその変化を通知します。
- Content observers は UI を更新します。
この design をレビューしたとき、通知/登録を二重化することは必要ないように思えました。folder は、RDF Content observers に、何か変化したときに、なぜ直接通しないのでしょうか?
ここに、この design の裏に隠れた合理性があります。:
- 全ての RDF datasource に関連した code を1箇所、それも、message や folder の場所以外の所にとどめます。 これは、mail code を、RDF から最も自由にします。 現在の RDF へ依存は小さいです。そして、RDF を folder や message の外にとどめることは道理にかなったことです。
- folder の変化を通知するために RDF 以外用の mechanism がある必要があります。 我々が、RDF で行う必要の無い folder への通知を望んだ所(例えば、JavaScript/XUL から)がいくつかあります。 RDF を使うためにそれらの listener を要求することは、不必要な API を持った不必要で負荷の高いことでしょう。
- folder、または mail session は、それぞれの datasource で、全ての RDF observer に知られる必要があるでしょう。これは、folder はそれらの observer のそれぞれに通知されなければならないことを意味します。 この design では、それぞれの datasource が、自身の observer を管理することを認めます。そして、それぞれのmail session が、folder listener の1つのリストを、RDF 的に関連しているそれらの listerner のいくつかを知る必要がなく、管理することを認めます。
Alec Flett Last modified: Thu Oct 7 11:33:42 PDT 1999
またドキュメントの管理の言語は現在も英語です。この日本語訳は、
利用者の利便のためにmozilla.org 和訳プロジェクトによって提供されたものです。
フィードバックは英語で、元の著者に送って下さい。
翻訳された文書の一覧は、現在以下のURLで見ることが出来ます。
http://www.mozilla-japan.org/jp/td/index.html