谷本 心 in せろ部屋 このページをアンテナに追加 RSSフィード

2006-12-11

[][]S2JSFでWebParts その17

「insertされたHTMLのinitAction実行」をコミットしました。

ちょっとコミッタ内で相談している点はありますが、

恐らく、次のバージョンから利用できるようになります。

また、insertを利用したサンプルも一緒に公開される予定です。


次の目標としては、

  • insertされたHTML(以降パーツと呼びます)のinitActionの戻り値も解釈する
    • 現状:パーツのinitActionの戻り値がnull以外であっても解釈しない
    • 目標:faces-config.xmlに定義したviewIdに対応したパーツを表示させる
  • WebPartsのサンプルも作成する

という所。

2006-08-16

[][]S2JSFでWebParts その16

さて、リフレッシュしたことだし、

「insertで呼び出されたHTMLの、InitActionを実行する」の続き。


まず、やりたい事を整理すると、

  • 親画面
    • 子画面1 (m:inject="s:insert"タグで挿入。以下同様)
    • 子画面2
    • 子画面3

こんな構成の画面を作ったとして、

子画面のInitActionの戻り値がnull以外の場合や、

子画面のInitActionで例外が発生した場合、どう表示すべきか。


例1)

子画面2の戻り値が、子画面4の画面名だった場合。

  • 親画面
    • 子画面1
    • 子画面4
    • 子画面3

という形で表示する。


例2)

子画面2のInitActionで、例外が発生した場合。

  • 親画面
    • 子画面1
    • 例外に対応したエラー画面
    • 子画面3

という形で表示する。


、、、という所を目指して、実装開始。

	protected void processInclude(JsfContext jsfContext, Tag parentTag,
			String src) throws JspException {

		S2Container container = SingletonS2ContainerFactory.getContainer();
		ViewTemplateFactory factory = (ViewTemplateFactory) container
				.getComponent(ViewTemplateFactory.class);
		ViewTemplate template = factory.getViewTemplate(src);
		ViewProcessor viewProcessor = (ViewProcessor) template
				.getRootTagProcessor();
		InsertProcessor insertProcessor = viewProcessor
				.getInsertProcessor(null);

		// -- 変更 BEGIN
		String initAction = viewProcessor.getInitAction();
		FacesContext context = FacesContext.getCurrentInstance();
		if (initAction != null) {
			String newSrc = executeInitAction(context, initAction);
			if (newSrc != null) {
				processInclude(jsfContext, parentTag, newSrc);
				return;
			}
		}

		insertProcessor.process(jsfContext, parentTag);
		// -- 変更 END
	}

	// -- メソッド追加 BEGIN
	protected String executeInitAction(FacesContext context, String initAction) {
		Application app = context.getApplication();
		MethodBinding mb = app.createMethodBinding(initAction, null);
		try {
			String outcome = InvokeUtil.invoke(mb, context);
			if (outcome == null || context.getResponseComplete()) {
				return null;
			}
			return "★outcomeに対応したページのパス★";
		} catch (EvaluationException ex) {
			return "★例外に対応したページのパス★";
		}
	}
	// -- メソッド追加 END

子画面のInitActionを実行した結果、

遷移する場合も、例外が発生した場合も、それぞれ対応したページのパス(src)を返す。

そのsrcを使って、呼び出し側で再度processIncludeを呼び出す、、、という形。

ひとまずこれで、大枠としては動く模様。


ただ、InitActionの戻り値に対応するページのパスを、

