You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by jk...@apache.org on 2007/01/20 20:07:48 UTC

svn commit: r498154 - in /tapestry/tapestry4/trunk: tapestry-framework/src/java/org/apache/tapestry/engine/ tapestry-framework/src/java/org/apache/tapestry/form/ tapestry-framework/src/java/org/apache/tapestry/services/ tapestry-framework/src/java/org/...

Author: jkuhnert
Date: Sat Jan 20 11:07:47 2007
New Revision: 498154

URL: http://svn.apache.org/viewvc?view=rev&rev=498154
Log:
Fixes TAPESTRY-1222. Hopefully the last time the timing of flush needs to be worried about. Now content should be properly
synced up in such a way that writing cookies / headers / state / etc should all work correctly until 
the actual rendering process has started. 

Modified:
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/engine/RequestCycle.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/form/FormSupportImpl.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/ResponseBuilder.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DefaultResponseBuilder.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DojoAjaxResponseBuilder.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/JSONResponseBuilder.java
    tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/DojoAjaxResponseBuilderTest.java
    tapestry/tapestry4/trunk/tapestry-portlet/src/java/org/apache/tapestry/portlet/PortletRendererImpl.java
    tapestry/tapestry4/trunk/tapestry-portlet/src/test/org/apache/tapestry/portlet/TestPortletRenderer.java

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/engine/RequestCycle.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/engine/RequestCycle.java?view=diff&rev=498154&r1=498153&r2=498154
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/engine/RequestCycle.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/engine/RequestCycle.java Sat Jan 20 11:07:47 2007
@@ -519,6 +519,20 @@
 
             recorder.commit();
         }
+        
+        try {
+            
+            // cause headers / cookies to be flushed out to browser 
+
+            _responseBuilder.flush();
+        
+        } catch (Throwable ex)
+        {
+            // But wrap other exceptions in a ApplicationRuntimeException ... this
+            // will ensure that some of the context is available.
+            
+            throw new ApplicationRuntimeException(ex.getMessage(), getPage(), null, ex);
+        }
     }
 
     /**

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/form/FormSupportImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/form/FormSupportImpl.java?view=diff&rev=498154&r1=498153&r2=498154
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/form/FormSupportImpl.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/form/FormSupportImpl.java Sat Jan 20 11:07:47 2007
@@ -113,6 +113,8 @@
 
     protected final IRequestCycle _cycle;
     
+    protected final IdAllocator _elementIdAllocator = new IdAllocator();
+    
     /**
      * Used when rewinding the form to figure to match allocated ids (allocated during the rewind)
      * against expected ids (allocated in the previous request cycle, when the form was rendered).
@@ -126,8 +128,6 @@
      */
 
     private final List _allocatedIds = new ArrayList();
