@Override
    public void renderView(FacesContext context, UIViewRoot view) throws IOException
    {
        if (!view.isRendered())
        {
            return;
        }

        // log request
        if (log.isLoggable(Level.FINE))
        {
            log.fine("Rendering View: " + view.getViewId());
        }

        try
        {
            // build view - but not if we're in "buildBeforeRestore"
            // land and we've already got a populated view. Note
            // that this optimizations breaks if there's a "c:if" in
            // the page that toggles as a result of request processing -
            // should that be handled? Or
            // is this optimization simply so minor that it should just
            // be trimmed altogether?
            // See JSF 2.0 spec section 2.2.6, buildView is called before
            // Render Response
            //if (!isFilledView(context, view))
            //{
            //    buildView(context, view);
            //}

            // setup writer and assign it to the context
            ResponseWriter origWriter = createResponseWriter(context);

            ExternalContext extContext = context.getExternalContext();
            Writer outputWriter = extContext.getResponseOutputWriter();

            StateWriter stateWriter = new StateWriter(outputWriter, 1024, context);
            try
            {
                ResponseWriter writer = origWriter.cloneWithWriter(stateWriter);
                try
                {
                    context.setResponseWriter(writer);

                    StateManager stateMgr = context.getApplication().getStateManager();
                    // force creation of session if saving state there
                    // -= Leonardo Uribe =- Do this does not have any sense!. The only reference
                    // about these lines are on http://java.net/projects/facelets/sources/svn/revision/376
                    // and it says: "fixed lazy session instantiation with eager response commit"
                    // This code is obviously to prevent this exception:
                    // java.lang.IllegalStateException: Cannot create a session after the response has been committed
                    // But in theory if that so, StateManager.saveState must happen before writer.close() is called,
                    // which can be done very easily.
                    //if (!stateMgr.isSavingStateInClient(context))
                    //{
                    //    extContext.getSession(true);
                    //}

                    // render the view to the response
                    writer.startDocument();

                    view.encodeAll(context);

                    writer.endDocument();

                    // finish writing
                    // -= Leonardo Uribe =- This does not has sense too, because that's the reason
                    // of the try/finally block. In practice, it only forces the close of the tag 
                    // in HtmlResponseWriter if necessary, but according to the spec, this should
                    // be done using writer.flush() instead.
                    // writer.close();

                    // flush to origWriter
                    if (stateWriter.isStateWritten())
                    {
                        // Call this method to force close the tag if necessary.
                        // The spec javadoc says this: 
                        // "... Flush any ouput buffered by the output method to the underlying 
                        // Writer or OutputStream. This method will not flush the underlying 
                        // Writer or OutputStream; it simply clears any values buffered by this 
                        // ResponseWriter. ..."
                        writer.flush();

                        // =-= markoc: STATE_KEY is in output ONLY if 
                        // stateManager.isSavingStateInClient(context)is true - see
                        // org.apache.myfaces.application.ViewHandlerImpl.writeState(FacesContext)
                        // TODO this class and ViewHandlerImpl contain same constant <!--@@JSF_FORM_STATE_MARKER@@-->
                        Object stateObj = stateMgr.saveView(context);
                        String content = stateWriter.getAndResetBuffer();
                        int end = content.indexOf(STATE_KEY);
                        // See if we can find any trace of the saved state.
                        // If so, we need to perform token replacement
                        if (end >= 0)
                        {
                            // save state
                            int start = 0;

                            while (end != -1)
                            {
                                origWriter.write(content, start, end - start);
                                
                                String stateStr;
                                if (view.isTransient())
                                {
                                    // Force state saving
                                    stateMgr.writeState(context, stateObj);
                                    stateStr = stateWriter.getAndResetBuffer();
                                }
                                else if (stateObj == null)
                                {
                                    stateStr = null;
                                }
                                else
                                {
                                    stateMgr.writeState(context, stateObj);
                                    stateStr = stateWriter.getAndResetBuffer();
                                }                                
                                
                                if (stateStr != null)
                                {
                                    origWriter.write(stateStr);
                                }
                                start = end + STATE_KEY_LEN;
                                end = content.indexOf(STATE_KEY, start);
                            }

                            origWriter.write(content, start, content.length() - start);
                            // No trace of any saved state, so we just need to flush
                            // the buffer
                        }
                        else
                        {
                            origWriter.write(content);
                        }
                    }
                    else if (stateWriter.isStateWrittenWithoutWrapper())
                    {
                        // The state token has been written but the state has not been
                        // saved yet.
                        stateMgr.saveView(context);
                    }
                    else
                    {
                        // GET case without any form that trigger state saving.
                        // Try to store it into cache.
                        if (_viewPoolProcessor != null && 
                            _viewPoolProcessor.isViewPoolEnabledForThisView(context, view))
                        {
                            ViewDeclarationLanguage vdl = context.getApplication().
                                    getViewHandler().getViewDeclarationLanguage(
                                        context, view.getViewId());

                            if (ViewDeclarationLanguage.FACELETS_VIEW_DECLARATION_LANGUAGE_ID.equals(
                                    vdl.getId()))
                            {
                                StateManagementStrategy sms = vdl.getStateManagementStrategy(
                                        context, view.getId());
                                if (sms != null)
                                {
                                    context.getAttributes().put(ViewPoolProcessor.FORCE_HARD_RESET, Boolean.TRUE);

                                    // Force indirectly to store the map in the cache
                                    try
                                    {
                                        Object state = sms.saveView(context);
                                    }
                                    finally
                                    {
                                        context.getAttributes().remove(ViewPoolProcessor.FORCE_HARD_RESET);
                                    }

                                    // Clear the calculated value from the application map
                                    context.getAttributes().remove(SERIALIZED_VIEW_REQUEST_ATTR);
                                }
                            }
                        }
                    }
                }
                finally
                {
                    // The Facelets implementation must close the writer used to write the response
                    writer.close();
                }
            }
            finally
            {
                stateWriter.release(context);
            }
        }
        catch (FileNotFoundException fnfe)
        {
            handleFaceletNotFound(context, view.getViewId());
        }
        catch (Exception e)
        {
            handleRenderException(context, e);
        }
    }