どうやれば取得できるかが分からない (^^;


まぁ、今日の所は、ここまで!

2006-08-09

[][]S2JSFでWebParts その15

script.aculo.us周辺のアレコレは、ちょっと置いといて、

「insertで呼び出されたHTMLの、InitActionを実行する」という処理を

正式にS2JSFコミットするために、最後の調整。


何かって言うと、呼び出されたInitActionで、

  • 例外が発生した
  • 戻り値がnull以外だった

場合のハンドリング。


http://d.hatena.ne.jp/cero-t/20060611/1150044902で書いた方法だと、

  • 例外が発生すると、Tomcatのエラーページが表示される
  • 戻り値がnull以外でも、無視されて、元のページが表示される

という状態。

これはいけない!(特に前者)


例外が発生した場合には、

  • そのパーツだけがエラーページとして表示される(たとえば「現在このパーツは利用できません」ってエラーメッセージを出すとか)
  • せめて、ページ全体がエラーページとなる(HSQLDBを起動せずに、Employee Exampleを表示しようとした時と同じ)

の、どちらかにすべき。まぁ、前者が妥当かな。


また、戻り値がnull以外の場合は、

  • そのパーツは、戻り値に対応したHTML(別のパーツ)が表示される

としてやるのが、妥当かな。


そう考えて、ViewRendererImpl#executeInitActionを参考にしながら

コードを移植したんだけど、、、今のところ、うまく行かない(汗


まぁ、問題を整理しながら、考えていくので、こうご期待〜。

2006-07-20

[][]S2JSFでWebParts その14

WebPartsのHTMLでは、同じレイアウト(m:extends)を使うことになるはず。

「閉じる」ボタンとか、「最大化」ボタンとかって、共通的なものだし。


そうすると、<span m:inject="s:insert" m:src="#{xxxList}"/> を使って読み込んだ時に、

insertされる側(Parts側)のページで、m:extends属性を解釈する必要がある。


ただ、現在のS2JSFでは、insertされる側のm:exnteds属性を解釈していないので、

下手に解釈するように変更すると、既存のアプリケーションが反乱しかねない(笑

誰も意図的に、insertされる側のページにm:extends属性なんて書いてないと思うけど、

属性を消し忘れていて、解釈されないから結果オーライで動いている、、、なんて事はあり得るでしょう。

そう考えると、insertされる側のm:extends属性を解釈するのは、無理がある。


逆に、insertする側(s:insertタグ)にm:extends属性を追加する、ってのはどうだろう?

<span m:inject="s:insert" m:src="#{xxxList}" m:extends="/WEB-INF/layout/partslayout.html"/>

と記述すると、xxxListの全HTMLに、同じレイアウトが適用される、というもの。

もちろん、xxxListでなくて、通常のHTMLファイルを指定していても同様。


実現性は検討してないけど、やってみようかな、と。


ちなみに、Teedaだったら、同じディレクトリ内のHTML

AutoRegisterで同じm:extends属性を適用できたりするんですかね?

2006-07-13

[][]S2JSFでWebParts その13

S2JSF WebPartsの動かせるサンプルを公開します。


今回のサンプルで出来ること

  • ドラッグ&ドロップで、パーツ(HTML)を動かすことが出来る
  • 保存ボタンを押して、パーツの位置を(セッションに)保存できる
  • もちろん、HTMLに書いてあるinitActionが呼び出される

動かし方

  1. S2JSF-Example 1.0.14を実行できるようにする。
  2. http://hatena.tanimoto.ninja/s2jsf/archive/S2JSF_WebParts2.zipをダウンロード
  3. 解凍してできたファイルを、S2JSF-Exampleのディレクトリにコピー。(いくつかのファイルを上書きしますが、既存のExampleのファイルには影響しないはず)
  4. Eclipseを使っているならプロジェクトを更新してから)クリーンビルド。
  5. WEB-INF/bin/runHsqldb.batを実行。Employeeのサンプルを使うので。
  6. Tomcatを起動して、http://localhost:8080/s2jsf-example/にアクセス。

使い方

  • S2JSF-Exampleの、メニューの一番下にある「S2JSF WebParts Sample」をクリック。
  • 各パーツのタイトル部分をドラッグ&ドロップして、適当に場所移動。
  • ページ一番右上にある「保存」ボタンをクリック。
  • 「Hello」とかの別ページに、いったん移動。
  • また「S2JSF WebParts Sample」をクリックして戻ってくる。
  • パーツの位置は保存されたまま!

それだけ。


ソースは、かなりハードコーディングなんだけど、

まずは技術解を確かめたかったので、ゴリゴリやりました (^^;