JCR 1.0 (JSR-170) ナナメ読み

http://jcp.org/aboutJava/communityprocess/final/jsr170/index.html

何で今更こんな仕様をナナメ読み!

1 Preface

とばす

2 INTRODUCTION

いろんなベンダーが独自コンテントリポジトリを作ってるから共通APIが必要だと。このAPIは実装アーキテクチャ、データソース、プロトコルには依存しません。

2つの compliance level と、オプショナルなfeaturesを定義します。

Level 1 : read-only リポジトリ
Level 2 : 書き込み
Optional Features : トランザクションとか

3 USE CASES

共通APIがあれば便利だぜ(それ以上のこと言ってるか?この章)

4 THE REPOSITORY MODEL

リポジトリは複数のワークスペースを持ちます。

ワークスペースはアイテムのツリーを持ちます。アイテムはノード、またはプロパティーです。ノードは子ノードと子プロパティを持ちます。ワークスペースには親のいないひとつのルートノードがあって、そこから木構造が始まります。プロパティは子供を持ちません。 --- XMLとかと同じ、普通の木構造ですね。このスタイルの源流って何なんだろう?

4.1 API Basics

Repository をどっかから(JNDIとか)もらってきて、 Credentials と ワークスペース名で login し、 Session を受け取る。 あとは Session が大活躍。

Session.getRootNode() とか、Node.getNode(String relPath), Node.getProperty(String relPath)とかで相対パスでアクセス。Session.getItem(String abspath) で絶対パスでアクセス。Session.getNodeByUUID(String uuid)でUUIDでアクセス。addNode(), setProperty() で書き込み。あとremove()とか。

Session.save()でValidationと永続化。save前の状態の変更点は"pending changes"と呼ぶ。Session.refresh(false)で破棄。トランザクションがある場合は、永続化はコミット時。ただしsave()はいずれにせよ必要。Validationはsave時に行われる。

4.2 Compliance Levels

Level 1 includes:

  • Retrieval and traversal of nodes and properties
  • Reading the values of properties
  • Transient namespace remapping
  • Export to XML/SAX
  • Query facility with XPath syntax
  • Discovery of available node types
  • Discovery of access control permissions

Level 2 adds:

  • Adding and removing nodes and properties
  • Writing the values of properties
  • Persistent namespace changes
  • Import from XML/SAX
  • Assigning node types to nodes

Optional:
Any combination of the following features may be added to an implementation of either level.

  • Transactions
  • Versioning
  • Observation (Events)
  • Locking
  • SQL syntax for query

まあ普通Level2までは実装するんじゃね?あとOptionalでもTransactionとVersioningはかなり欲しいところだろう。

4.3 Same–Name Siblings

同じ親に同じnameのノードが許されるノードタイプがある(プロパティはダメ)。Node.getNodes(String namePattern)でiteratorが返ってくる。パスは添字つけて /a/b[2]/c[3] とかになる。そのリスト内の順序も要考慮(Orderable Child Nodes)。

めんどくせーな、禁止すればいいのに。と言いたいが、「Portalノードの下に複数のPageノードがあります」って言われると、まあそうか、仕方ないな。

4.4 Orderable Child Nodes

Node.getNodes()で返ってくるノードの順番はNode.orderBefore()で変更できる。できるかどうかはノードタイプに依存。

4.5 Namespaces

built-in Namespaceは

  • jcr : Reserved for items defined within built-in node types.
  • nt : Reserved for the names of built-in primary node types.
  • mix : Reserved for the names of built-in mixin node types.
  • xml : Reserved for reasons of compatibility with XML.
  • “” : (the empty prefix) This indicates the default namespace.
4.6 Path Syntax

Name と Path は違うので注意。Name は添字無し ( myapp:paragraph )で、 Path は添字あり ( myapp:paragraph[3] )。

4.7 Properties

複数の値を持つプロパティあり。めんどくせーな。

PropertyTypeで、REFERENCE, PATH, NAME プロパティは特別。

NAME : ノードタイプ名とか。Namespace-aware
PATH : パス。Namespace-aware
REFERENCE : UUID

4.7.3 No Null Values

nullは不可。Multi-value propertyの場合は、nullをsetすると、リストからの削除を意味する。

4.8 Node Types

ノードは必ずひとつだけ、primary type を持つ。 -> プロパティ jcr:primaryType

primaryに加えて、さらに複数の mixin types を持つことが可能。 -> プロパティ jcr:mixinTypes

