View Javadoc

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