You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2007/11/27 02:01:18 UTC

svn commit: r598484 - in /tapestry/tapestry5/trunk: tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/ tapestry-core/src/main/java/org/apache/tapestry/dom/ tapestry-core/src/main/java/org/apache/tapestry/internal/services/ tapestry-core/sr...

Author: hlship
Date: Mon Nov 26 17:01:14 2007
New Revision: 598484

URL: http://svn.apache.org/viewvc?rev=598484&view=rev
Log:
Add support for multiple different component event response types for Ajax component event handler methods.

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessor.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/JSONObjectEventResultProcessor.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderCommandComponentEventResultProcessor.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessorTest.java
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/dom/Node.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentActionRequestHandler.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxFilter.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClassResultProcessor.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionRequestHandlerImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ConstructorArg.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageMarkupRenderer.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialMarkupRenderer.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialMarkupRendererImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64OutputStream.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/util/IntegerRange.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestFilter.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestHandler.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldStrategy.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/dom/DOMTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LocaleTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LoopTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/PrefixMethodTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java
    tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry/upload/components/Upload.java
    tapestry/tapestry5/trunk/tapestry-upload/src/test/java/org/apache/tapestry/upload/components/UploadTest.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java Mon Nov 26 17:01:14 2007
@@ -82,6 +82,10 @@
     private MarkupWriterFactory _factory;
 
     @Inject
+    @Path("${tapestry.scriptaculous}/controls.js")
+    private Asset _controlsLibrary;
+
+    @Inject
     @Path("classpath:org/apache/tapestry/ajax-loader.gif")
     private Asset _loader;
 
@@ -106,6 +110,11 @@
     @Parameter(defaultPrefix = "literal")
     private String _tokens;
 
+    void setupRender()
+    {
+        _pageRenderSupport.addScriptLink(_controlsLibrary);
+    }
+
     /**
      * Mixin afterRender phrase occurs after the component itself. This is where we write the <div>
      * element and the JavaScript.
@@ -191,7 +200,9 @@
         MarkupWriter writer = _factory.newMarkupWriter();
 
         // T4.1 has more flexibility, it can decorate the options with icons, etc.
-        // But this will do for now.
+        // But this will do for now.  The Autocompleter widget will display
+        // icons, but only the character text is stored into the target text field.
+        // TODO: Support alternate return types allowing the event handler method to more precisely control the output.
 
         writer.element("ul");
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/dom/Node.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/dom/Node.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/dom/Node.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/dom/Node.java Mon Nov 26 17:01:14 2007
@@ -56,16 +56,14 @@
 
     void addChild(Node child)
     {
-        if (_children == null)
-            _children = newList();
+        if (_children == null) _children = newList();
 
         _children.add(child);
     }
 
     void insertChildAt(int index, Node child)
     {
-        if (_children == null)
-            _children = newList();
+        if (_children == null) _children = newList();
 
         _children.add(index, child);
     }
@@ -77,8 +75,7 @@
 
     void writeChildMarkup(PrintWriter writer)
     {
-        if (_children == null)
-            return;
+        if (_children == null) return;
 
         for (Node child : _children)
             child.toMarkup(writer);
@@ -87,10 +84,12 @@
     /**
      * @return the concatenation of the String representations {@link #toString()} of its children.
      */
-    public String getChildText()
+    public final String getChildMarkup()
     {
         PrintOutCollector collector = new PrintOutCollector();
+
         writeChildMarkup(collector.getPrintWriter());
+
         return collector.getPrintOut();
     }
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentActionRequestHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentActionRequestHandler.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentActionRequestHandler.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentActionRequestHandler.java Mon Nov 26 17:01:14 2007
@@ -15,22 +15,15 @@
 package org.apache.tapestry.internal.services;
 
 import org.apache.tapestry.ComponentEventHandler;
-import org.apache.tapestry.MarkupWriter;
 import org.apache.tapestry.TapestryConstants;
-import org.apache.tapestry.dom.Element;
 import org.apache.tapestry.internal.structure.ComponentPageElement;
 import org.apache.tapestry.internal.structure.Page;
-import org.apache.tapestry.internal.util.ContentType;
 import org.apache.tapestry.internal.util.Holder;
 import org.apache.tapestry.json.JSONObject;
 import org.apache.tapestry.runtime.Component;
-import org.apache.tapestry.runtime.RenderCommand;
-import org.apache.tapestry.services.ComponentActionRequestHandler;
-import org.apache.tapestry.services.MarkupWriterFactory;
-import org.apache.tapestry.services.Response;
+import org.apache.tapestry.services.*;
 
 import java.io.IOException;