4.9 Referenceable Nodes

Referenceable Node は mix:referenceable を mixin する。プロパティ jcr:uuid を持つ。なのでUUIDで参照できる。

Referenceable Nodeが削除されるとき、そのノードに対するリファレンス(PropertyType.REFERENCEによってされているはず)も削除されていること。frozen version state の場合は例外。 

4.10 Workspaces

ひとつのリポジトリで、複数のワークスペースがある場合、あるワークスペースのノードは、別ワークスペースにcorresponding nodesを持つことができる。次のVersioningの仕様でサポートされる。。。がこの機能自体は重要ではないように思う。本当に必要か?

4.11 Versioning

Versioningをサポートする場合、ノードは mix:versionable を mixin。versionのsaveをchecking inと呼ぶ。Version historyはVersion storageに保存される。ひとつのrepositoryにひとつのVersion storageがある。各Workspaceには /jcr:system/jcr:versionStorage というノードがあり、そこから参照できる。

4.12 Metadata

結局「コンテンツ」はプロパティの中にある。APIは「コンテンツ」と「メタデータ」を区別しないが、アプリ的には区別したい。APIには"primary child item"というコンセプトがある。Node.getPrimaryItem()を呼べば、そのノードの"primary child item"が取れるので、一般的には(ノードタイプによるが)、そのノードの「コンテンツ」がとれるはず。

4.13 Hierarchical versus Direct Access

UUIDがあるので、Hierarchicalな構造は必須ではないよ、という話。

5 EXAMPLE IMPLEMENTATIONS

いろんな実装例。もちろん普通はDB。

6 LEVEL 1 REPOSITORY FEATURES

ここからが本番。。。だけどマジ長いのでナナメ読み度が増す。

Level 1 は read-only repository.

  • Retrieval and traversal of nodes and properties
  • Reading the values of properties
  • Transient namespace remapping
  • Export to XML/SAX
  • Query facility with XPath syntax
  • Discovery of available node types
6.1 Accessing the Repository

Repository.login(Credentials credentials, String workspaceName) でログインしたら Session が返ってくる。

6.2 Reading Repository Content

Session のメソッドでいろいろアクセス。getWorkspace()でWorkspaceオブジェクトも取れる。Node のメソッドでノードからいろいろ取ったり、相対パスアクセス。Propertyからプロパティ読む。プロパティの値はValueオブジェクト。ItemはNode, Propertyの親インターフェース。

6.3 Namespaces

Workspace.getNamespaceRegistry() で NamespaceRegistry オブジェクトが取れる。URIとprefixのマッピングを持っている。ビルトインのマッピング

ビルトインのノードタイプ内で定義されるItem(つまりNodeまたはProperty)用

プライマリノードタイプの名前用

mixinノードタイプの名前用

XMLの互換性のためにあるけどクライアントは使っちゃダメらしい

  • “” (the empty prefix) -> “” (the empty URI)

デフォルト名前空間。普通に使われるのかよくわからん

Session.setNamespacePrefix(String prefix, String uri) で当該セッションのみマッピングを変えられる。たぶん重要じゃない。

6.4 XML Mappings

リポジトリXMLで表現できる。system view と document view の2種類のマッピング方式がある。

system view はリポジトリの完全なSerialization。名前空間は xmlns:sv="http://www.jcp.org/jcr/sv/1.0" で、XMLで構成されることになる。あと細かいルールがいろいろ。

document viewはもっとhuman-readable。system view と比べて冗長さが無い感じ。細かいルールがいろいろ。

あと、文字のエスケープについて。

6.5 Exporting Repository Content

Session.exportSystemView()やSession.exportDocumentView()でexportできます。

6.6 Searching Repository Content

XPathSQL(optional)で検索可能。XPathはdocument viewに対してかける。

クエリの文法とか。jcr:like みたいな function が XPath内で使える。きもい。

Workspace.getQueryManager()でQueryManagerオブジェクトを取って、QueryManager.createQuery(String statement, String language)でQueryオブジェクトを作る。

6.7 Node Types

ノードタイプとは、そのノードがどのような子ノードもしくはプロパティを持つことができるか/持たなければいけないか、を定義したものです。

ノードタイプは Name, Supertypes, Mixin status, Orderable child nodes status, Property definitions, Child node definitions, Primary Item Name を持ちます。

すべてのノードはただ一つの primary node type を持ちます。さらに mixin node type を持つことができます。