-
-    protected final IdAllocator _elementIdAllocator = new IdAllocator();
 
     private String _encodingType;
 

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/ResponseBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/ResponseBuilder.java?view=diff&rev=498154&r1=498153&r2=498154
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/ResponseBuilder.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/ResponseBuilder.java Sat Jan 20 11:07:47 2007
@@ -95,6 +95,15 @@
     boolean isDynamic();
     
     /**
+     * Causes the output stream to be flushed, used primarily in concert with {@link IRequestCycle} to sync
+     * up flushing of headers to the browser once any page changes have been committed.
+     * 
+     * @throws IOException
+     */
+    void flush()
+    throws IOException;
+    
+    /**
      * Renders the response to a client. Handles transitioning logic
      * for setting up page and associated components for response.
      * 

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DefaultResponseBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DefaultResponseBuilder.java?view=diff&rev=498154&r1=498153&r2=498154
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DefaultResponseBuilder.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DefaultResponseBuilder.java Sat Jan 20 11:07:47 2007
@@ -106,6 +106,7 @@
         _webResponse = webResponse;
         
         // Used by PageRenderSupport
+        
         _assetFactory = assetFactory;
         _namespace = namespace;
     }
@@ -148,11 +149,6 @@
             _writer = _markupWriterSource.newMarkupWriter(printWriter, contentType);
         }
         
-        // Important - causes any cookies stored to properly be written out before the
-        // rest of the response starts being written - see TAPESTRY-825
-        
-        _writer.flush();
-        
         // render response
         
         _prs = new PageRenderSupportImpl(_assetFactory, _namespace, cycle.getPage().getLocation(), this);
@@ -165,6 +161,15 @@
         
         if (_closeWriter)
             _writer.close();
+    }
+    
+    public void flush()
+    throws IOException
+    {
+        // Important - causes any cookies stored to properly be written out before the
+        // rest of the response starts being written - see TAPESTRY-825
+
+        _writer.flush();
     }
     
     /**

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DojoAjaxResponseBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DojoAjaxResponseBuilder.java?view=diff&rev=498154&r1=498153&r2=498154
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DojoAjaxResponseBuilder.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DojoAjaxResponseBuilder.java Sat Jan 20 11:07:47 2007
@@ -13,16 +13,13 @@
 // limitations under the License.
 package org.apache.tapestry.services.impl;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.zip.GZIPOutputStream;
 
 import org.apache.hivemind.Resource;
 import org.apache.hivemind.util.Defense;
@@ -46,7 +43,6 @@
 import org.apache.tapestry.util.ContentType;
 import org.apache.tapestry.util.PageRenderSupportImpl;
 import org.apache.tapestry.util.ScriptUtils;
-import org.apache.tapestry.util.io.GzipUtil;
 import org.apache.tapestry.web.WebRequest;
 import org.apache.tapestry.web.WebResponse;
 
@@ -70,11 +66,10 @@
     // used to create IMarkupWriter
     private RequestLocaleManager _localeManager;
     private MarkupWriterSource _markupWriterSource;
-    private WebRequest _request;
     private WebResponse _response;
+    
     private List _errorPages;
     
-    private ByteArrayOutputStream _output;
     private ContentType _contentType;
     
     // our response writer
@@ -95,6 +90,12 @@
     private boolean _pageRender = false;
     
     /**
+     * Used to keep track of whether or not the appropriate xml response start
+     * block has been started.
+     */
+    private boolean _responseStarted = false;
+    
+    /**
      * Creates a builder with a pre-configured {@link IMarkupWriter}. 
      * Currently only used for testing.
      * 
@@ -143,11 +144,11 @@
         _localeManager = localeManager;
         _markupWriterSource = markupWriterSource;
         _response = webResponse;
-        _request = request;
         _errorPages = errorPages;
         _pageService = service;
         
         // Used by PageRenderSupport
+        
         _assetFactory = assetFactory;
         _namespace = namespace;
     }
@@ -181,21 +182,14 @@
             _contentType.setParameter(ENCODING_KEY, encoding);
         }
         
-        // _output = new ByteArrayOutputStream();
-        
-        PrintWriter printWriter = _response.getPrintWriter(_contentType);
-        // PrintWriter printWriter = new PrintWriter(_output, true);
-        
-        _writer = _markupWriterSource.newMarkupWriter(printWriter, _contentType);
-        
-        // Important - causes any cookies stored to properly be written out before the
-        // rest of the response starts being written - see TAPESTRY-825
-        
-        _writer.flush();
-        
-        parseParameters(cycle);
-        
-        beginResponse();
+        if (_writer == null) {
+            
+            parseParameters(cycle);
+            
+            PrintWriter printWriter = _response.getPrintWriter(_contentType);
+            
+            _writer = _markupWriterSource.newMarkupWriter(printWriter, _contentType);
+        }
         
         // render response
         
@@ -210,41 +204,18 @@
         endResponse();
         
         _writer.close();
-        
-        // writeResponse();
     }
     
-    /**
-     * Causes the actual / real response to be written to the output stream.
-     */
-    void writeResponse()
+    public void flush()
     throws IOException
     {
-        byte[] data = _output.toByteArray();
-        
-        if (GzipUtil.isGzipCapable(_request)) {
-            
-            // reset data buffer
-            _output.reset();
-            
-            GZIPOutputStream gzip = new GZIPOutputStream(_output);
-            
-            gzip.write(data);
-            gzip.close();
-            
-            data = _output.toByteArray();
-            
-            _response.setHeader("Content-Encoding", "gzip");
-        }
-        
-        _response.setContentLength(data.length);
-        
-        OutputStream output = _response.getOutputStream(_contentType);
+        // Important - causes any cookies stored to properly be written out before the
+        // rest of the response starts being written - see TAPESTRY-825
         
-        output.write(data);
+        _writer.flush();
         
-        output.flush();
-        output.close();
+        if (!_responseStarted)
+            beginResponse();
     }
     
     /** 
@@ -592,6 +563,9 @@
     {
         Defense.notNull(id, "id can't be null");
         
+        if (!_responseStarted)
+            beginResponse();
+        
         IMarkupWriter w = (IMarkupWriter)_writers.get(id);
         if (w != null) 
             return w;
@@ -619,6 +593,8 @@
      */
     void beginResponse()
     {
+        _responseStarted = true;
+        
         _writer.printRaw("<?xml version=\"1.0\" encoding=\"" + _cycle.getInfrastructure().getOutputEncoding() + "\"?>");
         _writer.printRaw("<!DOCTYPE html "
                 + "PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/JSONResponseBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/JSONResponseBuilder.java?view=diff&rev=498154&r1=498153&r2=498154
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/JSONResponseBuilder.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/JSONResponseBuilder.java Sat Jan 20 11:07:47 2007
@@ -13,14 +13,11 @@
 // limitations under the License.
 package org.apache.tapestry.services.impl;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.zip.GZIPOutputStream;
 
 import org.apache.hivemind.Resource;
 import org.apache.hivemind.util.Defense;
@@ -41,7 +38,6 @@
 import org.apache.tapestry.services.ServiceConstants;
 import org.apache.tapestry.util.ContentType;
 import org.apache.tapestry.util.PageRenderSupportImpl;
-import org.apache.tapestry.util.io.GzipUtil;
 import org.apache.tapestry.web.WebRequest;
 import org.apache.tapestry.web.WebResponse;
 
@@ -63,10 +59,9 @@
     
     protected RequestLocaleManager _localeManager;
     protected MarkupWriterSource _markupWriterSource;
-    private WebRequest _request;
+    
     private WebResponse _response;
     
-    private ByteArrayOutputStream _output;
     private ContentType _contentType;
     
     private final AssetFactory _assetFactory;
@@ -98,9 +93,9 @@
         _localeManager = localeManager;
         _markupWriterSource = markupWriterSource;
         _response = webResponse;
-        _request = request;
         
         // Used by PageRenderSupport
+        
         _assetFactory = assetFactory;
         _namespace = namespace;
     }
@@ -135,22 +130,17 @@
             _contentType.setParameter(ENCODING_KEY, encoding);
         }
         