-import java.io.PrintWriter;
 
 /**
  * Similar to {@link ComponentActionRequestHandlerImpl}, but built around the Ajax request cycle, where the action request
@@ -46,19 +39,31 @@
 
     private final Response _response;
 
+    private final PageRenderQueue _queue;
+
+    private final ComponentEventResultProcessor _resultProcessor;
+
     public AjaxComponentActionRequestHandler(RequestPageCache cache, MarkupWriterFactory factory,
-                                             PartialMarkupRenderer renderer, Response response)
+                                             PartialMarkupRenderer renderer, Response response, PageRenderQueue queue,
+                                             @Ajax ComponentEventResultProcessor resultProcessor)
     {
         _cache = cache;
         _factory = factory;
         _renderer = renderer;
         _response = response;
+        _queue = queue;
+        _resultProcessor = resultProcessor;
     }
 
-    public boolean handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
-                          String[] activationContext) throws IOException
+    public void handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
+                       String[] activationContext) throws IOException
     {
-        final Page page = _cache.get(logicalPageName);
+        Page page = _cache.get(logicalPageName);
+
+        // If we end up doing a partial render, the page render queue service needs to know the
+        // page that will be rendered (for logging purposes, if nothing else).
+
+        _queue.initializeForCompletePage(page);
 
         ComponentPageElement element = page.getComponentElementByNestedId(nestedComponentId);
 
@@ -70,24 +75,17 @@
             @SuppressWarnings("unchecked")
             public boolean handleResult(Object result, Component component, String methodDescription)
             {
-                // TODO: Very limiting; event handler should be able to return a component or a StreamResponse
-                // as well.  Perhaps others.  The problem is the page. Maybe we need to store the
-                // page in a global?
-
-                if (!(result instanceof RenderCommand)) throw new IllegalArgumentException(
-                        String.format("Return type %s is not supported.", result.getClass().getName()));
-
-
                 try
                 {
-                    sendClientResponse(page, (RenderCommand) result);
+                    _resultProcessor.processComponentEvent(result, component, methodDescription);
                 }
                 catch (IOException ex)
                 {
+                    // Jump through some hoops to escape this block, which doesn't
+                    // declare IOException
                     exceptionHolder.put(ex);
                 }
 
-
                 holder.put(true);
 
                 return true;
@@ -98,51 +96,17 @@
 
         if (exceptionHolder.hasValue()) throw exceptionHolder.get();
 
-        if (holder.hasValue()) return true;
+        if (holder.hasValue()) return;
 
         element.triggerEvent(eventType, context, handler);
 
         if (exceptionHolder.hasValue()) throw exceptionHolder.get();
 
-        if (holder.hasValue()) return true;
-
-        PrintWriter pw = _response.getPrintWriter("text/javascript");
-
-        pw.print("{ }");
-
-        pw.flush();
-
-        return true;
-    }
-
-    private void sendClientResponse(Page page, RenderCommand rootRenderCommand) throws IOException
-    {
-        // This may be problematic as the charset of the response is not
-        // going to be set properly I think.  We'll loop back to that.
-
-        ContentType contentType = new ContentType("text/javascript");
-
-        MarkupWriter writer = _factory.newMarkupWriter();
-
-        // The partial will quite often contain multiple elements (or just a block of plain text),
-        // so those must be enclosed in a root element.
-
-        Element root = writer.element("ajax-partial");
-
-        _renderer.renderPartialPageMarkup(page, rootRenderCommand, writer);
-
-        writer.end();
-
-        String content = root.getChildText().trim();
+        if (holder.hasValue()) return;
 
         JSONObject reply = new JSONObject();
 
-        reply.put("content", content);
-
-        PrintWriter pw = _response.getPrintWriter(contentType.toString());
-
-        pw.print(reply);
+        _resultProcessor.processComponentEvent(reply, null, null);
 
-        pw.flush();
     }
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessor.java?rev=598484&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessor.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessor.java Mon Nov 26 17:01:14 2007
@@ -0,0 +1,56 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+
+import java.io.IOException;
+
+/**
+ * Performs a partial page render based on a
+ */
+public class AjaxComponentInstanceEventResultProcessor implements ComponentEventResultProcessor<Component>
+{
+    private final RequestPageCache _cache;
+    private final PartialMarkupRenderer _renderer;
+
+    public AjaxComponentInstanceEventResultProcessor(PartialMarkupRenderer renderer, RequestPageCache cache)
+    {
+        _renderer = renderer;
+        _cache = cache;
+    }
+
+    public void processComponentEvent(Component value, Component component, String methodDescripion) throws IOException
+    {
+        ComponentResources resources = value.getComponentResources();
+
+        String pageName = resources.getPageName();
+
+        Page page = _cache.get(pageName);
+
+        String nestedId = resources.getNestedId();
+
+        // The user may return a complete page instance, which isn't really a partial render, I guess.
+        // Depends on the structure of the page returned.
+
+        RenderCommand command = nestedId == null ? page.getRootElement() : page.getComponentElementByNestedId(nestedId);
+
+        _renderer.renderPartialPageMarkup(command);
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxFilter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxFilter.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxFilter.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxFilter.java Mon Nov 26 17:01:14 2007
@@ -39,12 +39,12 @@
     }
 
 
-    public boolean handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
-                          String[] activationContext, ComponentActionRequestHandler handler) throws IOException
+    public void handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
+                       String[] activationContext, ComponentActionRequestHandler handler) throws IOException
     {
         ComponentActionRequestHandler next = _request.isXHR() ? _ajaxHandler : handler;
 
-        return next.handle(logicalPageName, nestedComponentId, eventType, context, activationContext);
+        next.handle(logicalPageName, nestedComponentId, eventType, context, activationContext);
     }
 
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClassResultProcessor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClassResultProcessor.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClassResultProcessor.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClassResultProcessor.java Mon Nov 26 17:01:14 2007
@@ -1,17 +1,17 @@
-// Copyright 2007 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package org.apache.tapestry.internal.services;
 
 import org.apache.tapestry.Link;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionDispatcher.java Mon Nov 26 17:01:14 2007
