Ruletとして必要なことは、以下の3つです。
package examples.org.seasar.nazuna;
import org.seasar.nazuna.Rulet;
public class HelloRulet extends Rulet {
public void doExecute() {
System.out.println("Hello World");
}
}
Ruletを実行するには、Nazuna.executeRulet(String className)を呼び出します。
最初の引数は、Ruletのクラス名です。
HelloRuletを呼び出すクライアントは次のようになります。
import org.seasar.nazuna.Nazuna;
import org.seasar.util.SeasarException;
public class HelloRuletClient {
private static final String RULET_CLASS_NAME =
"examples.org.seasar.nazuna.HelloRulet";
public static void main(String[] args) {
try {
Nazuna.executeRulet(RULET_CLASS_NAME);
} catch (SeasarException ex) {
ex.printStackTrace();
}
}
}
実行結果は、
Hello Worldになります。
doExecuteメソッドの引数や戻り値は、自由に決めることができます。
プリミティブ型も使うことができます。
例をあげると次のようになります。
| 引数の数 | executeRulet |
|---|---|
| 0 | executeRulet(String className) |
| 1 | executeRulet(String className, Object arg0) |
| 2〜5 | executeRulet(String className, Object arg0, Object arg1, ...) |
| 6〜 | executeRulet(String className, Object[] args) |
doExecuteメソッドの引数がプリミティブ型の場合、executeRuletメソッドの引数には、
プリミティブ型のラッパークラスのオブジェクトを使います。
例えば、intの場合、java.lang.Integerを使うことになります。
doExecuteメソッドの戻り値は、executeRuletメソッドの戻り値として返されます。
doExecuteメソッドの戻り値がプリミティブ型の場合、executeRuletメソッドの戻り値は、
ラッパークラスのオブジェクトになります。
足し算をするRuletは次のようになります。
package examples.org.seasar.nazuna;
import org.seasar.nazuna.Rulet;
public class AddRulet extends Rulet {
public int doExecute(int arg0, int arg1) {
return arg0 + arg1;
}
}
AddRuletを呼び出すクライアントは次のようになります。
package examples.org.seasar.nazuna;
import org.seasar.nazuna.Nazuna;
import org.seasar.util.SeasarException;
public class AddRuletClient {
private static final String RULET_CLASS_NAME =
"examples.org.seasar.nazuna.AddRulet";
public static void main(String[] args) {
try {
Integer ret = (Integer) Nazuna.executeRulet(
RULET_CLASS_NAME, new Integer(1), new Integer(2));
System.out.println(ret);
} catch (SeasarException ex) {
ex.printStackTrace();
}
}
}
実行結果は、
3になります。
ルールによっては、引数が指定されなかった場合に、デフォルトの値が
適用されて欲しい場合があります。
Ruletにpublic static finalな定数を定義することで、
引数にデフォルト値を適用させることができます。
定数名(フィールド名)は、「DEFAULT_ARG + 引数のインデックス」になります。
引数のインデックスは0からはじまります。
例えば、2番目の引数が指定されなかった場合のデフォルト値を設定したい場合は、
public static final int DEFAULT_ARG1 = 10;
と定義することになります。
デフォルト値の型に制限はありません。プリミティブ型も使えます。
次のRuletは、引数が指定されなかった場合、Hello Worldと出力されます。
package examples.org.seasar.nazuna;
import org.seasar.nazuna.Rulet;
public class ArgDefaultValueRulet extends Rulet {
public static final String DEFAULT_ARG0 = "World";
public void doExecute(String arg0) {
System.out.println("Hello " + arg0);
}
}
package examples.org.seasar.nazuna;
import org.seasar.nazuna.Nazuna;
public class ArgDefaultValueRuletClient {
private static final String RULET_CLASS_NAME =
"examples.org.seasar.nazuna.ArgDefaultValueRulet";
public static void main(String[] args) {
try {
Nazuna.executeRulet(RULET_CLASS_NAME);
Nazuna.executeRulet(RULET_CLASS_NAME, "Nazuna");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
実行結果は、
Hello World Hello Nazunaになります。
Ruletを呼び出すときに、Ruletが期待している引数の条件を事前条件といいます。
例をあげると次のようなものがあります。
package examples.org.seasar.nazuna;
import org.seasar.nazuna.Rulet;
import org.seasar.util.Assertion;
public class PreConditionRulet extends Rulet {
public void doValidate(String name) {
Assertion.assertNotNull("name", name);
}
public void doExecute(String name) {
System.out.println("Hello " + name);
}
}
Assertionクラスは、表明のためのユーティリティです。
下記のコードと同じ意味になります。
if (name == null) {
throw new SeasarRuntimeException("ESSR0007", "name");
}
package examples.org.seasar.nazuna;
import org.seasar.nazuna.Nazuna;
public class PreConditionRuletClient {
private static final String RULET_CLASS_NAME =
"examples.org.seasar.nazuna.PreConditionRulet";
public static void main(String[] args) {
try {
Nazuna.executeRulet(RULET_CLASS_NAME, (String) null);
} catch (Exception ex) {
System.out.println(ex);
}
}
}
実行結果は、
org.seasar.util.SeasarRuntimeException: [ESSR0007]name should not be nullになります。
RuletもServletと同様なライフサイクルがあります。
クライアントから最初にリクエストがあったときに、インスタンスが作成され
init()が呼び出されます。
リクエストを処理する直前に、doValidate()を呼び出して事前条件をチェックし、
OKならdoExecute()を呼び出します。
システムが終了するときには、destroy()が呼び出されます。
ホットデプロイが行われるときには、古いインスタンスのdestroy()が呼び出された後、
新しいインスタンスのinit()が呼び出されます。
org.seasar.nazunaにあるRequiredTx、RequiresNewTx、MandatoryTxインターフェースを
implementsするだけで、Nazunaにトランザクション制御を任せることもできます
これらのインターフェースは、実装は必要なくマーカーとして使われます。
インターフェースとtransAttribute
の関係は、以下のようになります。
| インターフェース | transAttribute |
|---|---|
| なし | Supports |
| RequiredTx | Required |
| RequiresNewTx | RequiresNew |
| MandatoryTx | Mandatory |