Jayashri,
A couple of options;
(1) Simplify this code, and eliminate the
buffering, by stating that components added after the
first call to UIForm.encodeEnd() are not guaranteed to be
saved? I'm uncomfortable with requiring all ViewHandlers
to support dynamically adding components during Render
Response - in general, this is bad coding style.
Or,
(2) Write the state marker immediately - since it certainly
won't change - but delay actually saving the state and structure
of the UIViewRoot by using an RI-specific PhaseListener
that is coupled to the RI StateManager that runs in afterPhase()
of Render Response.
I prefer #2.
-- Adam
Jayashri Visvanathan wrote:
> Hi Ed,
> If you have ideas on how to simplify this, please let me know. Based on
> that I can send another iteration of the change bundle.
> Thanks
> -Jayashri
>
> M com/sun/faces/application/ViewHandlerImpl.java
> Put back the state marker replace logic we used have before
> TCCI changes to enable components to be added programatically
> during encode.
>
>
> ------------------------------------------------------------------------
>
> Index: com/sun/faces/application/ViewHandlerImpl.java
> ===================================================================
> RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/application/ViewHandlerImpl.java,v
> retrieving revision 1.52
> diff -u -r1.52 ViewHandlerImpl.java
> --- com/sun/faces/application/ViewHandlerImpl.java 2 May 2005 14:58:44 -0000 1.52
> +++ com/sun/faces/application/ViewHandlerImpl.java 17 May 2005 00:06:59 -0000
> @@ -45,6 +45,7 @@
> import com.sun.faces.RIConstants;
> import com.sun.faces.util.Util;
>
> +import java.io.StringWriter;
>
> /**
> * <B>ViewHandlerImpl</B> is the default implementation class for ViewHandler.
> @@ -123,34 +124,65 @@
> ServletResponse response = (ServletResponse) extContext.getResponse();
>
> ResponseWriter oldWriter = context.getResponseWriter();
> + StringWriter strWriter = new StringWriter();
> ResponseWriter newWriter = null;
> if (null != oldWriter) {
> - newWriter = oldWriter.cloneWithWriter(response.getWriter());
> + newWriter = oldWriter.cloneWithWriter(strWriter);
> }
> else {
> - newWriter = renderKit.createResponseWriter(response.getWriter(),
> - null,
> - request.getCharacterEncoding());
> + newWriter = renderKit.createResponseWriter(strWriter, null,
> + request.getCharacterEncoding());
> }
> context.setResponseWriter(newWriter);
> -
> +
> newWriter.startDocument();
>
> doRenderView(context, viewToRender);
>
> newWriter.endDocument();
> -
> +
> + // replace markers in the body content and write it to response.
> + ResponseWriter responseWriter = null;
> + if (null != oldWriter) {
> + responseWriter = oldWriter.cloneWithWriter(response.getWriter());
> + } else {
> + responseWriter = renderKit.createResponseWriter(response.getWriter(),
> + null, request.getCharacterEncoding());
> + }
> + context.setResponseWriter(responseWriter);
> +
> + String bodyContent = strWriter.getBuffer().toString();
> + replaceMarkers(bodyContent, context);
> +
> if (null != oldWriter) {
> context.setResponseWriter(oldWriter);
> }
>
> - if (!context.getExternalContext().getRequestMap().containsKey(RIConstants.SAVED_STATE)) {
> + // write any AFTER_VIEW_CONTENT to the response
> + Object content = extContext.getRequestMap().get(AFTER_VIEW_CONTENT);
> + assert(null != content);
> + if (content instanceof byte []) {
> + response.getWriter().write(new String((byte[]) content));
> + } else if (content instanceof char []) {
> + response.getWriter().write((char []) content);
> + } else {
> + assert(false);
> + }
> +
> + response.flushBuffer(); // PENDING(edburns): necessary?
> +
> + // remove the AFTER_VIEW_CONTENT from the view root
> + extContext.getRequestMap().remove(AFTER_VIEW_CONTENT);
> +
> + // PENDING (visvan) do we need this any more since we save the tree
> + // after encode ??
> + /* if (!context.getExternalContext().getRequestMap().containsKey(RIConstants.SAVED_STATE)) {
> // if we didn't serialize the state, or we didn't save it in
> // the client, we need to manually remove the transient
> // children and facets.
> removeTransientChildrenAndFacets(context, viewToRender,
> new HashSet());
> - }
> + } */
> }
>
> /**
> @@ -175,19 +207,6 @@
> UIViewRoot viewToRender) throws IOException,
> FacesException {
> ExternalContext extContext = context.getExternalContext();
> - ServletResponse response = (ServletResponse) extContext.getResponse();
> -
> - // NOTE: With tree pre-creation, components can be dynamically added
> - // to the tree by registering a beforeRender phaseListener. So, any
> - // component added during encodeAll, will not be persisted as a result.
> - // With this change, we can avoid buffering and the marker replacement
> - // complexity since the actual state is written out during
> - // ViewHandler.writeState(). saveSerializedView() must be called before
> - // encodeAll because writeState() needs the actual state which gets
> - // created during saveSerializedView
> - Object view =
> - Util.getStateManager(context).saveSerializedView(context);
> - extContext.getRequestMap().put(RIConstants.SAVED_STATE, view);
>
> ApplicationAssociate associate =
> ApplicationAssociate.getInstance(extContext);
> @@ -200,25 +219,7 @@
> logger.log(Level.FINE, "About to render view " + viewToRender.getViewId());
> }
>
> - viewToRender.encodeAll(context);
> -
> - // write any AFTER_VIEW_CONTENT to the response
> - Object content = extContext.getRequestMap().get(AFTER_VIEW_CONTENT);
> - assert(null != content);
> - if (content instanceof byte []) {
> - response.getWriter().write(new String((byte[]) content));
> - } else if (content instanceof char []) {
> - response.getWriter().write((char []) content);
> - } else {
> - assert(false);
> - }
> -
> - response.flushBuffer(); // PENDING(edburns): necessary?
> -
> - // remove the AFTER_VIEW_CONTENT from the view root
> - extContext.getRequestMap().remove(AFTER_VIEW_CONTENT);
> -
> -
> + viewToRender.encodeAll(context);
> }
>
> private void removeTransientChildrenAndFacets(FacesContext context,
> @@ -505,6 +506,7 @@
>
> // replace the original response
> extContext.setResponse(originalResponse);
> + // new com.sun.faces.util.DebugUtil().printTree(viewToExecute,System.out);
> }
>
>
> @@ -625,22 +627,16 @@
> message = message +"context " + context;
> throw new NullPointerException(message);
> }
> - StateManager stateManager = Util.getStateManager(context);
> -
> - SerializedView viewState = (SerializedView)
> - context.getExternalContext().getRequestMap().get(RIConstants.SAVED_STATE);
> - assert(null != viewState);
> -
> +
> if (logger.isLoggable(Level.FINE)) {
> - logger.fine("Begin writing state to response for viewId " +
> + logger.fine("Begin writing market for viewId " +
> context.getViewRoot().getViewId());
> }
>
> - // write out the state
> - stateManager.writeState(context, viewState);
> -
> + context.getResponseWriter().writeText(
> + RIConstants.SAVESTATE_FIELD_MARKER, null);
> if (logger.isLoggable(Level.FINE)) {
> - logger.fine("End writing state to response for viewId " +
> + logger.fine("End writing marker for viewId " +
> context.getViewRoot().getViewId());
> }
>
> @@ -876,6 +872,47 @@
>
> }
> return convertedViewId;
> + }
> +
> + public void replaceMarkers(String content, FacesContext context) {
> + SerializedView view = null;
> + try {
> + view = Util.getStateManager(context).saveSerializedView(context);
> + } catch (IllegalStateException ise) {
> + throw new FacesException(ise);
> + } catch (Exception ie) {
> + // catch any exception thrown while saving the view
> + throw new FacesException(Util.getExceptionMessageString(
> + Util.SAVING_STATE_ERROR_MESSAGE_ID), ie);
> + }
> + int
> + beginIndex = 0,
> + markerIndex = 0,
> + markerLen = RIConstants.SAVESTATE_FIELD_MARKER.length(),
> + contentLen = 0;
> +
> + try {
> + contentLen = content.length();
> + do {
> + // if we have no more markers
> + if (-1 == (markerIndex =
> + content.indexOf(RIConstants.SAVESTATE_FIELD_MARKER,
> + beginIndex))) {
> + // write out the rest of the content
> + context.getResponseWriter().write(content.substring(beginIndex));
> + } else {
> + // we have more markers, write out the current chunk
> +
> + context.getResponseWriter().write(content.substring(
> + beginIndex, markerIndex));
> + Util.getStateManager(context).writeState(context, view);
> + beginIndex = markerIndex + markerLen;
> + }
> + } while (-1 != markerIndex && beginIndex < contentLen);
> + } catch (Exception ex) {
> + // catch any thrown while write state.
> + throw new FacesException(ex);
> + }
> }
>
>
>
>
>
> ------------------------------------------------------------------------
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_javaserverfaces.dev.java.net
> For additional commands, e-mail: dev-help_at_javaserverfaces.dev.java.net