ORMとしてActiveObjectsを使用する
Atlassianのデータを保存する場所といえば、BandanaでありContentPropertyManagerである。
が、JIRA4.4からConfluence4.3からは特に意識しなくてもActiveObjectsが使えるようになった。こちらの方が早くて軽くて大容量でそのプラグイン固有のデータを保存して利用することができるということだ。
以下の記事をベースに使い方を見てみる。
Getting Started with Active Objects - Atlassian Developers
使えるようにするには
まず、pom.xmlにDependencyを記述
<dependency> <groupId>com.atlassian.activeobjects</groupId> <artifactId>activeobjects-plugin</artifactId> <version>${ao.version}</version> <scope>provided</scope> </dependency>
で、${ao.version}というのはこのURLから自由に選んでくれっていうことらしい。チュートリアルでは1.2.3を使っている。Confluence用っぽい0.24-m5-confluenceっていうのがあってこれを使うといいのだろうか・・・・。 https://maven.atlassian.com/content/repositories/atlassian-public/com/atlassian/activeobjects/activeobjects-plugin/
あと、なぜかGoogle.collectionsも入れておいてって言われた。
<!-- Google Collections, useful utilities for manipulating collections --> <dependency> <groupId>com.google.collections</groupId> <artifactId>google-collections</artifactId> <version>1.0</version> <scope>provided</scope> </dependency>
ActiveObjectsとして使用されるClassを指定
atlasian-plugin.xmlに
<ao key="ao-module"> <description>The module configuring the Active Objects service used by this plugin</description> <entity>com.atlassian.tutorial.ao.todo.Todo</entity> </ao>
というように、使用するActive Objects Classを記述する。上記の場合、com.atlassian.tutorial.ao.todo.TodoクラスがActiveObjectとなって使用されるようになる。
前述のClassを実装
atlassian-plugin.xmlで記述した com.atlassian.tutorial.ao.todo.Todo をinterfaceで実装する。
setter/getterでエンティティを定義。この時「ID」は net.java.ao.Entityが使っているのでよっぽどでない限りOverwriteはしない。
package com.atlassian.tutorial.ao.todo; import net.java.ao.Entity; public interface Todo extends Entity { String getDescription(); void setDescription(String description); boolean isComplete(); void setComplete(boolean complete); }
ServletやXWorkで使用する場合の準備
Servletの場合
public final class TodoServlet extends HttpServlet { private final ActiveObjects ao; public TodoServlet(ActiveObjects ao) { this.ao = checkNotNull(ao); }
という感じでいつものようにConstructorでInjectionする。このaoを使って先ほどのEntity化されたObjectをCRUDする。
XWorkの場合
XWorkの場合はConstructorによるInjectionが無いのでsetter/getterを使うかと思いきや、このActiveObjectsにはそれが使えないっぽい。なので一旦ActiveObjectsを使うClassをComponentとして登録する。
一旦Componentを作成する。
まずatlassian-plugin.xmlでcomponentとして登録する
<component key="foo-service" name="Foo-Service" class="jp.example.com.FooServiceImpl" public="true"> <interface>jp.example.com.FooService</interface> </component>
jp.example.com.Fooのinterfaceを作成し、jp.example.com.FooImplを実装する。public=trueでないならinterfaceは不要なわけだと思うけど。
で、こいつのConstructorにてActiveObjectsをInjectionしてもらう。
import static com.google.common.base.Preconditions.checkNotNull; public class FooServiceImpl implements FooService { private final ActiveObjects ao; public FooServiceImpl(ActiveObjects ao) { this.ao = checkNotNull(ao); }
で、XWorkの方でこのComponentを読み込む
XWorkでsetter/getterを定義してComponentを使えるようにする。
import static com.google.common.base.Preconditions.checkNotNull; private FooService fooService; public FooService getFooService() { return fooService; } public void setFooService(FooService fooService) { this.fooService = checkNotNull(fooService); }