I consider myself a little more draconian than most, but I would simply
disallow adding components at render time. I thought TCCI was supposed
to correct issues correlated to render time state saving?
Do we have a specific use case or request to tie this change to? Does
this re-enforce some of the discussion pertaining to a phase event
before rendering in the client side scripting issues Ed/Roger brought
up?
-- Jacob
Adam Winer <adam.winer_at_oracle.com> wrote on 05/17/2005, 06:22:45 PM:
> 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;
> >
> > /**
> > * ViewHandlerImpl 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
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_javaserverfaces.dev.java.net
> For additional commands, e-mail: dev-help_at_javaserverfaces.dev.java.net