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.internal.controller.impl;
    17
    18  import static org.seasar.cubby.CubbyConstants.ATTR_ACTION;
    19  import static org.seasar.cubby.CubbyConstants.ATTR_ACTION_CONTEXT;
    20  import static org.seasar.cubby.CubbyConstants.ATTR_ERRORS;
    21  import static org.seasar.cubby.CubbyConstants.ATTR_FLASH;
    22  import static org.seasar.cubby.internal.util.LogMessages.format;
    23
    24  import java.lang.reflect.Method;
    25  import java.util.Iterator;
    26  import java.util.Map;
    27
    28  import javax.servlet.http.HttpServletRequest;
    29  import javax.servlet.http.HttpServletResponse;
    30
    31  import org.seasar.cubby.action.Action;
    32  import org.seasar.cubby.action.ActionContext;
    33  import org.seasar.cubby.action.ActionErrors;
    34  import org.seasar.cubby.action.ActionException;
    35  import org.seasar.cubby.action.ActionResult;
    36  import org.seasar.cubby.action.FlashMap;
    37  import org.seasar.cubby.internal.controller.ActionProcessor;
    38  import org.seasar.cubby.internal.controller.ActionResultWrapper;
    39  import org.seasar.cubby.plugin.ActionInvocation;
    40  import org.seasar.cubby.plugin.Plugin;
    41  import org.seasar.cubby.plugin.PluginRegistry;
    42  import org.seasar.cubby.routing.Routing;
    43  import org.seasar.cubby.spi.ContainerProvider;
    44  import org.seasar.cubby.spi.ProviderFactory;
    45  import org.seasar.cubby.spi.container.Container;
    46  import org.slf4j.Logger;
    47  import org.slf4j.LoggerFactory;
    48
    49  /**
    50   * 要求のパスを元にアクションメソッドを決定して実行するクラスの実装です。
    51   *
    52   * @author baba
    53   */
    54  public class ActionProcessorImpl implements ActionProcessor {
    55
    56  	/** ロガー。 */
    57  	private static final Logger logger = LoggerFactory
    58  			.getLogger(ActionProcessorImpl.class);
    59
    60  	/**
    61  	 * {@inheritDoc}
    62  	 */
    63  	public ActionResultWrapper process(final HttpServletRequest request,
    64  			final HttpServletResponse response, final Routing routing)
    65  			throws Exception {
    66
    67  		final Method actionMethod = routing.getActionMethod();
    68  		if (logger.isDebugEnabled()) {
    69  			logger.debug(format("DCUB0004", request.getRequestURI()));
    70  			logger.debug(format("DCUB0005", actionMethod));
    71  		}
    72
    73  		final Class<?> actionClass = routing.getActionClass();
    74
    75  		final Container container = ProviderFactory
    76  				.get(ContainerProvider.class).getContainer();
    77
    78  		final Object action = container.lookup(actionClass);
    79  		request.setAttribute(ATTR_ACTION, action);
    80
    81  		final ActionErrors actionErrors = container.lookup(ActionErrors.class);
    82  		request.setAttribute(ATTR_ERRORS, actionErrors);
    83
    84  		final FlashMap flashMap = container.lookup(FlashMap.class);
    85  		request.setAttribute(ATTR_FLASH, flashMap);
    86
    87  		final ActionContext actionContext = container
    88  				.lookup(ActionContext.class);
    89  		actionContext.initialize(action, actionClass, actionMethod,
    90  				actionErrors, flashMap);
    91  		request.setAttribute(ATTR_ACTION_CONTEXT, actionContext);
    92
    93  		if (action instanceof Action) {
    94  			initializeAction((Action) action, actionErrors, flashMap);
    95  		}
    96
    97  		actionContext.invokeInitializeMethod();
    98
    99  		final ActionInvocation actionInvocation = new ActionInvocationImpl(
    100 				request, response, actionContext);
    101 		final ActionResult actionResult = actionInvocation.proceed();
    102 		if (actionResult == null) {
    103 			throw new ActionException(format("ECUB0101", actionMethod));
    104 		}
    105
    106 		final ActionResultWrapper actionResultWrapper = new ActionResultWrapperImpl(
    107 				actionResult, actionContext);
    108 		return actionResultWrapper;
    109 	}
    110
    111 	private void initializeAction(final Action action,
    112 			final ActionErrors actionErrors, final Map<String, Object> flashMap) {
    113 		action.setErrors(actionErrors);
    114 		action.setFlash(flashMap);
    115 	}
    116
    117 	/**
    118 	 * アクションの実行情報の実装です。
    119 	 *
    120 	 * @author baba
    121 	 */
    122 	static class ActionInvocationImpl implements ActionInvocation {
    123
    124 		/** 要求。 */
    125 		private final HttpServletRequest request;
    126
    127 		/** 応答。 */
    128 		private final HttpServletResponse response;
    129
    130 		/** アクションのコンテキスト。 */
    131 		private final ActionContext actionContext;
    132
    133 		/** プラグインのイテレータ。 */
    134 		private final Iterator<Plugin> pluginsIterator;
    135
    136 		/**
    137 		 * インスタンス化します。
    138 		 *
    139 		 * @param request
    140 		 *            要求
    141 		 * @param response
    142 		 *            応答
    143 		 * @param actionContext
    144 		 *            アクションのコンテキスト
    145 		 */
    146 		public ActionInvocationImpl(final HttpServletRequest request,
    147 				final HttpServletResponse response,
    148 				final ActionContext actionContext) {
    149 			this.request = request;
    150 			this.response = response;
    151 			this.actionContext = actionContext;
    152
    153 			final PluginRegistry pluginRegistry = PluginRegistry.getInstance();
    154 			this.pluginsIterator = pluginRegistry.getPlugins().iterator();
    155 		}
    156
    157 		/**
    158 		 * {@inheritDoc}
    159 		 */
    160 		public ActionResult proceed() throws Exception {
    161 			final ActionResult actionResult;
    162 			if (pluginsIterator.hasNext()) {
    163 				final Plugin plugin = pluginsIterator.next();
    164 				actionResult = plugin.invokeAction(this);
    165 			} else {
    166 				final ActionContext actionContext = getActionContext();
    167 				final Object action = actionContext.getAction();
    168 				final Method actionMethod = actionContext.getActionMethod();
    169 				actionResult = (ActionResult) actionMethod.invoke(action);
    170 			}
    171 			return actionResult;
    172 		}
    173
    174 		/**
    175 		 * {@inheritDoc}
    176 		 */
    177 		public HttpServletRequest getRequest() {
    178 			return request;
    179 		}
    180
    181 		/**
    182 		 * {@inheritDoc}
    183 		 */
    184 		public HttpServletResponse getResponse() {
    185 			return response;
    186 		}
    187
    188 		/**
    189 		 * {@inheritDoc}
    190 		 */
    191 		public ActionContext getActionContext() {
    192 			return actionContext;
    193 		}
    194
    195 	}
    196
    197 }