2007年01月28日

SQL出力

WebObjectsのデバグ方法はいつも一カ所にまとまった資料があればいいなあと思いつつ、なかなか自分でもまとめられない。たまたま一つ使ったのでメモしておきます。

実行時にEOがDBサーバーからデータを取得するタイミングなどを知りたい場合に、以下のオプションをつけて起動すればコンソールにSQL文が出力されます。

-DEOAdaptorDebugEnabled=true

posted by 永遠製作所 at 17:32| 東京 ☁| Comment(0) | TrackBack(0) | WebObjects | このブログの読者になる | 更新情報をチェックする

2006年09月17日

WOFormのactionバインディング

今日、昔作ったプロジェクトを触っていて気がついたので記録しておく。
というか、こんな機能あることを知らなかったというくらい記憶から消えていた。

WOFormのactionにはそのフォーム内でのデフォルトのアクションをバインドするものだと思っていた。私が使うのはフォーム内のJavaScriptを使ってサーバーで処理を実行するときなんかにFormのsubmitを使ってここにバインドしたアクションを呼び出していた。

ところが、昔(と言っても半年くらい前だ)では、ここにエラーチェックをするアクションがバインドされていたのだ。そしてそのWOFormで囲まれた中のsubmitボタンを押すと、どれを押しても必ずそのそこにバインドしたアクションが実行される。そしてその処理の後、実際のsubmitボタンにバインドしたアクションが実行されていた。


今回、処理を変更してデフォルトの値を別の所で代入するのでエラーチェックが必要なくなったのだが、こういう仕組みになっているとまったく気がつかなったので、目的の処理が呼び出される前に、エラーチェックルーチンが呼ばれてエラーになってしまい、先に進まないのではまってしまった。なにしろ目的の処理の中で代入しているので、エラーチェック時には値が入っていないのだからエラーになるのは当たり前。でも、コードだけを見るとその処理はどこでもよんでいない。悩みました。

普段ならこのようなどのアクションを実行する前にも行いたい処理は、takeValuesFromRequest()中で書いていたのになぜこの時だけ、WOFormのactionにバインドしたのか?謎です。偶々誰かに教えてもらったのか?


でも今後はこんな後で追いかけにくい方法は使わないだろうなあ。
posted by 永遠製作所 at 00:47| 東京 ☁| Comment(0) | TrackBack(0) | WebObjects | このブログの読者になる | 更新情報をチェックする

2006年05月20日

disabledなコントロールはフォームで送信されない

なぜ、Hidden Fieldなんて使おうと思ったのかというとdisabledに設定したText Fieldの値がサーバーアプリケーションで受け取れなかったからです。

そもそもブラウザが送信していないのか、WebObjectsがフィルタしているのかわかりませんが、バインドした変数には何にも入ってきていません。

そもそもHiddenなコントロールでは値は変更されないのだから意味がないのでは?と思うかもしれません。実は、ブラウザ上でJavaScriptを使って値を設定してサーバーで受け取ろうという考えです。直接テキストを編集されたくないのでdisabledに設定したのですが、サーバー側で受け取れませんでした。

そこで、disabledに設定したText FieldとdisabledでないHidden Fieldを画面上に置いて、JavaScriptでは両方のフィールドに同じ値を設定するようにしました。これで見える所では入力不可。見えないところのデータはサーバーに送られるということが可能です。
posted by 永遠製作所 at 19:46| 東京 ☀| Comment(1) | TrackBack(0) | WebObjects | このブログの読者になる | 更新情報をチェックする

2006年05月19日

WOBuilderでHiddenFieldを使うと

WebObjectsで画面を作成時ですが、WOBuilder上でHiddenFieldの扱いに不具合があるようです。

HiddenFieldを作る方法として、TextFieldを作成してからStatic InspectorでHiddenに切り替える方法があります。

このとき、要素名が作成時にTextField4のような名前で作成されますが、HiddenFieldに切り替えたとしても名称は変更されません。

