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.commons.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   * This provides some functionality for determining some things about the
32   * native request object that is not provided by JSF.  This class is useful
33   * for use in places where Portlet API's may or may not be present and can
34   * also provide access to some request-specific items which are not available on
35   * the JSF ExternalContext.  If portlet API's are not present, this class simply 
36   * handles the Servlet Request type.
37   */
38  public final class ExternalContextUtils
39  {
40      // prevent this from being instantiated
41      private ExternalContextUtils()
42      {
43      }
44  
45      /**
46       * Returns the content length or -1 if the unknown.
47       *
48       * @param externalContext
49       *          the ExternalContext
50       * @return the length or -1
51       */
52      public static final int getContentLength(ExternalContext externalContext)
53      {
54          RequestType type = getRequestType(externalContext);
55          
56          if(type.isRequestFromClient())
57          {
58              try
59              {
60                  Object request = externalContext.getRequest();
61                  Method contentLenMethod = request.getClass().getMethod("getContentLength");
62                  return (Integer) contentLenMethod.invoke(request); //this will autobox
63              }
64              catch(Exception e)
65              {
66                  _LOG.error("Unsupported request type.", e);
67              }
68          }
69              
70          return -1;
71      }
72  
73      /**
74       * Returns the request input stream if one is available
75       *
76       * @param externalContext
77       * @return
78       * @throws IOException
79       */
80      public static final InputStream getRequestInputStream(ExternalContext externalContext)
81              throws IOException
82      {
83          RequestType type = getRequestType(externalContext);
84          
85          if(type.isRequestFromClient())
86          {
87            try
88              {
89                Object request = externalContext.getRequest();
90                
91                Method method = request.getClass().getMethod(type.isPortlet()?"getPortletInputStream":"getInputStream");
92                return (InputStream) method.invoke(request);
93              }
94              catch (Exception e)
95              {
96                  _LOG.error("Unable to get the request input stream because of an error", e);
97              }
98          }
99          return null;
100     }
101     
102     /**
103      * Returns the requestType of this ExternalContext.
104      * 
105      * @param externalContext the current external context
106      * @return the appropriate RequestType for this external context
107      * @see RequestType
108      */
109     public static final RequestType getRequestType(ExternalContext externalContext)
110     {
111         //Stuff is laid out strangely in this class in order to optimize
112         //performance.  We want to do as few instanceof's as possible so
113         //things are laid out according to the expected frequency of the
114         //various requests occurring.
115         if(_PORTLET_CONTEXT_CLASS != null)
116         {
117             if (_PORTLET_CONTEXT_CLASS.isInstance(externalContext.getContext()))
118             {
119                 //We are inside of a portlet container
120                 Object request = externalContext.getRequest();
121                 
122                 if(_PORTLET_RENDER_REQUEST_CLASS.isInstance(request))
123                 {
124                     return RequestType.RENDER;
125                 }
126                 
127                 if(_PORTLET_RESOURCE_REQUEST_CLASS != null)
128                 {
129                     if(_PORTLET_ACTION_REQUEST_CLASS.isInstance(request))
130                     {
131                         return RequestType.ACTION;
132                     }
133 
134                     //We are in a JSR-286 container
135                     if(_PORTLET_RESOURCE_REQUEST_CLASS.isInstance(request))
136                     {
137                         return RequestType.RESOURCE;
138                     }
139                     
140                     return RequestType.EVENT;
141                 }
142                 
143                 return RequestType.ACTION;
144             }
145         }
146         
147         return RequestType.SERVLET;
148     }
149 
150   private static final Log _LOG = LogFactory.getLog(TagUtils.class);
151 
152     private static final Class<?>    _PORTLET_ACTION_REQUEST_CLASS;
153     private static final Class<?> _PORTLET_RENDER_REQUEST_CLASS;
154     private static final Class<?> _PORTLET_RESOURCE_REQUEST_CLASS; //Will be present in JSR-286 containers only
155     private static final Class<?>    _PORTLET_CONTEXT_CLASS;
156     
157     static
158     {
159         Class<?> context;
160         Class<?> actionRequest;
161         Class<?> renderRequest;
162         Class<?> resourceRequest;
163         try
164         {
165             ClassLoader loader = Thread.currentThread().getContextClassLoader();
166             context = loader.loadClass("javax.portlet.PortletContext");
167             actionRequest = loader.loadClass("javax.portlet.ActionRequest");
168             renderRequest = loader.loadClass("javax.portlet.RenderRequest");
169             
170             try
171             {
172                 resourceRequest = loader.loadClass("javax.portlet.ResourceRequest");
173             }
174             catch (ClassNotFoundException e)
175             {
176                 resourceRequest = null;
177             }
178         }
179         catch (ClassNotFoundException e)
180         {
181             context = null;
182             actionRequest = null;
183             renderRequest = null;
184             resourceRequest = null;
185         }
186 
187         _PORTLET_CONTEXT_CLASS = context;
188         _PORTLET_ACTION_REQUEST_CLASS = actionRequest;
189         _PORTLET_RENDER_REQUEST_CLASS = renderRequest;
190         _PORTLET_RESOURCE_REQUEST_CLASS = resourceRequest;
191     }    
192 }