-        // _output = new ByteArrayOutputStream();
-        
-        PrintWriter printWriter = _response.getPrintWriter(_contentType);
-        // PrintWriter printWriter = new PrintWriter(_output, true);
-        
-        _writer = _markupWriterSource.newJSONWriter(printWriter, _contentType);
-        
-        // Important - causes any cookies stored to properly be written out before the
-        // rest of the response starts being written - see TAPESTRY-825
-        
-        _writer.flush();
+        if (_writer == null) {
+            
+            parseParameters(cycle);
+
+            PrintWriter printWriter = _response.getPrintWriter(_contentType);
+            
+            _writer = _markupWriterSource.newJSONWriter(printWriter, _contentType);
+        }
         
         // render response
         
-        parseParameters(cycle);
-        
         _prs = new PageRenderSupportImpl(_assetFactory, _namespace, cycle.getPage().getLocation(), this);
         
         TapestryUtils.storePageRenderSupport(cycle, _prs);
@@ -160,41 +150,15 @@
         TapestryUtils.removePageRenderSupport(cycle);
         
         _writer.close();
-        
-        // writeResponse();
     }
     
-    /**
-     * Causes the actual / real response to be written to the output stream.
-     */
-    void writeResponse()
+    public void flush()
     throws IOException
     {
-        byte[] data = _output.toByteArray();
-        
-        if (GzipUtil.isGzipCapable(_request)) {
-            
-            // reset data buffer
-            _output.reset();
-            
-            GZIPOutputStream gzip = new GZIPOutputStream(_output);
-            
-            gzip.write(data);
-            gzip.close();
-            
-            data = _output.toByteArray();
-            
-            _response.setHeader("Content-Encoding", "gzip");
-        }
-        
-        _response.setContentLength(data.length);
-        
-        OutputStream output = _response.getOutputStream(_contentType);
-        
-        output.write(data);
+        // Important - causes any cookies stored to properly be written out before the
+        // rest of the response starts being written - see TAPESTRY-825
         
-        output.flush();
-        output.close();
+        _writer.flush();
     }
     
     /**

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/DojoAjaxResponseBuilderTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/DojoAjaxResponseBuilderTest.java?view=diff&rev=498154&r1=498153&r2=498154
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/DojoAjaxResponseBuilderTest.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/DojoAjaxResponseBuilderTest.java Sat Jan 20 11:07:47 2007
@@ -140,6 +140,8 @@
         IMarkupWriter writer = newMock(IMarkupWriter.class);
         NestedMarkupWriter nested = newMock(NestedMarkupWriter.class);
         
+        Infrastructure infra = newMock(Infrastructure.class);
+        
         List parts = new ArrayList();
         parts.add("id1");
         
@@ -150,6 +152,18 @@
         expect(comp1.getClientId()).andReturn("id1").anyTimes();
         
         expect(comp1.peekClientId()).andReturn("id1").anyTimes();
+        
+        expect(cycle.getInfrastructure()).andReturn(infra);
+        
+        expect(infra.getOutputEncoding()).andReturn("UTF-8");
+        
+        writer.printRaw("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+        writer.printRaw("<!DOCTYPE html "
+                + "PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
+                + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\" [\n"
+                + "<!ENTITY nbsp '&#160;'>\n"
+                + "]>\n");
+        writer.printRaw("<ajax-response>");
         
         expect(writer.getNestedWriter()).andReturn(nested);
         

Modified: tapestry/tapestry4/trunk/tapestry-portlet/src/java/org/apache/tapestry/portlet/PortletRendererImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-portlet/src/java/org/apache/tapestry/portlet/PortletRendererImpl.java?view=diff&rev=498154&r1=498153&r2=498154
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-portlet/src/java/org/apache/tapestry/portlet/PortletRendererImpl.java (original)
+++ tapestry/tapestry4/trunk/tapestry-portlet/src/java/org/apache/tapestry/portlet/PortletRendererImpl.java Sat Jan 20 11:07:47 2007
@@ -63,7 +63,7 @@
                 contentType);
         
         String namespace = _response.getNamespace();
-
+        
         IMarkupWriter nested = writer.getNestedWriter();
         
         ResponseBuilder builder = new DefaultResponseBuilder(nested, _assetFactory, namespace, false);
@@ -71,7 +71,7 @@
         builder.renderResponse(cycle);
         
         String id = "Tapestry Portlet " + _applicationId + " " + namespace;
-
+        
         writer.comment("BEGIN " + id);
         writer.comment("Page: " + page.getPageName());
         writer.comment("Generated: " + new Date());
@@ -86,7 +86,7 @@
         writer.comment("END " + id);
         
         writer.close();
-
+        
         // TODO: Trap errors and do some error reporting here?
     }
 

Modified: tapestry/tapestry4/trunk/tapestry-portlet/src/test/org/apache/tapestry/portlet/TestPortletRenderer.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-portlet/src/test/org/apache/tapestry/portlet/TestPortletRenderer.java?view=diff&rev=498154&r1=498153&r2=498154
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-portlet/src/test/org/apache/tapestry/portlet/TestPortletRenderer.java (original)
+++ tapestry/tapestry4/trunk/tapestry-portlet/src/test/org/apache/tapestry/portlet/TestPortletRenderer.java Sat Jan 20 11:07:47 2007
@@ -123,7 +123,7 @@
         return cycle;
     }
 
-    public void testSuccess() throws Exception
+    public void test_Success() throws Exception
     {
         ContentType ct = new ContentType("text/html");
         PrintWriter pw = newPrintWriter();
@@ -135,8 +135,6 @@
         IMarkupWriter writer = newWriter();
         
         expect(writer.getNestedWriter()).andReturn((NestedMarkupWriter)nested);
-        
-        nested.flush();
         
         MarkupWriterSource source = newSource(pw, ct, writer);
         IPage page = newPage(ct);