Mayaaについて思う事あれこれ
今Mayaaを使ってスクリプトライクにアプリ開発できないか考えている。S2StrutsでもS2JSFでもなくS2とMayaaを直につないでMayaaのテンプレート上にヴァリデーションとかアクションをごりごり書くという感じ。以下、そう思うようになった発端など。
発端その1. アクションに書くことが無くなってきた
前回のプロジェクトでようやくまともにS2Dao-S2Struts-Mayaaでプログラムを書いたのだけど、無設定Strutsと自動バインドが本当によく出来ていて助かった。特にActionFormをPOJOで書けるのが良い。Dto→Formのマッピングさえ用意すれば、Daoに渡すConditionとかキャッシュ用のキーとか一覧/詳細ページのハイパーリンクの記述がかなりの範囲全部同じ方式で出来る。
データアクセスとかページ送りの処理とか、とにかく共通で書ける所を全部ライブラリ化したりGenerics化したりしてたら、結局各アクションの処理が1行か2行ぐらいになってしまった。(あとはDIするためのインスタンス変数とsetter/getterと無設定Struts用のアノテーション。) これだったらAction要らなくね?と思ったのが発端のその1。
発端その2. プレゼンテーション層は柔軟にしたい
もともと要件がまとまりやすくテストをしっかりしたい業務ロジック層はJavaで、仕様変更が多く対応にスピードが求められるプレゼンテーション層はスクリプトで書きたいという気持ちが強かったのだけど、じゃあスクリプト何が良いかという悩みが有った。Groovy?JRuby?
他のスクリプトだとテンプレートエンジン+スクリプト+Javaとなるところだけど、テンプレートエンジンにMayaaを使うんならMayaa上でそのままJavaScriptが使えるので、JavaScriptが一番手っ取り早い。
発端その3. Mayaaがかなり良く出来ている
まず拡張ポイントが豊富でカスタマイズが効きやすい。前述のプロジェクトで、「HTMLはツールでテンプレートを投入することで変更出来る」というのがあった。ツールで投入したHTMLのパスを渡してやればそれをテンプレートとして使って表示出来ますよ、という機能。一つの.mayaaに対応する.htmlがファイルシステム上のどこに置かれるか分からないというシチュエーションだけど、MayaaならSourceDescriptorをカスタマイズすることで対応出来た。
ELがJavaScriptなのも良い。ちょっとした処理なら.mayaa上に書いてしまえる。(例えばテーブルの一行毎に背景色を変えるとか。${ (i % 2 == 0) ?'#ececec' : '#f5f5f5'})
外部のHTMLをインクルードする際にインクルードされる側のスコープが独立しているのが良い。bindingという読み出し専用のスコープを使っている。これは再利用可能な部品を作る場合にとても重要だと思う。
Mayaaの機能は.htmlまたは.mayaaファイル上でm:writeなどのプロセッサで記述するんだけど、このプロセッサというのがとても簡単に作れる。taglibのように処理を記述する事も出来るし、フッターのような只のHTMLもプロセッサで記述出来る。taglibというよりはWebObjectsやTapestryのコンポーネントのような感じで使える。(但し階層的にForm部品として使うにはいろいろ課題あり。)
Page内部がHTMLの構造に従ってツリー化されている。JSFのコンポーネントツリーの力を借りなくてもページベースでのプログラムを書ける可能性を持ってる。
やりたいことその1. 全部HTML側に書く
PHP使いの人にヒアリングすると、.htmlと.mayaaに分かれているのは面倒らしいので、それならHTML側に全部書いちゃいましょう。プログラムとリソースの分離は出来ないけど、プレゼンテーションと業務ロジックが分離出来てればOKでは?どうせ書き直す所だし。
これは元からある機能なのですぐにやれる。
やりたいことその2. S2ContainerからPageコンテキストにDI
サービス/ワークフロー層のオブジェクトをJavaScriptから使うのに、シングルトンにしてクラス経由でアクセスするはイマイチ。それならDIコンテナから自動バインディングの手法を真似て直接Mayaaのページコンテキストにセットしてしまえば良い。
useBean的なプロセッサを書けばS2のコンテナからgetComponent()で取得するようにしたい。(そういえばかつてMayaaにもuseBean的なものがあったらしい?)
やりたいことその3. ページベースで記述したい。
その1の全部HTML側に書くと被ってるんだけど、ヴァリデーションとかフォーマッタとかアクションはHTML上に書いてしまいたい。
ヴァリデーションやフォーマッタは入力パーツと一緒に、アクションはsubmitボタンに書ければ分かりやすいと思う。
イメージ的にはこんな感じ(想定はログインフォーム。) 少しJSF風だけど。
<mm:var mm:name="loginLogic"/> <mm:var mm:name="profileForm"/> <mm:messages/> <mm:form mm:bean="profileForm"> ユーザ名: <mm:text mm:name="username"> <mm:required/> </mm:input><br> パスワード: <mm:password mm:name="password"> <mm:required/> <mm:length mm:minimum="4"/> </mm:input><br> <mm:submit mm:action="${ if (loginLogic.login(profileForm)) { dispatch('/mypage/top.html'); } else { messages.add('ユーザー名またはパスワードが違います'); } }"/> </mm:form>