001 package com.mockrunner.mock.web;
002
003 import java.io.IOException;
004 import java.io.Writer;
005 import java.util.Enumeration;
006 import java.util.HashMap;
007 import java.util.Iterator;
008 import java.util.NoSuchElementException;
009 import java.util.Stack;
010
011 import javax.el.ELContext;
012 import javax.servlet.RequestDispatcher;
013 import javax.servlet.Servlet;
014 import javax.servlet.ServletConfig;
015 import javax.servlet.ServletContext;
016 import javax.servlet.ServletException;
017 import javax.servlet.ServletRequest;
018 import javax.servlet.ServletResponse;
019 import javax.servlet.http.HttpServletRequest;
020 import javax.servlet.http.HttpServletResponse;
021 import javax.servlet.http.HttpSession;
022 import javax.servlet.jsp.JspWriter;
023 import javax.servlet.jsp.PageContext;
024 import javax.servlet.jsp.el.ExpressionEvaluator;
025 import javax.servlet.jsp.el.VariableResolver;
026 import javax.servlet.jsp.tagext.BodyContent;
027
028 import com.mockrunner.base.NestedApplicationException;
029
030 /**
031 * Mock implementation of <code>PageContext</code>.
032 * Please note that EL support using the
033 * the <b>Unified Expression Language</b> API is only available,
034 * if the {@link JasperJspFactory} is configured as the default
035 * <code>JspFactory</code>. By default, {@link #getELContext}
036 * returns <code>null</code>.
037 */
038 //Some methods of this class were copied from org.apache.struts.mock.MockPageContext
039 //and modified
040 public class MockPageContext extends PageContext
041 {
042 protected ServletConfig config;
043 protected ServletRequest request;
044 protected ServletResponse response;
045 private JspWriter jspWriter;
046 private Stack outStack;
047 private Exception exception;
048 private Object page;
049 private HashMap attributes;
050 private ExpressionEvaluator evaluator;
051 private VariableResolver resolver;
052 private ELContext elContext;
053
054 public MockPageContext()
055 {
056 this(null, null, null);
057 }
058
059 public MockPageContext(ServletConfig config, ServletRequest request, ServletResponse response)
060 {
061 this.config = config;
062 this.request = request;
063 jspWriter = new MockJspWriter();
064 initJspWriterWithResponse(response);
065 outStack = new Stack();
066 attributes = new HashMap();
067 evaluator = new MockExpressionEvaluator();
068 resolver = new MockVariableResolver();
069 }
070
071 private void initJspWriterWithResponse(ServletResponse response)
072 {
073 this.response = response;
074 if((null != response) && (response instanceof HttpServletResponse))
075 {
076 try
077 {
078 jspWriter = new MockJspWriter((HttpServletResponse)response);
079 }
080 catch(IOException exc)
081 {
082 throw new NestedApplicationException(exc);
083 }
084 }
085 }
086
087 /**
088 * This method allows to set custom implementations
089 * of <code>JspWriter</code>. Per default, {@link MockJspWriter}
090 * is used.
091 * @param jspWriter the <code>JspWriter</code>
092 */
093 public void setJspWriter(JspWriter jspWriter)
094 {
095 this.jspWriter = jspWriter;
096 }
097
098 public void setPage(Object page)
099 {
100 this.page = page;
101 }
102
103 /**
104 * Sets the <code>ServletConfig</code>.
105 * @param config the <code>ServletConfig</code>
106 */
107 public void setServletConfig(ServletConfig config)
108 {
109 this.config = config;
110 }
111
112 /**
113 * Sets the <code>ServletRequest</code>.
114 * @param request the <code>ServletRequest</code>
115 */
116 public void setServletRequest(ServletRequest request)
117 {
118 this.request = request;
119 }
120
121 /**
122 * Sets the <code>ServletResponse</code>.
123 * @param response the <code>ServletResponse</code>
124 */
125 public void setServletResponse(ServletResponse response)
126 {
127 this.response = response;
128 initJspWriterWithResponse(response);
129 }
130
131 public void setException(Exception exception)
132 {
133 this.exception = exception;
134 }
135
136 public Object findAttribute(String name)
137 {
138 Object value = getAttribute(name, PageContext.PAGE_SCOPE);
139 if(value == null)
140 {
141 value = getAttribute(name, PageContext.REQUEST_SCOPE);
142 }
143 if(value == null)
144 {
145 value = getAttribute(name, PageContext.SESSION_SCOPE);
146 }
147 if(value == null)
148 {
149 value = getAttribute(name, PageContext.APPLICATION_SCOPE);
150 }
151 return value;
152 }
153
154 public Object getAttribute(String name)
155 {
156 return getAttribute(name, PageContext.PAGE_SCOPE);
157 }
158
159 public Object getAttribute(String name, int scope)
160 {
161 if(scope == PageContext.PAGE_SCOPE)
162 {
163 return attributes.get(name);
164 }
165 else if(scope == PageContext.REQUEST_SCOPE)
166 {
167 if(null == request) return null;
168 return request.getAttribute(name);
169 }
170 else if(scope == PageContext.SESSION_SCOPE)
171 {
172 if(null == getSession()) return null;
173 return getSession().getAttribute(name);
174 }
175 else if(scope == PageContext.APPLICATION_SCOPE)
176 {
177 if(null == getServletContext()) return null;
178 return getServletContext().getAttribute(name);
179 }
180 else
181 {
182 throw new IllegalArgumentException("Invalid scope " + scope);
183 }
184 }
185
186 public void removeAttribute(String name)
187 {
188 int scope = getAttributesScope(name);
189 if (scope != 0)
190 {
191 removeAttribute(name, scope);
192 }
193 }
194
195 public void removeAttribute(String name, int scope)
196 {
197 if(scope == PageContext.PAGE_SCOPE)
198 {
199 attributes.remove(name);
200 }
201 else if(scope == PageContext.REQUEST_SCOPE)
202 {
203 if(request != null)
204 {
205 request.removeAttribute(name);
206 }
207 }
208 else if(scope == PageContext.SESSION_SCOPE)
209 {
210 if(getSession() != null)
211 {
212 getSession().removeAttribute(name);
213 }
214 }
215 else if(scope == PageContext.APPLICATION_SCOPE)
216 {
217 if(getServletContext() != null)
218 {
219 getServletContext().removeAttribute(name);
220 }
221 }
222 else
223 {
224 throw new IllegalArgumentException("Invalid scope " + scope);
225 }
226 }
227
228 public void setAttribute(String name, Object value)
229 {
230 setAttribute(name, value, PageContext.PAGE_SCOPE);
231 }
232
233
234 public void setAttribute(String name, Object value, int scope)
235 {
236 if(scope == PageContext.PAGE_SCOPE)
237 {
238 attributes.put(name, value);
239 }
240 else if(scope == PageContext.REQUEST_SCOPE)
241 {
242 if(request != null)
243 {
244 request.setAttribute(name, value);
245 }
246 }
247 else if(scope == PageContext.SESSION_SCOPE)
248 {
249 if(getSession() != null)
250 {
251 getSession().setAttribute(name, value);
252 }
253 }
254 else if(scope == PageContext.APPLICATION_SCOPE)
255 {
256 if(getServletContext() != null)
257 {
258 getServletContext().setAttribute(name, value);
259 }
260 }
261 else
262 {
263 throw new IllegalArgumentException("Invalid scope " + scope);
264 }
265 }
266
267 public int getAttributesScope(String name)
268 {
269 if(getAttribute(name, PageContext.PAGE_SCOPE) != null)
270 {
271 return PageContext.PAGE_SCOPE;
272 }
273 else if(getAttribute(name, PageContext.REQUEST_SCOPE) != null)
274 {
275 return PageContext.REQUEST_SCOPE;
276 }
277 else if(getAttribute(name, PageContext.SESSION_SCOPE) != null)
278 {
279 return PageContext.SESSION_SCOPE;
280 }
281 else if(getAttribute(name, PageContext.APPLICATION_SCOPE) != null)
282 {
283 return PageContext.APPLICATION_SCOPE;
284 }
285 return 0;
286 }
287
288 public Enumeration getAttributeNamesInScope(int scope)
289 {
290 if(scope == PageContext.PAGE_SCOPE)
291 {
292 return new WrappedEnumeration(attributes.keySet().iterator());
293 }
294 else if(scope == PageContext.REQUEST_SCOPE)
295 {
296 if(request == null) return new NullEnumeration();
297 return request.getAttributeNames();
298 }
299 else if(scope == PageContext.SESSION_SCOPE)
300 {
301 if(getSession() == null) return new NullEnumeration();
302 return getSession().getAttributeNames();
303 }
304 else if(scope == PageContext.APPLICATION_SCOPE)
305 {
306 if(getServletContext() == null) return new NullEnumeration();
307 return getServletContext().getAttributeNames();
308 }
309 else
310 {
311 throw new IllegalArgumentException("Invalid scope " + scope);
312 }
313 }
314
315 public JspWriter getOut()
316 {
317 return jspWriter;
318 }
319
320 public Exception getException()
321 {
322 return exception;
323 }
324
325 public Object getPage()
326 {
327 return page;
328 }
329
330 public ServletRequest getRequest()
331 {
332 return request;
333 }
334
335 public ServletResponse getResponse()
336 {
337 return response;
338 }
339
340 public ServletConfig getServletConfig()
341 {
342 return config;
343 }
344
345 public ServletContext getServletContext()
346 {
347 if(null == config) return null;
348 return config.getServletContext();
349 }
350
351
352 public HttpSession getSession()
353 {
354 if(null == request) return null;
355 return ((HttpServletRequest)request).getSession();
356 }
357
358 public void handlePageException(Exception exc)
359 {
360
361 }
362
363 public void handlePageException(Throwable thr)
364 {
365
366 }
367
368 public void forward(String path) throws ServletException, IOException
369 {
370 if(null != request)
371 {
372 RequestDispatcher dispatcher = request.getRequestDispatcher(path);
373 if(null != dispatcher)
374 {
375 dispatcher.forward(request, response);
376 }
377 }
378 }
379
380 public void include(String path) throws ServletException, IOException
381 {
382 if(null != request)
383 {
384 RequestDispatcher dispatcher = request.getRequestDispatcher(path);
385 if(null != dispatcher)
386 {
387 dispatcher.include(request, response);
388 }
389 }
390 }
391
392 public void include(String path, boolean flush) throws ServletException, IOException
393 {
394 if(flush)
395 {
396 jspWriter.flush();
397 }
398 include(path);
399 }
400
401 public void initialize(Servlet servlet, ServletRequest request,
402 ServletResponse response, String errorPageURL,
403 boolean needsSession, int bufferSize,
404 boolean autoFlush)
405 {
406 this.config = servlet.getServletConfig();
407 this.request = request;
408 this.response = response;
409 jspWriter = new MockJspWriter();
410 outStack = new Stack();
411 attributes = new HashMap();
412 }
413
414 public JspWriter popBody()
415 {
416 jspWriter = (JspWriter)outStack.pop();
417 return jspWriter;
418 }
419
420 public BodyContent pushBody()
421 {
422 outStack.push(jspWriter);
423 jspWriter = new MockBodyContent(jspWriter);
424 return (BodyContent)jspWriter;
425 }
426
427 public JspWriter pushBody(Writer writer)
428 {
429 outStack.push(jspWriter);
430 jspWriter = new MockJspWriter(writer);
431 return jspWriter;
432 }
433
434 public void release()
435 {
436 jspWriter = new MockJspWriter();
437 outStack = new Stack();
438 }
439
440 /**
441 * Sets the expression evaluator. The default expression evaluator
442 * is {@link MockExpressionEvaluator}.
443 * @param evaluator the <code>ExpressionEvaluator</code>
444 */
445 public void setExpressionEvaluator(ExpressionEvaluator evaluator)
446 {
447 this.evaluator = evaluator;
448 }
449
450 /**
451 * Sets the variable resolver. The default variable resolver
452 * is {@link MockVariableResolver}.
453 * @param resolver the <code>VariableResolver</code>
454 */
455 public void setVariableResolver(VariableResolver resolver)
456 {
457 this.resolver = resolver;
458 }
459
460 /**
461 * Sets the <code>ELContext</code>. There is no default
462 * <code>ELContext</code>. Configure the {@link JasperJspFactory}
463 * to set one.
464 * @param elContext the <code>ELContext</code>
465 */
466 public void setELContext(ELContext elContext)
467 {
468 this.elContext = elContext;
469 }
470
471 public ExpressionEvaluator getExpressionEvaluator()
472 {
473 return evaluator;
474 }
475
476 public VariableResolver getVariableResolver()
477 {
478 return resolver;
479 }
480
481 public ELContext getELContext()
482 {
483 return elContext;
484 }
485
486 private class NullEnumeration implements Enumeration
487 {
488 public boolean hasMoreElements()
489 {
490 return false;
491 }
492
493 public Object nextElement()
494 {
495 throw new NoSuchElementException();
496 }
497 }
498
499 private class WrappedEnumeration implements Enumeration
500 {
501 private Iterator iterator;
502
503 public WrappedEnumeration(Iterator iterator)
504 {
505 this.iterator = iterator;
506 }
507
508 public boolean hasMoreElements()
509 {
510 return iterator.hasNext();
511 }
512
513 public Object nextElement()
514 {
515 return iterator.next();
516 }
517 }
518 }