読者です 読者をやめる 読者になる 読者になる

sandbox

Scala, Android, Architecture, Management, Service Design あたりを主戦場としております

Jackrabbit OCM 続き

前回は、本当に触りを試しただけなので、もう少し詳細に以下の流れで検証してみます。

  1. マッピングするクラスの作成と、マッピングの定義
  2. OCM で使用されるカスタムノードタイプ ocm:discriminator の登録
  3. Mapper の作成と、Object Content Manager オブジェクトの生成
  4. OCM を使用した登録、削除、検索

では、順にやってみます。

マッピングするクラスの作成と、マッピングの定義

今回はアノテーションでマッピングを定義してみます。

Parent.java

@Node
public class Parent{
	@Field(path=true) private String path;
	@Field private String title;
	@Field private Date created;
	@Collection(elementClassName=Child.class, collectionConverter=NTCollectionConverterImpl.class)

    //getter,setter...
}

Child.java

@Node
public class Child{
	@Field(path=true) private String path;
	@Field private String title;

    //getter, setter...
}
@Node アノテーション

簡単に使用しているアノテーションを見ていくと、まず

@Node

で、このクラスをノードにマップする事を示しています。
@Node には、下記のプロパティも指定出来ます。

プロパティ 意味
jcrType JCR のプライマリノードタイプを指定します。指定しなければ、nt:unstructured になる。
jcrSuperTypes 継承しているノードタイプであれば、スーパータイプを指定する。※どういうケースで指定しなければいけないのかは、まだ未調査。
jcrMixinTypes mix:versionable などの、Mixin Node Type を指定する。
@Field アノテーション

次に、各プロパティに JCR プロパティにマップする為に @Field を指定します。
@Field にも、下記のプロパティが用意されています。
※JCR のプロパティと、Java のプロパティが混同するので、Java のプロパティは、フィールドと言い換えます。

プロパティ データ型 デフォルト 意味
jcrName String "" 実際に登録するノードプロパティ名を指定する。何も指定しないと、フィールド名で登録される。
id boolean false このオブジェクトの ID を指定出来る。※自動生成ではない。ID を定義すると幾つかの処理が早くなるらしい。また、各コレクションコンバータを使用した時のパス名の生成方法が変る。※詳細は後述
path boolean false JCR のノードパスとマップされる。※Each persistent class must have a path field と書いてあるのですが、何故かデフォルト false です。
uuid boolean false mix:referencable を指定した時の UUID プロパティがマップ出来る。
converter Class Object.class AtomicTypeConverter インタフェースを実装した Int2BooleanTypeConverterImpl などのコンバータを指定出来る。
jcrDefaultValue String "" デフォルト値を指定出来る。
jcrValueConstraints String "" ※未検証 カンマ区切りで、許可する値を指定出来る。
jcrType String "" ※未検証 JCR プロパティタイプを指定出来る。(String, Date, Long, Double, Boolean, Binary)
jcrAutoCreated boolean false ※未検証 プロパティを自動生成するかを指定出来る。
jcrMandatory boolean false ※未検証 プロパティを強制するかを指定出来る。
jcrOnParentVersion String COPY ※未検証 (COPY, VERSION, INITIALIZE, COMPUTE, IGNORE, ABORT)
jcrProtected boolean false ※未検証 プロパティが protected がどうかを指定する。
jcrMultiple boolean false ※未検証 プロパティがマルチバリューかどうかを指定する。

※未検証となっているところは、実際まだよく分かってません。。
おそらく、カスタムノードタイプの定義をアノテーションでも記述する必要があるのかな、と推測してます。
(ノードタイプ定義で、jcrMandatory=true だったら、アノテーションでも記述しておかないと駄目とか)

@Collection

@Field と同じプロパティは省きます。

プロパティ データ型 デフォルト 意味
proxy boolean false 遅延ロードを行うかを指定する。true を指定した場合、親オブジェクトの get メソッドが呼ばれた時にロードされる。
autoRetrieve boolean true
autoUpdate boolean true
autoInsert boolean true
elementClassName Class Object.class 各エレメントのクラスを指定する。
collectionClassName Class Object.class java.util.Collection の実装クラス、サブクラスでない場合に、コレクションクラスのクラスを指定する。
collectionConverter Class DefaultCollectionConverterImpl.class コレクションの変換に使用するコンバータクラスを指定する。
jcrSameNameSiblings boolean false ※未検証 SameNameSiblings を許可するか?

コレクションコンバータにも、標準で用意されているだけでも幾つか種類があります。
まだ、各コンバータの意味は正確に理解していないですが、種類だけでも載せておきます。

クラス名 意味
DefaultCollectionConverterImpl デフォルトのコンバータ。親ノードの子ノードの間に、nt:unstructured タイプのノードが、コレクションをもつプロパティ名で作成される。
NTCollectionConveretrImpl 親ノードの直下に各子ノードが作成される。ただし、2 つの制限があり、1 つめは、2 つ以上のコレクションは持てない事。2 つ目は、null と、空のコレクションの区別が出来ない事。
BeanReferenceCollectionConverterImpl
MultiValueCollectionConvereterImpl
ReferenceCollectionConverterImpl
ResidualNodesCollectionConverterImpl
ResidualPropertiesCollectionConverterImpl

例. DefaultCollectionConverterImpl を使用した場合

/parent
  /kids ← ノードタイプ nt:unstructured で、パス名にはフィールド名が使用される
    /collection-element
    /collection-element[2]
    /collection-element[3]

例. NTCollectionConverterImpl を使用した場合

/parent
  /collection-element
  /collection-element[2]
  /collection-element[3]

また、各エレメントクラスに @Field(id=true) を使用して、 id フィールドを定義すると、
collection-element となっているパス名を変えることができます。

例. コレクションのエレメントクラスに、ID フィールドを定義した場合

for(int i : new int[]{1,2,3}){
	Child c = new Child();
	c.setId("kids");
	c.setTitle("Huga " + i);
	kids.add(c);
}
/parent
  /kids
  /kids[2]
  /kids[3]  

長くなったので...

記事が長くなったので続きは次回書きます。
次にやることですが、OCM は内部的に ocm:discriminator という mixin ノードタイプを使用していて、
OCM 経由でオブジェクトを取得する為には、これを予め定義する必要があります。
※なんか美しくないけど。

そのファイルの用意やら、定義方法を次回紹介します。


それにしてもドキュメント無さ過ぎ orz