1 /*
2 * $Id: ServletTilesRequestContext.java 632818 2008-03-02 19:48:05Z apetrelli $
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21 package org.apache.tiles.servlet.context;
22
23 import java.io.IOException;
24 import java.util.Locale;
25 import java.util.Map;
26
27 import javax.servlet.RequestDispatcher;
28 import javax.servlet.ServletContext;
29 import javax.servlet.ServletException;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32
33 import org.apache.tiles.context.TilesRequestContext;
34 import org.apache.tiles.util.TilesIOException;
35
36 /**
37 * Servlet-based implementation of the TilesApplicationContext interface.
38 *
39 * @version $Rev: 632818 $ $Date: 2008-03-02 20:48:05 +0100 (Sun, 02 Mar 2008) $
40 */
41 public class ServletTilesRequestContext extends ServletTilesApplicationContext implements TilesRequestContext {
42
43 /**
44 * The request object to use.
45 */
46 private HttpServletRequest request;
47
48 /**
49 * The response object to use.
50 */
51 private HttpServletResponse response;
52
53
54 /**
55 * <p>The lazily instantiated <code>Map</code> of header name-value
56 * combinations (immutable).</p>
57 */
58 private Map<String, String> header = null;
59
60
61 /**
62 * <p>The lazily instantitated <code>Map</code> of header name-values
63 * combinations (immutable).</p>
64 */
65 private Map<String, String[]> headerValues = null;
66
67
68 /**
69 * <p>The lazily instantiated <code>Map</code> of request
70 * parameter name-value.</p>
71 */
72 private Map<String, String> param = null;
73
74
75 /**
76 * <p>The lazily instantiated <code>Map</code> of request
77 * parameter name-values.</p>
78 */
79 private Map<String, String[]> paramValues = null;
80
81 /**
82 * <p>The lazily instantiated <code>Map</code> of request scope
83 * attributes.</p>
84 */
85 private Map<String, Object> requestScope = null;
86
87 /**
88 * <p>The lazily instantiated <code>Map</code> of session scope
89 * attributes.</p>
90 */
91 private Map<String, Object> sessionScope = null;
92
93
94 /**
95 * Creates a new instance of ServletTilesRequestContext.
96 *
97 * @param servletContext The servlet context.
98 * @param request The request object.
99 * @param response The response object.
100 */
101 public ServletTilesRequestContext(ServletContext servletContext,
102 HttpServletRequest request,
103 HttpServletResponse response) {
104 super(servletContext);
105 initialize(request, response);
106 }
107
108
109 /** {@inheritDoc} */
110 public Map<String, String> getHeader() {
111
112 if ((header == null) && (request != null)) {
113 header = new ServletHeaderMap(request);
114 }
115 return (header);
116
117 }
118
119
120 /** {@inheritDoc} */
121 public Map<String, String[]> getHeaderValues() {
122
123 if ((headerValues == null) && (request != null)) {
124 headerValues = new ServletHeaderValuesMap(request);
125 }
126 return (headerValues);
127
128 }
129
130
131 /** {@inheritDoc} */
132 public Map<String, String> getParam() {
133
134 if ((param == null) && (request != null)) {
135 param = new ServletParamMap(request);
136 }
137 return (param);
138
139 }
140
141
142 /** {@inheritDoc} */
143 public Map<String, String[]> getParamValues() {
144
145 if ((paramValues == null) && (request != null)) {
146 paramValues = new ServletParamValuesMap(request);
147 }
148 return (paramValues);
149
150 }
151
152
153 /** {@inheritDoc} */
154 public Map<String, Object> getRequestScope() {
155
156 if ((requestScope == null) && (request != null)) {
157 requestScope = new ServletRequestScopeMap(request);
158 }
159 return (requestScope);
160
161 }
162
163
164 /** {@inheritDoc} */
165 public Map<String, Object> getSessionScope() {
166
167 if ((sessionScope == null) && (request != null)) {
168 sessionScope = new ServletSessionScopeMap(request);
169 }
170 return (sessionScope);
171
172 }
173
174 /** {@inheritDoc} */
175 public void dispatch(String path) throws IOException {
176 if (response.isCommitted() || ServletUtil.isForceInclude(request)) {
177 include(path);
178 } else {
179 forward(path);
180 }
181 }
182
183 /**
184 * Forwards to a path.
185 *
186 * @param path The path to forward to.
187 * @throws IOException If something goes wrong during the operation.
188 */
189 protected void forward(String path) throws IOException {
190 RequestDispatcher rd = request.getRequestDispatcher(path);
191
192 if (rd == null) {
193 throw new IOException("No request dispatcher returned for path '"
194 + path + "'");
195 }
196
197 try {
198 rd.forward(request, response);
199 } catch (ServletException ex) {
200 throw wrapServletException(ex, "ServletException including path '"
201 + path + "'.");
202 }
203 }
204
205
206 /** {@inheritDoc} */
207 public void include(String path) throws IOException {
208 ServletUtil.setForceInclude(request, true);
209 RequestDispatcher rd = request.getRequestDispatcher(path);
210
211 if (rd == null) {
212 throw new IOException("No request dispatcher returned for path '"
213 + path + "'");
214 }
215
216 try {
217 rd.include(request, response);
218 } catch (ServletException ex) {
219 throw wrapServletException(ex, "ServletException including path '"
220 + path + "'.");
221 }
222 }
223
224 /** {@inheritDoc} */
225 public Locale getRequestLocale() {
226 return request.getLocale();
227 }
228
229 /** {@inheritDoc} */
230 public HttpServletRequest getRequest() {
231 return request;
232 }
233
234 /** {@inheritDoc} */
235 public HttpServletResponse getResponse() {
236 return response;
237 }
238
239 /**
240 * <p>Initialize (or reinitialize) this {@link ServletTilesRequestContext} instance
241 * for the specified Servlet API objects.</p>
242 *
243 * @param request The <code>HttpServletRequest</code> for this request
244 * @param response The <code>HttpServletResponse</code> for this request
245 */
246 public void initialize(HttpServletRequest request,
247 HttpServletResponse response) {
248
249 // Save the specified Servlet API object references
250 this.request = request;
251 this.response = response;
252 // Perform other setup as needed
253 }
254
255
256 /**
257 * <p>Release references to allocated resources acquired in
258 * <code>initialize()</code> of via subsequent processing. After this
259 * method is called, subsequent calls to any other method than
260 * <code>initialize()</code> will return undefined results.</p>
261 */
262 public void release() {
263 // Release references to allocated collections
264 header = null;
265 headerValues = null;
266 param = null;
267 paramValues = null;
268 requestScope = null;
269 sessionScope = null;
270
271 // Release references to Servlet API objects
272 request = null;
273 response = null;
274 super.release();
275
276 }
277
278
279 /** {@inheritDoc} */
280 public boolean isUserInRole(String role) {
281 return request.isUserInRole(role);
282 }
283
284 /**
285 * Wraps a ServletException to create an IOException with the root cause if present.
286 *
287 * @param ex The exception to wrap.
288 * @param message The message of the exception.
289 * @return The wrapped exception.
290 * @since 2.0.6
291 */
292 protected IOException wrapServletException(ServletException ex, String message) {
293 IOException retValue;
294 Throwable rootCause = ex.getRootCause();
295 if (rootCause != null) {
296 // Replace the ServletException with an IOException, with the root
297 // cause of the first as the cause of the latter.
298 retValue = new TilesIOException(message, rootCause);
299 } else {
300 retValue = new TilesIOException(message, ex);
301 }
302
303 return retValue;
304 }
305 }