View Javadoc

1   /*
2    * Copyright 2004-2009 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.cubby.action;
17  
18  import java.lang.reflect.InvocationTargetException;
19  import java.lang.reflect.Method;
20  import java.util.Map;
21  
22  /**
23   * アクションの基底クラスです。
24   * <p>
25   * アクションはビューのコントローラーの役割を果たします。
26   * </p>
27   * 
28   * @author agata
29   * @author baba
30   */
31  public abstract class Action {
32  
33  	/** アクションエラーオブジェクト。 */
34  	protected ActionErrors errors;
35  
36  	/** 揮発性メッセージ。 */
37  	protected Map<String, Object> flash;
38  
39  	/**
40  	 * アクションエラーオブジェクトを取得します。
41  	 * 
42  	 * @return アクションエラーオブジェクト
43  	 */
44  	public ActionErrors getErrors() {
45  		return errors;
46  	}
47  
48  	/**
49  	 * アクションエラーオブジェクトをセットします。
50  	 * 
51  	 * @param errors
52  	 *            アクションエラーオブジェクト
53  	 */
54  	public void setErrors(final ActionErrors errors) {
55  		this.errors = errors;
56  	}
57  
58  	/**
59  	 * 揮発性メッセージを取得します。
60  	 * 
61  	 * @return 揮発性メッセージ
62  	 */
63  	public Map<String, Object> getFlash() {
64  		return flash;
65  	}
66  
67  	/**
68  	 * 揮発性メッセージをセットします。
69  	 * 
70  	 * @param flash
71  	 *            揮発性メッセージ
72  	 */
73  	public void setFlash(final Map<String, Object> flash) {
74  		this.flash = flash;
75  	}
76  
77  	/**
78  	 * アクションメソッドの実行前に呼ばれます。
79  	 * <p>
80  	 * 指定されたアクションメソッドに {@link InitializeMethod} でメソッド名が指定されている場合はそのメソッドを呼び出します。
81  	 * そうでない場合は {@link #initialize()} を呼び出します。
82  	 * </p>
83  	 * <p>
84  	 * パラメータのバインディング前に呼ばれるので、パラメータを使用したい場合はサーブレットへの要求から直接取得する必要があります。
85  	 * </p>
86  	 * 
87  	 * @param actionMethod
88  	 *            アクションメソッド
89  	 */
90  	public void invokeInitializeMethod(final Method actionMethod) {
91  		if (actionMethod.isAnnotationPresent(InitializeMethod.class)) {
92  			final InitializeMethod initializeMethod = actionMethod
93  					.getAnnotation(InitializeMethod.class);
94  			final String methodName = initializeMethod.value();
95  			this.invoke(methodName);
96  		} else {
97  			this.initialize();
98  		}
99  	}
100 
101 	/**
102 	 * アクションメソッドが {@link InitializeMethod} で装飾されていない場合に
103 	 * {@link #invokeInitializeMethod(Method)} から呼ばれるメソッドです。
104 	 */
105 	protected void initialize() {
106 	}
107 
108 	/**
109 	 * フォーワードの直前に呼ばれます。
110 	 * <p>
111 	 * 指定されたアクションメソッドが {@link PreRenderMethod} でメソッド名が指定されている場合はそのメソッドを呼び出します。
112 	 * そうでない場合は {@link #prerender()} を呼び出します。
113 	 * </p>
114 	 * <p>
115 	 * 対象のActionクラスのフォワード先で必ず使用する共通のデータなどを取得する目的で使用します。
116 	 * </p>
117 	 * 
118 	 * @param actionMethod
119 	 *            アクションメソッド
120 	 */
121 	public void invokePreRenderMethod(final Method actionMethod) {
122 		if (actionMethod.isAnnotationPresent(PreRenderMethod.class)) {
123 			final PreRenderMethod preRenderMethod = actionMethod
124 					.getAnnotation(PreRenderMethod.class);
125 			final String methodName = preRenderMethod.value();
126 			this.invoke(methodName);
127 		} else {
128 			this.prerender();
129 		}
130 	}
131 
132 	/**
133 	 * アクションメソッドが {@link PreRenderMethod} で装飾されていない場合に
134 	 * {@link #invokePreRenderMethod(Method)} から呼ばれるメソッドです。
135 	 */
136 	protected void prerender() {
137 	}
138 
139 	/**
140 	 * フォワードの直後に呼ばれます。
141 	 * <p>
142 	 * 指定されたアクションメソッドが {@link PostRenderMethod} でメソッド名が指定されている場合はそのメソッドを呼び出します。
143 	 * そうでない場合は {@link #postrender()} を呼び出します。
144 	 * </p>
145 	 * <p>
146 	 * 通常はあまり使用することはないでしょう。
147 	 * </p>
148 	 * 
149 	 * @param actionMethod
150 	 *            アクションメソッド
151 	 */
152 	public void invokePostRenderMethod(final Method actionMethod) {
153 		if (actionMethod.isAnnotationPresent(PostRenderMethod.class)) {
154 			final PostRenderMethod postRenderMethod = actionMethod
155 					.getAnnotation(PostRenderMethod.class);
156 			final String methodName = postRenderMethod.value();
157 			this.invoke(methodName);
158 		} else {
159 			this.postrender();
160 		}
161 	}
162 
163 	/**
164 	 * アクションメソッドが {@link PostRenderMethod} で装飾されていない場合に
165 	 * {@link #invokePostRenderMethod(Method)} から呼ばれるメソッドです。
166 	 */
167 	protected void postrender() {
168 	}
169 
170 	/**
171 	 * このアクションに定義された指定されたメソッド名のメソッドを実行します。
172 	 * 
173 	 * @param methodName
174 	 *            メソッド名
175 	 */
176 	protected void invoke(final String methodName) {
177 		try {
178 			final Method method = this.getClass().getMethod(methodName);
179 			method.invoke(this);
180 		} catch (final NoSuchMethodException e) {
181 			throw new ActionException(e);
182 		} catch (final IllegalAccessException e) {
183 			throw new ActionException(e);
184 		} catch (final InvocationTargetException e) {
185 			throw new ActionException(e);
186 		}
187 	}
188 
189 }