最後に SuperPage クラスについての説明です。
先に簡略化して説明しましたが、実際には以下のように処理されています。
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145:
package tutorial1; import tutorial1.base.*; import paraselene.*; import paraselene.supervisor.*; import paraselene.tag.*; import paraselene.tag.attr.*; import paraselene.tag.form.*; import paraselene.tag.list.*; import paraselene.tag.table.*; /** * サイトページ基底クラス。 * 全てのページの共通メソッドを持たせたい場合にはこのクラスに記述できます。 */ public abstract class SuperPage extends Page { /** * 入力値の検証メイン処理。 * @param req リクエスト内容。 * @param fw デフォルト遷移先。 * @exception PageException 処理の継続が不可能(ブラウザには500を返す)。 */ public abstract Forward inputMain( RequestParameter req, Forward fw ) throws PageException; /** * 出力情報の設定メイン処理。 * @param from 遷移元ページ。 * @param req リクエスト内容。 * @return 出力ページ。 * nullを返すとthisをリターンしたのと同じ扱いにされます。 * @exception PageException 処理の継続が不可能(ブラウザには500を返す)。 */ public abstract Page outputMain( Page from, RequestParameter req ) throws PageException; /** * コンストラクタ。 */ public SuperPage() { super(); } /** * 出力文字コード。 * @return UTF-8 */ public String getCharset() { // 各ページで、出力文字コードを変更したい場合はオーバーライド // して下さい。 // または、下記を直接書き換えて下さい。 return "UTF-8"; } /** * 出力コンテントタイプ。 * nullを返すと自動選定されます。選定方法は以下です。 * isXML()がtrueを返し、且つ * (リクエストヘッダAcceptに application/xhtml+xml が明示されている、 * または携帯からのアクセスである)場合に * application/xhtml+xml を返します。それ以外では text/html を返します。 * またその時、getCharset()の戻り値を charset に指定します。 * @return null。 */ public String getContentType() { // 各ページで、コンテキストタイプを変更したい場合はオーバーライド // して下さい。 return null; } /** * 履歴追加方法。 * 過去に同一ページがあれば、直近からそのページまでの履歴をクリアする。 * trueならクリア、falseなら維持する。 * @return true */ public boolean isHistoryClear() { // 各ページで、履歴クリアをしたくない場合にはオーバーライドして // falseを返して下さい。 return true; } /** * 履歴追加許可。 * @return true */ public boolean isAllowHistoryAdd() { // 各ページで、履歴に追加したくない場合にはオーバーライドして // falseを返して下さい。 return true; } /** * アップロードファイルの最大バイト数。 * @return 負数なら無制限に受け付けます。 */ public int getUploadMaxBytes() { // アップロードに制限をかける場合は下記を修正するか、 // 各ページでオーバーライドして下さい。 return -1; } /** * 処理済みリクエストの再呼び出しを検出するか? * このページに遷移するためのURIを生成する際のリクエストID付与をコントロール * します。trueを返すとリクエストIDが付与されます。 * @return true:検出する、false:検出しない。 */ public boolean isCheckRepeatSameRequest() { // 各ページで、処理済みリクエストの再呼び出しを検出したい場合には // オーバーライドしてtrueを返して下さい。 return false; } /** * 初期化。 */ public void init() { // 全ページ共通の初期化処理があれば記述して下さい。 } /** * 入力値の検証を行う。 * このメソッドが呼ばれる際には必ずセッションが発生しています。 * 入力値のエラーチェックや入力値に即した動作を記述します。 * @param req リクエスト内容。 * @param fw デフォルト遷移先。 * @exception PageException 処理の継続が不可能(ブラウザには500を返す)。 */ public final Forward input( RequestParameter req, Forward fw ) throws PageException { // 共通処理等あれば記述して下さい。 return inputMain( req, fw ); } /** * 出力情報の設定を行う。 * @param from 遷移元ページ。直接呼ばれている場合はnullです。 * @param req リクエスト内容。 * @return 出力ページ。 * nullを返すとthisをリターンしたのと同じ扱いにされます。 * @exception PageException 処理の継続が不可能(ブラウザには500を返す)。 */ public final Page output( Page from, RequestParameter req ) throws PageException { // 共通処理等あれば記述して下さい。 return outputMain( from, req ); } }
例として、ログイン画面・Hello 画面ともにページのヘッダとフッタを付けてみます。
まずは以下の html を新しく準備します。
チュートリアル1
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Style-Type" content="text/css"> <title name="title"></title> </head> <body> <p><font size="+4">チュートリアル1</font></p> <hr> <div name="body"></div> <hr> <center>Copyright (C) 2009</center> </body> </html>
モックアップからスケルトンを作成します。
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
out/source/tutorial1/DummyPage.java は既に存在するため作成しません。 out/source/tutorial1/Gate.java は既に存在するため作成しません。 out/source/tutorial1/SuperPage.java は既に存在するため作成しません。 out/source/tutorial1/view//HelloHtml.java の変更はありません。 out/source/tutorial1/logic//HelloHtml.java は既に存在するため作成しません。 out/source/tutorial1/view//LoginHtml.java の変更はありません。 out/source/tutorial1/logic//LoginHtml.java は既に存在するため作成しません。 out/source/tutorial1/view//TemplateHtml.java を作成しました。 out/source/tutorial1/logic//TemplateHtml.java を作成しました。 out/source/tutorial1/base/PageLoader.java を作成しました。 out/source/tutorial1/base/PageType.java を作成しました。 out/web.xml を作成しました。 out/Readme.html を作成しました。 処理が終了しました。Readme.html を確認して下さい。
スケルトン出力ツールは、開発者が変更するソースファイルについては存在すれば出力しません。せっかく書き入れたロジックを上書きしないためです。
view の中にあるソースファイルは、 html とタイムスタンプを比較し、ソースファイルが古ければ再生成されます。
変更を禁止しているソースファイルは、このような理由によりツールにより上書きされる虞があります。ですので、コードを書き加えないで下さい。
※現在のバージョンではメッセージが英語に変更されていますので、上記のように出力されません。
| No | モックアップファイル名 | ページタイトル | クラス名 | PageID | 実行時URL ※getAliasURI()が優先されます。 | 特記 |
|---|---|---|---|---|---|---|
| 1 | /hello.html | Hello | tutorial1.logic.HelloHtml | tutorial1.base.PageType.HELLO_HTML | on.ex257q.na | |
| 2 | /login.html | ログイン | tutorial1.logic.LoginHtml | tutorial1.base.PageType.LOGIN_HTML | on.i8qot9.na | |
| 3 | /template.html | (タイトルなし) | tutorial1.logic.TemplateHtml | tutorial1.base.PageType.TEMPLATE_HTML | on.1psl4c.na |
SuperPage.javaを以下のように変更します。
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
public final Page output( Page from, RequestParameter req ) throws PageException { // 共通処理等あれば記述して下さい。 // return outputMain( from, req ); Page original = outputMain( from, req ); TemplateHtml template = (TemplateHtml)PageLoader.getPageFactory().getPage( PageType.TEMPLATE_HTML ); Tag title = original.getFirstTagByType( "title" ); template.getTitleTitle().setValueString( title.getValueString() ); template.getBodyDiv().include( original ); return template; }
これにより、以下のように表示されます。
チュートリアル1
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
<html> <head> <meta content="text/css" http-equiv="Content-Style-Type"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title name="title">ログイン</title> </head> <body> <p><font size="+4">チュートリアル1</font></p> <hr> <div name="body"> <form action="lu.utw5q8.mo.i8qot9.on.ex257q.na"> <input name="paraselene$form" value="3" type="hidden"> ユーザーID <input name="user_id" type="text" size="20"><br> パスワード <input name="password" type="password" size="20"> <br> <br> <input src=".//button1.gif" type="image"></form> </div> <hr> <center>Copyright (C) 2009</center> </body> </html>
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
<html> <head> <meta content="text/css" http-equiv="Content-Style-Type"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title name="title">Hello</title> </head> <body> <p><font size="+4">チュートリアル1</font></p> <hr> <div name="body"> <p>こんにちは<span name="user_id">ユーザー</span>さん。</p> <p><a href="lu.uu1bsx.mo.ex257q.on.i8qot9.na">ログアウト</a></p> </div> <hr> <center>Copyright (C) 2009</center> </body> </html>
この場合、output から TemplateHtml のインスタンスがリターンされますが、履歴へ蓄積されるのは実際に呼び出されている LoginHtml または HelloHtml になります。