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 }