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.ActionContext;
32  import org.seasar.cubby.action.ActionErrors;
33  import org.seasar.cubby.action.ActionException;
34  import org.seasar.cubby.action.ActionResult;
35  import org.seasar.cubby.internal.action.impl.ActionContextImpl;
36  import org.seasar.cubby.internal.action.impl.ActionErrorsImpl;
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   * @since 1.0.0
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 ActionErrors actionErrors = new ActionErrorsImpl();
80  		request.setAttribute(ATTR_ERRORS, actionErrors);
81  
82  		final Map<String, Object> flashMap = new FlashMap<String, Object>(
83  				request);
84  		request.setAttribute(ATTR_FLASH, flashMap);
85  
86  		final Object action = container.lookup(actionClass);
87  		request.setAttribute(ATTR_ACTION, action);
88  
89  		final ActionContext actionContext = new ActionContextImpl(action,
90  				actionClass, actionMethod, actionErrors, flashMap);
91  		request.setAttribute(ATTR_ACTION_CONTEXT, actionContext);
92  
93  		actionContext.invokeInitializeMethod();
94  
95  		final ActionInvocation actionInvocation = new ActionInvocationImpl(
96  				request, response, actionContext);
97  		final ActionResult actionResult = actionInvocation.proceed();
98  		if (actionResult == null) {
99  			throw new ActionException(format("ECUB0101", actionMethod));
100 		}
101 
102 		final ActionResultWrapper actionResultWrapper = new ActionResultWrapperImpl(
103 				actionResult, actionContext);
104 		return actionResultWrapper;
105 	}
106 
107 	/**
108 	 * アクションの実行情報の実装です。
109 	 * 
110 	 * @author baba
111 	 */
112 	static class ActionInvocationImpl implements ActionInvocation {
113 
114 		/** 要求。 */
115 		private final HttpServletRequest request;
116 
117 		/** 応答。 */
118 		private final HttpServletResponse response;
119 
120 		/** アクションのコンテキスト。 */
121 		private final ActionContext actionContext;
122 
123 		/** プラグインのイテレータ。 */
124 		private final Iterator<Plugin> pluginsIterator;
125 
126 		/**
127 		 * インスタンス化します。
128 		 * 
129 		 * @param request
130 		 *            要求
131 		 * @param response
132 		 *            応答
133 		 * @param actionContext
134 		 *            アクションのコンテキスト
135 		 */
136 		public ActionInvocationImpl(final HttpServletRequest request,
137 				final HttpServletResponse response,
138 				final ActionContext actionContext) {
139 			this.request = request;
140 			this.response = response;
141 			this.actionContext = actionContext;
142 
143 			final PluginRegistry pluginRegistry = PluginRegistry.getInstance();
144 			this.pluginsIterator = pluginRegistry.getPlugins().iterator();
145 		}
146 
147 		/**
148 		 * {@inheritDoc}
149 		 */
150 		public ActionResult proceed() throws Exception {
151 			final ActionResult actionResult;
152 			if (pluginsIterator.hasNext()) {
153 				final Plugin plugin = pluginsIterator.next();
154 				actionResult = plugin.invokeAction(this);
155 			} else {
156 				final ActionContext actionContext = getActionContext();
157 				final Object action = actionContext.getAction();
158 				final Method actionMethod = actionContext.getActionMethod();
159 				actionResult = (ActionResult) actionMethod.invoke(action);
160 			}
161 			return actionResult;
162 		}
163 
164 		/**
165 		 * {@inheritDoc}
166 		 */
167 		public HttpServletRequest getRequest() {
168 			return request;
169 		}
170 
171 		/**
172 		 * {@inheritDoc}
173 		 */
174 		public HttpServletResponse getResponse() {
175 			return response;
176 		}
177 
178 		/**
179 		 * {@inheritDoc}
180 		 */
181 		public ActionContext getActionContext() {
182 			return actionContext;
183 		}
184 
185 	}
186 
187 }