@ Override public void renderView ( FacesContext context , UIViewRoot view ) throws IOException { if ( ! view . isRendered ( ) ) { return ; } if ( log . isLoggable ( Level . FINE ) ) { log . fine ( "Rendering View: " + view . getViewId ( ) ) ; } try { ResponseWriter origWriter = createResponseWriter ( context ) ; ExternalContext extContext = context . getExternalContext ( ) ; Writer outputWriter = extContext . getResponseOutputWriter ( ) ; StateWriter stateWriter = new StateWriter ( outputWriter , 1024 , context ) ; try { ResponseWriter writer = origWriter . cloneWithWriter ( stateWriter ) ; try { context . setResponseWriter ( writer ) ; StateManager stateMgr = context . getApplication ( ) . getStateManager ( ) ; writer . startDocument ( ) ; view . encodeAll ( context ) ; writer . endDocument ( ) ; if ( stateWriter . isStateWritten ( ) ) { writer . flush ( ) ; Object stateObj = stateMgr . saveView ( context ) ; String content = stateWriter . getAndResetBuffer ( ) ; int end = content . indexOf ( STATE_KEY ) ; if ( end >= 0 ) { int start = 0 ; while ( end != - 1 ) { origWriter . write ( content , start , end - start ) ; String stateStr ; if ( view . isTransient ( ) ) { stateMgr . writeState ( context , stateObj ) ; stateStr = stateWriter . getAndResetBuffer ( ) ; } else if ( stateObj == null ) { stateStr = null ; } else { stateMgr . writeState ( context , stateObj ) ; stateStr = stateWriter . getAndResetBuffer ( ) ; } if ( stateStr != null ) { origWriter . write ( stateStr ) ; } start = end + STATE_KEY_LEN ; end = content . indexOf ( STATE_KEY , start ) ; } origWriter . write ( content , start , content . length ( ) - start ) ; } else { origWriter . write ( content ) ; } } else if ( stateWriter . isStateWrittenWithoutWrapper ( ) ) { stateMgr . saveView ( context ) ; } else { if ( _viewPoolProcessor != null && _viewPoolProcessor . isViewPoolEnabledForThisView ( context , view ) ) { ViewDeclarationLanguage vdl = context . getApplication ( ) . getViewHandler ( ) . getViewDeclarationLanguage ( context , view . getViewId ( ) ) ; if ( ViewDeclarationLanguage . FACELETS_VIEW_DECLARATION_LANGUAGE_ID . equals ( vdl . getId ( ) ) ) { StateManagementStrategy sms = vdl . getStateManagementStrategy ( context , view . getId ( ) ) ; if ( sms != null ) { context . getAttributes ( ) . put ( ViewPoolProcessor . FORCE_HARD_RESET , Boolean . TRUE ) ; try { Object state = sms . saveView ( context ) ; } finally { context . getAttributes ( ) . remove ( ViewPoolProcessor . FORCE_HARD_RESET ) ; } context . getAttributes ( ) . remove ( SERIALIZED_VIEW_REQUEST_ATTR ) ; } } } } } finally { writer . close ( ) ; } } finally { stateWriter . release ( context ) ; } } catch ( FileNotFoundException fnfe ) { handleFaceletNotFound ( context , view . getViewId ( ) ) ; } catch ( Exception e ) { handleRenderException ( context , e ) ; } }
{@inheritDoc}