WebObjectsのオープンソースライブラリ
Project Wonder のフレームワークの一つ、WOOgnl.framework。
WebObjectsのwodファイルに、「〜」に続けて
Ognl式を書いておくと、その
Ognl式が評価されるようになります。
まずはサンプルを見てもらいます。
計算を行う。
wodファイルに下のように書くと、WOStringのvalueは、実行時に文字列 "7"に変換、表示されます。
String1: WOString {
value = "〜2 + 5";
}
"〜"の次に、評価して欲しい
Ognl式を書きます。
文字列を結合する
例えば、ある人を表すデータがあるとします。
それぞれの人のデータは、姓と名を持っています。
ここで、その人のフルネームを表示する時にどうしますか?
姓と名の文字列を結合して返すメソッドを用意しますか?
もしくは、WOStringを2つ用意して並べますか?
そんな時に、このWOOgnl.frameworkを使うと、下のように書けば済んでしまいます。
/**
* 姓。文字列の結合用。
*/
public String familyName() {
return "姓";
}
/**
* 名。文字列の結合用。
*/
public String givenName() {
return "名";
}
String3: WOString {
value = "〜familyName() + ' ' + givenName()";
}
Ognl式で、メソッド、変数にアクセスすることができます。
person().name()
というように繋げることもできます。
staticメソッドの呼び出し
staticメソッドを(変数も)呼び出すことができます。
呼び出す時は、クラス名をフルネームで。
/**
* static メソッド。
*/
public static String statisMethodValue() {
return "this method is static method.";
}
String2: WOString {
value = "〜@WOOgnl.WOOgnlSample@statisMethodValue()";
}
引数を渡す。
メソッドに引数を渡すこともできれば、
引数付きのメソッドを呼び出して返り値を受け取ることもできます。
String6: WOString {
value = "〜setChangingValue(\"second value\")";
}
String4: WOString {
value = "〜alphs.objectAtIndex(alphIndex)";
}
「"」は\でエスケープします。
WOBuilderのInspectorからエスケープを入れようとすると、
下のように、勝手にエスケープされるので気をつけましょう。
String6: WOString {
value = "〜setChangingValue(\\"second value\\")";
}
上から順に評価される。
ファイルの上から順に、パース、評価されていくので、
下のようにすると、だんだん値が変わっていきます。
<WEBOBJECT NAME=String5></WEBOBJECT>
<WEBOBJECT NAME=String6></WEBOBJECT>
<WEBOBJECT NAME=String8></WEBOBJECT>
<WEBOBJECT NAME=String7></WEBOBJECT>
<WEBOBJECT NAME=String9></WEBOBJECT>
String5: WOString {
value = "〜getChangingValue()";
}
String6: WOString {
value = "〜setChangingValue(\"second valu\")";
}
String7: WOString {
value = "〜setChangingValue(\"third value\")";
}
String8: WOString {
value = "〜getChangingValue()";
}
String9: WOString {
value = "〜getChangingValue()";
}
private String changingValue = "first value";
public String getChangingValue() {
return this.changingValue;
}
public void setChangingValue(String v) {
this.changingValue = v;
}
条件式、ループ
他にも、条件式に、foreachループのようなこともできるのですが、
後は自分で調べていただきたい。
さて、この便利なWOOgnl.framework。使うにはどうしたら良いかというと。
WOOgnl.frameworkをプロジェクトに入れるだけです。
プロジェクトに加えると、それだけでWOOgnl.frameworkが使えるようになります。とってもお手軽ですね。
おまけ。その1。
「〜」が、Ognl式開始の目印になっているのだけど、
これが都合の悪い場合があるかもしれません。
もしくは、パース時に、パーミッションチェックだの、バリデーションだの
カスタムな処理を加えたい場合もあるかもしれません。
そんなときは、
ognl.webobjects.WOOgnlのsetFactory()メソッドの引数に、
カスタムな実装をしたWOOgnlの継承クラスを渡せば、
WOOgnl.frameworkの挙動を変更することができます。
(サンプルソースを後ろの方に用意しておきます。)
おまけ。その2。
環境変数"ognl.active"に"false"をセットすると、WOOgnl.framworkがパース処理を行わないようにすることができます。
以下、サンプルソースの一部。
WOOgnlSample.java
package WOOgnl;
import com.webobjects.foundation.*;
import com.webobjects.appserver.*;
import com.webobjects.eocontrol.*;
import com.webobjects.eoaccess.*;
/**
* WOOgnl.frameworkのサンプルソースです。
*/
public class WOOgnlSample extends WOComponent {
/**
* 本クラスを生成します。
*/
public WOOgnlSample(WOContext context) {
super(context);
}
/**
* static メソッド。
*/
public static String statisMethodValue() {
return "this method is static method.";
}
/**
* 姓。文字列の結合用。
*/
public String familyName() {
return "姓";
}
/**
* 名。文字列の結合用。
*/
public String givenName() {
return "名";
}
/**
* nullを返すだけのメソッド。
*/
public WOComponent nullAction() {
return null;
}
/**
* アルファベットのリスト。
*/
public NSArray alphs = new NSArray(new Object[]{
"A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z",
});
/**
* 引数つきメソッド呼び出し用。
*/
public int alphIndex;
/**
* 順番にパースされていく様子を示すためのメソッド。
*/
private String changingValue = "first value";
/**
* changingValueのgetメソッド。
*/
public String getChangingValue() {
return this.changingValue;
}
/**
* changingValueのgetメソッド。
*/
public void setChangingValue(String v) {
this.changingValue = v;
}
}
WOOgnlSample.wo/WOOgnlSample.wod
<HTML>
<HEAD>
<META NAME="generator" CONTENT="WebObjects 5.2">
<TITLE>WOOgnlサンプルソース</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<WEBOBJECT NAME=Form1>計算を行う。<BR>
"〜2 + 5"<BR>
<WEBOBJECT NAME=String1></WEBOBJECT><BR>
<BR>
<BR>
static メソッドの呼び出し。<BR>
"〜@WOOgnl.WOOgnlSample@statisMethodValue()"<BR>
<WEBOBJECT NAME=String2></WEBOBJECT><BR>
<BR>
<BR>
文字列の連結<BR>
"〜familyName() + ' ' + givenName()"<BR>
<WEBOBJECT NAME=String3></WEBOBJECT><BR>
<BR>
<BR>
引数付きのメソッド呼び出し。<BR>
入力した順番のアルファベットを表示する。<BR>
"〜alphs.objectAtIndex(alphIndex)"<BR>
<WEBOBJECT NAME=TextField1></WEBOBJECT>
[<WEBOBJECT NAME=String4></WEBOBJECT>]<BR>
<BR>
<BR>
<WEBOBJECT NAME=String5></WEBOBJECT><BR>
<WEBOBJECT NAME=String6></WEBOBJECT><BR>
<WEBOBJECT NAME=String8></WEBOBJECT><BR>
<WEBOBJECT NAME=String7></WEBOBJECT><BR>
<WEBOBJECT NAME=String9></WEBOBJECT><BR>
<BR>
<BR>
<WEBOBJECT NAME=SubmitButton1>
</WEBOBJECT></WEBOBJECT>
</BODY>
</HTML>
WOOgnlSample.wo/WOOgnlSample.wod
Form1: WOForm {
multipleSubmit = true;
}
String1: WOString {
value = "〜2 + 5";
}
String2: WOString {
value = "〜@WOOgnl.WOOgnlSample@statisMethodValue()";
}
String3: WOString {
value = "〜familyName() + ' ' + givenName()";
}
String4: WOString {
value = "〜alphs.objectAtIndex(alphIndex)";
}
String5: WOString {
value = "〜getChangingValue()";
}
String6: WOString {
value = "〜setChangingValue(\"second valu\")";
}
String7: WOString {
value = "〜setChangingValue(\"third value\")";
}
String8: WOString {
value = "〜getChangingValue()";
}
String9: WOString {
value = "〜getChangingValue()";
}
SubmitButton1: WOSubmitButton {
action = nullAction;
}
TextField1: WOTextField {
numberformat = "0";
value = alphIndex;
}
ここより、下は、WOOgnl.javaの挙動を変えるソースのサンプル。
Application.java
package Main;
import com.webobjects.foundation.*;
import com.webobjects.appserver.*;
import com.webobjects.eocontrol.*;
import er.extensions.*;
import ognl.webobjects.*;
import WOOgnl.*;
public class Application extends ERXApplication {
public static void main(String argv[]) {
ERXApplication.main(argv, Application.class);
}
public Application() {
super();
// カスタムな処理を行う場合は、
// 下のコメントアウトを外します。
WOOgnl.setFactory(new CustomWOOgnl());
}
}
CustomWOOgnl.java
package WOOgnl;
import com.webobjects.foundation.*;
import com.webobjects.appserver.*;
import com.webobjects.eocontrol.*;
import com.webobjects.eoaccess.*;
import ognl.webobjects.*;
/**
* WOOgnl.javaを継承して、WOOgnl.framworkの挙動を
* 変更します。
*/
public class CustomWOOgnl extends WOOgnl {
/**
* コンストラクタ。
*/
public CustomWOOgnl(){
super();
}
/**
* デフォルトの"〜"ではなく、"#"を代わりに使用する。
*/
public String ognlBindingFlag() {
return "#";
}
}
最後に、今回使ったサンプルを、置いておきます。
WOOgnl サンプルソース