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 }