private void checkActionOutputs ( PageFlowActionForward fc ) { PageFlowActionForward . ActionOutput [ ] actionOutputs = fc . getActionOutputs ( ) ; boolean doExpensiveChecks = _actionOutputs != null && ! AdapterManager . getServletContainerAdapter ( _servletContext ) . isInProductionMode ( ) ; for ( int i = 0 ; i < actionOutputs . length ; ++ i ) { PageFlowActionForward . ActionOutput actionOutput = actionOutputs [ i ] ; if ( ! actionOutput . getNullable ( ) ) { String actionOutputName = actionOutput . getName ( ) ; if ( _actionOutputs == null || ! _actionOutputs . containsKey ( actionOutputName ) ) { PageFlowException ex = new MissingActionOutputException ( _mappingPath , _flowController , actionOutput . getName ( ) , getName ( ) ) ; InternalUtils . throwPageFlowException ( ex ) ; } else if ( _actionOutputs . get ( actionOutputName ) == null ) { PageFlowException ex = new NullActionOutputException ( _mappingPath , _flowController , actionOutput . getName ( ) , getName ( ) ) ; InternalUtils . throwPageFlowException ( ex ) ; } } // // If we're *not* in production mode, do some (expensive) checks to ensure that the types for the // action outputs match their declared types. // if ( doExpensiveChecks ) { Object actualActionOutput = _actionOutputs . get ( actionOutput . getName ( ) ) ; if ( actualActionOutput != null ) { String expectedTypeName = actionOutput . getType ( ) ; int expectedArrayDims = 0 ; while ( expectedTypeName . endsWith ( "[]" ) ) { ++ expectedArrayDims ; expectedTypeName = expectedTypeName . substring ( 0 , expectedTypeName . length ( ) - 2 ) ; } Class expectedType = ( Class ) PRIMITIVE_TYPES . get ( expectedTypeName ) ; if ( expectedType == null ) { try { ReloadableClassHandler rch = Handlers . get ( _servletContext ) . getReloadableClassHandler ( ) ; expectedType = rch . loadClass ( expectedTypeName ) ; } catch ( ClassNotFoundException e ) { _log . error ( "Could not load expected action output type " + expectedTypeName + " for action output '" + actionOutput . getName ( ) + "' on forward '" + fc . getName ( ) + "'; skipping type check." ) ; continue ; } } Class actualType = actualActionOutput . getClass ( ) ; int actualArrayDims = 0 ; InternalStringBuilder arraySuffix = new InternalStringBuilder ( ) ; while ( actualType . isArray ( ) && actualArrayDims <= expectedArrayDims ) { ++ actualArrayDims ; arraySuffix . append ( "[]" ) ; actualType = actualType . getComponentType ( ) ; } if ( actualArrayDims != expectedArrayDims || ! expectedType . isAssignableFrom ( actualType ) ) { PageFlowException ex = new MismatchedActionOutputException ( _mappingPath , _flowController , actionOutput . getName ( ) , getName ( ) , expectedTypeName , actualType . getName ( ) + arraySuffix ) ; InternalUtils . throwPageFlowException ( ex ) ; } } } } }
Make sure required action outputs are present and are of the right type ( only make the latter check when not in production mode