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.impl;
17  
18  import static org.seasar.cubby.action.RequestParameterBindingType.NONE;
19  import static org.seasar.cubby.internal.util.LogMessages.format;
20  
21  import java.lang.reflect.InvocationTargetException;
22  import java.lang.reflect.Method;
23  import java.util.Map;
24  
25  import org.seasar.cubby.action.Action;
26  import org.seasar.cubby.action.ActionContext;
27  import org.seasar.cubby.action.ActionErrors;
28  import org.seasar.cubby.action.ActionException;
29  import org.seasar.cubby.action.Form;
30  import org.seasar.cubby.action.InitializeMethod;
31  import org.seasar.cubby.action.PostRenderMethod;
32  import org.seasar.cubby.action.PreRenderMethod;
33  import org.seasar.cubby.action.RequestParameterBindingType;
34  import org.seasar.cubby.spi.beans.Attribute;
35  import org.seasar.cubby.spi.beans.BeanDesc;
36  import org.seasar.cubby.spi.beans.BeanDescFactory;
37  
38  /**
39   * アクションのコンテキストの実装です。
40   * 
41   * @author baba
42   */
43  public class ActionContextImpl implements ActionContext {
44  
45  	/** アクション。 */
46  	private Object action;
47  
48  	/** アクションクラス。 */
49  	private Class<?> actionClass;
50  
51  	/** アクションメソッド。 */
52  	private Method actionMethod;
53  
54  	/** アクションエラー。 */
55  	private ActionErrors actionErrors;
56  
57  	/** 揮発性メッセージ。 */
58  	private Map<String, Object> flashMap;
59  
60  	/**
61  	 * {@inheritDoc}
62  	 */
63  	public void initialize(final Object action, final Class<?> actionClass,
64  			final Method actionMethod, final ActionErrors actionErrors,
65  			final Map<String, Object> flashMap) {
66  		this.action = action;
67  		this.actionClass = actionClass;
68  		this.actionMethod = actionMethod;
69  		this.actionErrors = actionErrors;
70  		this.flashMap = flashMap;
71  	}
72  
73  	/**
74  	 * {@inheritDoc}
75  	 */
76  	public Object getAction() {
77  		return action;
78  	}
79  
80  	/**
81  	 * {@inheritDoc}
82  	 */
83  	public Class<?> getActionClass() {
84  		return actionClass;
85  	}
86  
87  	/**
88  	 * {@inheritDoc}
89  	 */
90  	public Method getActionMethod() {
91  		return actionMethod;
92  	}
93  
94  	/**
95  	 * {@inheritDoc}
96  	 */
97  	public Object getFormBean() {
98  		final Form form = getForm();
99  		if (form == null) {
100 			return action;
101 		}
102 		if (form.bindingType() == NONE) {
103 			return null;
104 		}
105 		if (Form.THIS.equals(form.value())) {
106 			return action;
107 		}
108 
109 		final String attributeName = form.value();
110 		final Object formBean;
111 		final BeanDesc beanDesc = BeanDescFactory.getBeanDesc(actionClass);
112 		if (beanDesc.hasPropertyAttribute(attributeName)) {
113 			final Attribute attribute = beanDesc
114 					.getPropertyAttribute(attributeName);
115 			formBean = attribute.getValue(action);
116 			if (formBean == null) {
117 				throw new ActionException(format("ECUB0102", actionClass,
118 						attributeName));
119 			}
120 		} else if (beanDesc.hasFieldAttribute(attributeName)) {
121 			final Attribute attribute = beanDesc
122 					.getFieldAttribute(attributeName);
123 			formBean = attribute.getValue(action);
124 			if (formBean == null) {
125 				throw new ActionException(format("ECUB0111", actionClass,
126 						attributeName));
127 			}
128 		} else {
129 			throw new ActionException(format("ECUB0112", actionClass,
130 					attributeName));
131 		}
132 		return formBean;
133 	}
134 
135 	/**
136 	 * 指定されたアクションメソッドを修飾する {@link Form} を取得します。
137 	 * 
138 	 * @return {@link Form}、修飾されていない場合はメソッドが定義されたクラスを修飾する {@link Form}
139 	 *         、クラスも修飾されていない場合は <code>null</code>
140 	 */
141 	private Form getForm() {
142 		final Form form;
143 		if (actionMethod.isAnnotationPresent(Form.class)) {
144 			form = actionMethod.getAnnotation(Form.class);
145 		} else {
146 			form = actionClass.getAnnotation(Form.class);
147 		}
148 		return form;
149 	}
150 
151 	/**
152 	 * {@inheritDoc}
153 	 */
154 	public boolean isBindRequestParameterToAllProperties() {
155 		final Form form = this.getForm();
156 		if (form == null) {
157 			return false;
158 		}
159 
160 		final RequestParameterBindingType type = form.bindingType();
161 		switch (type) {
162 		case ALL_PROPERTIES:
163 			return true;
164 		case ONLY_SPECIFIED_PROPERTIES:
165 			return false;
166 		default:
167 			throw new IllegalStateException(type.toString());
168 		}
169 	}
170 
171 	/**
172 	 * {@inheritDoc}
173 	 */
174 	public void invokeInitializeMethod() {
175 		if (action instanceof Action) {
176 			((Action) action).invokeInitializeMethod(actionMethod);
177 		} else if (actionMethod.isAnnotationPresent(InitializeMethod.class)) {
178 			final InitializeMethod initializeMethod = actionMethod
179 					.getAnnotation(InitializeMethod.class);
180 			final String methodName = initializeMethod.value();
181 			this.invoke(action, methodName);
182 		}
183 	}
184 
185 	/**
186 	 * {@inheritDoc}
187 	 */
188 	public void invokePreRenderMethod() {
189 		if (action instanceof Action) {
190 			((Action) action).invokePreRenderMethod(actionMethod);
191 		} else if (actionMethod.isAnnotationPresent(PreRenderMethod.class)) {
192 			final PreRenderMethod preRenderMethod = actionMethod
193 					.getAnnotation(PreRenderMethod.class);
194 			final String methodName = preRenderMethod.value();
195 			this.invoke(action, methodName);
196 		}
197 	}
198 
199 	/**
200 	 * {@inheritDoc}
201 	 */
202 	public void invokePostRenderMethod() {
203 		if (action instanceof Action) {
204 			((Action) action).invokePostRenderMethod(actionMethod);
205 		} else if (actionMethod.isAnnotationPresent(PostRenderMethod.class)) {
206 			final PostRenderMethod postRenderMethod = actionMethod
207 					.getAnnotation(PostRenderMethod.class);
208 			final String methodName = postRenderMethod.value();
209 			this.invoke(action, methodName);
210 		}
211 	}
212 
213 	/**
214 	 * {@inheritDoc}
215 	 */
216 	public ActionErrors getActionErrors() {
217 		return actionErrors;
218 	}
219 
220 	/**
221 	 * {@inheritDoc}
222 	 */
223 	public Map<String, Object> getFlashMap() {
224 		return flashMap;
225 	}
226 
227 	/**
228 	 * {@inheritDoc}
229 	 */
230 	public void clearFlash() {
231 		if (flashMap != null) {
232 			flashMap.clear();
233 		}
234 	}
235 
236 	/**
237 	 * アクションの指定されたメソッド名のメソッドを実行します。
238 	 * 
239 	 * @param methodName
240 	 *            メソッド名
241 	 */
242 	private void invoke(final Object action, final String methodName) {
243 		try {
244 			final Method method = action.getClass().getMethod(methodName);
245 			method.invoke(action);
246 		} catch (final NoSuchMethodException e) {
247 			throw new ActionException(e);
248 		} catch (final IllegalAccessException e) {
249 			throw new ActionException(e);
250 		} catch (final InvocationTargetException e) {
251 			throw new ActionException(e);
252 		}
253 	}
254 
255 	/**
256 	 * {@inheritDoc}
257 	 */
258 	@Override
259 	public String toString() {
260 		final StringBuilder builder = new StringBuilder();
261 		builder.append("ActionContext[");
262 		builder.append("action=").append(action);
263 		builder.append(",actionClass=").append(actionClass);
264 		builder.append(",actionMethod=").append(actionMethod);
265 		builder.append("]");
266 		return builder.toString();
267 	}
268 
269 }