DSpace システム説明書: ビジネスロジック層

目次に戻る
アーキテクチャ概要に戻る

コアクラス

org.dspace.coreパッケージはDSpaceプログラム全体で使用される基本的なクラスを提供します。

設定マネージャ(ConfigurationManager

設定マネージャは、メインプロパティファイルdspace.cfgの読み込み、Apacheなどの他のアプリケーション向けの「テンプレート」設定ファイルの管理、電子メール通知文の取得を担当します。

システムの設定で説明したように、/dspace/configにある該当するファイルを編集することによりシステムを設定します。

ApacheなどのDSpaceが使用するアプリケーションの設定ファイルを編集する際は、「実際に使用している」ファイルを直接修正するのではなく、/dspace/config/templatesにあるファイルを編集して、/dspace/bin/install-configsを実行することを忘れないでください。

ConfigurationManagerクラスは以下の2つの方法で、コマンドラインツールとして実行することもできます。

Constantsクラス

このクラスは、データベースにおいてオブジェクトの種別およびアクションを表わすために使用される定数を保持しています。 たとえば、権限ポリシーは様々な種別のオブジェクトに関連しており、resourcepolicyテーブルは、オブジェクトの内部IDであるresource_idカラム、オブジェクトがアイテム、コレクション、ビットストリームなどのいずれであるのかを示すresource_type_idカラムを持っています。このresource_type_idの値は、たとえば、Constants.ITEMのように、Constantsクラスから選ばれています。

Contextクラス

Contextクラスは、DSpace操作の中心となるものです。 ビジネスロジック層のAPIを使用するプログラムはすべて、まず、自分自身をContextオブジェクトとして作成する必要があります。 これは、データベースへのコネクションを開始することに似ています(これは実際行なわれる処理の1つです)

コンテクストオブジェクトはほとんどのメソッド呼び出しやオブジェクトコンストラクタの引数になっており、その結果、メソッドやオブジェクトは現在の操作についての情報にアクセスすることができます。 コンテクストオブジェクトが生成される際、以下の情報が自動的に初期化されます。

以下の情報もコンテクストオブジェクトに保持されます。ただし、コンテクストオブジェクトを作成して、情報を正しく設定するのはアプリケーションの責任です。

コンテクストオブジェクトの一般的な使用法は次のとおりです。まず、コンテクストオブジェクトを作成して、現在のユーザが認証されている場合はそのユーザを設定します。 このコンテクストオブジェクトを使っていくつかの操作を実行します。 すべてがうまくいったら、completeを呼び出し、変更をコミットして、コンテクストが使用したリソースを開放します。 何かうまくいかなかった場合は、abortを呼び出し、変更をロールバックし、リソースを開放します。

処理の途中で何らかのエラーが発生した場合は、必ずコンテクストをabortする必要があります。そうでないと、システム上のデータが不整合のまま放置されることになります。コンテクストをcommitすることもできます。これは、変更をデータベースに書きこみ、コンテクストをさらなる使用のために保存しておくことを意味します。

Emailクラス

電子メールを送付することはきわめて簡単です。設定マネージャのgetEmailメソッドを使って、引数と受信者を設定し、送付するだけです。

電子メールの本文は、/dspace/config/emailsにあります。 これは、標準的なjava.text.MessageFormatで処理されます。 各電子メール本文の先頭には、送信者により埋め込まれるべき引数がリストアップされています。 使用例は、org.dspace.core.EmailのJavadoc API説明書にあります。

LogManagerクラス

ログマネージャクラスは、標準的なログヘッダを作成し、ログ出力にふさわしい文字列でそれを返すメソッドで構成されています。 このクラスは実際にはログに何も出力しないことに注意してください。送信者は返されたログヘッダを適当なLog4Jのメソッドを使って直接出力しなければなりません。そうするとログ出力が行われた場所に関する情報も設定されます。

ログ出力のレベルは、/dspace/config/templates/log4j.propertiesを編集して、/dspace/bin/install-configsを実行することにより、パッケージ単位あるいはクラス単位で設定することができます。 設定を有効にするためにはTomcatを終了させて、リスタートする必要があります。

一般的なログエントリは次のような形をしています。

2002-11-11 08:11:32,903 INFO org.dspace.app.webui.servlet.DSpaceServlet @ anonymous:session_id=BD84E7C194C2CF4BD0EC3A6CAD0142BB:view_item:handle=1721.1/1686

これは次のように分解することができます。

日付、時間、ミリ秒 2002-11-11 08:11:32,903
レベル(FATAL, WARN, INFO, DEBUG INFO
Java クラス org.dspace.app.webui.servlet.DSpaceServlet
@
ユーザのメールアドレス、あるいは anonymous anonymous
:
コンテクストによる追加ログ情報 session_id=BD84E7C194C2CF4BD0EC3A6CAD0142BB
:
アクション view_item
:
追加情報 handle=1721.1/1686

ログはこの形式をしているので簡単にパースして分析することができます。/dspace/bin/log-reporterスクリプトはログを分析する簡単なツールです。次のコマンドを試してみてください。

/dspace/bin/log-reporter --help

サーバのパフォーマンスに影響を与えないように、このログリポータの「nice値」を調整すると良いでしょう。

Utilsクラス

Utilsクラスは、プログラムの様々な場所で必要とされ、それゆえ、サブシステムとして特定の「ホーム」を持たない、種々雑多なユーティリティメソッドを含んでいます。

コンテンツ管理API

コンテンツ管理APIパッケージorg.dspace.contentは、DSpaceシステムに保存されているコンテンツを読み込んだり、操作したりするためのJavaクラスを含んでいます。 おそらくアプリケーション層のコンポーネントがもっとも良く使用すると思われるAPIです。

DSpaceデータモデルの主要な要素(Community, Collection, Item, Bundle, Bitstream)に対応するクラスは、抽象クラスDSpaceObjectのサブクラスです。 Itemオブジェクトはダブリンコアメタデータレコードを扱います。

一般に、各クラスはコンテンツオブジェクトのインスタンス化に使用する1つ以上のスタティックなfindメソッドを持っています。 コンストラクタは外部からアクセスできず、内部的に使用されるだけです。その理由は以下のとおりです。

Collection, Bundle, Bitstreamは、createメソッドを持っていません。代わりに、そのコンテナが持つ関連メソッドを使ってオブジェクトを作成しなければなりません。 たとえば、コレクションを作成するには、次のように、コレクションが所属するコミュニティオブジェクトのcreateCollectionメソッドを呼び出さなければなりません。

Context context = new Context();
Community existingCommunity = Community.find(context, 123);
Collection myNewCollection = existingCommunity.createCollection();

その第1の理由は、権限を決定することにあります。e-personがオブジェクトを作成することができるかどうかを知るには、どのコンテナにオブジェクトが追加されるのかをシステムは知る必要があります。コミュニティの外にコレクションを作成しても意味がありませんし、権限付与システムはそれに対するポリシーを持っていません。

Itemは、まずInProgressSubmissionの実装の形で作成されます。 InProgressSubmissionは作成中のアイテムを表します。 そして、作成が完了すると、InstallItemクラスを使ってアーカイブにインストールされ、該当するコレクションに追加されます。 org.dspace.contentパッケージは、WorkspaceItemと呼ばれるInProgressSubmissionの実装を提供しています。これは、Web投稿用ユーザインターフェースで使用されるいくつかのフィールドを持つ簡単な実装です。 org.dspace.workflowパッケージにも、ワークフロー処理中の投稿を表すWorkflowItemと呼ばれる実装があります。

先の章で、アイテム受入プロセスの概要を説明していますが、これを読めば上の説明が明らかになるでしょう。ワークフローシステムの節も参考にしてください。

CommunityBitstreamFormatはスタティックなcreateメソッドを持っています。しかし、これを実行する権限を持つのはサイト管理者だけです。

その他のクラス

名前の先頭にDCが付くクラスは、後で説明するように、ダブリンコアメタデータを操作するクラスです。

FormatIdentifierクラスは、ビットストリームのフォーマットを推定します。 現在のところ、ビットストリーム名の拡張子を見て、フォーマットに対応するファイル拡張子と照らし合わせるという簡単な方法を採っています。 できれば、将来これをもっと改善できたらと考えています。

ItemIteratorクラスは、ストレージからアイテムを1つずつ取り出せるようにします。このクラスは、メモリ上に一度に持つことができる数より多くのアイテムを返す可能性のあるメソッドの戻り値になります。

ItemComparatorクラスは標準的なjava.util.Comparatorを実装したもので、任意のダブリンコアメタデータフィールドに基づいてアイテムを比較・整列することができます。

変更

コンテンツ管理APIを使ってデータを作成、修正、理由はともあれ削除する場合、変更が、メモリ上ではいつ行なわれ、DSpaceの物理的なストレージ上ではいつ行なわれるのかを知っておくことが重要です。

まず、org.dspace.core.Contextオブジェクトを使用して行なった変更は、そのContext上で、completeあるいは commitメソッドが呼び出されないかぎり、実際にストレージに反映することはないということに注意するべきです。 処理の途中で何か問題が生じた場合は、不整合な状態をストレージに書き込まないことを保証するために、必ずabortメソッドを使ってコンテクストを異常終了させる必要があります。

さらに、オブジェクトに行なった変更がメモリ上でのみ行なわれる場合もあります。 この場合、updateメソッドを呼び出して、Contextがcommitあるいはcompleteされる際に、メモリ上の変更がストレージに反映されるように手配します。 一般に、(メタ)データを変更するメソッドはメモリ上でのみ変更を行います。一方、他のオブジェクトとの関連を有するメソッドはコンテクストがコミットされる際に変更が反映されるように手配します。 個々のメソッドについては、API Javadocを参照してください。

これを説明する例を以下に示します。

Context context = new Context();
Bitstream b = Bitstream.find(context, 1234);
b.setName("newfile.txt");
b.update();
context.complete();
ストレージを変更する
Context context = new Context();
Bitstream b = Bitstream.find(context, 1234);
b.setName("newfile.txt");
b.update();
context.abort();
ストレージを変更しない(コンテクストがアボートしたため)
Context context = new Context();
Bitstream b = Bitstream.find(context, 1234);
b.setName("newfile.txt");
context.complete();
updateが実行されていないので、新しい名前は保存されない
Context context = new Context();
Bitstream bs = Bitstream.find(context, 1234);
Bundle bnd = Bundle.find(context, 5678);
bnd.add(bs);
context.complete();
updateを呼び出す必要はないので、ビットストリームはバンドルに追加される

メモリ上にあるものは何か

コンテンツオブジェクトのインスタンス化により、他のコンテンツオブジェクトがメモリにロードされることがあります。

Bitstreamオブジェクトのインスタンス化は、対応するBitstreamFormatオブジェクトのインスタンス化を引き起こします。 もちろん、Bitstreamオブジェクトが、対応するビットストリームをビットストリーム格納場所からメモリにロードすることはありません。

Bundleオブジェクトのインスタンス化は、対応するBitstreamオブジェクト(とBitstreamFormat)のインスタンス化を引き起こします。

Itemオブジェクトのインスタンス化は、対応するBundleオブジェクト(など)とBitstreamFormatのインスタンス化を引き起こします。 また、アイテムに付随するすべてのダブリンコアメタデータもメモリにロードされます。

その理由は、アイテムオブジェクトをインスタンス化する時は、ほとんどの場合、それに含まれているバンドルやビットストームに関する情報も必要になるでしょうから、この方法がもっとも効率的、かつ、呼び出し元にとっても簡単だからです。 たとえば、Webユーザインターフェースでは、サーブレット(コントローラ)は、アイテムに関する情報をビューア(JSP)に渡す必要がありますが、その際、ビューアはすべての情報をメモリ上に持つ必要があります。アイテムを表示中に、エラーを発生する可能性のあるデータベースのアクセスをしなくてもすむようにするためです。

同一のオブジェクトのインスタンスがメモリ上に複数存在することや、その結果生じるかもしれない不整合について心配する必要はありません。 Contextオブジェクトはインスタンス化されたオブジェクトをキャッシュしているからです。 org.dspace.contentパッケージのクラスが持つfindメソッドは、キャッシュされたオブジェクトがあれば、それを使用します。

この包含するオブジェクトの自動インスタンス化は、パフォーマンスが重要な状況でパフォーマンスを低下させることがあるかもしれません。もしそれが証明されたら、loadContentsのようなメソッドを追加したり、何をするのかを示す論理値パラメタをfindメソッドに追加したりするといった変更を将来APIに加えるかもしれません。

Contextオブジェクトが完了、異常終了、ガーベッジコレクションされると、コンテクストを使ってインスタンス化されたオブジェクトは無効になりますので使用してはいけません(ウィンドウが削除されると、そこにあったボタンが無効になることと同じです)。

ダブリンコアメタデータ

DCValueクラスは単純なコンテナであり、1つのダブリンコア要素、(オプションの)限定子、値、言語を表します。 その他のDCで始まる名前を持つクラスは、人名や日付など、その名前を持つダブリンコアのデータを処理するユーティリティクラスです。 提供されたファイルを見ればわかりますように、DSpaceの要素・限定子のレジストリは、ダブリンコアについての図書館応用プロファイル(LAP)に対応しています。 これらのユーティリティクラスは、その値があるシンタックスで書かれていることを仮定しています。これは、DSpaceで作成されたデータについてはすべて当てはまりますが、ダブリンコアはシンタックスに関しては厳密に定義しているわけではありませんので、DSpace以外で作成されたダブリンコアメタデータについては、この仮定が当てはまらない場合もあることに注意するべきです。

DSpaceは各フィールドが次のシンタックスに従うことを想定しています。

要素 限定子 シンタックス ヘルパークラス
日付(date) 任意、あるいは、限定子なし

協定世界時(UTC)のISO 8601日付形式。年、年月、年月日、年月日プラス秒精度時間、のいずれか。たとえば、以下のとおり。

2000
2002-10
2002-08-14
1999-01-01T14:35:23Z
DCDate
寄与者(contributor) 任意、あるいは、限定子なし

一般に、姓、カンマ、名、その他の情報(たとえば、"Jr."など)の形。 寄与者が団体の場合は、単にその名称。たとえば、以下のとおり。

Doe, John
Smith, John Jr.
van Dyke, Dick
Massachusetts Institute of Technology
DCPersonName
言語(language) iso

ISO 639の2文字の言語コード。オプションとして後に、ISO 3166の2文字の国コードを付けてもよい。たとえば、以下のとおり。

en
fr
en_US
DCLanguage
関係(relation) ispartofseries

シリーズ名、セミコロン、シリーズ内の番号。単に自由文でもよい。

MIT-TR; 1234
My Report Series; ABC-1234
NS1234
DCSeriesNumber

ワークフローシステム

主要なクラスは以下のとおりです。

org.dspace.content.WorkspaceItem ワークフローに入る前のアイテムを持つ
org.dspace.workflow.WorkflowItem ワークフロー処理中のアイテムを持つ
org.dspace.workflow.WorkflowManager イベントに応じて、WorkflowItem の状態を管理する
org.dspace.content.Collection 定義済みのワークフローステップのリストを持つ
org.dspace.eperson.Group ワークフロータスクを処理できる者は、e-personグループで定義される
org.dspace.core.Email グループメンバーおよび投稿者に電子メール通知をするために使用される

ワークフローシステムは、アイテムの状態を5つの状態(SUBMIT, STEP_1, STEP_2, STEP_3, ARCHIVE)を持つ状態機械でモデル化したものです。 異なるグループのメンバーがアイテムを査読・修正できるように3つのオプションステップがあります。 実際には、むしろ、STEP_1_POOL, STEP_2_POOL, STEP_3_POOLを持つ8状態に近いものです。 このPOOL状態は、アイテムが本来のステップに入るために待機している状態です。

WorkflowManagerはイベントにより呼びだされます。 アイテムは投稿作業の間、WorkspaceItemとして保持されます。WorkflowManagerのstart()メソッドを呼び出すと、WorkspaceItemからWorkflowItemに変換され、WorkflowItemの状態を処理することが開始されます。 ワークフローの3つのステップはすべてオプションですので、ステップが1つも定義されていない場合は、アイテムはただちにアーカイブされます。

ワークフローはコレクション毎に設定されます。ステップはworkflowGroupと呼ぶリストに、対応するエントリを作成することで定義されます。 ステップ1のワークフローを設定したい場合は、管理ツールを使って、アイテムを査読・承認できるようにしたい者をメンバーとするワークフローグループをコレクションに作成します。 すると、workflowGroup[0]にグループのIDが設定されます。

あるステップがコレクションのワークフローに定義されると、WorkflowItemの状態が対応するstep_POOLに設定されます。 このPOOL状態は、グループのメンバーがそのステップのタスクの実行を宣言することをWorkflowItemが待っている状態です。 WorkflowManagerは、グループのメンバーに実行するべきタスクがあることを知らせるメール(その本文は、config/emailsで定義されています)を送信します。 そして、1人のe-personが自分の「My DSpace」にアクセスしてタスクの実行を宣言すると、WorkflowManagerの宣言イベントが呼び出され、WorkfowItemの状態は、STEP_x_POOLからSTEP_x(ここで、xは対応するステップ)に進みます。 e-personは「宣言取り消し」イベントを生成することもでき、この場合、WorkflowItemの状態は、STEP_x_POOLに戻ります。

WorkflowManagerが処理するその他のイベントに、advance()があります。これは、WorkflowItemを次の状態に進めます。 それ以上ステップがない場合は、WorkflowItemは除去されて、アイテムはアーカイブされます。 タスクを実行するe-personは、アイテムを却下することができます。するとワークフローは中断され、そのアイテムのためのWorkspaceItemが再作成され、投稿者には却下理由が送信されます。 もっと抜本的には、管理ツールでabort()イベントを生成するとワークフローは完全に取り消されます。

管理用ツールキット

org.dspace.administerパッケージはDSpaceシステムを管理するためのクラスを含んでいますが、一般に、ほとんどのアプリケーションにとっては必要がないでしょう。

CreateAdministratorクラスは簡単なコマンドラインツールです。/dspace/bin/create-administratorにより実行され、標準入力から入力された情報を元に管理者を作成します。 これは一般に、DSpaceシステムのインストールの際に1度だけ使用されるもので、最初の管理者を作成します。この管理者は管理用Webユーザインターフェースを使ってさらにシステムを設定することができます。 このスクリプトは権限をチェックしません。なぜなら、このスクリプトは一般に権限を与えるべきe-personが存在する前に実行されるものだからです。 このスクリプトはサーバマシン上でコマンドラインツールとして実行されるべきものですので、一般に問題を引き起こすことはないはずです。 可能性があるのは、システムにe-personがまだいない状態でスクリプトを実行させるということだけですが、一般に、サーバ上のコマンドラインスクリプトにアクセスできる者は、どうせしたいことなら何でもできる立場にある人でしょう。

DCTypeクラスは、org.dspace.content.BitstreamFormatクラスと似たもので、 ダブリンコア・レジストリのエントリ、すなわち、特定の限定子付きの要素、あるいは、限定子なしの要素を表しています。 このクラスがadministerパッケージにあるのは、一般にレジストリ自体を処理する際にしか必要とされないからです。 org.dspace.content.Itemメソッドやorg.dspace.content.DCValueクラスでは、要素と限定子はリテラルとして指定されます。 ダブリンコア・レジストリを変更するのは管理者だけでしょう。

org.dspace.administer.RegistryLoaderクラスは、XMLファイルにあるエントリでダブリンコア・レジストリとビットストリームフォーマット・レジストリを初期化するメソッドを持っています。 一般に、これはシステムの初期構築時にコマンドラインから実行されます(ソースディレクトリのbuild.xmlを参照)。 XMLフォーマットの例は、ソースディレクトリのconfig/registriesにあるファイルを参照してください。XMLスキーマがありませんので、ロードの際に厳密な検証はされません。

e-person/グループ・マネージャ

DSpaceは、org.dspace.eperson.EPersonクラスを使って登録ユーザを把握しています。 このクラスは、姓や名、メールアドレス、パスワードを取得・設定するメソッドなど、EPersonオブジェクトを作成・操作するメソッドを持っています(実際は、getPassword()メソッドはありません。パスワードはMD5ハッシュで格納されており、checkPassword()メソッドで検証することができるだけです)。 e-personを(ユニークであると仮定されている)メールアドレスで見つけたり、システムに登録されたすべてのe-personを見つけたりするfindメソッドがあります。

EPersonオブジェクトはおそらく、簡単な拡張ができるように改訂されるべきでしょう。 現在、EPersonオブジェクトが把握しているものは、氏名、メールアドレス、電話番号など、MITが把握したいと考えていた情報だけです。 アクセスメソッドはハードコーディングされていますので、EPersonオブジェクトに格納されている情報をカスタマイズしたい場合は、おそらくこのメソッドを名前と値の任意の組でアクセスできるメソッドで置き換える必要があるでしょう。

グループは単なるEPersonオブジェクトのリストです。 メンバー以外にGroupオブジェクトが持つ属性は名前だけです。 グループ名はユニークでなければなりませんので、私たちは、COLLECTION_100_ADDのようにグループの役割をグループ名とする命名規約を採用しています。 グループにEPersonオブジェクトを追加するにはaddMember()を、削除するにはremoveMember()を使用します。 グループクラスについて知っておくべき重要なことは、update()メソッドが呼ばれるまで、グループクラスはメンバーをメモリ上に置いているということです。従って、メンバーを変更した場合は、update()を呼び出すことを忘れないでください。そうでないと、その変更は失われてしまいます。 グループメンバーの確認は権限付与システムで多用されますので、処理速度の速いisMember()メソッドも提供されています。

DSpaceはもう1つ別の種類のグループ、スペシャルグループ、を実装しています。 各セッションのContextオブジェクトは、ユーザが所属するグループのIDリストを持っています。 現在のところ、あるIPアドレスあるいは証明書を持つユーザのスペシャルグループのリストには、MITUserグループのIDが追加されています。

権限付与

主要なクラスは以下のとおりです。

org.dspace.authorize.AuthorizeManager グループに対するポリシーをチェックして権限を付与する
org.dspace.authorize.ResourcePolicy オブジェクトに対して許可するすべてのアクションを定義する
org.dspace.eperson.Group すべてのポリシーはEPersonグループに対して定義されている

権限付与システムはセキュリティについての古典的な「警察国家」モデルに基づいています。 つまり、ポリシーで表明されていない限り、どのようなアクションも許可されません。 ポリシーはリソースに付随しており(そのためResourcePolicyと言います)、誰がアクションを実行できるかを列挙しています。 リソースは、org.dspace.core.ConstantsにリストアップされているDSpaceの任意のオブジェクトタイプ(BITSTREAM, COLLECTIONなど)です。 「誰が」は、EPersonグループで指定します。 アクションもConstants.javaにリストアップされています(READWRITEADDなど)。 このうち、ADDREMOVEアクションは説明が必要です。これらはコンテナオブジェクトに対する権限です。 たとえば、アイテムを作成するためには、アイテムのコンテナであるコレクションに対するADD権限を持っていなければなりません(コミュニティ、コレクション、アイテム、バンドルはすべてコンテナオブジェクトです)。

現在のところ、READポリシーのチェックはほとんどアイテムについて行われています。コミュニティとコレクションは誰でも読むことができることが想定されていますが、アイテムとビットストリームはチェックされます。 アイテムとそのビットストリームをチェックするポリシーを別にすることで、アイテムは一般に読めるようにした上で、そのコンテンツの一部を特定のグループに制限することができます。

AuthorizeManagerクラスのauthorizeAction(Context, object, action)メソッドがシステムにおけるすべての権限付与の主たる源です。 これは、オブジェクトとアクションにマッチするシステム上のすべてのリソースポリシーのリストを取得します。 そして、リスト上のポリシーを順に当たって、ポリシーからEPsersonグループを抽出し、コンテクストに設定されているEPersonIDがそのグループのメンバーであるかをチェックします。 すべてのポリシーに当たっても何の権限も見つからなかった場合は、AuthorizeException例外を投げます。 ハイパフォーマンスを必要とするアプリケーションのために、論理値を返すauthorizeActionBoolean()メソッドも提供されています。

リソースポリシーは非常に簡単なものであり、非常に多くのポリシーが存在します。 各ポリシーは、1グループ、1アクション、1オブジェクトをリストできるだけです。 従って、各オブジェクトはおそらく複数のポリシーを持つことになるでしょう。 また、もし複数のグループがあるオブジェクトに対するアクション権限を共有していても、各グループは自身のポリシーを得ることができます(小さいことはいいことだ)。

スペシャルグループ

すべてのユーザはパブリックグループ(ID=0)のメンバーであると仮定されています。 DSpace管理者グループ(ID=1)のメンバーは、自動的にすべてのグループの一員となります。丁度、Unix OSにおけるスーパーユーザに似ています。 コンテクストオブジェクトはスペシャルグループのリストも持っており、このグループのメンバーであるか否かも最初にチェックされます。 MITにおいては、このスペシャルグループをユーザがMITコミュニティの一員であることを示すために使用しています。このコミュニティのメンバーをすべてデータベースに登録することは非常に難しいからです。 MITの証明書、あるいは、MITのIPアドレスでユーザがログインすると、ログインプログラムはユーザのコンテクストにこのMITユーザグループを追加します。

権限付与に関するその他の注意点

アイテムはどこで自身のreadポリシーを得るのでしょうか。自身が属するコレクションのreadポリシーからです。 かつて、各コレクションにはアイテムに関する独自のデフォルトread権限が存在しました。そして、おそらくこれは復活されそうです。 なぜなら、管理者はコレクションのreadポリシーを定義するのが苦手であると評判だからです。 また、期間指定(開始日付と終了日付を持つ)のポリシーを可能にするプログラムも用意されています。ただし、この種のポリシーを有効にするための管理ツールはまだ作成されていません。

ハンドル・マネージャ/プラグイン

org.dspace.handleパッケージは2つのクラスを持っています。 HandleManagerクラスは、ハンドルの作成と照合に使用します。 HandlePluginクラスは、DSpaceのハンドルをCNRIハンドルサーバプログラムにより外部世界に公開・解決するために使用します。

ハンドルは、内部的には次の形で、データベースのhandleテーブルに格納されています。

1721.123/4567

これがシステムの外で使用される場合は、一般に、次のように、URIか「URLプロキシー」の形で表示されます。

hdl:1721.123/4567
http://hdl.handle.net/1721.123/4567

どちらの形が使われているにせよ、表示形から基本形を取り出すのは呼び出し元の責任です。

handleテーブルでは、ハンドルをリソースタイプとリソースIDの組にマッピングします。 ここで、リソースタイプは、org.dspace.core.Constantsで指定されている値であり、リソースIDは、オブジェクトの内部識別子(データベースの主キー)です。 これによりシステムの任意の型のオブジェクトにハンドルを割り当てることが可能ですが、機能概要で説明したように、現在のところハンドルが割り当てられるのは、コミュニティ、コレクション、アイテムだけです。

HandleManagerクラスは、次の機能を持つスタティックメソッドを持っています。

HandlePluginクラスは、ハンドルサーバのnet.handle.hdllib.HandleStorageインターフェースの簡単な実装で、データベースのhandleテーブルから情報を取得するという基本的なハンドル検索メソッドを実装しているだけです。 CNRIハンドルサーバがこのプラグインを使用するようconfig.dctファイルで設定します。

ハンドルサーバはWebユーザインターフェースとは別のJVMとして実行しますので、別の「Log4J」設定を使用することに注意してください。なぜなら、Log4Jは、複数のJVMが1つの日次ログを共有することをサポートしていないからです。 このハンドルサーバ用の設定は、/dspace/config/templates/log4j-handle-plugin.propertiesのテンプレートにありますので、install-configsスクリプトを実行して、/dspace/config/log4j-handle-plugin.propertiesに書き込んでください。 /dspace/bin/start-handle-serverスクリプトは、ハンドルサーバがこの設定を使用するように適当なコマンドラインパラメタを設定しています。

検索

DSpaceの検索プログラムは現在のところ、Lucene検索エンジンをラップする簡単なAPIです。 検索タスクの半分は、インデックスの作成です。org.dspace.search.DSIndexerがインデックス作成のためのクラスで、indexContent()メソッドを持っています。 このメソッドに、ItemCommunityCollectionを渡すと、そのコンテンツのフィールドをインデックスに追加します。 unIndexContent()メソッドとreIndexContent()メソッドは各々、コンテンツのインデックス情報を削除、更新します。 DSIndexerクラスは、インデックスを完全に再作成するmain()メソッドも持っています。これは、dspace/bin/index-allスクリプトにより呼び出されます。 main()メソッドが定期的に実行されると考えたのは、インデックスが破壊されることを防ぐことにあったのですが、今のところ問題は生じていません。 どのフィールドがDSIndexerによりインデックス化されるのでしょうか。 現在のところ、対象フィールドは indexItemContent()indexCollectionContent()indexCommunityContent()メソッドにハードコーディングされています。

クエリクラスであるDSQueryは3種類のdoQuery()メソッドを持っています。1つはDSpaceサイト全体を、残りの2つはコレクションとコミュニティに検索対象を限定するものです。 クエリの結果は、3種類のハンドルリストとして返されます。各リストは結果の種別を表します。 リストのうち、1つはマッチしたアイテムのリストで、残りの2つはマッチしたコレクションとコニュニティのリストです。 この分離により、ユーザインターフェースは、まずすべてのハンドルを解決してハンドルがどんな種類のコンテンツを指しているかを調べる必要がなく、その種別の結果を直接処理することが可能になっています。 DSQueryクラスは、コマンドライン検索を使ってデバッグするためにmain()メソッドも持っています。

DSpaceにおける Lucene の実装

現在のところ、DSpaceはインデックス作成をカスタマイズするために独自のAnalyzerクラスとTokenizerクラスを持っています(DSAnalyzerDSTokenizer)。 これらを使って、Luceneにおいてステミングとストップワード処理を実現しています。 DSpaceでは、クエリごとにIndexReaderを作成します。今では気づいていますが、これはリソースの最も効率的な使用法ではありません。 実際の高負荷状況においてはファイルハンドルを使い切ってしまうようです。(ワイルドカードクエリが多くのファイルハンドルをオープンするようです)。 Luceneはスレッドセーフですので、すべてのクエリで共有する1つのLucene IndexReaderを持ち、インデックスが変化した場合に無効にして再オープンする方法がより良い実装となると考えられます。 将来のAPIの改善には、適合スコア(Luceneはこれを生成していますが、DSpaceでは無視しています)の採用と、論理演算などのもっと高度な検索概念のための抽象化があげられます。

インデックス化されるフィールド

DSpaceに含まれているDSIndexerクラスは、次のようにダブリンコアメタデータをインデックス化します。

(訳注: バージョン1.2.1からインデックス化の対象となるフィールドは設定できるようになりました。詳細は、Lucene検索インデックスの設定を参照してください。)

検索フィールド 対象となるダブリンコアフィールド
Authors contributor.*
creator.*
description.statementofresponsibility
Titles title.*
Keywords subject.*
Abstracts description.abstract
description.tableofcontents
Series relation.ispartofseries
MIME types format.mimetype
Sponsors description.sponsorship
Identifiers identifier.*

ハーベスティングAPI

org.dspace.searchパッケージは、「ハーベスティング」APIも提供しています。 これにより呼び出し元は、特定の時間範囲内で、あるいは、特定のスコープ(DSpace全体、あるコミュニティ、またはあるコレクション)内で変更されたアイテムの情報を抽出することが可能になります。 現在のところ、OAI-PMHアプリケーションと電子メール購読プログラムで使用されています。

Harvest.harvestメソッドは、必要なスコープと開始日付、終了日付を付けて呼び出されます。 日付はどちらもオプションです。日付は、DSpaceの他の場所でも使用されているUTCのISO8601形式でなければなりません。

HarvestedItemInfoオブジェクトが返されます。 このオブジェクトは、指定されたスコープと日付範囲に該当するアイテムについての基本的な情報を持つ簡単なコンテナです。 harvestメソッドにわたす引数により、containersフィールドにはアイテムが所属するコミュニティやコレクションのIDが、itemフィールドには、該当するItemオブジェクトが、設定されます。 これらのフィールドを設定しないことを選択すると、ハーベスト処理は極めて早く実行されます。

Harvestクラスは、単一のHarvestedItemInfoオブジェクトを作成するメソッドも提供しています。場合によっては、これを使った方が呼び出し元にとって都合がいいかもしれません。

ブラウズAPI

ブラウズAPI は日付、著者、タイトルの索引をメンテナンスし、呼び出し元がこれらの一部を抽出できるようにします。

タイトル

ダブリンコア要素title(限定子なし)の値が索引化される。冒頭の冠詞は除去され、大文字、小文字を区別せずにソートされる。たとえば、

The DSpace System

は、「T」ではなく、「D」の位置に現れる。

著者

contributor(任意の限定子付きの、もしくは、限定子なしの)要素の値が索引化される。 一般に、contributorの値は、「姓、名」の形であり、単純な大文字、小文字を区別しないソートを使って、著者は姓順に並べられる。

これは、著者の索引であって、著者によるアイテムの索引ではないことに注意すること。 4つのアイテムが同じ著者を持っている場合、著者が索引に現れるのは、1回きりである。 したがって、著者索引は、タイトル索引にくらべて多い場合もあれば、少ない場合もある。アイテムが2人以上の著者を持つ場合もあるし、逆に、1人の著者が複数のアイテムの著者の場合もあるからである。

ブラウズAPIにおける著者索引には、次のような制限がある。

  • 理想的には、2つ以上のアイテムの著者は、著者索引には1回だけ出現するものである。 しかし、現実的には、著者の名前はしばしば次の例のように少しずつ違った形で現れることがある。

    Doe, John
    Doe, John Stewart
    Doe, John S.

    現在のところ、上の3つの名前は、たとえ、同一著者を意味しているとしても、著者索引としてはすべて別のエントリとして出現する。 複数の論文を書いている著者を、索引として正確に1回だけ出現させるには、各アイテムに同じ形の著者名を正確に指定する必要がある。ただし、これは実際には難しいものである。

  • もう1つの問題は、同姓同名の著者である。これは1つの機関内でも生じる可能性がある。この場合、索引には1人の著者として出現することになる。

これらの問題は、図書館では一般に著者名典拠レコードにより解決されている。 著者名典拠では、同姓同名の著者を区別するために(生没年などの)追加情報を使って、著者名の「優先」形を管理している。 そのようなレコードを保守・管理することは非常に手間のかかる作業であり、問題も多く発生する。 特に、訓練を受けた図書館の目録担当者ではなく教員からメタデータを直接受け取る場合はなおさらである。 このような理由から、DSpaceは今のところ「典拠コントロール」機能を持っていない。

発行日

アイテムは発行日で索引化される。 この日付は、アイテムがDSpaceに収録された日付ではない。 アイテムはもともと、前もってどこか別の場所で出版されているものが多いからである。 使用されるダブリンコアフィールドは、date.issuedである。 この索引のソート順は逆にすることも可能で、日付の「昇順」、「降順」のどちらも可能である。

この索引は、日付によるアイテムの索引であり日付の索引ではないことに注意すること。 たとえば、30のアイテムが同一の発行日(2002年とする)を持っている場合、2002年というエントリが1つ出現するだけではなく、索引上には30のアイテムがすべて並んで出現する。

ダブリンコアにおける日付は、すべてUTCのISO8601形式なので、日付のソートは、さまざまな粒度をもつ日付表示の単純なアルファベット順で十分である。たとえば、次のようになる。

2001-12-10
2002
2002-04
2002-04-05
2002-04-09T15:34:12Z
2002-04-09T19:21:12Z
2002-04-10
登録日

もっとも最近収録されたアイテムを決めるためには、発行日を使わずに、アイテムの受入日を使用する。これは、ダブリンコアのdate.accessionedフィールドである。 この索引のその他の解釈は、発行日と同じである。

特定の著者のアイテム

ブラウズAPIで行なうことができるもう1つの処理は、特定の著者のアイテムを抽出することである。 著者は、抽出されるアイテムの第1著者である必要はない。 また、スコープを指定することも可能である。したがって、たとえば、コレクションYにおける著者Xのアイテムといった形で指定することができる。

この一風変ったブラウズは他のブラウズ機能よりいくぶん単純なものである。 現在のところ、結果の一部を返すように指定することはできない。 APIを呼び出すと、単に、あるスコープにある特定の著者のアイテムをすべて返すだけである。

抽出されるアイテムの著者は、APIに渡した著者の形と正確に一致するものだけであるということに注意すること。なぜそうなるのかは、著者索引によるブラウズの注意点についての説明を参照のこと。

一般に、このAPIは、BrowseScopeオブジェクトを作成し、抽出したい索引の範囲をパラメタに設定して呼び出されます。 次に、これは該当するBrowseメソッドに渡され、処理の結果を含むBrowseInfoオブジェクトが返されます。 BrowseScopeオブジェクトに設定するパラメタは次のとおりです。

以下の例を使って、説明します。

このパラメタを指定して、Browse.getItemsByTitleを実行した結果は、次のような感じになります。

        Rabble-Rousing Rabbis From Sardinia
        Reality TV: Love It or Hate It?
FOCUS>  The Really Exciting Research Video
        Recreational Housework Addicts: Please Visit My House
        Regional Television Variation Studies
        Revenue Streams
        Ridiculous Example Titles:  I'm Out of Ideas

タイトルと日付によるブラウズの場合は、実際のタイトルではなくItemオブジェクトが返されることに注意してください。 これらの場合、「フォーカス」としては、特定のアイテムや、リテラル値の一部、または、完全形を指定することができます。 リテラル値が指定された場合で、正確に一致する索引がない時には、一番近いものがフォーカスとして使用されます。 従って、たとえば、1文字のフォーカスを指定することはまったく問題ありません。

同一発行日を持つアイテムは多いでしょうから、特定のアイテムを開始点にできることは日付によるブラウズにとっては特に重要です。 たとえば、あるコレクションに発行日として2002年を持つアイテムが30あるとします。 1回あたり1ページに20アイテムの索引を見られるようにするには、2002年のどのアイテムがブラウズのフォーカスであるかを正確に指定できる必要があります。そうでないと、ブラウズを呼び出すたびに、発行日に2002年を持つ最初のアイテムから結果の表示が開始することになります。

著者によるブラウズは実際の著者名を持つStringオブジェクトを返します。 指定できるフォーカスは、リテラルStringの完全形あるいは部分形だけです。

もう一つ重要な注意点は、現在のところ、ブラウズ用の索引には権限ポリシーに関係なくアーカイブにあるすべてのアイテムのメタデータが含まれていることです。 これは、ブラウズの際には、アーカイブにあるすべてのアイテムがすべてのユーザに公開されることを意味します。 もちろん、非公開アイテムにアクセスしようとすると、一般的な権限メカニズムが適用されます。 このアプローチが望ましいものであるかは検討中です。 たとえば、抽出される結果にユーザの権限レベルを反映させるようなブラウズAPIの実装は可能だと思われますが、少し大変になるでしょう。

索引のメンテナンス

ブラウズAPIには、索引にアイテムを追加・削除するメソッドや、索引を1から再作成するメソッドが含まれています。 一般に、コンテンツ管理APIが必要なブラウズAPIメソッドを呼び出して、アーカイブにあるアイテムに同期させてブラウズ用の索引を管理しています。 ですので、ほどんどのアプリケーションはこれらのメソッドを呼び出す必要はありません。

もし何らかの原因でブラウズ用の索引に矛盾が生じた場合は、InitializeBrowseクラスが索引を1から再作成するコマンドラインツールです(一般に、/dspace/bin/index-allシェルスクリプトを使って実行します)。

警告

現在のところ、ブラウズAPIはとほうもなく非効率的です。 「索引化」作業は、関連するダブリンコア値の抽出、その正規化(小文字化とタイトルの場合は冒頭の冠詞の除去)、正規化した値とアイテムIDを該当するブラウズテーブルへ登録、という単純な手順を取っています。 このテーブルのビューには、スコープを限定したブラウズ操作のために、コレクションIDとコミュニティIDが含まれています。 ブラウズ操作が実行されると、次のような単純なSELECTクエリが実行されます。

SELECT item_id FROM ItemsByTitle ORDER BY sort_title OFFSET 40 LIMIT 20

これには主に2つの欠点があります。1つは、LIMITOFFSETが、PostgreSQL独自のキーワードであることです。 もう1つは、データベースにより動的にタイトルのソートを行なうので、現在のブラウズプログラムはスケーラビリティに欠けることです。 プログラムはBrowseInfoオブジェクトをキャッシュしているので、共通のブラウズ操作の実行速度を上げることができますが、これは理想的な解ではありません。

履歴レコーダ

履歴サブシステムの目的は、後々のリファクタリングや再利用で使えるように、DSpaceで生じた重要な変化を時間ベースの記録として残しておくことです。 履歴データはアーカイブについての現在の情報を提供するものではないことに注意してください。 単に過去に生じたことを記録するだけです。

Harmonyプロジェクトは、一時的なデータをモデル化する単純だが強力な方法を提供しています。 DSpaceの履歴フレームワークにはこのモデルを採用しています。 Harmonyモデルは、シリアライズのメカニズムで使用されています(そして、最終的にはシリアル化されたデータを解釈するエージェントで使用されます)。 しかし、履歴APIを使用するユーザはこれを気にする必要はありません。 コンテンツ管理APIがこの履歴システムの実行を担当します。 DSpace公開APIのユーザは、一般に履歴APIを使用する必要はありません。

DSpaceにおいてアーカイブ上関心のある何かが発生すると、HistoryManagerクラスのsaveHistoryメソッドが呼び出されます。 パラメタには、アーカイブ上関心のある何らかのオブジェクトへの参照が含まれています。 オブジェクトを受け付けると、参照により示されるすべてのアーカイブオブジェクトの状態をシリアル化し、Harmony形式のオブジェクトと、オブジェクト間の関係を記述するアソシエーションを作成します。(簡単な例を後で示します。) 各アーカイブオブジェクトは、異なるイベント間で追跡できるようにユニークな識別子を持っていなければならないことに注意してください。これについては、後で「ユニークなID」の項で説明します。

シリアライズ(Harmonyオブジェクトとアソシエーションを持っている)は、(設定によりますが)/dspace/historyディレクトリにファイルとして永久に保存されます。 historyテーブと historystateテーブルは、ファイルシステム上にあるシリアライズへの簡単な索引を格納しています。

アーカイブイベント

以下のイベントが履歴レコードとして記録される重要なイベントです。

シリアライズ

アーカイブオブジェクトのシリアライズは次の要素からなります。

ユニークなID

オブジェクトの履歴を追跡するためには、オブジェクトがユニークな識別子を持っていることが必要不可欠です。 システムのすべてのオブジェクトがハンドルを持っているわけではありませんので、ユニークな識別子とハンドルシステムとの結びつきはあまり強くありません。その代わりに、識別子は以下の要素からなります。

履歴データの保存

アーカイブオブジェクトがシリアル化されると、オブジェクトIDとMD5チェックサムが記録されます。 別のオブジェクトがシリアル化される際、シリアライズのチェックサムと、そのオブジェクトについての既存のチェックサムとがマッチングされます。そして、チェックサムがすでに存在する場合は、オブジェクトは保存されず、その代わりに、そのオブジェクトへの参照が使用されます。 シリアライズは削除されませんので、参照カウンタは必要ないことに注意してください。

履歴データは当初、照会可能な形では保存されません。 2つの簡単なRDBMSのテーブルが、何が、どこに保存されているかについての基本的な指標を提供します。 historyテーブルは、チェックサムと日付を持つシリアライズの索引です。 history_idカラムは、シリアライズが格納されているファイルに相当します。 たとえば、履歴IDが123456である場合、シリアライズは次のファイルに格納されていることになります。

/dspace/history/00/12/34/123456

テーブルには、シリアライズが書き込まれた日付と、シリアライズのMD5チェックサムも格納されています。

historystateテーブルは、指定されたオブジェクトの最も新しいシリアライズを示すために用意されています。

あるアイテムが一括アップロードで、あるコレクションに投稿されたとします。アイテムが最終的にコレクションに追加される際に、アイテム、コレクション、一括アップロードを実行したe-personに対する参照と、一括アップロードで投稿されたという事実を示す何らかの指標を持って、履歴メソッドが呼び出されます。

HistoryManagerは、呼び出されると次の処理を行います。まず、次の新規リソース(すべてユニークな識別子を持ちます)を作成します。

また、次の関係を生成します。

event  --atTime-->    time
event  --hasOutput--> state
Item   --inState-->   state
state  --contains-->  Item
action --creates-->   Item
event  --hasAction--> action
action --usesTool-->  DSpace Upload
action --hasAgent-->  User

履歴コンポーネントは、関係するすべてのアーカイブオブジェクト(この例では、アイテム、e-person、コレクション)の状態をシリアル化します。 また、生成されたシリアライズにアーカイブオブジェクトを関連させる2つの履歴テーブルのエントリを作成します。

警告

この履歴システムは大部分、未テストの実験状態にあります。 また、さらなるドキュメントを必要としています。 ファイルへの出力であれ、データベーステーブルへの出力であれ、履歴システムにより出力される情報が正確であるかどうかを確定するための本格的な作業はされていません。 特に、historystateテーブルには正しく出力されているとは思われません。


Copyright © 2002-2004 MIT and Hewlett Packard