1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.profiler.impl;
18
19 import java.io.IOException;
20 import java.security.Principal;
21 import java.util.HashMap;
22 import java.util.Map;
23
24 import javax.security.auth.Subject;
25 import javax.servlet.http.HttpServletResponse;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.jetspeed.PortalReservedParameters;
30 import org.apache.jetspeed.decoration.PageActionAccess;
31 import org.apache.jetspeed.om.page.ContentPageImpl;
32 import org.apache.jetspeed.om.page.Page;
33 import org.apache.jetspeed.page.document.NodeNotFoundException;
34 import org.apache.jetspeed.pipeline.PipelineException;
35 import org.apache.jetspeed.pipeline.valve.AbstractValve;
36 import org.apache.jetspeed.pipeline.valve.PageProfilerValve;
37 import org.apache.jetspeed.pipeline.valve.ValveContext;
38 import org.apache.jetspeed.portalsite.PortalSite;
39 import org.apache.jetspeed.portalsite.PortalSiteRequestContext;
40 import org.apache.jetspeed.portalsite.PortalSiteSessionContext;
41 import org.apache.jetspeed.profiler.ProfileLocator;
42 import org.apache.jetspeed.profiler.Profiler;
43 import org.apache.jetspeed.profiler.ProfilerException;
44 import org.apache.jetspeed.request.RequestContext;
45 import org.apache.jetspeed.security.SecurityHelper;
46 import org.apache.jetspeed.security.UserPrincipal;
47
48 /***
49 * ProfilerValveImpl
50 *
51 * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
52 * @version $Id: ProfilerValveImpl.java 569464 2007-08-24 17:43:28Z taylor $
53 */
54 public class ProfilerValveImpl extends AbstractValve implements PageProfilerValve
55 {
56 protected Log log = LogFactory.getLog(ProfilerValveImpl.class);
57
58 /***
59 * PORTAL_SITE_REQUEST_CONTEXT_ATTR_KEY - session portal site context attribute key
60 */
61 public static final String PORTAL_SITE_SESSION_CONTEXT_ATTR_KEY = "org.apache.jetspeed.portalsite.PortalSiteSessionContext";
62
63 /***
64 * PORTAL_SITE_REQUEST_CONTEXT_ATTR_KEY - request portal site context attribute key
65 */
66 public static final String PORTAL_SITE_REQUEST_CONTEXT_ATTR_KEY = "org.apache.jetspeed.portalsite.PortalSiteRequestContext";
67
68 /***
69 * PROFILED_PAGE_CONTEXT_ATTR_KEY - legacy request portal site context attribute key
70 */
71 public static final String PROFILED_PAGE_CONTEXT_ATTR_KEY = "org.apache.jetspeed.profiledPageContext";
72
73 /***
74 * session key for storing map of PageActionAccess instances
75 */
76 private static final String PAGE_ACTION_ACCESS_MAP_SESSION_ATTR_KEY = "org.apache.jetspeed.profiler.pageActionAccessMap";
77
78 /***
79 * profiler - profiler component
80 */
81 private Profiler profiler;
82
83 /***
84 * portalSite - portal site component
85 */
86 private PortalSite portalSite;
87
88 /***
89 * requestFallback - flag indicating whether request should fallback to root folder
90 * if locators do not select a page or access is forbidden
91 */
92 private boolean requestFallback;
93
94 /***
95 * useHistory - flag indicating whether to use visited page
96 * history to select default page per site folder
97 */
98 private boolean useHistory;
99
100 /***
101 * ProfilerValveImpl - constructor
102 *
103 * @param profiler profiler component reference
104 * @param portalSite portal site component reference
105 * @param requestFallback flag to enable root folder fallback
106 * @param useHistory flag to enable selection of last visited folder page
107 */
108 public ProfilerValveImpl( Profiler profiler, PortalSite portalSite,
109 boolean requestFallback, boolean useHistory)
110 {
111 this.profiler = profiler;
112 this.portalSite = portalSite;
113 this.requestFallback = requestFallback;
114 this.useHistory = useHistory;
115 }
116
117 /***
118 * ProfilerValveImpl - constructor
119 *
120 * @param profiler profiler component reference
121 * @param portalSite portal site component reference
122 * @param requestFallback flag to enable root folder fallback
123 */
124 public ProfilerValveImpl(Profiler profiler, PortalSite portalSite,
125 boolean requestFallback)
126 {
127 this(profiler, portalSite, requestFallback, true);
128 }
129
130 /***
131 * ProfilerValveImpl - constructor
132 *
133 * @param profiler profiler component reference
134 * @param portalSite portal site component reference
135 */
136 public ProfilerValveImpl(Profiler profiler, PortalSite portalSite)
137 {
138 this(profiler, portalSite, true, true);
139 }
140
141
142
143
144
145
146
147 public void invoke( RequestContext request, ValveContext context ) throws PipelineException
148 {
149 try
150 {
151
152 Subject subject = request.getSubject();
153 if (subject == null)
154 {
155 throw new ProfilerException("Missing subject for request: " + request.getPath());
156 }
157 Principal principal = SecurityHelper.getBestPrincipal(subject, UserPrincipal.class);
158 if (principal == null)
159 {
160 throw new ProfilerException("Missing principal for request: " + request.getPath());
161 }
162
163
164 Map locators = null;
165 String locatorName = (String)request.getAttribute(PROFILE_LOCATOR_REQUEST_ATTR_KEY);
166 if ( locatorName != null )
167 {
168 ProfileLocator locator = profiler.getProfile(request,locatorName);
169 if ( locator != null )
170 {
171 locators = new HashMap();
172 locators.put(ProfileLocator.PAGE_LOCATOR, locator);
173 }
174 }
175
176
177
178
179 if ( locators == null )
180 {
181 locators = profiler.getProfileLocators(request, principal);
182 }
183 if (locators.size() == 0)
184 {
185 locators = profiler.getDefaultProfileLocators(request);
186 }
187 if (locators.size() == 0)
188 {
189 locators.put(ProfileLocator.PAGE_LOCATOR, profiler.getProfile(request, ProfileLocator.PAGE_LOCATOR));
190 }
191
192
193
194 if (locators != null)
195 {
196
197
198
199
200
201
202
203
204
205
206 PortalSiteSessionContext sessionContext = (PortalSiteSessionContext)request.getSessionAttribute(PORTAL_SITE_SESSION_CONTEXT_ATTR_KEY);
207 String pipeline = request.getPipeline().getName();
208 if ((sessionContext == null) || !sessionContext.isValid() || hasPipelineChanged(pipeline, sessionContext.getPipeline()))
209 {
210 sessionContext = portalSite.newSessionContext();
211 sessionContext.setPipeline(pipeline);
212 request.setSessionAttribute(PORTAL_SITE_SESSION_CONTEXT_ATTR_KEY, sessionContext);
213 }
214
215
216
217
218
219
220
221
222
223
224
225 PortalSiteRequestContext requestContext = sessionContext.newRequestContext(locators, requestFallback, useHistory);
226 request.setAttribute(PORTAL_SITE_REQUEST_CONTEXT_ATTR_KEY, requestContext);
227
228
229
230 request.setAttribute(PROFILED_PAGE_CONTEXT_ATTR_KEY, requestContext);
231
232
233
234
235
236
237
238
239
240
241 request.setPage(new ContentPageImpl(requestContext.getManagedPage()));
242 request.setProfileLocators(requestContext.getLocators());
243
244 request.setAttribute(PortalReservedParameters.PAGE_EDIT_ACCESS_ATTRIBUTE,getPageActionAccess(request));
245 }
246
247
248 context.invokeNext(request);
249 }
250 catch (SecurityException se)
251 {
252
253
254
255
256
257
258 if (request.getRequest().getUserPrincipal() == null &&
259 request.getPath() != null &&
260 !request.getPath().equals("/"))
261 {
262 try
263 {
264 request.getResponse().sendRedirect(request.getRequest().getContextPath());
265 }
266 catch (IOException ioe){}
267 return;
268 }
269
270
271 log.error(se.getMessage(), se);
272 try
273 {
274 request.getResponse().sendError(HttpServletResponse.SC_FORBIDDEN, se.getMessage());
275 }
276 catch (IOException ioe)
277 {
278 log.error("Failed to invoke HttpServletReponse.sendError: " + ioe.getMessage(), ioe);
279 }
280 }
281 catch (NodeNotFoundException nnfe)
282 {
283
284 log.error(nnfe.getMessage(), nnfe);
285 try
286 {
287 request.getResponse().sendError(HttpServletResponse.SC_NOT_FOUND, nnfe.getMessage());
288 }
289 catch (IOException ioe)
290 {
291 log.error("Failed to invoke HttpServletReponse.sendError: " + ioe.getMessage(), ioe);
292 }
293 }
294 catch (Exception e)
295 {
296 log.error("Exception in request pipeline: " + e.getMessage(), e);
297 throw new PipelineException(e.toString(), e);
298 }
299 }
300
301 protected boolean hasPipelineChanged(String requestPipeline, String sessionPipeline)
302 {
303 if (!requestPipeline.equals(sessionPipeline))
304 {
305 if (requestPipeline.equals(PortalReservedParameters.JETSPEED_CONFIG_PIPELINE_NAME)
306 || sessionPipeline.equals(PortalReservedParameters.JETSPEED_CONFIG_PIPELINE_NAME))
307 return true;
308 }
309 return false;
310 }
311
312 /***
313 * Returns the <code>PageActionAccess</code> for the current user request.
314 * @see PageActionAccess
315 * @param requestContext RequestContext of the current portal request.
316 * @return PageActionAccess for the current user request.
317 */
318 protected PageActionAccess getPageActionAccess(RequestContext requestContext)
319 {
320 Page page = requestContext.getPage();
321 String key = page.getId();
322 boolean loggedOn = requestContext.getRequest().getUserPrincipal() != null;
323 boolean anonymous = !loggedOn;
324 PageActionAccess pageActionAccess = null;
325
326 Map sessionActions = null;
327 synchronized (this)
328 {
329 sessionActions = (Map) requestContext.getSessionAttribute(PAGE_ACTION_ACCESS_MAP_SESSION_ATTR_KEY);
330 if (sessionActions == null)
331 {
332 sessionActions = new HashMap();
333 requestContext.setSessionAttribute(PAGE_ACTION_ACCESS_MAP_SESSION_ATTR_KEY, sessionActions);
334 }
335 else
336 {
337 pageActionAccess = (PageActionAccess) sessionActions.get(key);
338 }
339 }
340 synchronized (sessionActions)
341 {
342 if (pageActionAccess == null)
343 {
344 pageActionAccess = new PageActionAccess(anonymous, page);
345 sessionActions.put(key, pageActionAccess);
346 }
347 else
348 {
349 pageActionAccess.checkReset(anonymous, page);
350 }
351 }
352
353 return pageActionAccess;
354 }
355
356 public String toString()
357 {
358 return "ProfilerValve";
359 }
360
361 }