You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by im...@apache.org on 2007/10/28 19:59:23 UTC

svn commit: r589395 - in /myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp: JspStateManagerImpl.java JspViewHandlerImpl.java

Author: imario
Date: Sun Oct 28 11:59:22 2007
New Revision: 589395

URL: http://svn.apache.org/viewvc?rev=589395&view=rev
Log:
https://issues.apache.org/jira/browse/MYFACES-1753
Do not require buffering of JSF render output with server side state saving.

Modified:
    myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspStateManagerImpl.java
    myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspViewHandlerImpl.java

Modified: myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspStateManagerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspStateManagerImpl.java?rev=589395&r1=589394&r2=589395&view=diff
==============================================================================
--- myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspStateManagerImpl.java (original)
+++ myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspStateManagerImpl.java Sun Oct 28 11:59:22 2007
@@ -43,7 +43,7 @@
 /**
  * Default StateManager implementation for use when views are defined
  * via tags in JSP pages.
- * 
+ *
  * @author Thomas Spiegl (latest modification by $Author$)
  * @author Manfred Geiler
  * @version $Revision$ $Date$
@@ -104,6 +104,8 @@
     private static final int UNCOMPRESSED_FLAG = 0;
     private static final int COMPRESSED_FLAG = 1;
 
+	private static final int JSF_SEQUENCE_INDEX = 0;
+
     private RenderKitFactory _renderKitFactory = null;
 
     public JspStateManagerImpl()
@@ -163,12 +165,12 @@
         // first, locate the saved state information
         //===========================================
 
-        Object serializedComponentStates;
+		RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
+		ResponseStateManager responseStateManager = renderKit.getResponseStateManager();
+
+		Object serializedComponentStates;
         if (isSavingStateInClient(facesContext))
         {
-            RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
-            ResponseStateManager responseStateManager = renderKit.getResponseStateManager();
-
             if (isLegacyResponseStateManager(responseStateManager))
             {
                 serializedComponentStates = responseStateManager.getComponentStateToRestore(facesContext);
@@ -187,7 +189,9 @@
         }
         else
         {
-            Object[] stateObj = (Object[]) getSerializedViewFromServletSession(facesContext, uiViewRoot.getViewId());
+			Integer serverStateId = getServerStateId((Object[]) responseStateManager.getState(facesContext, uiViewRoot.getViewId()));
+
+			Object[] stateObj = (Object[]) getSerializedViewFromServletSession(facesContext, uiViewRoot.getViewId(), serverStateId);
             if (stateObj == null)
             {
                  log.error("No serialized view found in server session!");
@@ -216,7 +220,12 @@
         if (log.isTraceEnabled()) log.trace("Exiting restoreComponentState");
     }
 
-    /**
+	protected Integer getServerStateId(Object[] state)
+	{
+		return Integer.valueOf((String) state[JSF_SEQUENCE_INDEX], Character.MAX_RADIX);
+	}
+
+	/**
      * See getTreeStructureToSave.
      */
     protected UIViewRoot restoreTreeStructure(FacesContext facesContext,
@@ -225,12 +234,13 @@
     {
         if (log.isTraceEnabled()) log.trace("Entering restoreTreeStructure");
 
-        UIViewRoot uiViewRoot;
+		RenderKit rk = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
+		ResponseStateManager responseStateManager = rk.getResponseStateManager();
+
+		UIViewRoot uiViewRoot;
         if (isSavingStateInClient(facesContext))
         {
             //reconstruct tree structure from request
-            RenderKit rk = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
-            ResponseStateManager responseStateManager = rk.getResponseStateManager();
             Object treeStructure = responseStateManager.getTreeStructureToRestore(facesContext, viewId);
             if (treeStructure == null)
             {
@@ -245,7 +255,9 @@
         else
         {
             //reconstruct tree structure from ServletSession
-            Object[] stateObj = (Object[]) getSerializedViewFromServletSession(facesContext, viewId);
+			Integer serverStateId = getServerStateId((Object[]) responseStateManager.getState(facesContext, viewId));
+
+			Object[] stateObj = (Object[]) getSerializedViewFromServletSession(facesContext, viewId, serverStateId);
             if (stateObj == null)
             {
                 if (log.isDebugEnabled()) log.debug("Exiting restoreTreeStructure - No serialized view found in server session!");
@@ -273,20 +285,23 @@
     {
         if (log.isTraceEnabled()) log.trace("Entering restoreView - viewId: "+viewId+" ; renderKitId: "+renderKitId);
 
-        Object state;
+		RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
+		ResponseStateManager responseStateManager = renderKit.getResponseStateManager();
+
+		Object state;
         if (isSavingStateInClient(facesContext))
         {
             if (log.isTraceEnabled()) log.trace("Restoring view from client");
 
-            RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
-            ResponseStateManager responseStateManager = renderKit.getResponseStateManager();
             state = responseStateManager.getState(facesContext, viewId);
         }
         else
         {
             if (log.isTraceEnabled()) log.trace("Restoring view from session");
 
-            state = getSerializedViewFromServletSession(facesContext, viewId);
+			Integer serverStateId = getServerStateId((Object[]) responseStateManager.getState(facesContext, viewId));
+
+			state = getSerializedViewFromServletSession(facesContext, viewId, serverStateId);
         }
 
         UIViewRoot uiViewRoot = null;
@@ -455,8 +470,14 @@
         {
             responseStateManager.writeState(facesContext, serializedView);
         }
-        else
-        {
+        else if (!isSavingStateInClient(facesContext))
+		{
+			Object[] state = new Object[2];
+			state[JSF_SEQUENCE_INDEX] = Integer.toString(getNextViewSequence(facesContext), Character.MAX_RADIX);
+			responseStateManager.writeState(facesContext, state);
+		}
+		else
+		{
             Object[] state = new Object[2];
             state[0] = serializedView.getStructure();
             state[1] = serializedView.getState();
@@ -527,7 +548,7 @@
         sessionMap.put(SERIALIZED_VIEW_SESSION_ATTR, viewCollection);
     }
 
-    protected Object getSerializedViewFromServletSession(FacesContext context, String viewId)
+    protected Object getSerializedViewFromServletSession(FacesContext context, String viewId, Integer sequence)
     {
         ExternalContext externalContext = context.getExternalContext();
         Map<String, Object> requestMap = externalContext.getRequestMap();
@@ -542,8 +563,9 @@
                     .getSessionMap().get(SERIALIZED_VIEW_SESSION_ATTR);
             if (viewCollection != null)
             {
-                String sequenceStr = externalContext.getRequestParameterMap().get(
-                        RendererUtils.SEQUENCE_PARAM);
+				/*
+				String sequenceStr = externalContext.getRequestParameterMap().get(
+                       RendererUtils.SEQUENCE_PARAM);
                 Integer sequence = null;
                 if (sequenceStr == null)
                 {
@@ -555,6 +577,7 @@
                 {
                     sequence = new Integer(sequenceStr);
                 }
+                */
                 if (sequence != null)
                 {
                     Object state = viewCollection.get(sequence, viewId);
@@ -570,11 +593,24 @@
         return serializedView;
     }
 
-    protected void nextViewSequence(FacesContext facescontext)
+	protected int getNextViewSequence(FacesContext context)
+	{
+		ExternalContext externalContext = context.getExternalContext();
+
+		if (!externalContext.getRequestMap().containsKey(RendererUtils.SEQUENCE_PARAM))
+		{
+			nextViewSequence(context);
+		}
+
+		Integer sequence = (Integer) externalContext.getRequestMap().get(RendererUtils.SEQUENCE_PARAM);
+		return sequence.intValue();
+	}
+
+	protected void nextViewSequence(FacesContext facescontext)
     {
         ExternalContext externalContext = facescontext.getExternalContext();
         Object sessionObj = externalContext.getSession(true);
-        synchronized(sessionObj) // synchronized to increase sequence if multiple requests 
+        synchronized(sessionObj) // synchronized to increase sequence if multiple requests
                                  // are handled at the same time for the session
         {
             Map<String, Object> map = externalContext.getSessionMap();
@@ -635,13 +671,13 @@
                 return null;
             }
         }
-        
-        
-        if (log.isTraceEnabled()) 
+
+
+        if (log.isTraceEnabled())
         	log.trace("Exiting serializeView - do not serialize state in session.");
-        
+
         return serializedView;
-        
+
     }
 
     /**
@@ -751,7 +787,7 @@
         private final List<Object> _keys = new ArrayList<Object>(DEFAULT_NUMBER_OF_VIEWS_IN_SESSION);
         private final Map<Object, Object> _serializedViews = new HashMap<Object, Object>();
 
-        // old views will be hold as soft references which will be removed by 
+        // old views will be hold as soft references which will be removed by
         // the garbage collector if free memory is low
         private transient Map<Object, Object> _oldSerializedViews = null;
 
@@ -759,7 +795,7 @@
         {
             Object key = new SerializedViewKey(context);
             _serializedViews.put(key, state);
-            
+
             while (_keys.remove(key));
             _keys.add(key);
 

Modified: myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspViewHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspViewHandlerImpl.java?rev=589395&r1=589394&r2=589395&view=diff
==============================================================================
--- myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspViewHandlerImpl.java (original)
+++ myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspViewHandlerImpl.java Sun Oct 28 11:59:22 2007
@@ -242,7 +242,7 @@
 
         if (log.isTraceEnabled())
             log.trace("Rendering JSP view: " + viewId);
-        
+
         ServletResponse response = (ServletResponse) externalContext.getResponse();
         ServletRequest request = (ServletRequest) externalContext.getRequest();
 
@@ -272,24 +272,47 @@
         RenderKitFactory renderFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
         RenderKit renderKit = renderFactory.getRenderKit(facesContext, viewToRender.getRenderKitId());
 
-        StateMarkerAwareWriter stateAwareWriter = new StateMarkerAwareWriter();
+		ResponseWriter responseWriter = facesContext.getResponseWriter();
+		if (responseWriter == null)
+		{
+			responseWriter = renderKit.createResponseWriter(response.getWriter(), null,
+					((HttpServletRequest) externalContext.getRequest()).getCharacterEncoding());
+			facesContext.setResponseWriter(responseWriter);
+		}
+
+		ResponseWriter oldResponseWriter = responseWriter;
+		StateMarkerAwareWriter stateAwareWriter = null;
 
-        // Create a new response-writer using as an underlying writer the stateAwareWriter
-        // Effectively, all output will be buffered in the stateAwareWriter so that later
-        // this writer can replace the state-markers with the actual state.
-        ResponseWriter oldResponseWriter = facesContext.getResponseWriter();
-        ResponseWriter newResponseWriter = hookInStateAwareWriter(
-                oldResponseWriter, stateAwareWriter, renderKit, externalContext);
+		StateManager stateManager = facesContext.getApplication().getStateManager();
+		if (stateManager.isSavingStateInClient(facesContext))
+		{
+			stateAwareWriter = new StateMarkerAwareWriter();
 
+			// Create a new response-writer using as an underlying writer the stateAwareWriter
+			// Effectively, all output will be buffered in the stateAwareWriter so that later
+			// this writer can replace the state-markers with the actual state.
+			responseWriter = hookInStateAwareWriter(
+					oldResponseWriter, stateAwareWriter, renderKit, externalContext);
+			facesContext.setResponseWriter(responseWriter);
+		}
 
-        actuallyRenderView(facesContext, newResponseWriter, oldResponseWriter, viewToRender);
+		actuallyRenderView(facesContsext, viewToRender);
 
-        //We're done with the document - now we can write all content
+		facesContext.setResponseWriter(oldResponseWriter);
+
+		//We're done with the document - now we can write all content
         //to the response, properly replacing the state-markers on the way out
         //by using the stateAwareWriter
-        stateAwareWriter.flushToWriter(response.getWriter());
+		if (stateManager.isSavingStateInClient(facesContext))
+		{
+			stateAwareWriter.flushToWriter(response.getWriter());
+		}
+		else
+		{
+			stateManager.saveView(facesContext);
+		}
 
-        // Final step - we output any content in the wrappedResponse response from above to the response,
+		// Final step - we output any content in the wrappedResponse response from above to the response,
         // removing the wrappedResponse response from the request, we don't need it anymore
         ViewResponseWrapper afterViewTagResponse = (ViewResponseWrapper) externalContext.getRequestMap().get(
                 AFTER_VIEW_TAG_CONTENT_PARAM);
@@ -311,29 +334,21 @@
      * @throws IOException
      */
     private void actuallyRenderView(FacesContext facesContext,
-                                    ResponseWriter newResponseWriter, ResponseWriter oldResponseWriter,
                                     UIViewRoot viewToRender) throws IOException {
         // Set the new ResponseWriter into the FacesContext, saving the old one aside.
-        facesContext.setResponseWriter(newResponseWriter);
+        ResponseWriter responseWriter = facesContext.getResponseWriter();
 
         //Now we actually render the document
         // Call startDocument() on the ResponseWriter.
-        newResponseWriter.startDocument();
+        responseWriter.startDocument();
 
         // Call encodeAll() on the UIViewRoot
         viewToRender.encodeAll(facesContext);
 
         // Call endDocument() on the ResponseWriter
-        newResponseWriter.endDocument();
+        responseWriter.endDocument();
 
-        newResponseWriter.flush();
-
-        // If the old ResponseWriter was not null, place the old ResponseWriter back
-        // into the FacesContext.
-        if (oldResponseWriter != null)
-        {
-            facesContext.setResponseWriter(oldResponseWriter);
-        }
+        responseWriter.flush();
     }
 
     /**Create a new response-writer using as an underlying writer the stateAwareWriter
@@ -351,12 +366,14 @@
      * @return
      */
     private ResponseWriter hookInStateAwareWriter(ResponseWriter oldResponseWriter, StateMarkerAwareWriter stateAwareWriter, RenderKit renderKit, ExternalContext externalContext) {
+		return oldResponseWriter.cloneWithWriter(stateAwareWriter);
+		/*
         ResponseWriter newResponseWriter;
         if (oldResponseWriter != null)
         {
             newResponseWriter = oldResponseWriter.cloneWithWriter(stateAwareWriter);
         }
-        else
+		else
         {
             if (log.isTraceEnabled())
                 log.trace("Creating new ResponseWriter");
@@ -364,6 +381,7 @@
                     ((HttpServletRequest) externalContext.getRequest()).getCharacterEncoding());
         }
         return newResponseWriter;
+        */
     }
 
     /**Build the view-tree before rendering.
@@ -410,18 +428,26 @@
 
     /**
      * Writes a state marker that is replaced later by one or more hidden form inputs.
-     * 
+     *
      * @param facesContext
      * @throws IOException
      */
     public void writeState(FacesContext facesContext) throws IOException
     {
+		StateManager stateManager = facesContext.getApplication().getStateManager();
+		if (stateManager.isSavingStateInClient(facesContext))
+		{
         // Only write state marker if javascript view state is disabled
     	ExternalContext extContext = facesContext.getExternalContext();
         if (!(JavascriptUtils.isJavascriptAllowed(extContext) && MyfacesConfig.getCurrentInstance(extContext).isViewStateJavascript())) {
         	facesContext.getResponseWriter().write(FORM_STATE_MARKER);
         }
-    }
+		}
+		else
+		{
+			stateManager.writeState(facesContext, new Object[2]);
+		}
+	}
 
     /**
      * Writes the response and replaces the state marker tags with the state information for the current context
@@ -503,13 +529,13 @@
                 	write(contentBuffer, lastFormMarkerPos, contentBuffer.length(), writer);
                 }
             }
-            
+
         }
 
         /**
-         * Writes the content of the specified StringBuffer from index 
+         * Writes the content of the specified StringBuffer from index
          * <code>beginIndex</code> to index <code>endIndex - 1</code>.
-         * 
+         *
          * @param contentBuffer  the <code>StringBuffer</code> to copy content from
          * @param begin  the beginning index, inclusive.
          * @param end  the ending index, exclusive