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.tomahawk.util;
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 tomahawk 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.1.7
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(type.isPortlet()?"getPortletInputStream":"getInputStream",new Class[]{});
101               return (InputStream) method.invoke(request,new Object[]{});
102             }
103             catch (Exception e)
104             {
105                 _LOG.error("Unable to get the request input stream because of an error", e);
106             }
107         }
108         return null;
109     }
110     
111     /**
112      * Returns the requestType of this ExternalContext.
113      * 
114      * @param externalContext the current external context
115      * @return the appropriate RequestType for this external context
116      * @see RequestType
117      */
118     public static final RequestType getRequestType(ExternalContext externalContext)
119     {
120         //Stuff is laid out strangely in this class in order to optimize
121         //performance.  We want to do as few instanceof's as possible so
122         //things are laid out according to the expected frequency of the
123         //various requests occurring.
124         if(_PORTLET_CONTEXT_CLASS != null)
125         {
126             if (_PORTLET_CONTEXT_CLASS.isInstance(externalContext.getContext()))
127             {
128                 //We are inside of a portlet container
129                 Object request = externalContext.getRequest();
130                 
131                 if(_PORTLET_RENDER_REQUEST_CLASS.isInstance(request))
132                 {
133                     return RequestType.RENDER;
134                 }
135                 
136                 if(_PORTLET_RESOURCE_REQUEST_CLASS != null)
137                 {
138                     if(_PORTLET_ACTION_REQUEST_CLASS.isInstance(request))
139                     {
140                         return RequestType.ACTION;
141                     }
142 
143                     //We are in a JSR-286 container
144                     if(_PORTLET_RESOURCE_REQUEST_CLASS.isInstance(request))
145                     {
146                         return RequestType.RESOURCE;
147                     }
148                     
149                     return RequestType.EVENT;
150                 }
151                 
152                 return RequestType.ACTION;
153             }
154         }
155         
156         return RequestType.SERVLET;
157     }
158 
159     /**
160      * This method is used when a ExternalContext object is not available,
161      * like in TomahawkFacesContextFactory.
162      * 
163      * According to TOMAHAWK-1331, the object context could receive an
164      * instance of javax.portlet.PortletContext or javax.portlet.PortletConfig,
165      * so we check both cases.
166      * 
167      * @param context
168      * @param request
169      * @return
170      */
171     public static final RequestType getRequestType(Object context, Object request)
172     {
173         //Stuff is laid out strangely in this class in order to optimize
174         //performance.  We want to do as few instanceof's as possible so
175         //things are laid out according to the expected frequency of the
176         //various requests occurring.
177 
178         if(_PORTLET_CONTEXT_CLASS != null)
179         {
180             if (_PORTLET_CONFIG_CLASS.isInstance(context) ||
181                 _PORTLET_CONTEXT_CLASS.isInstance(context))
182             {
183                 //We are inside of a portlet container
184                 
185                 if(_PORTLET_RENDER_REQUEST_CLASS.isInstance(request))
186                 {
187                     return RequestType.RENDER;
188                 }
189                 
190                 if(_PORTLET_RESOURCE_REQUEST_CLASS != null)
191                 {
192                     if(_PORTLET_ACTION_REQUEST_CLASS.isInstance(request))
193                     {
194                         return RequestType.ACTION;
195                     }
196 
197                     //We are in a JSR-286 container
198                     if(_PORTLET_RESOURCE_REQUEST_CLASS.isInstance(request))
199                     {
200                         return RequestType.RESOURCE;
201                     }
202                     
203                     return RequestType.EVENT;
204                 }
205                 
206                 return RequestType.ACTION;
207             }
208         }
209         
210         return RequestType.SERVLET;
211     }
212 
213     private static final Log _LOG = LogFactory.getLog(ExternalContextUtils.class);
214 
215     private static final Class    _PORTLET_ACTION_REQUEST_CLASS;
216     private static final Class _PORTLET_RENDER_REQUEST_CLASS;
217     private static final Class _PORTLET_RESOURCE_REQUEST_CLASS; //Will be present in JSR-286 containers only
218     private static final Class    _PORTLET_CONTEXT_CLASS;
219     private static final Class    _PORTLET_CONFIG_CLASS;
220     
221     static
222     {
223         Class context;
224         Class config;
225         Class actionRequest;
226         Class renderRequest;
227         Class resourceRequest;
228         try
229         {
230             ClassLoader loader = Thread.currentThread().getContextClassLoader();
231             context = loader.loadClass("javax.portlet.PortletContext");
232             config = loader.loadClass("javax.portlet.PortletConfig");
233             actionRequest = loader.loadClass("javax.portlet.ActionRequest");
234             renderRequest = loader.loadClass("javax.portlet.RenderRequest");
235             
236             try
237             {
238                 resourceRequest = loader.loadClass("javax.portlet.ResourceRequest");
239             }
240             catch (ClassNotFoundException e)
241             {
242                 resourceRequest = null;
243             }
244         }
245         catch (ClassNotFoundException e)
246         {
247             context = null;
248             config = null;
249             actionRequest = null;
250             renderRequest = null;
251             resourceRequest = null;
252         }
253 
254         _PORTLET_CONTEXT_CLASS = context;
255         _PORTLET_CONFIG_CLASS = config;
256         _PORTLET_ACTION_REQUEST_CLASS = actionRequest;
257         _PORTLET_RENDER_REQUEST_CLASS = renderRequest;
258         _PORTLET_RESOURCE_REQUEST_CLASS = resourceRequest;
259     }    
260 }