View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
    10   *   http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing,
    13   * software distributed under the License is distributed on an
    14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   * KIND, either express or implied.  See the License for the
    16   * specific language governing permissions and limitations
    17   * under the License.
    18   */
    19  package org.apache.myfaces.orchestra.lib.jsf;
    20
    21  import java.io.IOException;
    22  import java.io.InputStream;
    23  import java.lang.reflect.Method;
    24
    25  import javax.faces.context.ExternalContext;
    26
    27  import org.apache.commons.logging.Log;
    28  import org.apache.commons.logging.LogFactory;
    29
    30  /**
    31   * TODO: This class is a copy of
    32   * org.apache.myfaces.commons.util.ExternalContextUtils
    33   *
    34   * Since orchestra should be compatible with 1.1, this is placed
    35   * here and there is not a dependency for myfaces-commons-utils, because
    36   * this stuff only works for 1.2
    37   *
    38   * This provides some functionality for determining some things about the
    39   * native request object that is not provided by JSF.  This class is useful
    40   * for use in places where Portlet API's may or may not be present and can
    41   * also provide access to some request-specific items which are not available on
    42   * the JSF ExternalContext.  If portlet API's are not present, this class simply
    43   * handles the Servlet Request type.
    44   *
    45   * @since 1.4
    46   */
    47  public final class ExternalContextUtils
    48  {
    49      // prevent this from being instantiated
    50      private ExternalContextUtils()
    51      {
    52      }
    53
    54      /**
    55       * Returns the content length or -1 if the unknown.
    56       *
    57       * @param externalContext
    58       *          the ExternalContext
    59       * @return the length or -1
    60       */
    61      public static final int getContentLength(ExternalContext externalContext)
    62      {
    63          RequestType type = getRequestType(externalContext);
    64
    65          if(type.isRequestFromClient())
    66          {
    67              try
    68              {
    69                  Object request = externalContext.getRequest();
    70                  Method contentLenMethod = request.getClass().getMethod("getContentLength",new Class[]{});
    71                  return ((Integer) contentLenMethod.invoke(request,new Object[]{})).intValue(); //this will autobox
    72              }
    73              catch(Exception e)
    74              {
    75                  _LOG.error("Unsupported request type.", e);
    76              }
    77          }
    78
    79          return -1;
    80      }
    81
    82      /**
    83       * Returns the request input stream if one is available
    84       *
    85       * @param externalContext
    86       * @return
    87       * @throws IOException
    88       */
    89      public static final InputStream getRequestInputStream(ExternalContext externalContext)
    90              throws IOException
    91      {
    92          RequestType type = getRequestType(externalContext);
    93
    94          if(type.isRequestFromClient())
    95          {
    96            try
    97              {
    98                Object request = externalContext.getRequest();
    99
    100               Method method = request.getClass().getMethod(
    101                       type.isPortlet()?"getPortletInputStream":"getInputStream",new Class[]{});
    102               return (InputStream) method.invoke(request,new Object[]{});
    103             }
    104             catch (Exception e)
    105             {
    106                 _LOG.error("Unable to get the request input stream because of an error", e);
    107             }
    108         }
    109         return null;
    110     }
    111
    112     /**
    113      * Returns the requestType of this ExternalContext.
    114      *
    115      * @param externalContext the current external context
    116      * @return the appropriate RequestType for this external context
    117      * @see RequestType
    118      */
    119     public static final RequestType getRequestType(ExternalContext externalContext)
    120     {
    121         //Stuff is laid out strangely in this class in order to optimize
    122         //performance.  We want to do as few instanceof's as possible so
    123         //things are laid out according to the expected frequency of the
    124         //various requests occurring.
    125         if(_PORTLET_CONTEXT_CLASS != null)
    126         {
    127             if (_PORTLET_CONTEXT_CLASS.isInstance(externalContext.getContext()))
    128             {
    129                 //We are inside of a portlet container
    130                 Object request = externalContext.getRequest();
    131
    132                 if(_PORTLET_RENDER_REQUEST_CLASS.isInstance(request))
    133                 {
    134                     return RequestType.RENDER;
    135                 }
    136
    137                 if(_PORTLET_RESOURCE_REQUEST_CLASS != null)
    138                 {
    139                     if(_PORTLET_ACTION_REQUEST_CLASS.isInstance(request))
    140                     {
    141                         return RequestType.ACTION;
    142                     }
    143
    144                     //We are in a JSR-286 container
    145                     if(_PORTLET_RESOURCE_REQUEST_CLASS.isInstance(request))
    146                     {
    147                         return RequestType.RESOURCE;
    148                     }
    149
    150                     return RequestType.EVENT;
    151                 }
    152
    153                 return RequestType.ACTION;
    154             }
    155         }
    156
    157         return RequestType.SERVLET;
    158     }
    159
    160     /**
    161      * This method is used when a ExternalContext object is not available,
    162      * like in TomahawkFacesContextFactory.
    163      *
    164      * According to TOMAHAWK-1331, the object context could receive an
    165      * instance of javax.portlet.PortletContext or javax.portlet.PortletConfig,
    166      * so we check both cases.
    167      *
    168      * @param context
    169      * @param request
    170      * @return
    171      */
    172     public static final RequestType getRequestType(Object context, Object request)
    173     {
    174         //Stuff is laid out strangely in this class in order to optimize
    175         //performance.  We want to do as few instanceof's as possible so
    176         //things are laid out according to the expected frequency of the
    177         //various requests occurring.
    178
    179         if(_PORTLET_CONTEXT_CLASS != null)
    180         {
    181             if (_PORTLET_CONFIG_CLASS.isInstance(context) ||
    182                 _PORTLET_CONTEXT_CLASS.isInstance(context))
    183             {
    184                 //We are inside of a portlet container
    185
    186                 if(_PORTLET_RENDER_REQUEST_CLASS.isInstance(request))
    187                 {
    188                     return RequestType.RENDER;
    189                 }
    190
    191                 if(_PORTLET_RESOURCE_REQUEST_CLASS != null)
    192                 {
    193                     if(_PORTLET_ACTION_REQUEST_CLASS.isInstance(request))
    194                     {
    195                         return RequestType.ACTION;
    196                     }
    197
    198                     //We are in a JSR-286 container
    199                     if(_PORTLET_RESOURCE_REQUEST_CLASS.isInstance(request))
    200                     {
    201                         return RequestType.RESOURCE;
    202                     }
    203
    204                     return RequestType.EVENT;
    205                 }
    206
    207                 return RequestType.ACTION;
    208             }
    209         }
    210
    211         return RequestType.SERVLET;
    212     }
    213
    214     private static final Log _LOG = LogFactory.getLog(ExternalContextUtils.class);
    215
    216     private static final Class    _PORTLET_ACTION_REQUEST_CLASS;
    217     private static final Class _PORTLET_RENDER_REQUEST_CLASS;
    218     private static final Class _PORTLET_RESOURCE_REQUEST_CLASS; //Will be present in JSR-286 containers only
    219     private static final Class    _PORTLET_CONTEXT_CLASS;
    220     private static final Class    _PORTLET_CONFIG_CLASS;
    221
    222     static
    223     {
    224         Class context;
    225         Class config;
    226         Class actionRequest;
    227         Class renderRequest;
    228         Class resourceRequest;
    229         try
    230         {
    231             ClassLoader loader = Thread.currentThread().getContextClassLoader();
    232             context = loader.loadClass("javax.portlet.PortletContext");
    233             config = loader.loadClass("javax.portlet.PortletConfig");
    234             actionRequest = loader.loadClass("javax.portlet.ActionRequest");
    235             renderRequest = loader.loadClass("javax.portlet.RenderRequest");
    236
    237             try
    238             {
    239                 resourceRequest = loader.loadClass("javax.portlet.ResourceRequest");
    240             }
    241             catch (ClassNotFoundException e)
    242             {
    243                 resourceRequest = null;
    244             }
    245         }
    246         catch (ClassNotFoundException e)
    247         {
    248             context = null;
    249             config = null;
    250             actionRequest = null;
    251             renderRequest = null;
    252             resourceRequest = null;
    253         }
    254
    255         _PORTLET_CONTEXT_CLASS = context;
    256         _PORTLET_CONFIG_CLASS = config;
    257         _PORTLET_ACTION_REQUEST_CLASS = actionRequest;
    258         _PORTLET_RENDER_REQUEST_CLASS = renderRequest;
    259         _PORTLET_RESOURCE_REQUEST_CLASS = resourceRequest;
    260     }
    261 }