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 }