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.trinidad.util;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  
24  import javax.faces.context.ExternalContext;
25  import javax.portlet.ActionRequest;
26  import javax.servlet.ServletRequest;
27  
28  import org.apache.myfaces.trinidad.logging.TrinidadLogger;
29  
30  /**
31   * This provides some functionality for determining some things about the
32   * native request object that is not provided by the base utils.
33   *
34   * @version $Revision$ $Date$
35   */
36  public final class ExternalContextUtils
37  {
38    /**
39     * Returns the character encoding or null if there isn't any
40     *
41     * @param externalContext
42     * @return
43     */
44    public static String getCharacterEncoding(final ExternalContext externalContext)
45    {
46      if (isAction(externalContext))
47      {
48        try
49        {
50          if (isPortlet(externalContext))
51          {
52            // Allows us to not have the portal api's in the classpath
53            return _getPortletCharacterEncoding(externalContext.getRequest());
54          }
55          else
56          {
57            return ((ServletRequest) externalContext.getRequest()).getCharacterEncoding();
58          }
59        }
60        catch (final ClassCastException e)
61        {
62          _LOG.severe(e);
63        }
64      }
65  
66      return null;
67    }
68  
69    /**
70     * Returns the content length or -1 if the unknown.
71     *
72     * @param externalContext
73     *          the ExternalContext
74     * @return the length or -1
75     */
76    public static int getContentLength(final ExternalContext externalContext)
77    {
78      if (isAction(externalContext))
79      {
80        try
81        {
82          if (isPortlet(externalContext))
83          {
84            // Allows us to not have the portal api's in the classpath
85            _getPortletContentLength(externalContext.getRequest());
86          }
87          else
88          {
89            return ((ServletRequest) externalContext.getRequest()).getContentLength();
90          }
91        }
92        catch (final ClassCastException e)
93        {
94          _LOG.severe(e);
95        }
96      }
97      return -1;
98    }
99  
100   /**
101    * Returns the content type from the current externalContext or <code>null</code> if unknown.
102    *
103    * @param externalContext
104    *          the ExternalContext
105    * @return the content type or <code>null</code>
106    */
107   public static String getContentType(final ExternalContext externalContext)
108   {
109     if (isAction(externalContext))
110     {
111       try
112       {
113         if (isPortlet(externalContext))
114         {
115           // Allows us to not have the portal api's in the classpath
116           return _getPortletContentType(externalContext.getRequest());
117         }
118         else
119         {
120           return ((ServletRequest) externalContext.getRequest()).getContentType();
121         }
122       }
123       catch (final ClassCastException e)
124       {
125         // probably won't happen, but it could if we don't have a portlet OR a servlet container.
126         _LOG.severe(e);
127       }
128     }
129     return null;
130   }
131 
132   /**
133    * Returns the request input stream if one is available
134    *
135    * @param externalContext
136    * @return
137    * @throws IOException
138    */
139   public static InputStream getRequestInputStream(final ExternalContext externalContext)
140       throws IOException
141   {
142     if (isAction(externalContext))
143     {
144       try
145       {
146         if (isPortlet(externalContext))
147         {
148           // Allows us to not have the portal api's in the classpath
149           return _getPortletInputStream(externalContext.getRequest());
150         }
151         else
152         {
153           return ((ServletRequest) externalContext.getRequest()).getInputStream();
154         }
155       }
156       catch (final ClassCastException e)
157       {
158         _LOG.severe(e);
159       }
160     }
161     return null;
162   }
163 
164   /**
165    * Returns <code>true</code> if this externalContext represents an "action". An action request
166    * is any ServletRequest or a portlet ActionRequest. It is assumed that the ExternalContext
167    *
168    * @return a boolean of <code>true</code> if this is a Portlet ActionRequest or an non-portlet
169    *         request.
170    */
171   public static boolean isAction(final ExternalContext externalContext)
172   {
173     final Object request = externalContext.getRequest();
174 
175     if (_PORTLET_ACTION_REQUEST_CLASS == null)
176     {
177       _LOG
178           .fine("Portlet API's are not on the classpath so isAction will only check for servlet request.");
179       return request instanceof ServletRequest;
180     }
181 
182     return request instanceof ServletRequest || _PORTLET_ACTION_REQUEST_CLASS.isInstance(request);
183   }
184 
185   /**
186    * Returns whether or not this external context is from a Portlet or a Servlet.
187    *
188    * @param externalContext
189    *          the ExternalContext to check
190    *
191    * @return <code>true</code> if this is a portlet RenderRequest or ActionRequest and
192    *         <code>false<code> if it is not.
193    */
194   public static boolean isPortlet(final ExternalContext externalContext)
195   {
196     if (_PORTLET_CONTEXT_CLASS == null)
197     {
198       _LOG.fine("Portlet API's are not on the classpath therefore isPortlet is false.");
199       return false;
200     }
201 
202     return _PORTLET_CONTEXT_CLASS.isInstance(externalContext.getContext());
203   }
204 
205   private static final String _getPortletCharacterEncoding(final Object request)
206   {
207     if (!(request instanceof ActionRequest))
208       return null;
209 
210     return ((ActionRequest) request).getCharacterEncoding();
211   }
212 
213   private static final int _getPortletContentLength(final Object request)
214   {
215     if (!(request instanceof ActionRequest))
216       return -1;
217 
218     return ((ActionRequest) request).getContentLength();
219   }
220 
221   private static final String _getPortletContentType(final Object request)
222   {
223     if (!(request instanceof ActionRequest))
224       return null;
225 
226     return ((ActionRequest) request).getContentType();
227   }
228 
229   private static final InputStream _getPortletInputStream(final Object request) throws IOException
230   {
231     return ((ActionRequest) request).getPortletInputStream();
232   }
233 
234   // prevent this from being instantiated
235   private ExternalContextUtils()
236   {}
237 
238   private static final TrinidadLogger _LOG = TrinidadLogger
239                                                .createTrinidadLogger(ExternalContextUtils.class);
240 
241   // =-= Scott O'Bryan =-=
242   // Performance enhancement. These will be needed anyway, let's not get them every time.
243   private static final Class<?>       _PORTLET_ACTION_REQUEST_CLASS;
244   private static final Class<?>       _PORTLET_CONTEXT_CLASS;
245 
246   static
247   {
248     Class<?> context;
249     Class<?> actionRequest;
250     try
251     {
252       context = ClassLoaderUtils.loadClass("javax.portlet.PortletContext");
253       actionRequest = ClassLoaderUtils.loadClass("javax.portlet.ActionRequest");
254     }
255     catch (final ClassNotFoundException e)
256     {
257       _LOG
258           .fine("Portlet API is not available on the classpath.  Portlet configurations are disabled.");
259       context = null;
260       actionRequest = null;
261     }
262 
263     _PORTLET_CONTEXT_CLASS = context;
264     _PORTLET_ACTION_REQUEST_CLASS = actionRequest;
265   }
266 }