1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.context.servlet;
20
21 import java.io.IOException;
22 import java.io.OutputStream;
23 import java.io.UnsupportedEncodingException;
24 import java.io.Writer;
25 import java.net.URLDecoder;
26 import java.net.URLEncoder;
27 import java.security.Principal;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Locale;
33 import java.util.Map;
34 import java.util.logging.Logger;
35
36 import javax.faces.FacesException;
37 import javax.faces.context.FacesContext;
38 import javax.faces.context.Flash;
39 import javax.faces.context.PartialResponseWriter;
40 import javax.faces.context.PartialViewContext;
41 import javax.servlet.RequestDispatcher;
42 import javax.servlet.ServletContext;
43 import javax.servlet.ServletException;
44 import javax.servlet.ServletRequest;
45 import javax.servlet.ServletResponse;
46 import javax.servlet.http.Cookie;
47 import javax.servlet.http.HttpServletRequest;
48 import javax.servlet.http.HttpServletResponse;
49 import javax.servlet.http.HttpSession;
50
51 import org.apache.myfaces.shared.context.flash.FlashImpl;
52 import org.apache.myfaces.util.EnumerationIterator;
53
54
55
56
57
58
59
60
61 public final class ServletExternalContextImpl extends ServletExternalContextImplBase
62 {
63
64 private static final Logger log = Logger.getLogger(ServletExternalContextImpl.class.getName());
65
66 private static final String URL_PARAM_SEPERATOR="&";
67 private static final String URL_QUERY_SEPERATOR="?";
68 private static final String URL_FRAGMENT_SEPERATOR="#";
69 private static final String URL_NAME_VALUE_PAIR_SEPERATOR="=";
70
71 private ServletRequest _servletRequest;
72 private ServletResponse _servletResponse;
73 private Map<String, Object> _sessionMap;
74 private Map<String, Object> _requestMap;
75 private Map<String, String> _requestParameterMap;
76 private Map<String, String[]> _requestParameterValuesMap;
77 private Map<String, String> _requestHeaderMap;
78 private Map<String, String[]> _requestHeaderValuesMap;
79 private Map<String, Object> _requestCookieMap;
80 private HttpServletRequest _httpServletRequest;
81 private HttpServletResponse _httpServletResponse;
82 private String _requestServletPath;
83 private String _requestPathInfo;
84
85 public ServletExternalContextImpl(final ServletContext servletContext,
86 final ServletRequest servletRequest,
87 final ServletResponse servletResponse)
88 {
89 super(servletContext);
90
91 _servletRequest = servletRequest;
92 _servletResponse = servletResponse;
93 _sessionMap = null;
94 _requestMap = null;
95 _requestParameterMap = null;
96 _requestParameterValuesMap = null;
97 _requestHeaderMap = null;
98 _requestHeaderValuesMap = null;
99 _requestCookieMap = null;
100 _httpServletRequest = isHttpServletRequest(servletRequest) ? (HttpServletRequest) servletRequest : null;
101 _httpServletResponse = isHttpServletResponse(servletResponse) ? (HttpServletResponse) servletResponse : null;
102
103 if (_httpServletRequest != null)
104 {
105
106
107
108 _requestServletPath = _httpServletRequest.getServletPath();
109 _requestPathInfo = _httpServletRequest.getPathInfo();
110 }
111 }
112
113 public void release()
114 {
115 super.release();
116
117 _servletRequest = null;
118 _servletResponse = null;
119 _sessionMap = null;
120 _requestMap = null;
121 _requestParameterMap = null;
122 _requestParameterValuesMap = null;
123 _requestHeaderMap = null;
124 _requestHeaderValuesMap = null;
125 _requestCookieMap = null;
126 _httpServletRequest = null;
127 _httpServletResponse = null;
128 }
129
130 @Override
131 public Object getSession(boolean create)
132 {
133 checkHttpServletRequest();
134 return ((HttpServletRequest) _servletRequest).getSession(create);
135 }
136
137 @Override
138 public Object getRequest()
139 {
140 return _servletRequest;
141 }
142
143
144
145
146 @Override
147 public int getRequestContentLength()
148 {
149 return _servletRequest.getContentLength();
150 }
151
152 @Override
153 public Object getResponse()
154 {
155 return _servletResponse;
156 }
157
158
159
160
161 @Override
162 public int getResponseBufferSize()
163 {
164 return _servletResponse.getBufferSize();
165 }
166
167 @Override
168 public String getResponseContentType()
169 {
170 return _servletResponse.getContentType();
171 }
172
173 @Override
174 public OutputStream getResponseOutputStream() throws IOException
175 {
176 return _servletResponse.getOutputStream();
177 }
178
179
180
181
182 @Override
183 public Writer getResponseOutputWriter() throws IOException
184 {
185 return _servletResponse.getWriter();
186 }
187
188 @Override
189 public Map<String, Object> getSessionMap()
190 {
191 if (_sessionMap == null)
192 {
193 checkHttpServletRequest();
194 _sessionMap = new SessionMap(_httpServletRequest);
195 }
196 return _sessionMap;
197 }
198
199 @Override
200 public Map<String, Object> getRequestMap()
201 {
202 if (_requestMap == null)
203 {
204 _requestMap = new RequestMap(_servletRequest);
205 }
206 return _requestMap;
207 }
208
209 @Override
210 public Map<String, String> getRequestParameterMap()
211 {
212 if (_requestParameterMap == null)
213 {
214 _requestParameterMap = new RequestParameterMap(_servletRequest);
215 }
216 return _requestParameterMap;
217 }
218
219 @Override
220 public Map<String, String[]> getRequestParameterValuesMap()
221 {
222 if (_requestParameterValuesMap == null)
223 {
224 _requestParameterValuesMap = new RequestParameterValuesMap(_servletRequest);
225 }
226 return _requestParameterValuesMap;
227 }
228
229 @Override
230 public int getRequestServerPort()
231 {
232 return _servletRequest.getServerPort();
233 }
234
235 @Override
236 @SuppressWarnings("unchecked")
237 public Iterator<String> getRequestParameterNames()
238 {
239 return new EnumerationIterator(_servletRequest.getParameterNames());
240 }
241
242 @Override
243 public Map<String, String> getRequestHeaderMap()
244 {
245 if (_requestHeaderMap == null)
246 {
247 checkHttpServletRequest();
248 _requestHeaderMap = new RequestHeaderMap(_httpServletRequest);
249 }
250 return _requestHeaderMap;
251 }
252
253 @Override
254 public Map<String, String[]> getRequestHeaderValuesMap()
255 {
256 if (_requestHeaderValuesMap == null)
257 {
258 checkHttpServletRequest();
259 _requestHeaderValuesMap = new RequestHeaderValuesMap(_httpServletRequest);
260 }
261 return _requestHeaderValuesMap;
262 }
263
264
265
266 @Override
267 public Map<String, Object> getRequestCookieMap()
268 {
269 if (_requestCookieMap == null)
270 {
271 checkHttpServletRequest();
272 _requestCookieMap = new CookieMap(_httpServletRequest);
273 }
274
275 return _requestCookieMap;
276 }
277
278 @Override
279 public Locale getRequestLocale()
280 {
281 return _servletRequest.getLocale();
282 }
283
284 @Override
285 public String getRequestPathInfo()
286 {
287 checkHttpServletRequest();
288
289
290 return _requestPathInfo;
291 }
292
293 @Override
294 public String getRequestContentType()
295 {
296 return _servletRequest.getContentType();
297 }
298
299 @Override
300 public String getRequestContextPath()
301 {
302 checkHttpServletRequest();
303 return _httpServletRequest.getContextPath();
304 }
305
306 @Override
307 public String getRequestScheme()
308 {
309 return _servletRequest.getScheme();
310 }
311
312 @Override
313 public String encodeActionURL(final String url)
314 {
315 checkNull(url, "url");
316 checkHttpServletRequest();
317 return ((HttpServletResponse) _servletResponse).encodeURL(url);
318 }
319
320 @Override
321 public String encodeBookmarkableURL(String baseUrl, Map<String,List<String>> parameters)
322 {
323 return encodeURL(baseUrl, parameters);
324 }
325
326 @Override
327 public String encodeResourceURL(final String url)
328 {
329 checkNull(url, "url");
330 checkHttpServletRequest();
331 return ((HttpServletResponse) _servletResponse).encodeURL(url);
332 }
333
334 @Override
335 public String encodeNamespace(final String s)
336 {
337 return s;
338 }
339
340 @Override
341 public String encodePartialActionURL(String url)
342 {
343 checkNull(url, "url");
344 checkHttpServletRequest();
345 return ((HttpServletResponse) _servletResponse).encodeURL(url);
346 }
347
348 @Override
349 public String encodeRedirectURL(String baseUrl, Map<String,List<String>> parameters)
350 {
351 return _httpServletResponse.encodeRedirectURL(encodeURL(baseUrl, parameters));
352 }
353
354 @Override
355 public void dispatch(final String requestURI) throws IOException, FacesException
356 {
357 RequestDispatcher requestDispatcher = _servletRequest.getRequestDispatcher(requestURI);
358
359
360 if (requestDispatcher == null)
361 {
362 ((HttpServletResponse) _servletResponse).sendError(HttpServletResponse.SC_NOT_FOUND);
363
364 return;
365 }
366
367 try
368 {
369 requestDispatcher.forward(_servletRequest, _servletResponse);
370 }
371 catch (ServletException e)
372 {
373 if (e.getMessage() != null)
374 {
375 throw new FacesException(e.getMessage(), e);
376 }
377
378 throw new FacesException(e);
379
380 }
381 }
382
383 @Override
384 public String getRequestServerName()
385 {
386 return _servletRequest.getServerName();
387 }
388
389 @Override
390 public String getRequestServletPath()
391 {
392 checkHttpServletRequest();
393
394
395 return _requestServletPath;
396 }
397
398 @Override
399 public String getAuthType()
400 {
401 checkHttpServletRequest();
402 return _httpServletRequest.getAuthType();
403 }
404
405 @Override
406 public String getRemoteUser()
407 {
408 checkHttpServletRequest();
409 return _httpServletRequest.getRemoteUser();
410 }
411
412 @Override
413 public boolean isUserInRole(final String role)
414 {
415 checkNull(role, "role");
416 checkHttpServletRequest();
417 return _httpServletRequest.isUserInRole(role);
418 }
419
420 @Override
421 public Principal getUserPrincipal()
422 {
423 checkHttpServletRequest();
424 return _httpServletRequest.getUserPrincipal();
425 }
426
427 @Override
428 public void invalidateSession()
429 {
430 HttpSession session = (HttpSession) getSession(false);
431
432 if (session != null)
433 {
434 session.invalidate();
435 }
436 }
437
438
439
440
441 @Override
442 public boolean isResponseCommitted()
443 {
444 return _httpServletResponse.isCommitted();
445 }
446
447 @Override
448 public void redirect(final String url) throws IOException
449 {
450 FacesContext facesContext = FacesContext.getCurrentInstance();
451 PartialViewContext partialViewContext = facesContext.getPartialViewContext();
452 if (partialViewContext.isPartialRequest())
453 {
454 PartialResponseWriter writer = partialViewContext.getPartialResponseWriter();
455 this.setResponseContentType("text/xml");
456 this.setResponseCharacterEncoding("UTF-8");
457 this.addResponseHeader("Cache-control", "no-cache");
458 writer.startDocument();
459 writer.redirect(url);
460 writer.endDocument();
461 facesContext.responseComplete();
462 }
463 else if (_servletResponse instanceof HttpServletResponse)
464 {
465 ((HttpServletResponse) _servletResponse).sendRedirect(url);
466 facesContext.responseComplete();
467 }
468 else
469 {
470 throw new IllegalArgumentException("Only HttpServletResponse supported");
471 }
472 }
473
474
475
476
477 @Override
478 public void responseFlushBuffer() throws IOException
479 {
480 checkHttpServletResponse();
481 _httpServletResponse.flushBuffer();
482 }
483
484
485
486
487 @Override
488 public void responseReset()
489 {
490 checkHttpServletResponse();
491 _httpServletResponse.reset();
492 }
493
494
495
496
497 @Override
498 public void responseSendError(int statusCode, String message) throws IOException
499 {
500 checkHttpServletResponse();
501 if (message == null)
502 {
503 _httpServletResponse.sendError(statusCode);
504 }
505 else
506 {
507 _httpServletResponse.sendError(statusCode, message);
508 }
509 }
510
511 @Override
512 @SuppressWarnings("unchecked")
513 public Iterator<Locale> getRequestLocales()
514 {
515 checkHttpServletRequest();
516 return new EnumerationIterator(_httpServletRequest.getLocales());
517 }
518
519
520
521
522
523 @Override
524 public void setRequest(final java.lang.Object request)
525 {
526 this._servletRequest = (ServletRequest) request;
527 this._httpServletRequest = isHttpServletRequest(_servletRequest) ? (HttpServletRequest) _servletRequest : null;
528 this._httpServletRequest = isHttpServletRequest(_servletRequest) ? (HttpServletRequest) _servletRequest : null;
529 this._requestHeaderMap = null;
530 this._requestHeaderValuesMap = null;
531 this._requestMap = null;
532 this._requestParameterMap = null;
533 this._requestParameterValuesMap = null;
534 this._requestCookieMap = null;
535 this._sessionMap = null;
536 }
537
538
539
540
541
542
543 @Override
544 public void setRequestCharacterEncoding(final java.lang.String encoding) throws java.io.UnsupportedEncodingException
545 {
546
547 this._servletRequest.setCharacterEncoding(encoding);
548
549 }
550
551
552
553
554 @Override
555 public String getRequestCharacterEncoding()
556 {
557 return _servletRequest.getCharacterEncoding();
558 }
559
560
561
562
563 @Override
564 public String getResponseCharacterEncoding()
565 {
566 return _servletResponse.getCharacterEncoding();
567 }
568
569
570
571
572
573 @Override
574 public void setResponse(final java.lang.Object response)
575 {
576 this._servletResponse = (ServletResponse) response;
577 }
578
579
580
581
582 @Override
583 public void setResponseBufferSize(int size)
584 {
585 checkHttpServletResponse();
586 _httpServletResponse.setBufferSize(size);
587 }
588
589
590
591
592
593 @Override
594 public void setResponseCharacterEncoding(final java.lang.String encoding)
595 {
596 this._servletResponse.setCharacterEncoding(encoding);
597 }
598
599
600
601
602 @Override
603 public void setResponseContentLength(int length)
604 {
605 checkHttpServletResponse();
606 _httpServletResponse.setContentLength(length);
607 }
608
609 @Override
610 public void setResponseContentType(String contentType)
611 {
612
613 if (!_servletResponse.isCommitted())
614 {
615
616 _servletResponse.setContentType(contentType);
617 }
618 else
619 {
620
621 log.severe("Cannot set content type. Response already committed");
622 }
623 }
624
625
626
627
628 @Override
629 public void setResponseHeader(String name, String value)
630 {
631 checkHttpServletResponse();
632 _httpServletResponse.setHeader(name, value);
633 }
634
635 @Override
636 public void setResponseStatus(int statusCode)
637 {
638 checkHttpServletResponse();
639 _httpServletResponse.setStatus(statusCode);
640 }
641
642 private void checkHttpServletRequest()
643 {
644 if (_httpServletRequest == null)
645 {
646 throw new UnsupportedOperationException("Only HttpServletRequest supported");
647 }
648 }
649
650 private boolean isHttpServletRequest(final ServletRequest servletRequest)
651 {
652 return servletRequest instanceof HttpServletRequest;
653 }
654
655 private void checkHttpServletResponse()
656 {
657 if (_httpServletRequest == null)
658 {
659 throw new UnsupportedOperationException("Only HttpServletResponse supported");
660 }
661 }
662 private boolean isHttpServletResponse(final ServletResponse servletResponse)
663 {
664 return servletResponse instanceof HttpServletResponse;
665 }
666
667
668
669
670 @Override
671 public void addResponseCookie(final String name,
672 final String value, final Map<String, Object> properties)
673 {
674 checkHttpServletResponse();
675 Cookie cookie = new Cookie(name, value);
676 if (properties != null)
677 {
678 for (Map.Entry<String, Object> entry : properties.entrySet())
679 {
680 String propertyKey = entry.getKey();
681 Object propertyValue = entry.getValue();
682 if ("comment".equals(propertyKey))
683 {
684 cookie.setComment((String) propertyValue);
685 continue;
686 }
687 else if ("domain".equals(propertyKey))
688 {
689 cookie.setDomain((String)propertyValue);
690 continue;
691 }
692 else if ("maxAge".equals(propertyKey))
693 {
694 cookie.setMaxAge((Integer) propertyValue);
695 continue;
696 }
697 else if ("secure".equals(propertyKey))
698 {
699 cookie.setSecure((Boolean) propertyValue);
700 continue;
701 }
702 else if ("path".equals(propertyKey))
703 {
704 cookie.setPath((String) propertyValue);
705 continue;
706 }
707 throw new IllegalArgumentException("Unused key when creating Cookie");
708 }
709 }
710 _httpServletResponse.addCookie(cookie);
711 }
712
713 @Override
714 public void addResponseHeader(String name, String value)
715 {
716 _httpServletResponse.addHeader(name, value);
717 }
718
719 private String encodeURL(String baseUrl, Map<String, List<String>> parameters)
720 {
721 checkNull(baseUrl, "url");
722 checkHttpServletRequest();
723
724 String fragment = null;
725 String queryString = null;
726 Map<String, List<String>> paramMap = null;
727
728
729 int index = baseUrl.indexOf(URL_FRAGMENT_SEPERATOR);
730 if (index != -1)
731 {
732 fragment = baseUrl.substring(index+1);
733 baseUrl = baseUrl.substring(0,index);
734 }
735
736
737 index = baseUrl.indexOf(URL_QUERY_SEPERATOR);
738 if (index != -1)
739 {
740 queryString = baseUrl.substring(index + 1);
741 baseUrl = baseUrl.substring(0, index);
742 String[] nameValuePairs = queryString.split(URL_PARAM_SEPERATOR);
743 for (int i = 0; i < nameValuePairs.length; i++)
744 {
745 String[] currentPair = nameValuePairs[i].split(URL_NAME_VALUE_PAIR_SEPERATOR);
746
747 ArrayList<String> value = new ArrayList<String>(1);
748 try
749 {
750 value.add(currentPair.length > 1
751 ? URLDecoder.decode(currentPair[1], getResponseCharacterEncoding())
752 : "");
753 }
754 catch (UnsupportedEncodingException e)
755 {
756
757 throw new UnsupportedOperationException("Encoding type=" + getResponseCharacterEncoding()
758 + " not supported", e);
759 }
760 if (paramMap == null)
761 {
762 paramMap = new HashMap<String, List<String>>();
763 }
764 paramMap.put(currentPair[0], value);
765 }
766 }
767
768
769 if (parameters != null && parameters.size() > 0)
770 {
771 for (Map.Entry<String, List<String>> pair : parameters.entrySet())
772 {
773 if (pair.getKey() != null && pair.getKey().trim().length() != 0)
774 {
775 if (paramMap == null)
776 {
777 paramMap = new HashMap<String, List<String>>();
778 }
779 paramMap.put(pair.getKey(), pair.getValue());
780 }
781 }
782 }
783
784
785 StringBuilder newUrl = new StringBuilder(baseUrl);
786
787
788 if (paramMap != null && paramMap.size()>0)
789 {
790 boolean isFirstPair = true;
791 for (Map.Entry<String, List<String>> pair : paramMap.entrySet())
792 {
793 for (String value : pair.getValue())
794 {
795 if (!isFirstPair)
796 {
797 newUrl.append(URL_PARAM_SEPERATOR);
798 }
799 else
800 {
801 newUrl.append(URL_QUERY_SEPERATOR);
802 isFirstPair = false;
803 }
804
805 newUrl.append(pair.getKey());
806 newUrl.append(URL_NAME_VALUE_PAIR_SEPERATOR);
807 try
808 {
809 newUrl.append(URLEncoder.encode(value,getResponseCharacterEncoding()));
810 }
811 catch (UnsupportedEncodingException e)
812 {
813
814 throw new UnsupportedOperationException("Encoding type=" + getResponseCharacterEncoding()
815 + " not supported", e);
816 }
817 }
818 }
819 }
820
821
822 if (fragment != null)
823 {
824 newUrl.append(URL_FRAGMENT_SEPERATOR + fragment);
825 }
826
827 return newUrl.toString();
828 }
829
830
831
832
833 public Flash getFlash()
834 {
835 return FlashImpl.getCurrentInstance(this);
836 }
837 }