ところが、次にTextFieldを作成しようとすると、TextField全体の中で重複しない名前を探しているのか、TextField4が空いているのでその名前をつけてしまいます。HiddenFieldの要素に同じ名前があるかどうかは考慮せれません。このため同じ名前のWebObjectsタグ要素が複数あることになってしまいます。アプリケーションサーバーがこれをパースしてブラウザに返すhtmlを作成するときに、TextFiedld4という名前のタグを変換するのにWOTextFieldの情報を使うのかWOHiddenFieldの情報を使うのかは不定です。この結果、ブラウザに表示される画面は意図したものにはならなくなってしまいます。


今の所、HiddenFieldを作成後、手で名前を変えることで回避しています。

上記現象が常に発生するのかある条件下でのみ発生するのかまでは調べていません。


なお、条件はわかりませんが
TeTextField4WOHiddenField {
}
のような上書きされた状態になってしまい.wo自体の読み込みに失敗するようなこともありました。

本来は
TextField4: WOHiddenField {
}
ですかね。
posted by 永遠製作所 at 12:48| 東京 ☔| Comment(0) | TrackBack(0) | WebObjects | このブログの読者になる | 更新情報をチェックする

2006年04月29日

ソートキーの値を変更してしまうとアクションが呼ばれない問題

珍しくWebObjectsのコードの話。

EOの配列をソートして使っているときに、ソートキーの属性値を変更するとsubmitアクションが呼ばれなくなる現象について報告します。

ちょっと状況説明がややこしいのですが:
(1)EOのリストをRepitationで表示します。このとき、ソートした配列をRepitationのlistに設定します。例ではTableのTRにRepitationを設定しています。
(2)表示結果が図1です。データは名称とソート順という名の属性を持っています。
fig1.png
(3)編集はインラインで行います。例ではソート順だけが変更できるようになっています。そして値を変更して順番が変わる場合を見てみましょう。図3のようになりました。
fig2.png
fig3.png
(4)WOBuilderでの設定は図4です。
WORepitationで複数のTRを囲み、編集対象の行であるかどうかを判定して表示行を使うか、編集行を使うかをWOConditionalを使って設定しています。
fig4.png

WORepitationのlistに設定しているのは以下で得たtypeListです。

public NSArray _typeList;

public Main(WOContext context) {
super(context);
_typeList = EOUtilities.objectsForEntityNamed(
session().defaultEditingContext(), "MPCategoryType" );
}


/** @TypeInfo MPCategoryType */
public NSArray getTypeList()
{
return EOSortOrdering.sortedArrayUsingKeyOrderArray(
_typeList,
new NSArray( EOSortOrdering.sortOrderingWithKey(
"sortOrder", EOSortOrdering.CompareAscending ) )
);
}


そしてサブミットボタンを押すと以下のアクションを実行します。

public WOComponent actionSave()
{
selectedType = null;
session().defaultEditingContext().saveChanges();
return null;
}


しかし上記の例では、実はactionSave()メソッドは呼ばれません。
Formデータを受け取った後、typeListの順が変わってしまうとWebObjectsはなぜかinvokeAction()を呼ばずそのままResponseを作ってしまうのです。

ちょっと理由はわかりませんが、フォームデータがRepitaionで順番に評価するときに、配列の評価をして表示したときと、データを読み込むときで不整合になるのでどこかでエラーになるのかもしれません。

結果、ブラウザ上では編集中の画面のままもどってしまいます。


対策は簡単で、ソートキーそのものを編集させるのをやめる図5のようにすればいいのです。ソート順属性をEOから取ってくるのではなく、編集用の変数を用意して、これを保存するときにEOの属性値に代入します。
fig5.png

コードはこうなります。

public WOComponent actionSave()
{
selectedType.takeValueForKey( sortOrder, "sortOrder" );
selectedType = null;
session().defaultEditingContext().saveChanges();
return null;
}


対応は簡単なのですが、サブミットボタンに設定したアクションにプリント文を設定しても表示しないのでどうなっているのかかなり悩みました。同じ失敗を繰り返さないために、記録しておきます。

確認:Mac OS X 10.4.2/WebObjects 5.2.2
posted by 永遠製作所 at 18:04| 東京 🌁| Comment(0) | TrackBack(0) | WebObjects | このブログの読者になる | 更新情報をチェックする