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
String stateStr;
if (stateObj == null)
{
stateStr = null;
}
else
{
stateMgr.writeState(context, stateObj);
stateStr = stateWriter.getAndResetBuffer();
}
int start = 0;
while (end != -1)
{
origWriter.write(content, start, end - start);
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);
}
}
finally
{
// The Facelets implementation must close the writer used to write the response