Property Definition は name, type, value constraints, default value, auto-createdかどうか, mandatoryかどうか, onParentVersion, protectedかどうか, multiple valuesかどうか、を持ちます。

Child Node Definition は name, required primary node types, default primary node type, auto-createdかどうか, mandatoryかどうか, onParentVersion, protectedかどうか, same-name siblingsかどうか、を持ちます。

note type は supertype から継承可能。

NodeTypeオブジェクトから、いろいろ取れる。

nt:base はすべてのノードタイプの親タイプ。

mix:referenceable, mix:versionable, mix:lockable が定義されている(optional)

6.7.22 Predefined Primary Node Types にpredefined ノードタイプの詳細が! これを書き留める気は。。。無いです。ヒエラルキーもあります。nt:unstructured は nt:base の子なんですね。

6.8 System Node

/jcr:system はシステムフォルダ。/jcr:system/jcr:nodeTypes とか /jcr:system/jcr:versionStorage とか。

6.9 Access Control

JAASも使えるよ。

7 LEVEL 2 REPOSITORY FEATURES

Level 2 は書く方。

  • Adding and removing nodes and properties
  • Writing the values of properties
  • Persistent namespace changes
  • Import from XML/SAX
  • Assigning node types to nodes
7.1 Writing Repository Content

Sessionで行った更新処理は 'Transient Storage' に書き込まれ、Session.save()でWorkspaceに書き込まれる(Transactionサポートの時はcommit時)。Session.refresh(false)を呼べば捨てることができる。Item.save、 Item.refresh(false)でItemレベルでもできる。

以下のメソッドはダイレクトにWorkspaceに書き込む。

  • Node.checkin, checkout, restore, restoreByLabel, merge, cancelMerge, doneMerge, update, lock and unlock.
  • Workspace.move, copy, clone, restore and importXML
  • VersionHistory.addVersionLabel, removeVersionLabel, removeVersion.

Validationは可能ならすぐやるが、遅くともsave時に行う。

7.1.3.4 Seeing Changes Made by Other Sessions に複数Sessionのconcurrencyの記述。Copy-on-Read にするか Copy-on-Write にするかは実装依存

ValueFactory.createValue(String)でValueを作る。

7.2 Adding and Deleting Namespaces

アプリケーション固有のノードタイプ、プロパティ定義などを追加するには必須かな?

7.3 Importing Repository Content

system view のXMLリポジトリの完全なSerializationだからいいとして、document viewの場合はここにある細かいルールにしたがってimportされる。暗黙にノードを追加したりノードタイプを決めたりしたりして、怪しい。

7.4 Assigning Node Types

ノード作成時に primary/mixin node type を決める。自動的につけても良い。

7.5 Thread-Safety Requirements

javax.jcr.Repository のすべてのメソッドはスレッドセーフでなければならない。あとは必須ではない。のでSessionのマルチスレッド操作に注意!

8 OPTIONAL REPOSITORY FEATURES

Level 1/2 以外のオプショナルな機能です。各JCR実装がこれらの機能をサポートしてるかどうかは注意しましょう。

8.1 Transactions

JTAトランザクションに乗っかってcommit/rollbackされるということ。

8.1.1 Container Managed Transactions: Sample Request Flow のシーケンス図は重要かな。実際はXARepositoryなどというインターフェースは無く、XASession自身がXAResourceをimplementsするのが普通と思われる。

Sessionの処理が複数のトランザクションにまたがる場合、Session内のsave前のtransient storageはどうなるかという話。

8.2 Versioning

The versioning system is modelled after the Workspace Versioning and Configuration Management (WVCM) API defined by JSR 147. えー、これ読まないとだめすかねえ。

ノードは要mix:versionable。Node.checkin() でバージョンが作られる。

8.2.2 Version Storage でバージョンのノード構造が語られている。。。頭がぐるぐるするよ。

うーん、ここかなり重いです。

8.3 Observation

普通にEventListenerとかでやるみたい

8.4 Locking

mix:lockable なノードに対して、Node.lock() したら、他のユーザはwriteオペレーションができない、ということ。ロック取りっぱなし問題が発生しそうですね!タイムアウトは可能。

8.5 Searching Repository Content with SQL

WorkspaceをいかにRDBMSのようにみたててアクセスするか。Node Types as Tables とか。なんか本末転倒のような気がするのは僕だけでしょうか?!