001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: * $Header:$
018: */
019: package org.apache.beehive.netui.pageflow.internal;
020:
021: import org.apache.beehive.netui.util.internal.InternalStringBuilder;
022:
023: import org.apache.struts.action.ActionForward;
024: import org.apache.struts.action.ActionMapping;
025: import org.apache.struts.action.ActionForm;
026: import org.apache.struts.config.ModuleConfig;
027: import org.apache.struts.config.ExceptionConfig;
028:
029: import org.apache.beehive.netui.pageflow.interceptor.action.ActionInterceptor;
030: import org.apache.beehive.netui.pageflow.interceptor.action.AfterNestedInterceptContext;
031: import org.apache.beehive.netui.pageflow.interceptor.action.InterceptorForward;
032: import org.apache.beehive.netui.pageflow.*;
033: import org.apache.beehive.netui.pageflow.config.PageFlowExceptionConfig;
034: import org.apache.beehive.netui.pageflow.config.PageFlowActionMapping;
035: import org.apache.beehive.netui.pageflow.handler.FlowControllerHandlerContext;
036: import org.apache.beehive.netui.pageflow.handler.ActionForwardHandler;
037: import org.apache.beehive.netui.util.logging.Logger;
038: import org.apache.beehive.netui.script.common.ImplicitObjectUtil;
039:
040: import javax.servlet.http.HttpServletRequest;
041: import javax.servlet.http.HttpServletResponse;
042: import javax.servlet.ServletContext;
043:
044: public class DefaultActionForwardHandler extends DefaultHandler
045: implements ActionForwardHandler {
046: private static final Logger _log = Logger
047: .getInstance(DefaultActionForwardHandler.class);
048:
049: public DefaultActionForwardHandler(ServletContext servletContext) {
050: init(null, null, servletContext);
051: }
052:
053: public ActionForward processForward(
054: FlowControllerHandlerContext context, ActionForward fwd,
055: ActionMapping mapping, ExceptionConfig exceptionConfig,
056: String actionName, ModuleConfig altModuleConfig,
057: ActionForm form) {
058: boolean isSpecialForward = false;
059: boolean isReturnToCurrentPage = false;
060: boolean isNonInheritedGlobalForward = false;
061: assert context.getRequest() instanceof HttpServletRequest : "don't support ServletRequest currently.";
062: HttpServletRequest request = (HttpServletRequest) context
063: .getRequest();
064: FlowController flowController = context.getFlowController();
065:
066: //
067: // There is a special forward ("auto"), which signals us to render using a registered ViewRenderer.
068: // This is used as part of popup window support.
069: //
070: if (fwd != null
071: && PageFlowConstants.AUTO_VIEW_RENDER_FORWARD_NAME
072: .equals(fwd.getName())) {
073: return getRegisteredActionForwardHandler()
074: .doAutoViewRender(context, mapping, form);
075: }
076:
077: if (fwd != null && fwd instanceof Forward) {
078: Forward pageFlowFwd = (Forward) fwd;
079:
080: pageFlowFwd.initialize(mapping, flowController, request);
081: pageFlowFwd.setAlternateModuleConfig(altModuleConfig);
082:
083: if (!pageFlowFwd.doesResolve()) {
084: PageFlowException ex = new UnresolvableForwardException(
085: pageFlowFwd.getName(), actionName,
086: flowController);
087: InternalUtils.throwPageFlowException(ex, request);
088: }
089:
090: //
091: // If it's a return-to-page, do what's necessary to return to the previous page,
092: // with its state intact.
093: //
094: if (pageFlowFwd.isReturnToPage()) {
095: isSpecialForward = true;
096:
097: //
098: // We need access to _previousPageInfo from the *current PageFlow*. That is
099: // most likely this FlowController, but if it's Global.app, then we don't want
100: // to use that.
101: //
102: PageFlowController curJpf = PageFlowUtils
103: .getCurrentPageFlow(request,
104: getServletContext());
105:
106: if (curJpf == null) {
107: PageFlowException ex = new NoCurrentPageFlowException(
108: actionName, pageFlowFwd);
109: InternalUtils.throwPageFlowException(ex, request);
110: assert false; // throwPageFlowException() must throw.
111: }
112:
113: PreviousPageInfo prevPageInfo;
114:
115: switch (pageFlowFwd.getReturnToType()) {
116: case Forward.RETURN_TO_CURRENT_PAGE:
117: prevPageInfo = curJpf.theCurrentPageInfo();
118: isReturnToCurrentPage = true;
119: break;
120:
121: case Forward.RETURN_TO_PREVIOUS_PAGE:
122: prevPageInfo = curJpf.thePreviousPageInfo();
123: break;
124:
125: case Forward.RETURN_TO_PAGE:
126: prevPageInfo = flowController
127: .getPreviousPageInfoLegacy(curJpf, request);
128: break;
129:
130: default:
131: assert false : pageFlowFwd.getReturnToType();
132: prevPageInfo = curJpf.theCurrentPageInfo();
133: }
134:
135: fwd = getRegisteredActionForwardHandler()
136: .doReturnToPage(context, prevPageInfo, curJpf,
137: form, actionName, pageFlowFwd);
138:
139: if (prevPageInfo != null) {
140: mapping = prevPageInfo.getMapping();
141: if (form == null)
142: form = prevPageInfo.getForm();
143: }
144:
145: if (_log.isDebugEnabled()) {
146: _log.debug("return-to-page: "
147: + (fwd != null ? fwd.getPath() : "[null]"));
148: }
149: } else if (pageFlowFwd.isReturnToAction()) {
150: isSpecialForward = true;
151: fwd = getRegisteredActionForwardHandler()
152: .doReturnToAction(context, actionName,
153: pageFlowFwd);
154: } else if (pageFlowFwd.isNestedReturn()) {
155: //
156: // Pop the current PageFlowController (done nesting).
157: //
158: isSpecialForward = true;
159: fwd = getRegisteredActionForwardHandler()
160: .doNestingReturn(context, pageFlowFwd, mapping,
161: form);
162: }
163:
164: //
165: // Set ActionForms specified in the Forward. Note that this overwrites any forms restored
166: // during return-to="page".
167: //
168: PageFlowUtils.setOutputForms(mapping, pageFlowFwd, request);
169: InternalUtils.addActionOutputs(pageFlowFwd
170: .getActionOutputs(), request, true);
171:
172: // Check if this is a non-inherited global forward to help determine
173: // if we need to ensure we use a path local to the current page flow.
174: if (mapping != null
175: && mapping.findForwardConfig(pageFlowFwd.getName()) == null
176: && mapping.getModuleConfig().findForwardConfig(
177: pageFlowFwd.getName()) != null
178: && !pageFlowFwd.hasRelativeToPath()) {
179: isNonInheritedGlobalForward = true;
180: }
181: }
182:
183: if (fwd != null) {
184: // It's a normal path. Let the Forward object do some magic if we're specifying that it's relative
185: // to a particular directory path (as is the case when inheriting local paths from base classes).
186: // Note that if *either* the exception-config or the action-config specifies a value for
187: // getLocalPathsRelativeTo(), we use it. Also note that we do not do this for forward to other actions
188: // or if this is a non-inherited global forward; in those cases we always want paths to be local
189: // to the current page flow.
190: String localPathsRelativeTo = null;
191: if (exceptionConfig != null
192: && exceptionConfig instanceof PageFlowExceptionConfig) {
193: localPathsRelativeTo = ((PageFlowExceptionConfig) exceptionConfig)
194: .getLocalPathsRelativeTo();
195: }
196: if (localPathsRelativeTo == null
197: && mapping instanceof PageFlowActionMapping) {
198: localPathsRelativeTo = ((PageFlowActionMapping) mapping)
199: .getLocalPathsRelativeTo();
200: }
201: if (localPathsRelativeTo != null) {
202: String path = fwd.getPath();
203: if (!path.endsWith(PageFlowConstants.ACTION_EXTENSION)
204: && !isNonInheritedGlobalForward) {
205: Forward pageFlowFwd = fwd instanceof Forward ? (Forward) fwd
206: : new WrapperForward(fwd);
207: pageFlowFwd.initializeRelativePath(request,
208: localPathsRelativeTo);
209: fwd = pageFlowFwd;
210: }
211: } else if (fwd instanceof Forward) {
212: ((Forward) fwd).initializeRelativePath(request, null);
213: }
214:
215: if (_log.isDebugEnabled()) {
216: if (fwd.getRedirect()) {
217: _log.debug("Redirecting to " + fwd.getPath());
218: } else {
219: _log.debug("Forwarding to " + fwd.getPath());
220: }
221: }
222: } else {
223: _log
224: .debug("null ActionForward -- not doing any forward or redirect.");
225: }
226:
227: //
228: // Save info on this forward for return-to="currentPage" or return-to="previousPage".
229: // However, don't save the current forward as previous if this is a
230: // return-to="currentPage" -- we don't want this to turn into the page
231: // that's seen for *both* return-to="currentPage" and return-to="previousPage".
232: // Just set the request attribute indicating that prev page info state was saved.
233: //
234: if (!isReturnToCurrentPage) {
235: flowController.savePreviousPageInfo(fwd, form, mapping,
236: request, getServletContext(), isSpecialForward);
237: } else {
238: request.setAttribute(
239: InternalConstants.SAVED_PREVIOUS_PAGE_INFO_ATTR,
240: Boolean.TRUE);
241: }
242:
243: return fwd;
244: }
245:
246: private class WrapperForward extends Forward {
247: public WrapperForward(ActionForward base) {
248: super (base, getServletContext());
249: }
250: }
251:
252: public ActionForward doAutoViewRender(
253: FlowControllerHandlerContext context,
254: ActionMapping mapping, ActionForm form) {
255: assert context.getRequest() instanceof HttpServletRequest : "don't support ServletRequest currently.";
256: assert context.getResponse() instanceof HttpServletResponse : "don't support ServletResponse currently.";
257: HttpServletRequest request = (HttpServletRequest) context
258: .getRequest();
259: HttpServletResponse response = (HttpServletResponse) context
260: .getResponse();
261: ViewRenderer vr = PageFlowRequestWrapper.get(request)
262: .getViewRenderer();
263:
264: if (vr != null) {
265: _log.debug("ActionForward -- delegating to ViewRenderer "
266: + vr + " to handle response.");
267:
268: try {
269: request.setAttribute(
270: PageFlowConstants.VIEW_RENDERER_ATTRIBUTE_NAME,
271: vr);
272:
273: String ext = getServletContext()
274: .getInitParameter(
275: PageFlowConstants.VIEW_RENDERING_EXTENSION_PARAM);
276: if (ext == null || ext.length() == 0) {
277: ext = PageFlowConstants.DEFAULT_VIEW_RENDERING_EXTENSION;
278: }
279:
280: InternalStringBuilder path = new InternalStringBuilder(
281: 64);
282: path.append("/");
283: path
284: .append(PageFlowConstants.VIEW_RENDERER_URI_COMMAND);
285: path.append(".").append(ext);
286:
287: ActionForward fwd = new ActionForward(path.toString(),
288: false);
289: fwd.setContextRelative(true);
290: return fwd;
291: } catch (Throwable th) {
292: try {
293: return context.getFlowController().handleException(
294: th, mapping, form, request, response);
295: } catch (Exception e) {
296: _log.error(
297: "Exception thrown while handling exception in ViewRenderer "
298: + vr + ": " + e.getMessage(), th);
299: }
300: }
301:
302: } else {
303: _log
304: .error("Auto-render forward "
305: + PageFlowConstants.AUTO_VIEW_RENDER_FORWARD_NAME
306: + " used, but no ViewRenderer "
307: + "was registered -- not doing any forward or redirect.");
308: }
309:
310: return null;
311: }
312:
313: /**
314: * Get an ActionForward to the original page that was visible before the previous action.
315: */
316: public ActionForward doReturnToPage(
317: FlowControllerHandlerContext context,
318: PreviousPageInfo prevPageInfo,
319: PageFlowController currentPageFlow, ActionForm currentForm,
320: String actionName, Forward pageFlowFwd) {
321: assert context.getRequest() instanceof HttpServletRequest : "don't support ServletRequest currently.";
322: HttpServletRequest request = (HttpServletRequest) context
323: .getRequest();
324:
325: if (prevPageInfo == null) {
326: if (_log.isInfoEnabled()) {
327: _log
328: .info("Attempted return-to-page, but previous page info was missing.");
329: }
330:
331: PageFlowException ex = new NoPreviousPageException(
332: actionName, pageFlowFwd, currentPageFlow);
333: InternalUtils.throwPageFlowException(ex, request);
334: }
335:
336: //
337: // Figure out what URI to return to, and set the original form in the request or session.
338: //
339: ActionForward retFwd = prevPageInfo.getForward();
340: ActionMapping prevMapping = prevPageInfo.getMapping();
341:
342: //
343: // Restore any forms that are specified by this Forward (overwrite the original forms).
344: //
345: if (retFwd instanceof Forward) {
346: PageFlowUtils.setOutputForms(prevMapping, (Forward) retFwd,
347: request, false);
348: InternalUtils.addActionOutputs(((Forward) retFwd)
349: .getActionOutputs(), request, false);
350: }
351:
352: //
353: // If the user hit the previous page directly (without going through an action), prevMapping will be null.
354: //
355: if (prevMapping != null) {
356: //
357: // If the currently-posted form is of the right type, initialize the page with that (but we don't overwrite
358: // the form that was set above).
359: //
360: if (currentForm != null)
361: PageFlowUtils.setOutputForm(prevMapping, currentForm,
362: request, false);
363:
364: //
365: // Initialize the page with the original form it got forwarded (but we don't overwrite the form that was
366: // set above).
367: //
368: InternalUtils
369: .setFormInScope(prevMapping.getName(), prevPageInfo
370: .getForm(), prevMapping, request, false);
371: }
372:
373: //
374: // If we're forwarding to a page in a different pageflow, we need to make sure the returned ActionForward has
375: // the right module path, and that it has contextRelative=true.
376: //
377: FlowController flowController = context.getFlowController();
378:
379: if (!retFwd.getContextRelative()
380: && flowController != currentPageFlow) {
381:
382: retFwd = new ActionForward(retFwd.getName(),
383: currentPageFlow.getModulePath() + retFwd.getPath(),
384: retFwd.getRedirect(), true);
385:
386: }
387:
388: if (_log.isDebugEnabled()) {
389: _log.debug("Return-to-page in PageFlowController "
390: + flowController.getClass().getName()
391: + ": original URI " + retFwd.getPath());
392: }
393:
394: if (retFwd != null) {
395: //
396: // If the new (return-to) Forward specifies a redirect value explicitly, use that; otherwise
397: // use the redirect value from the original Forward.
398: //
399: if (pageFlowFwd.hasExplicitRedirectValue())
400: retFwd.setRedirect(pageFlowFwd.getRedirect());
401:
402: //
403: // If there's a query string, override the previous query string.
404: //
405: String fwdPath = retFwd.getPath();
406: String newQueryString = pageFlowFwd.getQueryString();
407: int existingQueryPos = fwdPath.indexOf('?');
408:
409: //
410: // If the new Forward (the one with Jpf.NavigateTo.currentPage/previousPage) has a query string, use that.
411: // Otherwise, if the old Forward has no query string, restore the one from the PreviousPageInfo if
412: // appropriate.
413: //
414: if (newQueryString != null) {
415: // Chop off the old query string if necessary.
416: if (existingQueryPos != -1)
417: fwdPath = fwdPath.substring(0, existingQueryPos);
418: retFwd.setPath(fwdPath + newQueryString);
419: } else if (existingQueryPos == -1) {
420: retFwd.setPath(fwdPath
421: + getQueryString(pageFlowFwd, prevPageInfo));
422: }
423: }
424:
425: PageFlowRequestWrapper.get(request).setPreviousPageInfo(
426: prevPageInfo);
427: return retFwd;
428: }
429:
430: public ActionForward doReturnToAction(
431: FlowControllerHandlerContext context, String actionName,
432: Forward pageFlowFwd) {
433: assert context.getRequest() instanceof HttpServletRequest : "don't support ServletRequest currently.";
434: HttpServletRequest request = (HttpServletRequest) context
435: .getRequest();
436:
437: //
438: // We need access to _previousPageInfo from the *current PageFlow*. That is
439: // most likely this FlowController, but if it's Global.app, then we don't want
440: // to use that.
441: //
442: PageFlowController curJpf = PageFlowUtils.getCurrentPageFlow(
443: request, getServletContext());
444:
445: if (curJpf == null) {
446: PageFlowException ex = new NoCurrentPageFlowException(
447: actionName, pageFlowFwd);
448: InternalUtils.throwPageFlowException(ex, request);
449: assert false; // throwPageFlowException() must throw.
450: }
451:
452: PreviousActionInfo prevActionInfo = curJpf
453: .thePreviousActionInfo();
454:
455: if (prevActionInfo != null) {
456: String actionURI = prevActionInfo.getActionURI();
457:
458: if (_log.isDebugEnabled())
459: _log.debug("return-to-action: " + actionURI);
460:
461: //
462: // If there's no form specified in this return-to-action forward, then use the original form that was saved
463: // in the action. Only do this if we're not doing a redirect, which precludes request attributes.
464: //
465: if (!pageFlowFwd.isRedirect()
466: && prevActionInfo.getForm() != null
467: && pageFlowFwd.getFirstOutputForm(request) == null) {
468: pageFlowFwd.addOutputForm(prevActionInfo.getForm());
469: }
470:
471: String query = getQueryString(pageFlowFwd, prevActionInfo);
472: ActionForward fwd = new ActionForward(actionURI + query,
473: pageFlowFwd.getRedirect());
474: fwd.setContextRelative(true);
475: return fwd;
476: } else {
477: if (_log.isInfoEnabled()) {
478: _log
479: .info("Attempted return-to-action, but previous action info was missing.");
480: }
481:
482: PageFlowException ex = new NoPreviousActionException(
483: actionName, pageFlowFwd, curJpf);
484: InternalUtils.throwPageFlowException(ex, request);
485: assert false; // previous method always throws
486: return null;
487: }
488: }
489:
490: private static String getQueryString(Forward pageFlowFwd,
491: PreviousInfo previousInfo) {
492: String query = pageFlowFwd.getQueryString();
493: if (query == null)
494: query = "";
495:
496: //
497: // If the restoreQueryString attribute was set, use the query string from the original action URI.
498: //
499: boolean restoreQueryString = pageFlowFwd
500: .doesRestoreQueryString();
501: if (restoreQueryString) {
502: String prevQuery = previousInfo.getQueryString();
503: if (prevQuery != null)
504: query += (query.length() > 0 ? "&" : "?") + prevQuery;
505: }
506:
507: return query;
508: }
509:
510: public ActionForward doNestingReturn(
511: FlowControllerHandlerContext context, Forward pageFlowFwd,
512: ActionMapping mapping, ActionForm form) {
513: assert context.getRequest() instanceof HttpServletRequest : "don't support ServletRequest currently.";
514: assert context.getResponse() instanceof HttpServletResponse : "don't support ServletResponse currently.";
515: HttpServletRequest request = (HttpServletRequest) context
516: .getRequest();
517: HttpServletResponse response = (HttpServletResponse) context
518: .getResponse();
519:
520: PageFlowStack pfStack = PageFlowStack.get(request,
521: getServletContext());
522: String returnAction = pageFlowFwd.getPath();
523:
524: if (pfStack.isEmpty()) {
525: PageFlowController curJpf = PageFlowUtils
526: .getCurrentPageFlow(request, getServletContext());
527:
528: if (_log.isInfoEnabled()) {
529: _log
530: .info("Tried to pop from empty PageFlow stack. Current = "
531: + curJpf.getClass().getName());
532: }
533:
534: if (_log.isWarnEnabled()) {
535: InternalStringBuilder msg = new InternalStringBuilder(
536: "Tried to pop from empty PageFlow stack.");
537: msg.append(" Current page flow is ");
538: msg.append(curJpf != null ? curJpf.getClass().getName()
539: : null);
540: _log.warn(msg.append('.').toString());
541: }
542:
543: PageFlowException ex = new EmptyNestingStackException(
544: returnAction, curJpf);
545: InternalUtils.throwPageFlowException(ex, request);
546: }
547:
548: // Only nested PageFlowControllers can have return actions.
549: assert context.getFlowController() instanceof PageFlowController : context
550: .getFlowController().getClass().getName()
551: + " is not a " + PageFlowController.class.getName();
552: ActionForward exceptionFwd = ((PageFlowController) context
553: .getFlowController()).exitNesting(request, response,
554: mapping, form);
555: if (exceptionFwd != null)
556: return exceptionFwd;
557:
558: PageFlowStack.PushedPageFlow pushedPageFlowWrapper = pfStack
559: .pop(request);
560: PageFlowController poppedPageFlow = pushedPageFlowWrapper
561: .getPageFlow();
562:
563: if (_log.isDebugEnabled()) {
564: _log.debug("Popped PageFlowController " + poppedPageFlow
565: + " from the nesting stack");
566: }
567:
568: InternalUtils.setCurrentPageFlow(poppedPageFlow, request,
569: getServletContext());
570:
571: //
572: // If an ActionInterceptor forwarded to the nested page flow, give it a chance to change the URI as the nested
573: // flow is returning. If it doesn't, we'll go to the originally-intended Forward.
574: //
575: ActionInterceptor interceptor = pushedPageFlowWrapper
576: .getInterceptor();
577:
578: if (interceptor != null) {
579: return getRegisteredActionForwardHandler()
580: .handleInterceptorReturn(context, poppedPageFlow,
581: pushedPageFlowWrapper, returnAction,
582: mapping, form, interceptor);
583: }
584:
585: //
586: // Raise the returned action on the popped pageflow.
587: //
588: assert returnAction.charAt(0) != '/' : returnAction;
589:
590: if (_log.isDebugEnabled()) {
591: _log.debug("Action on popped PageFlowController is "
592: + returnAction);
593: }
594:
595: InternalStringBuilder returnActionPath = new InternalStringBuilder(
596: poppedPageFlow.getModulePath());
597: returnActionPath.append('/').append(returnAction).append(
598: PageFlowConstants.ACTION_EXTENSION);
599:
600: //
601: // Store the returned form in the request.
602: //
603: ActionForm retForm = pageFlowFwd.getFirstOutputForm(request);
604: if (retForm != null) {
605: InternalUtils.setForwardedFormBean(request, retForm);
606: ImplicitObjectUtil.loadOutputFormBean(request,
607: InternalUtils.unwrapFormBean(retForm));
608: }
609:
610: // Keep track of the fact that we are returning from nesting in this request.
611: PageFlowRequestWrapper.get(request).setReturningFromNesting(
612: true);
613:
614: //
615: // Forward to the return-action on the nesting page flow.
616: //
617: ActionForward fwd = new ActionForward(returnActionPath
618: .toString(), false);
619: fwd.setContextRelative(true);
620: return fwd;
621: }
622:
623: public ActionForward handleInterceptorReturn(
624: FlowControllerHandlerContext context,
625: PageFlowController poppedPageFlow,
626: PageFlowStack.PushedPageFlow pushedPageFlowWrapper,
627: String returnAction, ActionMapping actionMapping,
628: ActionForm form, ActionInterceptor interceptor) {
629: assert context.getRequest() instanceof HttpServletRequest : "don't support ServletRequest currently.";
630: assert context.getResponse() instanceof HttpServletResponse : "don't support ServletResponse currently.";
631: HttpServletRequest request = (HttpServletRequest) context
632: .getRequest();
633: HttpServletResponse response = (HttpServletResponse) context
634: .getResponse();
635:
636: PageFlowRequestWrapper.get(request)
637: .setReturningFromActionIntercept(true);
638:
639: try {
640: AfterNestedInterceptContext interceptorContext = new AfterNestedInterceptContext(
641: request, response, getServletContext(),
642: poppedPageFlow, pushedPageFlowWrapper
643: .getInterceptedForward(),
644: pushedPageFlowWrapper.getInterceptedActionName(),
645: returnAction);
646:
647: interceptor.afterNestedIntercept(interceptorContext);
648:
649: if (interceptorContext.hasInterceptorForward()) {
650: InterceptorForward fwd = interceptorContext
651: .getInterceptorForward();
652:
653: if (_log.isDebugEnabled()) {
654: InternalStringBuilder message = new InternalStringBuilder();
655: message.append("Interceptor ");
656: message.append(interceptor.getClass().getName());
657: message.append(" after nested page flow: ");
658:
659: if (fwd != null) {
660: message.append("forwarding to ");
661: message.append(fwd.getPath());
662: } else {
663: message
664: .append("returned InterceptorForward is null.");
665: }
666:
667: _log.debug(message.toString());
668: }
669:
670: if (fwd != null)
671: fwd.rehydrateRequest(request);
672: return fwd;
673: }
674: } catch (Throwable e) {
675: //
676: // Yes, we *do* mean to catch Throwable here. It will get re-thrown if the page flow does not handle it.
677: //
678: _log.error("Exception in "
679: + interceptor.getClass().getName()
680: + ".afterNestedIntercept", e);
681:
682: try {
683: return poppedPageFlow.handleException(e, actionMapping,
684: form, request, response);
685: } catch (Exception anotherException) {
686: _log.error(
687: "Exception thrown while handling exception.",
688: anotherException);
689: }
690: }
691:
692: //
693: // The interceptor declined to forward us anywhere -- just go to the originally-intended Forward.
694: //
695: InterceptorForward fwd = pushedPageFlowWrapper
696: .getInterceptedForward();
697: fwd.rehydrateRequest(request);
698: return fwd;
699: }
700:
701: public ActionForwardHandler getRegisteredActionForwardHandler() {
702: return (ActionForwardHandler) super.getRegisteredHandler();
703: }
704: }
|