@@ -110,9 +110,10 @@
         String[] activationContext = activationContextValue == null ? _emptyString : decodeContext(
                 activationContextValue);
 
-        return _componentActionRequestHandler.handle(logicalPageName, nestedComponentId, eventType, eventContext,
-                                                     activationContext);
+        _componentActionRequestHandler.handle(logicalPageName, nestedComponentId, eventType, eventContext,
+                                              activationContext);
 
+        return true;
     }
 
     private String[] decodeContext(String input)

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionRequestHandlerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionRequestHandlerImpl.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionRequestHandlerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentActionRequestHandlerImpl.java Mon Nov 26 17:01:14 2007
@@ -47,8 +47,8 @@
         _response = response;
     }
 
-    public boolean handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
-                          String[] activationContext) throws IOException
+    public void handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
+                       String[] activationContext) throws IOException
     {
         Page page = _cache.get(logicalPageName);
 
@@ -83,16 +83,16 @@
 
         page.getRootElement().triggerEvent(TapestryConstants.ACTIVATE_EVENT, activationContext, handler);
 
-        if (holder.hasValue()) return true;
+        if (holder.hasValue()) return;
 
         element.triggerEvent(eventType, context, handler);
 
-        if (holder.hasValue()) return true;
+        if (holder.hasValue()) return;
 
         Link link = _linkFactory.createPageLink(page, false);
 
         _response.sendRedirect(link);
 
-        return true;
+        return;
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ConstructorArg.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ConstructorArg.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ConstructorArg.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ConstructorArg.java Mon Nov 26 17:01:14 2007
@@ -1,17 +1,17 @@
-// Copyright 2006 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package org.apache.tapestry.internal.services;
 
 import javassist.CtClass;

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/JSONObjectEventResultProcessor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/JSONObjectEventResultProcessor.java?rev=598484&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/JSONObjectEventResultProcessor.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/JSONObjectEventResultProcessor.java Mon Nov 26 17:01:14 2007
@@ -0,0 +1,48 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.json.JSONObject;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+import org.apache.tapestry.services.Response;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+
+/**
+ * Implemention of {@link ComponentEventResultProcessor} for {@link org.apache.tapestry.json.JSONObject}, allowing
+ * a component event handler to return a JSONObject that will be sent directly to the client as the reply.
+ * This is often used with custom components that need a custom JSON response.
+ */
+public class JSONObjectEventResultProcessor implements ComponentEventResultProcessor<JSONObject>
+{
+    private final Response _response;
+
+    public JSONObjectEventResultProcessor(Response response)
+    {
+        _response = response;
+    }
+
+    public void processComponentEvent(JSONObject value, Component component, String methodDescripion) throws IOException
+    {
+        PrintWriter pw = _response.getPrintWriter("text/javascript");
+
+        pw.print(value.toString());
+
+        pw.flush();
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageMarkupRenderer.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageMarkupRenderer.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageMarkupRenderer.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageMarkupRenderer.java Mon Nov 26 17:01:14 2007
@@ -1,17 +1,17 @@
-// Copyright 2006 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package org.apache.tapestry.internal.services;
 
 import org.apache.tapestry.MarkupWriter;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java Mon Nov 26 17:01:14 2007
@@ -35,7 +35,7 @@
     /**
      * Initializes the queue for rendering of a portion of a page.
      */
-    void initializeForPartialPageRender(Page page, RenderCommand rootCommand);
+    void initializeForPartialPageRender(RenderCommand rootCommand);
 
     /**
      * Render to the write, as setup by the initialize method.

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java Mon Nov 26 17:01:14 2007
@@ -33,9 +33,10 @@
         _rootCommand = page.getRootElement();
     }
 
-    public void initializeForPartialPageRender(Page page, RenderCommand rootCommand)
+    public void initializeForPartialPageRender(RenderCommand rootCommand)
     {
-        _page = page;
+        if (_page == null) throw new IllegalStateException("Page must be specified before root render command.");
+
         _rootCommand = rootCommand;
     }
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialMarkupRenderer.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialMarkupRenderer.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialMarkupRenderer.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialMarkupRenderer.java Mon Nov 26 17:01:14 2007
@@ -14,22 +14,21 @@
 
 package org.apache.tapestry.internal.services;
 
-import org.apache.tapestry.MarkupWriter;
-import org.apache.tapestry.internal.structure.Page;
 import org.apache.tapestry.runtime.RenderCommand;
 
+import java.io.IOException;
+
 /**
  * Used to render portions of a page as part of an
- * {@linkplain AjaxComponentActionRequestHandler Ajax request}.
+ * {@linkplain AjaxComponentActionRequestHandler Ajax request}.    This encapsulates
+ * rendering of the partial response and then the construction of a {@linkplain org.apache.tapestry.json.JSONObject JSON reply}.
  */
 public interface PartialMarkupRenderer
 {
     /**
      * Used to render a partial response as part of an Ajax action request.
      *
-     * @param page              page used to perform the render
-     * @param rootRenderCommand initial object to render
-     * @param writer            writer used to perform the render
+     * @param renderCommand command that will be executed to render the content
      */
-    void renderPartialPageMarkup(Page page, RenderCommand rootRenderCommand, MarkupWriter writer);
+    void renderPartialPageMarkup(RenderCommand renderCommand) throws IOException;
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialMarkupRendererImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialMarkupRendererImpl.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialMarkupRendererImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialMarkupRendererImpl.java Mon Nov 26 17:01:14 2007
@@ -15,9 +15,16 @@
 package org.apache.tapestry.internal.services;
 
 import org.apache.tapestry.MarkupWriter;
-import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.internal.util.ContentType;
+import org.apache.tapestry.json.JSONObject;
 import org.apache.tapestry.runtime.RenderCommand;
 import org.apache.tapestry.services.Environment;
+import org.apache.tapestry.services.MarkupWriterFactory;
+import org.apache.tapestry.services.Response;
+
+import java.io.IOException;
+import java.io.PrintWriter;
 
 public class PartialMarkupRendererImpl implements PartialMarkupRenderer
 {
@@ -25,20 +32,54 @@
 
     private final PageRenderQueue _pageRenderQueue;
 
-    public PartialMarkupRendererImpl(Environment environment, PageRenderQueue pageRenderQueue)
+    private final MarkupWriterFactory _factory;
+
+    private final Response _response;
+
+    public PartialMarkupRendererImpl(Environment environment, PageRenderQueue pageRenderQueue,
+                                     MarkupWriterFactory factory, Response response)
     {
         _environment = environment;
         _pageRenderQueue = pageRenderQueue;
+        _factory = factory;
+        _response = response;
     }
 
-    public void renderPartialPageMarkup(Page page, RenderCommand rootRenderCommand, MarkupWriter writer)
+    public void renderPartialPageMarkup(RenderCommand rootRenderCommand) throws IOException
     {
         _environment.clear();
 
-        _pageRenderQueue.initializeForPartialPageRender(page, rootRenderCommand);
+        // This may be problematic as the charset of the response is not
+        // going to be set properly I think.  We'll loop back to that.
+
+        ContentType contentType = new ContentType("text/javascript");
+
+        MarkupWriter writer = _factory.newMarkupWriter();
+
+        // The partial will quite often contain multiple elements (or just a block of plain text),
+        // so those must be enclosed in a root element.
+
+        Element root = writer.element("ajax-partial");
+
+        _pageRenderQueue.initializeForPartialPageRender(rootRenderCommand);
 
-        // No pipeline for partial rendering, yet.
+        // TODO: This is where we will set up a pipeline to provide environmentals and,
+        // perhaps, to catch errors and inform the client.
 
         _pageRenderQueue.render(writer);
+
+        writer.end();
+
+        String content = root.getChildMarkup().trim();
+
+        JSONObject reply = new JSONObject();
+
+        reply.put("content", content);
+
+        PrintWriter pw = _response.getPrintWriter(contentType.toString());
+
+        pw.print(reply);
+
+        pw.flush();
     }
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderCommandComponentEventResultProcessor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderCommandComponentEventResultProcessor.java?rev=598484&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderCommandComponentEventResultProcessor.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderCommandComponentEventResultProcessor.java Mon Nov 26 17:01:14 2007
@@ -0,0 +1,42 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+
+import java.io.IOException;
+
+/**
+ * Processor for objects that implement {@link RenderCommand} (such as {@link org.apache.tapestry.internal.structure.BlockImpl}).
+ *
+ * @see org.apache.tapestry.internal.services.PartialMarkupRenderer#renderPartialPageMarkup(org.apache.tapestry.runtime.RenderCommand)
+ */
+public class RenderCommandComponentEventResultProcessor implements ComponentEventResultProcessor<RenderCommand>
+{
+    private final PartialMarkupRenderer _renderer;
+
+    public RenderCommandComponentEventResultProcessor(PartialMarkupRenderer renderer)
+    {
+        _renderer = renderer;
+    }
+
+    public void processComponentEvent(RenderCommand value, Component component, String methodDescripion)
+            throws IOException
+    {
+        _renderer.renderPartialPageMarkup(value);
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64OutputStream.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64OutputStream.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64OutputStream.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64OutputStream.java Mon Nov 26 17:01:14 2007
@@ -1,17 +1,17 @@
-// Copyright 2006 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package org.apache.tapestry.internal.util;
 
 import org.apache.commons.codec.binary.Base64;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/util/IntegerRange.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/util/IntegerRange.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/util/IntegerRange.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/util/IntegerRange.java Mon Nov 26 17:01:14 2007
@@ -1,17 +1,17 @@
-// Copyright 2006 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package org.apache.tapestry.internal.util;
 
 import java.util.Iterator;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestFilter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestFilter.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestFilter.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestFilter.java Mon Nov 26 17:01:14 2007
@@ -31,8 +31,7 @@
      * @param context           context information to provide to the event handler
      * @param activationContext activation context for the page
      * @param handler           to delegate to
-     * @return true if the request has been handled (and a response sent to the client), false otherwise
      */
-    boolean handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
-                   String[] activationContext, ComponentActionRequestHandler handler) throws IOException;
+    void handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
+                String[] activationContext, ComponentActionRequestHandler handler) throws IOException;
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestHandler.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestHandler.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestHandler.java Mon Nov 26 17:01:14 2007
@@ -40,8 +40,7 @@
      * @param eventType         the type of event to trigger on the component
      * @param context           context information to provide to the event handler
      * @param activationContext activation context for the page
-     * @return true if the request has been handled (and a response sent to the client), false otherwise
      */
-    boolean handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
-                   String[] activationContext) throws IOException;
+    void handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
+                String[] activationContext) throws IOException;
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldStrategy.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldStrategy.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldStrategy.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldStrategy.java Mon Nov 26 17:01:14 2007
@@ -1,17 +1,17 @@
-// Copyright 2006 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package org.apache.tapestry.services;
 
 import java.util.Collection;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java Mon Nov 26 17:01:14 2007
@@ -38,6 +38,7 @@
 import org.apache.tapestry.ioc.internal.util.InternalUtils;
 import org.apache.tapestry.ioc.services.*;
 import org.apache.tapestry.ioc.util.StrategyRegistry;
+import org.apache.tapestry.json.JSONObject;
 import org.apache.tapestry.runtime.Component;
 import org.apache.tapestry.runtime.ComponentResourcesAware;
 import org.apache.tapestry.runtime.RenderCommand;
@@ -955,10 +956,30 @@
                                       ServletApplicationInitializerFilter.class, configuration, terminator);
     }
 
+    /**
+     * The component event result processor used for normal component requests.
+     */
     @Marker({Primary.class, Traditional.class})
     public ComponentEventResultProcessor buildComponentEventResultProcessor(
             Map<Class, ComponentEventResultProcessor> configuration)
     {
+        return constructComponentEventResultProcessor(configuration);
+    }
+
+    /**
+     * The component event result processor used for Ajax-oriented component requests.
+     */
+    @Marker(Ajax.class)
+    public ComponentEventResultProcessor buildAjaxComponentEventResultProcessor(
+            Map<Class, ComponentEventResultProcessor> configuration)
+    {
+        return constructComponentEventResultProcessor(configuration);
+
+    }
+
+    private ComponentEventResultProcessor constructComponentEventResultProcessor(
+            Map<Class, ComponentEventResultProcessor> configuration)
+    {
         Set<Class> handledTypes = CollectionFactory.newSet(configuration.keySet());
 
         // A slight hack!
@@ -1093,10 +1114,18 @@
      * <dl>
      * <dt>Object</dt>
      * <dd>Failure case, added to provide a more useful exception message</dd>
-     * <dt>Link</dt>
-     * <dd>Wraps the Link to send a redirect</dd>
+     * <dt>{@link Link}</dt>
+     * <dd>Sends a redirect to the link (which is typically a page render link)</dd>
      * <dt>String</dt>
-     * <dd>The name of the page to render the response (after a redirect)</dd>
+     * <dd>Sends a page render redirect</dd>
+     * <dt>Class</dt>
+     * <dd>Interpreted as the class name of a page, sends a page render render redirect (this is more refactoring safe
+     * than the page name)</dd>
+     * <dt>{@link Component}</dt>
+     * <dd>A page's root component (though a non-root component will work, but will generate a warning). A direct
+     * to the containing page is sent.</dd>
+     * <dt>{@link org.apache.tapestry.StreamResponse}</dt>
+     * <dd>The stream response is sent as the actual reply.</dd>
      * </dl>
      */
     public void contributeComponentEventResultProcessor(
@@ -1108,11 +1137,8 @@
 
             MappedConfiguration<Class, ComponentEventResultProcessor> configuration)
     {
-
-
         configuration.add(Link.class, new ComponentEventResultProcessor<Link>()
         {
-
             public void processComponentEvent(Link value, Component component, String methodDescripion)
                     throws IOException
             {
@@ -1130,6 +1156,29 @@
         configuration.add(StreamResponse.class, new StreamResponseResultProcessor(_response));
     }
 
+
+    /**
+     * Contributes handlers for the following types:
+     * <dl>
+     * <dt>Object</dt> <dd>Failure case, added to provide more useful exception message</dd>
+     * <dt>{@link RenderCommand}</dt> <dd>Typically, a {@link org.apache.tapestry.Block}</dd>
+     * <dt>{@link Component}</dt> <dd>Renders the component and its body</dd>
+     * <dt>{@link org.apache.tapestry.json.JSONObject}</dt>
+     * <dd>The JSONObject is returned as a text/javascript response</dd>
+     * <dt>{@link org.apache.tapestry.StreamResponse}</dt>
+     * <dd>The stream response is sent as the actual response</dd>*
+     * </dl>
+     */
+
+    public void contributeAjaxComponentEventResultProcessor(
+            MappedConfiguration<Class, ComponentEventResultProcessor> configuration, ObjectLocator locator)
+    {
+        configuration.add(RenderCommand.class, locator.autobuild(RenderCommandComponentEventResultProcessor.class));
+        configuration.add(Component.class, locator.autobuild(AjaxComponentInstanceEventResultProcessor.class));
+        configuration.add(JSONObject.class, new JSONObjectEventResultProcessor(_response));
+        configuration.add(StreamResponse.class, new StreamResponseResultProcessor(_response));
+    }
+
     public void contributeMasterDispatcher(OrderedConfiguration<Dispatcher> configuration,
 
                                            ClasspathAssetAliasManager aliasManager,
@@ -1835,12 +1884,12 @@
     {
         ComponentActionRequestFilter requestEncodingFilter = new ComponentActionRequestFilter()
         {
-            public boolean handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
-                                  String[] activationContext, ComponentActionRequestHandler handler) throws IOException
+            public void handle(String logicalPageName, String nestedComponentId, String eventType, String[] context,
+                               String[] activationContext, ComponentActionRequestHandler handler) throws IOException
             {
                 encodingInitializer.initializeRequestEncoding(logicalPageName);
 
-                return handler.handle(logicalPageName, nestedComponentId, eventType, context, activationContext);
+                handler.handle(logicalPageName, nestedComponentId, eventType, context, activationContext);
             }
 
         };

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/dom/DOMTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/dom/DOMTest.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/dom/DOMTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/dom/DOMTest.java Mon Nov 26 17:01:14 2007
@@ -212,8 +212,8 @@
         Element e0 = d.newRootElement("root");
         Element e1 = e0.element("e1");
         e1.text("123");
-        assertEquals(e1.getChildText(), "123");
-        assertEquals(e0.getChildText(), "<e1>123</e1>");
+        assertEquals(e1.getChildMarkup(), "123");
+        assertEquals(e0.getChildMarkup(), "<e1>123</e1>");
     }
 
     @Test

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LocaleTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LocaleTest.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LocaleTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LocaleTest.java Mon Nov 26 17:01:14 2007
@@ -31,7 +31,7 @@
     public void no_preferred_language()
     {
         Document doc = _tester.renderPage("TestPageForLocale");
-        assertEquals(doc.getElementById("id1").getChildText(), "English page");
+        assertEquals(doc.getElementById("id1").getChildMarkup(), "English page");
     }
 
     @Test
@@ -39,17 +39,17 @@
     {
         _tester.setPreferedLanguage(Locale.CANADA_FRENCH);
         Document doc = _tester.renderPage("TestPageForLocale");
-        assertEquals(doc.getElementById("id1").getChildText(), "French page");
+        assertEquals(doc.getElementById("id1").getChildMarkup(), "French page");
     }
 
     @Test
     public void change_language_in_browser()
     {
         Document doc = _tester.renderPage("TestPageForLocale");
-        assertEquals(doc.getElementById("id1").getChildText(), "English page");
+        assertEquals(doc.getElementById("id1").getChildMarkup(), "English page");
         _tester.setPreferedLanguage(Locale.CANADA_FRENCH);
         doc = _tester.renderPage("TestPageForLocale");
-        assertEquals(doc.getElementById("id1").getChildText(), "French page");
+        assertEquals(doc.getElementById("id1").getChildMarkup(), "French page");
     }
 
     @Test
@@ -57,7 +57,7 @@
     {
         Document doc = _tester.renderPage("TestPageForLocale");
         doc = _tester.clickLink(doc.getElementById("changeLocale"));
-        assertEquals(doc.getElementById("id1").getChildText(), "French page");
+        assertEquals(doc.getElementById("id1").getChildMarkup(), "French page");
     }
 
     @BeforeMethod

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LoopTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LoopTest.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LoopTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LoopTest.java Mon Nov 26 17:01:14 2007
@@ -14,11 +14,11 @@
 
 package org.apache.tapestry.integration.pagelevel;
 
-import org.apache.tapestry.dom.Document;
-import org.apache.tapestry.test.PageTester;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.Test;
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.test.PageTester;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
 
 public class LoopTest extends Assert
 {
@@ -32,10 +32,10 @@
         _tester = new PageTester(appPackage, appName);
         Document doc = _tester.renderPage("TestPageForLoop");
         assertTrue(doc.toString().contains("abcabcabc"));
-        assertEquals(doc.getElementById("1").getChildText(), "xyz");
+        assertEquals(doc.getElementById("1").getChildMarkup(), "xyz");
     }
 
-    @AfterMethod
+    @AfterMethod
     public void after()
     {
         if (_tester != null)

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/PrefixMethodTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/PrefixMethodTest.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/PrefixMethodTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/PrefixMethodTest.java Mon Nov 26 17:01:14 2007
@@ -33,10 +33,10 @@
         _tester = new PageTester(appPackage, appName, PageTester.DEFAULT_CONTEXT_PATH, LocaleAppModule.class);
         Document doc = _tester.renderPage("TestPrefixMethod");
 
-        assertEquals(doc.getElementById("value").getChildText(), "42");
+        assertEquals(doc.getElementById("value").getChildMarkup(), "42");
 
         // should override the method in the superclass
         doc = _tester.renderPage("TestPrefixMethod2");
-        assertEquals(doc.getElementById("value").getChildText(), "42");
+        assertEquals(doc.getElementById("value").getChildMarkup(), "42");
     }
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessorTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessorTest.java?rev=598484&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessorTest.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessorTest.java Mon Nov 26 17:01:14 2007
@@ -0,0 +1,91 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+
+public class AjaxComponentInstanceEventResultProcessorTest extends InternalBaseTestCase
+{
+    @Test
+    public void render_component_within_page() throws IOException
+    {
+        String nestedId = "foo.bar.baz";
+        String pageName = "Biff";
+
+        RequestPageCache cache = mockRequestPageCache();
+        PartialMarkupRenderer renderer = newMock(PartialMarkupRenderer.class);
+        Page page = mockPage();
+        ComponentResources resources = mockComponentResources();
+        Component component = mockComponent();
+        ComponentPageElement element = mockComponentPageElement();
+
+
+        train_getComponentResources(component, resources);
+        train_getPageName(resources, pageName);
+        train_get(cache, pageName, page);
+        train_getNestedId(resources, nestedId);
+        train_getComponentElementByNestedId(page, nestedId, element);
+
+        renderer.renderPartialPageMarkup(element);
+
+        replay();
+
+        ComponentEventResultProcessor<Component> processor = new AjaxComponentInstanceEventResultProcessor(renderer,
+                                                                                                           cache);
+
+        processor.processComponentEvent(component, null, null);
+
+        verify();
+    }
+
+    @Test
+    public void render_complete_page_as_partial() throws IOException
+    {
+        String pageName = "Biff";
+
+        RequestPageCache cache = mockRequestPageCache();
+        PartialMarkupRenderer renderer = newMock(PartialMarkupRenderer.class);
+        Page page = mockPage();
+        ComponentResources resources = mockComponentResources();
+        Component component = mockComponent();
+        ComponentPageElement element = mockComponentPageElement();
+
+
+        train_getComponentResources(component, resources);
+        train_getPageName(resources, pageName);
+        train_get(cache, pageName, page);
+        train_getNestedId(resources, null);
+        train_getRootElement(page, element);
+
+        renderer.renderPartialPageMarkup(element);
+
+        replay();
+
+        ComponentEventResultProcessor<Component> processor = new AjaxComponentInstanceEventResultProcessor(renderer,
+                                                                                                           cache);
+
+        processor.processComponentEvent(component, null, null);
+
+        verify();
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java Mon Nov 26 17:01:14 2007
@@ -112,9 +112,8 @@
 
         train_getParameter(request, InternalConstants.PAGE_CONTEXT_NAME, "alpha/beta");
 
-        expect(handler.handle(eq("mypage"), eq(""), eq("eventname"), aryEq(new String[0]),
-                              aryEq(new String[]{"alpha", "beta"}))).andReturn(true);
-
+        handler.handle(eq("mypage"), eq(""), eq("eventname"), aryEq(new String[0]),
+                       aryEq(new String[]{"alpha", "beta"}));
 
         replay();
 
@@ -136,8 +135,7 @@
 
         train_getParameter(request, InternalConstants.PAGE_CONTEXT_NAME, null);
 
-        expect(handler.handle(eq(logicalPageName), eq(nestedComponentId), eq(eventType), aryEq(context),
-                              aryEq(new String[0]))).andReturn(true);
+        handler.handle(eq(logicalPageName), eq(nestedComponentId), eq(eventType), aryEq(context), aryEq(new String[0]));
 
         replay();
 

Modified: tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry/upload/components/Upload.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry/upload/components/Upload.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry/upload/components/Upload.java (original)
+++ tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry/upload/components/Upload.java Mon Nov 26 17:01:14 2007
@@ -1,17 +1,17 @@
-// Copyright 2007 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package org.apache.tapestry.upload.components;
 
 import org.apache.tapestry.*;
@@ -103,7 +103,7 @@
 
     @SuppressWarnings({"unchecked"})
     @Override
-    protected void processSubmission(FormSupport formSupport, String elementName)
+    protected void processSubmission(String elementName)
     {
         UploadedFile uploaded = _decoder.getFileUpload(elementName);
 

Modified: tapestry/tapestry5/trunk/tapestry-upload/src/test/java/org/apache/tapestry/upload/components/UploadTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-upload/src/test/java/org/apache/tapestry/upload/components/UploadTest.java?rev=598484&r1=598483&r2=598484&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-upload/src/test/java/org/apache/tapestry/upload/components/UploadTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-upload/src/test/java/org/apache/tapestry/upload/components/UploadTest.java Mon Nov 26 17:01:14 2007
@@ -1,17 +1,17 @@
-// Copyright 2007 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package org.apache.tapestry.upload.components;
 
 import org.apache.tapestry.*;
@@ -150,7 +150,6 @@
     @Test
     public void process_submission_extracts_value_from_decoder() throws Exception
     {
-        FormSupport formSupport = mockFormSupport();
         MultipartDecoder decoder = mockMultipartDecoder();
         UploadedFile uploadedFile = mockUploadedFile();
         ComponentResources resources = mockComponentResources();
@@ -166,7 +165,7 @@
 
         replay();
 
-        component.processSubmission(formSupport, "test");
+        component.processSubmission("test");
 
         verify();
 
@@ -177,7 +176,6 @@
     @Test
     public void process_submission_ignores_null_value() throws Exception
     {
-        FormSupport formSupport = mockFormSupport();
         MultipartDecoder decoder = mockMultipartDecoder();
         UploadedFile uploadedFile = mockUploadedFile();
         ComponentResources resources = mockComponentResources();
@@ -194,7 +192,7 @@
 
         replay();
 
-        component.processSubmission(formSupport, "test");
+        component.processSubmission("test");
 
         verify();
 
@@ -205,7 +203,6 @@
     @Test
     public void process_submission_calls_validator() throws Exception
     {
-        FormSupport formSupport = mockFormSupport();
         MultipartDecoder decoder = mockMultipartDecoder();
         UploadedFile uploadedFile = mockUploadedFile();
         FieldValidator<Object> validate = mockFieldValidator();
@@ -221,7 +218,7 @@
 
         replay();
 
-        component.processSubmission(formSupport, "test");
+        component.processSubmission("test");
 
         verify();
     }
@@ -230,7 +227,6 @@
     @Test
     public void process_submission_tracks_validator_errors() throws Exception
     {
-        FormSupport formSupport = mockFormSupport();
         MultipartDecoder decoder = mockMultipartDecoder();
         UploadedFile uploadedFile = mockUploadedFile();
         FieldValidator<Object> validate = mockFieldValidator();
@@ -249,7 +245,7 @@
         tracker.recordError(component, "an error");
         replay();
 
-        component.processSubmission(formSupport, "test");
+        component.processSubmission("test");
 
         verify();
     }