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 }