1 18 package org.apache.beehive.netui.pageflow.internal; 19 20 import org.apache.beehive.netui.util.internal.InternalStringBuilder; 21 22 import org.apache.struts.action.ActionForward; 23 import org.apache.struts.action.ActionMapping; 24 import org.apache.struts.action.ActionForm; 25 import org.apache.struts.config.ModuleConfig; 26 27 import org.apache.beehive.netui.pageflow.interceptor.action.ActionInterceptor; 28 import org.apache.beehive.netui.pageflow.interceptor.action.AfterNestedInterceptContext; 29 import org.apache.beehive.netui.pageflow.interceptor.action.InterceptorForward; 30 import org.apache.beehive.netui.pageflow.interceptor.InterceptorException; 31 import org.apache.beehive.netui.pageflow.*; 32 import org.apache.beehive.netui.pageflow.handler.FlowControllerHandlerContext; 33 import org.apache.beehive.netui.pageflow.handler.ActionForwardHandler; 34 import org.apache.beehive.netui.util.logging.Logger; 35 import org.apache.beehive.netui.script.common.ImplicitObjectUtil; 36 37 38 import javax.servlet.http.HttpServletRequest ; 39 import javax.servlet.http.HttpServletResponse ; 40 import javax.servlet.ServletContext ; 41 42 public class DefaultActionForwardHandler 43 extends DefaultHandler 44 implements ActionForwardHandler 45 { 46 private static final Logger _log = Logger.getInstance( DefaultActionForwardHandler.class ); 47 48 public DefaultActionForwardHandler( ServletContext servletContext ) 49 { 50 init( null, null, servletContext ); 51 } 52 53 65 public ActionForward doForward( FlowControllerHandlerContext context, ActionForward fwd, ActionMapping mapping, 66 String actionName, ModuleConfig altModuleConfig, ActionForm form ) 67 { 68 boolean isSpecialForward = false; 69 boolean isReturnToCurrentPage = false; 70 assert context.getRequest() instanceof HttpServletRequest : "don't support ServletRequest currently."; 71 HttpServletRequest request = ( HttpServletRequest ) context.getRequest(); 72 FlowController flowController = context.getFlowController(); 73 74 if ( fwd != null && PageFlowConstants.AUTO_VIEW_RENDER_FORWARD_NAME.equals( fwd.getName() ) ) 79 { 80 return getRegisteredActionForwardHandler().doAutoViewRender( context, mapping, form ); 81 } 82 83 if ( fwd != null && fwd instanceof Forward ) 84 { 85 Forward pageFlowFwd = ( Forward ) fwd; 86 87 pageFlowFwd.initialize( mapping, flowController, request ); 88 pageFlowFwd.setAlternateModuleConfig( altModuleConfig ); 89 90 if ( ! pageFlowFwd.doesResolve() ) 91 { 92 PageFlowException ex = 93 new UnresolvableForwardException( pageFlowFwd.getName(), actionName, flowController ); 94 InternalUtils.throwPageFlowException( ex, request ); 95 } 96 97 if ( pageFlowFwd.isReturnToPage() ) 102 { 103 isSpecialForward = true; 104 105 PageFlowController curJpf = PageFlowUtils.getCurrentPageFlow( request ); 111 112 if ( curJpf == null ) 113 { 114 PageFlowException ex = new NoCurrentPageFlowException( actionName, pageFlowFwd ); 115 InternalUtils.throwPageFlowException( ex, request ); 116 assert false; } 118 119 PreviousPageInfo prevPageInfo; 120 121 switch ( pageFlowFwd.getReturnToType() ) 122 { 123 case Forward.RETURN_TO_CURRENT_PAGE: 124 prevPageInfo = curJpf.getCurrentPageInfo(); 125 isReturnToCurrentPage = true; 126 break; 127 128 case Forward.RETURN_TO_PREVIOUS_PAGE: 129 prevPageInfo = curJpf.getPreviousPageInfo(); 130 break; 131 132 case Forward.RETURN_TO_PAGE: 133 prevPageInfo = flowController.getPreviousPageInfoLegacy( curJpf, request ); 134 break; 135 136 default: 137 assert false : pageFlowFwd.getReturnToType(); 138 prevPageInfo = curJpf.getCurrentPageInfo(); 139 } 140 141 fwd = 142 getRegisteredActionForwardHandler().doReturnToPage( context, prevPageInfo, curJpf, form, actionName, pageFlowFwd ); 143 144 if ( prevPageInfo != null ) 145 { 146 mapping = prevPageInfo.getMapping(); 147 if ( form == null ) form = prevPageInfo.getForm(); 148 } 149 150 if ( _log.isDebugEnabled() ) 151 { 152 _log.debug( "return-to-page: " + ( fwd != null ? fwd.getPath() : "[null]" ) ); 153 } 154 } 155 else if ( pageFlowFwd.isReturnToAction() ) 156 { 157 isSpecialForward = true; 158 fwd = getRegisteredActionForwardHandler().doReturnToAction( context, actionName, pageFlowFwd ); 159 } 160 161 if ( pageFlowFwd.isNestedReturn() ) 165 { 166 isSpecialForward = true; 167 fwd = getRegisteredActionForwardHandler().doNestingReturn( context, pageFlowFwd, mapping, form ); 168 } 169 170 PageFlowUtils.setOutputForms( mapping, pageFlowFwd, request ); 175 InternalUtils.addActionOutputs( pageFlowFwd.getActionOutputs() , request, true ); 176 } 177 178 if ( fwd != null ) 179 { 180 if ( _log.isDebugEnabled() ) 181 { 182 if ( fwd.getRedirect() ) 183 { 184 _log.debug( "Redirecting to " + fwd.getPath() ); 185 } 186 else 187 { 188 _log.debug( "Forwarding to " + fwd.getPath() ); 189 } 190 } 191 } 192 else 193 { 194 _log.debug( "null ActionForward -- not doing any forward or redirect." ); 195 } 196 197 if ( ! isReturnToCurrentPage ) 203 { 204 flowController.savePreviousPageInfo( fwd, form, mapping, request, getServletContext(), isSpecialForward ); 205 } 206 207 return fwd; 208 } 209 210 public ActionForward doAutoViewRender( FlowControllerHandlerContext context, ActionMapping mapping, ActionForm form ) 211 { 212 assert context.getRequest() instanceof HttpServletRequest : "don't support ServletRequest currently."; 213 assert context.getResponse() instanceof HttpServletResponse : "don't support ServletResponse currently."; 214 HttpServletRequest request = ( HttpServletRequest ) context.getRequest(); 215 HttpServletResponse response = ( HttpServletResponse ) context.getResponse(); 216 ViewRenderer vr = PageFlowRequestWrapper.get( request ).getViewRenderer(); 217 218 if ( vr != null ) 219 { 220 _log.debug( "null ActionForward -- delegating to ViewRenderer " + vr + " to handle response." ); 221 222 try 223 { 224 vr.renderView( request, response, getServletContext() ); 225 } 226 catch ( Throwable th ) 227 { 228 try 229 { 230 return context.getFlowController().handleException( th, mapping, form, request, response ); 231 } 232 catch ( Exception e ) 233 { 234 _log.error( "Exception thrown while handling exception in ViewRenderer " + vr + ": " 235 + e.getMessage(), th ); 236 } 237 } 238 239 } 240 else 241 { 242 _log.error( "Auto-render forward " + PageFlowConstants.AUTO_VIEW_RENDER_FORWARD_NAME 243 + " used, but no ViewRenderer " + "was registered -- not doing any forward or redirect." ); 244 } 245 246 return null; 247 } 248 249 252 public ActionForward doReturnToPage( FlowControllerHandlerContext context, PreviousPageInfo prevPageInfo, 253 PageFlowController currentPageFlow, ActionForm currentForm, 254 String actionName, Forward pageFlowFwd ) 255 { 256 assert context.getRequest() instanceof HttpServletRequest : "don't support ServletRequest currently."; 257 HttpServletRequest request = ( HttpServletRequest ) context.getRequest(); 258 259 if ( prevPageInfo == null ) 260 { 261 if ( _log.isInfoEnabled() ) 262 { 263 _log.info( "Attempted return-to-page, but previous page info was missing." ); 264 } 265 266 PageFlowException ex = new NoPreviousPageException( actionName, pageFlowFwd, currentPageFlow ); 267 InternalUtils.throwPageFlowException( ex, request ); 268 } 269 270 ActionForward retFwd = prevPageInfo.getForward(); 274 ActionMapping prevMapping = prevPageInfo.getMapping(); 275 276 if ( retFwd instanceof Forward ) 280 { 281 PageFlowUtils.setOutputForms( prevMapping, ( Forward ) retFwd, request, false ); 282 InternalUtils.addActionOutputs( ( ( Forward ) retFwd ).getActionOutputs(), request, false ); 283 } 284 285 if ( prevMapping != null ) 289 { 290 if ( currentForm != null ) PageFlowUtils.setOutputForm( prevMapping, currentForm, request, false ); 295 296 InternalUtils.setFormInScope( prevMapping.getName(), prevPageInfo.getForm(), prevMapping, request, false ); 301 } 302 303 FlowController flowController = context.getFlowController(); 308 309 if ( ! retFwd.getContextRelative() && flowController != currentPageFlow ) 310 { 311 312 retFwd = new ActionForward( retFwd.getName(), 313 currentPageFlow.getModulePath() + retFwd.getPath(), 314 retFwd.getRedirect(), 315 true ); 316 317 } 318 319 if ( _log.isDebugEnabled() ) 320 { 321 _log.debug( "Return-to-page in PageFlowController " + flowController.getClass().getName() 322 + ": original URI " + retFwd.getPath() ); 323 } 324 325 if ( retFwd != null ) 326 { 327 if ( pageFlowFwd.hasExplicitRedirectValue() ) retFwd.setRedirect( pageFlowFwd.getRedirect() ); 332 333 String fwdPath = retFwd.getPath(); 337 String newQueryString = pageFlowFwd.getQueryString(); 338 int existingQueryPos = fwdPath.indexOf( '?' ); 339 340 if ( newQueryString != null ) 346 { 347 if ( existingQueryPos != -1 ) fwdPath = fwdPath.substring( 0, existingQueryPos ); 349 retFwd.setPath( fwdPath + newQueryString ); 350 } 351 else if ( existingQueryPos == -1 ) 352 { 353 retFwd.setPath( fwdPath + getQueryString( pageFlowFwd, prevPageInfo ) ); 354 } 355 } 356 357 PageFlowRequestWrapper.get( request ).setPreviousPageInfo( prevPageInfo ); 358 return retFwd; 359 } 360 361 public ActionForward doReturnToAction( FlowControllerHandlerContext context, String actionName, Forward pageFlowFwd ) 362 { 363 assert context.getRequest() instanceof HttpServletRequest : "don't support ServletRequest currently."; 364 HttpServletRequest request = ( HttpServletRequest ) context.getRequest(); 365 366 PageFlowController curJpf = PageFlowUtils.getCurrentPageFlow( request ); 372 373 if ( curJpf == null ) 374 { 375 PageFlowException ex = new NoCurrentPageFlowException( actionName, pageFlowFwd ); 376 InternalUtils.throwPageFlowException( ex, request ); 377 assert false; } 379 380 PreviousActionInfo prevActionInfo = curJpf.getPreviousActionInfo(); 381 382 if ( prevActionInfo != null ) 383 { 384 String actionURI = prevActionInfo.getActionURI(); 385 386 if ( _log.isDebugEnabled() ) _log.debug( "return-to-action: " + actionURI ); 387 388 if ( ! pageFlowFwd.isRedirect() && prevActionInfo.getForm() != null 393 && pageFlowFwd.getFirstOutputForm( request ) == null ) 394 { 395 pageFlowFwd.addOutputForm( prevActionInfo.getForm() ); 396 } 397 398 String query = getQueryString( pageFlowFwd, prevActionInfo ); 399 ActionForward fwd = new ActionForward( actionURI + query, pageFlowFwd.getRedirect() ); 400 fwd.setContextRelative( true ); 401 return fwd; 402 } 403 else 404 { 405 if ( _log.isInfoEnabled() ) 406 { 407 _log.info( "Attempted return-to-action, but previous action info was missing." ); 408 } 409 410 PageFlowException ex = new NoPreviousActionException( actionName, pageFlowFwd, curJpf ); 411 InternalUtils.throwPageFlowException( ex, request ); 412 assert false; return null; 414 } 415 } 416 417 private static String getQueryString( Forward pageFlowFwd, PreviousInfo previousInfo ) 418 { 419 String query = pageFlowFwd.getQueryString(); 420 if ( query == null ) query = ""; 421 422 boolean restoreQueryString = pageFlowFwd.doesRestoreQueryString(); 426 if ( restoreQueryString ) 427 { 428 String prevQuery = previousInfo.getQueryString(); 429 if ( prevQuery != null ) query += ( query.length() > 0 ? "&" : "?" ) + prevQuery; 430 } 431 432 return query; 433 } 434 435 public ActionForward doNestingReturn( FlowControllerHandlerContext context, Forward pageFlowFwd, 436 ActionMapping mapping, ActionForm form ) 437 { 438 assert context.getRequest() instanceof HttpServletRequest : "don't support ServletRequest currently."; 439 assert context.getResponse() instanceof HttpServletResponse : "don't support ServletResponse currently."; 440 HttpServletRequest request = ( HttpServletRequest ) context.getRequest(); 441 HttpServletResponse response = ( HttpServletResponse ) context.getResponse(); 442 443 PageFlowStack pfStack = PageFlowStack.get( request ); 444 String returnAction = pageFlowFwd.getPath(); 445 446 if ( pfStack.isEmpty() ) 447 { 448 PageFlowController curJpf = PageFlowUtils.getCurrentPageFlow( request ); 449 450 if ( _log.isInfoEnabled() ) 451 { 452 _log.info( "Tried to pop from empty PageFlow stack. Current = " 453 + curJpf.getClass().getName() ); 454 } 455 456 if ( _log.isWarnEnabled() ) 457 { 458 InternalStringBuilder msg = new InternalStringBuilder( "Tried to pop from empty PageFlow stack." ); 459 msg.append( " Current page flow is " ); 460 msg.append( curJpf != null ? curJpf.getClass().getName() : null ); 461 _log.warn( msg.append( '.' ).toString() ); 462 } 463 464 PageFlowException ex = new EmptyNestingStackException( returnAction, curJpf ); 465 InternalUtils.throwPageFlowException( ex, request ); 466 } 467 468 assert context.getFlowController() instanceof PageFlowController 470 : context.getFlowController().getClass().getName() + " is not a " + PageFlowController.class.getName(); 471 ActionForward exceptionFwd = 472 ( ( PageFlowController ) context.getFlowController() ).exitNesting( request, response, mapping, form ); 473 if ( exceptionFwd != null ) return exceptionFwd; 474 475 PageFlowStack.PushedPageFlow pushedPageFlowWrapper = pfStack.pop( request ); 476 PageFlowController poppedPageFlow = pushedPageFlowWrapper.getPageFlow(); 477 478 if ( _log.isDebugEnabled() ) 479 { 480 _log.debug( "Popped PageFlowController " + poppedPageFlow + " from the nesting stack" ); 481 } 482 483 InternalUtils.setCurrentPageFlow( poppedPageFlow, request ); 484 485 486 ActionInterceptor interceptor = pushedPageFlowWrapper.getInterceptor(); 491 492 if ( interceptor != null ) 493 { 494 return getRegisteredActionForwardHandler().handleInterceptorReturn( context, poppedPageFlow, 495 pushedPageFlowWrapper, returnAction, 496 mapping, form, interceptor ); 497 } 498 499 assert returnAction.charAt( 0 ) != '/' : returnAction; 503 504 if ( _log.isDebugEnabled() ) 505 { 506 _log.debug( "Action on popped PageFlowController is " + returnAction ); 507 } 508 509 InternalStringBuilder returnActionPath = new InternalStringBuilder( poppedPageFlow.getModulePath() ); 510 returnActionPath.append( '/' ).append( returnAction ).append( PageFlowConstants.ACTION_EXTENSION ); 511 512 ActionForm retForm = pageFlowFwd.getFirstOutputForm( request ); 516 if ( retForm != null ) 517 { 518 InternalUtils.setForwardedFormBean( request, retForm ); 519 ImplicitObjectUtil.loadOutputFormBean( request, InternalUtils.unwrapFormBean( retForm ) ); 520 } 521 522 request.setAttribute( InternalConstants.RETURNING_FROM_NESTING_ATTR, Boolean.TRUE ); 524 525 ActionForward fwd = new ActionForward( returnActionPath.toString(), false ); 529 fwd.setContextRelative( true ); 530 return fwd; 531 } 532 533 public ActionForward handleInterceptorReturn( FlowControllerHandlerContext context, 534 PageFlowController poppedPageFlow, 535 PageFlowStack.PushedPageFlow pushedPageFlowWrapper, 536 String returnAction, ActionMapping actionMapping, 537 ActionForm form, ActionInterceptor interceptor ) 538 { 539 assert context.getRequest() instanceof HttpServletRequest : "don't support ServletRequest currently."; 540 assert context.getResponse() instanceof HttpServletResponse : "don't support ServletResponse currently."; 541 HttpServletRequest request = ( HttpServletRequest ) context.getRequest(); 542 HttpServletResponse response = ( HttpServletResponse ) context.getResponse(); 543 544 PageFlowRequestWrapper.get( request ).setReturningFromActionIntercept( true ); 545 546 try 547 { 548 AfterNestedInterceptContext interceptorContext = 549 new AfterNestedInterceptContext( request, response, getServletContext(), poppedPageFlow, 550 pushedPageFlowWrapper.getInterceptedForward(), 551 pushedPageFlowWrapper.getInterceptedActionName(), 552 returnAction ); 553 554 interceptor.afterNestedIntercept( interceptorContext ); 555 556 if ( interceptorContext.hasInterceptorForward() ) 557 { 558 InterceptorForward fwd = interceptorContext.getInterceptorForward(); 559 560 if ( _log.isDebugEnabled() ) 561 { 562 InternalStringBuilder message = new InternalStringBuilder(); 563 message.append( "Interceptor " ); 564 message.append( interceptor.getClass().getName() ); 565 message.append( " after nested page flow: " ); 566 567 if ( fwd != null ) 568 { 569 message.append( "forwarding to " ); 570 message.append( fwd.getPath() ); 571 } 572 else 573 { 574 message.append( "returned InterceptorForward is null." ); 575 } 576 577 _log.debug( message.toString() ); 578 } 579 580 if ( fwd != null ) fwd.rehydrateRequest( request ); 581 return fwd; 582 } 583 } 584 catch ( InterceptorException e ) 585 { 586 _log.error( "Exception in " + interceptor.getClass().getName() + ".afterNestedIntercept", e ); 587 588 try 589 { 590 return poppedPageFlow.handleException( e, actionMapping, form, request, response ); 591 } 592 catch ( Exception anotherException ) 593 { 594 _log.error( "Exception thrown while handling exception.", anotherException ); 595 } 596 } 597 598 return pushedPageFlowWrapper.getInterceptedForward(); 602 } 603 604 public ActionForwardHandler getRegisteredActionForwardHandler() 605 { 606 return ( ActionForwardHandler ) super.getRegisteredHandler(); 607 } 608 } 609 | Popular Tags |