View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  package org.apache.portals.bridges.jsf;
    18
    19  import javax.faces.FacesException;
    20  import javax.faces.application.ViewHandler;
    21  import javax.faces.context.ExternalContext;
    22  import javax.faces.context.FacesContext;
    23  import javax.servlet.*;
    24  import javax.servlet.http.HttpServletRequest;
    25  import javax.servlet.http.HttpServletResponse;
    26  import javax.servlet.http.HttpSession;
    27  import java.io.IOException;
    28  import java.io.InputStream;
    29  import java.net.MalformedURLException;
    30  import java.net.URL;
    31  import java.security.Principal;
    32  import java.util.*;
    33  import java.lang.reflect.Method;
    34
    35  import org.apache.commons.logging.LogFactory;
    36  import org.apache.commons.logging.Log;
    37
    38  /***
    39    * @author Apache MyFaces team
    40   */
    41  public class ServletExternalContextImpl
    42      extends ExternalContext
    43  {
    44
    45      private static final Log log = LogFactory.getLog(ServletExternalContextImpl.class);
    46
    47      private static final String INIT_PARAMETER_MAP_ATTRIBUTE = InitParameterMap.class.getName();
    48
    49      private ServletContext _servletContext;
    50      private ServletRequest _servletRequest;
    51      private ServletResponse _servletResponse;
    52      private Map _applicationMap;
    53      private Map _sessionMap;
    54      private Map _requestMap;
    55      private Map _requestParameterMap;
    56      private Map _requestParameterValuesMap;
    57      private Map _requestHeaderMap;
    58      private Map _requestHeaderValuesMap;
    59      private Map _requestCookieMap;
    60      private Map _initParameterMap;
    61      private boolean _isHttpServletRequest;
    62      private String _requestServletPath;
    63      private String _requestPathInfo;
    64      private static Method setCharacterEncodingMethod = null;
    65
    66      static {
    67          try {
    68              setCharacterEncodingMethod = ServletRequest.class.getMethod("setCharacterEncoding", new Class[]{String.class});
    69          } catch (Exception e) {
    70                      log.warn("Detecting request character encoding is disable.");
    71                      log.warn("Failed to obtain ServletRequest#setCharacterEncoding() method: " + e);
    72          }
    73      }
    74
    75      public ServletExternalContextImpl(ServletContext servletContext,
    76                                        ServletRequest servletRequest,
    77                                        ServletResponse servletResponse)
    78      {
    79          _servletContext = servletContext;
    80          _servletRequest = servletRequest;
    81          _servletResponse = servletResponse;
    82          _applicationMap = null;
    83          _sessionMap = null;
    84          _requestMap = null;
    85          _requestParameterMap = null;
    86          _requestParameterValuesMap = null;
    87          _requestHeaderMap = null;
    88          _requestHeaderValuesMap = null;
    89          _requestCookieMap = null;
    90          _initParameterMap = null;
    91          _isHttpServletRequest = (servletRequest != null &&
    92                                   servletRequest instanceof HttpServletRequest);
    93          if (_isHttpServletRequest)
    94          {
    95              //HACK: MultipartWrapper scrambles the servletPath for some reason in Tomcat 4.1.29 embedded in JBoss 3.2.3!?
    96              // (this was reported by frederic.auge [frederic.auge@laposte.net])
    97              HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
    98
    99              _requestServletPath = httpServletRequest.getServletPath();
    100             _requestPathInfo = httpServletRequest.getPathInfo();
    101
    102             // try to set character encoding as described in section 2.5.2.2 of JSF 1.1 spec
    103             // we have to use reflection as method setCharacterEncoding is not supported Servlet API <= 2.3
    104             try
    105             {
    106                 if (setCharacterEncodingMethod != null) {
    107                     String contentType = httpServletRequest.getHeader("Content-Type");
    108
    109                     String characterEncoding = lookupCharacterEncoding(contentType);
    110
    111                     if (characterEncoding == null) {
    112                         HttpSession session = httpServletRequest.getSession(false);
    113
    114                         if (session != null) {
    115                             characterEncoding = (String) session.getAttribute(ViewHandler.CHARACTER_ENCODING_KEY);
    116                         }
    117
    118                         if (characterEncoding != null) {
    119                             setCharacterEncodingMethod.invoke(servletRequest, new Object[]{characterEncoding});
    120                         }
    121                     }
    122                 }
    123             } catch (Exception e)
    124             {
    125                 if (log.isWarnEnabled())
    126                     log.warn("Failed to set character encoding " + e);
    127             }
    128         }
    129     }
    130
    131
    132     private String lookupCharacterEncoding(String contentType)
    133     {
    134         String characterEncoding = null;
    135
    136         if (contentType != null)
    137         {
    138             int charsetFind = contentType.indexOf("charset=");
    139             if (charsetFind != -1)
    140             {
    141                 if (charsetFind == 0)
    142                 {
    143                     //charset at beginning of Content-Type, curious
    144                     characterEncoding = contentType.substring(8);
    145                 }
    146                 else
    147                 {
    148                     char charBefore = contentType.charAt(charsetFind - 1);
    149                     if (charBefore == ';' || Character.isWhitespace(charBefore))
    150                     {
    151                         //Correct charset after mime type
    152                         characterEncoding = contentType.substring(charsetFind + 8);
    153                     }
    154                 }
    155                 if (log.isDebugEnabled()) log.debug("Incoming request has Content-Type header with character encoding " + characterEncoding);
    156             }
    157             else
    158             {
    159                 if (log.isDebugEnabled()) log.debug("Incoming request has Content-Type header without character encoding: " + contentType);
    160             }
    161         }
    162         return characterEncoding;
    163     }
    164
    165
    166     public void release()
    167     {
    168         _servletContext = null;
    169         _servletRequest = null;
    170         _servletResponse = null;
    171         _applicationMap = null;
    172         _sessionMap = null;
    173         _requestMap = null;
    174         _requestParameterMap = null;
    175         _requestParameterValuesMap = null;
    176         _requestHeaderMap = null;
    177         _requestHeaderValuesMap = null;
    178         _requestCookieMap = null;
    179         _initParameterMap = null;
    180     }
    181
    182
    183     public Object getSession(boolean create)
    184     {
    185         if (!_isHttpServletRequest)
    186         {
    187             throw new IllegalArgumentException("Only HttpServletRequest supported");
    188         }
    189         return ((HttpServletRequest)_servletRequest).getSession(create);
    190     }
    191
    192     public Object getContext()
    193     {
    194         return _servletContext;
    195     }
    196
    197     public Object getRequest()
    198     {
    199         return _servletRequest;
    200     }
    201
    202     public Object getResponse()
    203     {
    204         return _servletResponse;
    205     }
    206
    207     public void setResponse(Object response) {
    208         if (response instanceof ServletResponse) {
    209             this._servletResponse = (ServletResponse) response;
    210         }
    211     }
    212
    213     public Map getApplicationMap()
    214     {
    215         if (_applicationMap == null)
    216         {
    217             _applicationMap = new ApplicationMap(_servletContext);
    218         }
    219         return _applicationMap;
    220     }
    221
    222     public Map getSessionMap()
    223     {
    224         if (_sessionMap == null)
    225         {
    226             if (!_isHttpServletRequest)
    227             {
    228                 throw new IllegalArgumentException("Only HttpServletRequest supported");
    229             }
    230             _sessionMap = new SessionMap((HttpServletRequest) _servletRequest);
    231         }
    232         return _sessionMap;
    233     }
    234
    235     public Map getRequestMap()
    236     {
    237         if (_requestMap == null)
    238         {
    239             _requestMap = new ServletRequestMap(_servletRequest);
    240         }
    241         return _requestMap;
    242     }
    243
    244     public Map getRequestParameterMap()
    245     {
    246         if (_requestParameterMap == null)
    247         {
    248             _requestParameterMap = new RequestParameterMap(_servletRequest);
    249         }
    250         return _requestParameterMap;
    251     }
    252
    253     public Map getRequestParameterValuesMap()
    254     {
    255         if (_requestParameterValuesMap == null)
    256         {
    257             _requestParameterValuesMap = new RequestParameterValuesMap(_servletRequest);
    258         }
    259         return _requestParameterValuesMap;
    260     }
    261
    262     public Iterator getRequestParameterNames()
    263     {
    264         final Enumeration enumer = _servletRequest.getParameterNames();
    265         Iterator it = new Iterator()
    266         {
    267             public boolean hasNext() {
    268                 return enumer.hasMoreElements();
    269             }
    270
    271             public Object next() {
    272                 return enumer.nextElement();
    273             }
    274
    275             public void remove() {
    276                 throw new UnsupportedOperationException(this.getClass().getName() + " UnsupportedOperationException");
    277             }
    278         };
    279         return it;
    280     }
    281
    282     public Map getRequestHeaderMap()
    283     {
    284         if (_requestHeaderMap == null)
    285         {
    286             if (!_isHttpServletRequest)
    287             {
    288                 throw new IllegalArgumentException("Only HttpServletRequest supported");
    289             }
    290             _requestHeaderMap = new ServletRequestHeaderMap((HttpServletRequest)_servletRequest);
    291         }
    292         return _requestHeaderMap;
    293     }
    294
    295     public Map getRequestHeaderValuesMap()
    296     {
    297         if (_requestHeaderValuesMap == null)
    298         {
    299             if (!_isHttpServletRequest)
    300             {
    301                 throw new IllegalArgumentException("Only HttpServletRequest supported");
    302             }
    303             _requestHeaderValuesMap = new ServletRequestHeaderValuesMap((HttpServletRequest)_servletRequest);
    304         }
    305         return _requestHeaderValuesMap;
    306     }
    307
    308     public Map getRequestCookieMap()
    309     {
    310         if (_requestCookieMap == null)
    311         {
    312             if (!_isHttpServletRequest)
    313             {
    314                 throw new IllegalArgumentException("Only HttpServletRequest supported");
    315             }
    316             _requestCookieMap = new ServletCookieMap((HttpServletRequest)_servletRequest);
    317         }
    318         return _requestCookieMap;
    319     }
    320
    321     public Locale getRequestLocale()
    322     {
    323         return _servletRequest.getLocale();
    324     }
    325
    326     public String getRequestPathInfo()
    327     {
    328         if (!_isHttpServletRequest)
    329         {
    330             throw new IllegalArgumentException("Only HttpServletRequest supported");
    331         }
    332         //return ((HttpServletRequest)_servletRequest).getPathInfo();
    333         //HACK: see constructor
    334         return _requestPathInfo;
    335     }
    336
    337     public String getRequestContextPath()
    338     {
    339         if (!_isHttpServletRequest)
    340         {
    341             throw new IllegalArgumentException("Only HttpServletRequest supported");
    342         }
    343         return ((HttpServletRequest)_servletRequest).getContextPath();
    344     }
    345
    346     public String getInitParameter(String s)
    347     {
    348         return _servletContext.getInitParameter(s);
    349     }
    350
    351     public Map getInitParameterMap()
    352     {
    353         if (_initParameterMap == null)
    354         {
    355             // We cache it as an attribute in ServletContext itself (is this circular reference a problem?)
    356             if ((_initParameterMap = (Map) _servletContext.getAttribute(INIT_PARAMETER_MAP_ATTRIBUTE)) == null)
    357             {
    358                 _initParameterMap = new InitParameterMap(_servletContext);
    359                 _servletContext.setAttribute(INIT_PARAMETER_MAP_ATTRIBUTE, _initParameterMap);
    360             }
    361         }
    362         return _initParameterMap;
    363     }
    364
    365     public Set getResourcePaths(String s)
    366     {
    367         return _servletContext.getResourcePaths(s);
    368     }
    369
    370     public InputStream getResourceAsStream(String s)
    371     {
    372         return _servletContext.getResourceAsStream(s);
    373     }
    374
    375     public String encodeActionURL(String s)
    376     {
    377         if (!_isHttpServletRequest)
    378         {
    379             throw new IllegalArgumentException("Only HttpServletRequest supported");
    380         }
    381         return ((HttpServletResponse)_servletResponse).encodeURL(s);
    382     }
    383
    384     public String encodeResourceURL(String s)
    385     {
    386         if (!_isHttpServletRequest)
    387         {
    388             throw new IllegalArgumentException("Only HttpServletRequest supported");
    389         }
    390         return ((HttpServletResponse)_servletResponse).encodeURL(s);
    391     }
    392
    393     public String encodeNamespace(String s)
    394     {
    395         return s;
    396     }
    397
    398     public void dispatch(String requestURI) throws IOException, FacesException
    399     {
    400         RequestDispatcher requestDispatcher
    401             = _servletRequest.getRequestDispatcher(requestURI);
    402
    403         // If there is no dispatcher, send NOT_FOUND
    404         if (requestDispatcher == null)
    405         {
    406            ((HttpServletResponse)_servletResponse).sendError(
    407                   HttpServletResponse.SC_NOT_FOUND);
    408
    409            return;
    410        }
    411
    412         try
    413         {
    414             requestDispatcher.forward(_servletRequest, _servletResponse);
    415         }
    416         catch (ServletException e)
    417         {
    418         	if (e.getMessage() != null)
    419             {
    420                 throw new FacesException(e.getMessage(), e);
    421             }
    422             else
    423             {
    424                 throw new FacesException(e);
    425             }
    426         }
    427     }
    428
    429     public String getRequestServletPath()
    430     {
    431         if (!_isHttpServletRequest)
    432         {
    433             throw new IllegalArgumentException("Only HttpServletRequest supported");
    434         }
    435         //return ((HttpServletRequest)_servletRequest).getServletPath();
    436         //HACK: see constructor
    437         return _requestServletPath;
    438     }
    439
    440     public String getAuthType()
    441     {
    442         if (!_isHttpServletRequest)
    443         {
    444             throw new IllegalArgumentException("Only HttpServletRequest supported");
    445         }
    446         return ((HttpServletRequest)_servletRequest).getAuthType();
    447     }
    448
    449     public String getRemoteUser()
    450     {
    451         if (!_isHttpServletRequest)
    452         {
    453             throw new IllegalArgumentException("Only HttpServletRequest supported");
    454         }
    455         return ((HttpServletRequest)_servletRequest).getRemoteUser();
    456     }
    457
    458     public boolean isUserInRole(String role)
    459     {
    460         if (!_isHttpServletRequest)
    461         {
    462             throw new IllegalArgumentException("Only HttpServletRequest supported");
    463         }
    464         return ((HttpServletRequest)_servletRequest).isUserInRole(role);
    465     }
    466
    467     public Principal getUserPrincipal()
    468     {
    469         if (!_isHttpServletRequest)
    470         {
    471             throw new IllegalArgumentException("Only HttpServletRequest supported");
    472         }
    473         return ((HttpServletRequest)_servletRequest).getUserPrincipal();
    474     }
    475
    476     public void log(String message) {
    477         _servletContext.log(message);
    478     }
    479
    480     public void log(String message, Throwable t) {
    481         _servletContext.log(message, t);
    482     }
    483
    484     public void redirect(String url) throws IOException
    485     {
    486         if (_servletResponse instanceof HttpServletResponse)
    487         {
    488             ((HttpServletResponse)_servletResponse).sendRedirect(url);
    489             FacesContext.getCurrentInstance().responseComplete();
    490         }
    491         else
    492         {
    493             throw new IllegalArgumentException("Only HttpServletResponse supported");
    494         }
    495     }
    496
    497     public Iterator getRequestLocales()
    498     {
    499         if (!_isHttpServletRequest)
    500         {
    501             throw new IllegalArgumentException("Only HttpServletRequest supported");
    502         }
    503         return new EnumerationIterator(((HttpServletRequest)_servletRequest).getLocales());
    504     }
    505
    506     public URL getResource(String s) throws MalformedURLException
    507     {
    508         return _servletContext.getResource(s);
    509     }
    510 }