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 }