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 2009/02/17 20:12:54 UTC

svn commit: r745195 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/internal/pageload/ main/java/org/apache/tapestry5/internal/services/ test/java/org/apache/tapestry5/integration/app1/pages/

Author: hlship
Date: Tue Feb 17 19:12:54 2009
New Revision: 745195

URL: http://svn.apache.org/viewvc?rev=745195&view=rev
Log:
TAP5-95: Optimize page construction for repeated construction of the same page

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/AssemblerContext.java
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentModelSource.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentModelSourceImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BadMixinIdDemo.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/DupeMixinDemo.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/UnsupportedParameterBlockDemo.java

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/AssemblerContext.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/AssemblerContext.java?rev=745195&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/AssemblerContext.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/AssemblerContext.java Tue Feb 17 19:12:54 2009
@@ -0,0 +1,106 @@
+// Copyright 2009 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.tapestry5.internal.pageload;
+
+import org.apache.tapestry5.internal.parser.TemplateToken;
+import org.apache.tapestry5.internal.parser.TokenType;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.runtime.RenderCommand;
+
+import java.util.List;
+
+/**
+ * Used when constructing a {@link org.apache.tapestry5.internal.pageload.AssemblerContext}, encapsulating the
+ * assembler, the {@link org.apache.tapestry5.internal.pageload.TokenStream} for the component's template, and helping
+ * to consolidate composable render commands (that is, a series of render commands that are not components can be
+ * replaced with a single {@link org.apache.tapestry5.internal.pageload.CompositeRenderCommand} which reduces the number
+ * of render operations for the page).
+ */
+class AssemblerContext implements TokenStream
+{
+    final ComponentAssembler assembler;
+
+    final TokenStream stream;
+
+    private final List<RenderCommand> composable = CollectionFactory.newList();
+
+    AssemblerContext(ComponentAssembler assembler, TokenStream stream)
+    {
+        this.assembler = assembler;
+        this.stream = stream;
+    }
+
+    public boolean more()
+    {
+        return stream.more();
+    }
+
+    public TemplateToken next()
+    {
+        return stream.next();
+    }
+
+    public <T extends TemplateToken> T next(Class<T> type)
+    {
+        return stream.next(type);
+    }
+
+    public TokenType peekType()
+    {
+        return stream.peekType();
+    }
+
+    void addComposable(RenderCommand command)
+    {
+        composable.add(command);
+    }
+
+    void flushComposable()
+    {
+        switch (composable.size())
+        {
+            case 0:
+                return;
+
+            case 1:
+                addRenderCommand(composable.get(0));
+                break;
+
+            default:
+                addRenderCommand(new CompositeRenderCommand(composable.toArray(new RenderCommand[composable.size()])));
+                break;
+        }
+
+        composable.clear();
+    }
+
+    void add(PageAssemblyAction action)
+    {
+        flushComposable();
+
+        assembler.add(action);
+    }
+
+    private void addRenderCommand(final RenderCommand command)
+    {
+        assembler.add(new PageAssemblyAction()
+        {
+            public void execute(PageAssembly pageAssembly)
+            {
+                pageAssembly.addRenderCommand(command);
+            }
+        });
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java?rev=745195&r1=745194&r2=745195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java Tue Feb 17 19:12:54 2009
@@ -46,8 +46,6 @@
 
     final List<PageAssemblyAction> deferred = CollectionFactory.newList();
 
-    private final List<RenderCommand> composableRenderCommands = CollectionFactory.newList();
-
     private final Set<String> flags = CollectionFactory.newSet();
 
     PageAssembly(Page page)
@@ -63,49 +61,9 @@
      */
     void addRenderCommand(RenderCommand command)
     {
-        flushComposableRenderCommands();
-
         bodyElement.peek().addToBody(command);
     }
 
-    /**
-     * Adds the command to the list of composable commands. Composable commands are added to the top element of the body
-     * element stack when {@linkplain #flushComposableRenderCommands() flushed}.
-     *
-     * @param command
-     */
-    void addComposableRenderCommand(RenderCommand command)
-    {
-        composableRenderCommands.add(command);
-    }
-
-    /**
-     * Adds any composed render commands to the top element of the bodyElement stack. Render commands may be combined as
-     * a {@link org.apache.tapestry5.internal.pageload.CompositeRenderCommand}.
-     */
-    void flushComposableRenderCommands()
-    {
-        int count = composableRenderCommands.size();
-
-        switch (count)
-        {
-            case 0:
-                break;
-
-            case 1:
-                bodyElement.peek().addToBody(composableRenderCommands.get(0));
-                break;
-
-            default:
-                RenderCommand[] commands = composableRenderCommands.toArray(new RenderCommand[count]);
-
-                bodyElement.peek().addToBody(new CompositeRenderCommand(commands));
-                break;
-        }
-
-        composableRenderCommands.clear();
-    }
-
     boolean checkAndSetFlag(String flagName)
     {
         boolean result = flags.contains(flagName);

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java?rev=745195&r1=745194&r2=745195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java Tue Feb 17 19:12:54 2009
@@ -89,8 +89,6 @@
     {
         public void execute(PageAssembly pageAssembly)
         {
-            pageAssembly.flushComposableRenderCommands();
-
             pageAssembly.createdElement.pop();
             pageAssembly.bodyElement.pop();
             pageAssembly.embeddedAssembler.pop();
@@ -111,22 +109,6 @@
         }
     };
 
-    private static final PageAssemblyAction END_ELEMENT_ACTION = new PageAssemblyAction()
-    {
-        public void execute(PageAssembly pageAssembly)
-        {
-            pageAssembly.addRenderCommand(END_ELEMENT);
-        }
-    };
-
-    private static final PageAssemblyAction FLUSH_COMPOSABLE_RENDER_COMMANDS_ACTION = new PageAssemblyAction()
-    {
-        public void execute(PageAssembly pageAssembly)
-        {
-            pageAssembly.flushComposableRenderCommands();
-        }
-    };
-
     private final Map<Key, ComponentAssembler> cache = CollectionFactory.newConcurrentMap();
 
     private final ComponentInstantiatorSource instantiatorSource;
@@ -234,94 +216,99 @@
 
     private void processTemplate(ComponentAssembler assembler, ComponentTemplate template)
     {
+        TokenStream stream = new TokenStreamImpl(template);
+
+        AssemblerContext context = new AssemblerContext(assembler, stream);
+
         if (template.isMissing())
         {
             // Pretend the template has a single <t:body> element.
 
-            body(assembler);
+            body(context);
 
             return;
         }
 
-        TokenStream stream = new TokenStreamImpl(template);
 
-        while (stream.more())
+        while (context.more())
         {
-            processTemplateToken(assembler, stream);
+            processTemplateToken(context);
         }
 
-        addFlushAction(assembler);
+        context.flushComposable();
     }
 
-    private void processTemplateToken(ComponentAssembler assembler, TokenStream stream)
+    private void processTemplateToken(AssemblerContext context)
     {
         // These tokens can appear at the top level, or at lower levels (this method is invoked
         // from token-processing loops inside element(), component(), etc.
 
-        switch (stream.peekType())
+        switch (context.peekType())
         {
             case TEXT:
 
-                text(assembler, stream.next(TextToken.class));
+                text(context);
                 break;
 
             case EXPANSION:
-                expansion(assembler, stream.next(ExpansionToken.class));
+                expansion(context);
                 break;
 
             case BODY:
-                stream.next();
+                context.next();
 
-                body(assembler);
+                body(context);
                 break;
 
             case START_ELEMENT:
                 // Will consume past matching end token
-                element(assembler, stream);
+                element(context);
                 break;
 
             case START_COMPONENT:
                 // Will consume past matching end token
-                component(assembler, stream);
+                component(context);
                 break;
 
             // ATTRIBUTE and END_ELEMENT can't happen at the top level, they're
             // handled at a lower level. (inside element(), component(), etc.)
 
             case COMMENT:
-                comment(assembler, stream.next(CommentToken.class));
+                comment(context);
                 break;
 
             case BLOCK:
                 // Will consume past matching end token
-                block(assembler, stream);
+                block(context);
                 break;
 
             case PARAMETER:
                 // Will consume past the matching end token
-                parameter(assembler, stream);
+                parameter(context);
                 break;
 
             case DTD:
-                dtd(assembler, stream.next(DTDToken.class));
+                dtd(context);
                 break;
 
             case DEFINE_NAMESPACE_PREFIX:
 
-                defineNamespacePrefix(assembler, stream.next(DefineNamespacePrefixToken.class));
+                defineNamespacePrefix(context);
                 break;
 
             case CDATA:
-                cdata(assembler, stream.next(CDATAToken.class));
+                cdata(context);
                 break;
 
             default:
-                throw new IllegalStateException("Not yet implemented: " + stream.peekType());
+                throw new IllegalStateException("Not yet implemented: " + context.peekType());
         }
     }
 
-    private void cdata(ComponentAssembler assembler, final CDATAToken token)
+    private void cdata(AssemblerContext context)
     {
+        final CDATAToken token = context.next(CDATAToken.class);
+
         RenderCommand command = new RenderCommand()
         {
             public void render(MarkupWriter writer, RenderQueue queue)
@@ -336,12 +323,14 @@
             }
         };
 
-        addComposableCommand(assembler, command);
+        context.addComposable(command);
 
     }
 
-    private void defineNamespacePrefix(ComponentAssembler assembler, final DefineNamespacePrefixToken token)
+    private void defineNamespacePrefix(AssemblerContext context)
     {
+        final DefineNamespacePrefixToken token = context.next(DefineNamespacePrefixToken.class);
+
         RenderCommand command = new RenderCommand()
         {
             public void render(MarkupWriter writer, RenderQueue queue)
@@ -357,12 +346,14 @@
         };
 
 
-        addComposableCommand(assembler, command);
+        context.addComposable(command);
     }
 
-    private void dtd(ComponentAssembler assembler, final DTDToken token)
+    private void dtd(AssemblerContext context)
     {
-        assembler.add(new PageAssemblyAction()
+        final DTDToken token = context.next(DTDToken.class);
+
+        context.add(new PageAssemblyAction()
         {
             public void execute(PageAssembly pageAssembly)
             {
@@ -374,24 +365,22 @@
                     // It doesn't really matter where this ends up in the tree as long as its inside
                     // a portion that always renders.
 
-                    pageAssembly.addComposableRenderCommand(command);
+                    pageAssembly.addRenderCommand(command);
                 }
             }
         });
     }
 
-    private void parameter(ComponentAssembler assembler, TokenStream stream)
+    private void parameter(AssemblerContext context)
     {
-        final ParameterToken token = stream.next(ParameterToken.class);
+        final ParameterToken token = context.next(ParameterToken.class);
 
-        assembler.add(new PageAssemblyAction()
+        context.add(new PageAssemblyAction()
         {
             public void execute(PageAssembly pageAssembly)
             {
                 String parameterName = token.getName();
 
-                pageAssembly.flushComposableRenderCommands();
-
                 ComponentPageElement element = pageAssembly.createdElement.peek();
 
                 BlockImpl block = new BlockImpl(token.getLocation(),
@@ -421,14 +410,14 @@
             }
         });
 
-        consumeToEndElementAndPopBodyElement(assembler, stream);
+        consumeToEndElementAndPopBodyElement(context);
     }
 
-    private void block(ComponentAssembler assembler, TokenStream stream)
+    private void block(AssemblerContext context)
     {
-        final BlockToken token = stream.next(BlockToken.class);
+        final BlockToken token = context.next(BlockToken.class);
 
-        assembler.add(new PageAssemblyAction()
+        context.add(new PageAssemblyAction()
         {
             public void execute(PageAssembly pageAssembly)
             {
@@ -446,29 +435,27 @@
                     element.addBlock(blockId, block);
 
                 // Start directing template content into the Block
-                pageAssembly.flushComposableRenderCommands();
                 pageAssembly.bodyElement.push(block);
             }
         });
 
-        consumeToEndElementAndPopBodyElement(assembler, stream);
+        consumeToEndElementAndPopBodyElement(context);
     }
 
-    private void consumeToEndElementAndPopBodyElement(ComponentAssembler assembler, TokenStream stream)
+    private void consumeToEndElementAndPopBodyElement(AssemblerContext context)
     {
         while (true)
         {
-            switch (stream.peekType())
+            switch (context.peekType())
             {
                 case END_ELEMENT:
 
-                    stream.next();
+                    context.next();
 
-                    assembler.add(new PageAssemblyAction()
+                    context.add(new PageAssemblyAction()
                     {
                         public void execute(PageAssembly pageAssembly)
                         {
-                            pageAssembly.flushComposableRenderCommands();
                             pageAssembly.bodyElement.pop();
                         }
                     });
@@ -476,90 +463,93 @@
                     return;
 
                 default:
-                    processTemplateToken(assembler, stream);
+                    processTemplateToken(context);
             }
         }
     }
 
-    private void comment(ComponentAssembler assembler, CommentToken token)
+    private void comment(AssemblerContext context)
     {
+        CommentToken token = context.next(CommentToken.class);
+
         RenderCommand commentElement = new CommentPageElement(token.getComment());
 
-        addComposableCommand(assembler, commentElement);
+        context.addComposable(commentElement);
     }
 
-    private void component(ComponentAssembler assembler, TokenStream stream)
+    private void component(AssemblerContext context)
     {
-        StartComponentToken token = stream.next(StartComponentToken.class);
-
-        EmbeddedComponentAssembler embeddedAssembler = startComponent(assembler, token);
+        EmbeddedComponentAssembler embeddedAssembler = startComponent(context);
 
         while (true)
         {
-            switch (stream.peekType())
+            switch (context.peekType())
             {
                 case ATTRIBUTE:
 
-                    bindAttributeAsParameter(assembler, embeddedAssembler, stream.next(AttributeToken.class));
+                    bindAttributeAsParameter(context, embeddedAssembler);
 
                     break;
 
                 case END_ELEMENT:
 
-                    stream.next();
+                    context.next();
 
-                    assembler.add(POP_EMBEDDED_COMPONENT_ACTION);
+                    context.add(POP_EMBEDDED_COMPONENT_ACTION);
 
                     return;
 
                 default:
-                    processTemplateToken(assembler, stream);
+                    processTemplateToken(context);
             }
         }
-
     }
 
-    private void bindAttributeAsParameter(ComponentAssembler assembler, EmbeddedComponentAssembler embeddedAssembler,
-                                          AttributeToken token)
+    private void bindAttributeAsParameter(AssemblerContext context, EmbeddedComponentAssembler embeddedAssembler)
     {
-        addParameterBindingAction(assembler, embeddedAssembler, token.getName(), token.getValue(),
+        AttributeToken token = context.next(AttributeToken.class);
+
+        addParameterBindingAction(context, embeddedAssembler, token.getName(), token.getValue(),
                                   BindingConstants.LITERAL, token.getLocation());
     }
 
-    private void element(ComponentAssembler assembler, TokenStream stream)
+    private void element(AssemblerContext context)
     {
-        StartElementToken token = stream.next(StartElementToken.class);
+        StartElementToken token = context.next(StartElementToken.class);
 
         RenderCommand element = new StartElementPageElement(token.getNamespaceURI(), token.getName());
 
-        addComposableCommand(assembler, element);
+        context.addComposable(element);
 
         while (true)
         {
-            switch (stream.peekType())
+            switch (context.peekType())
             {
                 case ATTRIBUTE:
-                    attribute(assembler, stream.next(AttributeToken.class));
+                    attribute(context);
                     break;
 
                 case END_ELEMENT:
 
-                    assembler.add(END_ELEMENT_ACTION);
+                    context.next();
 
-                    stream.next();
+                    context.addComposable(END_ELEMENT);
 
                     // Pop out a level.
                     return;
 
                 default:
-                    processTemplateToken(assembler, stream);
+                    processTemplateToken(context);
             }
         }
 
     }
 
-    private EmbeddedComponentAssembler startComponent(ComponentAssembler assembler, StartComponentToken token)
+    private EmbeddedComponentAssembler startComponent(AssemblerContext context)
     {
+        StartComponentToken token = context.next(StartComponentToken.class);
+
+        ComponentAssembler assembler = context.assembler;
         String elementName = token.getElementName();
 
         // Initial guess: the type from the token (but this may be null in many cases).
@@ -631,9 +621,9 @@
                                                   token.getMixins(),
                                                   token.getLocation());
 
-        addActionForEmbeddedComponent(assembler, embeddedAssembler, embeddedId, elementName, componentClassName);
+        addActionForEmbeddedComponent(context, embeddedAssembler, embeddedId, elementName, componentClassName);
 
-        addParameterBindingActions(assembler, embeddedAssembler, embeddedModel);
+        addParameterBindingActions(context, embeddedAssembler, embeddedModel);
 
         if (embeddedModel != null && embeddedModel.getInheritInformalParameters())
         {
@@ -683,7 +673,7 @@
         }
     }
 
-    private void addParameterBindingActions(ComponentAssembler assembler,
+    private void addParameterBindingActions(AssemblerContext context,
                                             EmbeddedComponentAssembler embeddedAssembler,
                                             EmbeddedComponentModel embeddedModel)
     {
@@ -693,7 +683,7 @@
         {
             String parameterValue = embeddedModel.getParameterValue(parameterName);
 
-            addParameterBindingAction(assembler,
+            addParameterBindingAction(context,
                                       embeddedAssembler,
                                       parameterName,
                                       parameterValue,
@@ -702,7 +692,7 @@
         }
     }
 
-    private void addParameterBindingAction(ComponentAssembler assembler,
+    private void addParameterBindingAction(AssemblerContext context,
                                            final EmbeddedComponentAssembler embeddedAssembler,
                                            final String parameterName,
                                            final String parameterValue,
@@ -717,12 +707,12 @@
         {
             String containerParameterName = parameterValue.substring(InternalConstants.INHERIT_BINDING_PREFIX.length());
 
-            addInheritedBindingAction(assembler, parameterName, containerParameterName);
+            addInheritedBindingAction(context, parameterName, containerParameterName);
             return;
         }
 
 
-        assembler.add(new PageAssemblyAction()
+        context.add(new PageAssemblyAction()
         {
             public void execute(PageAssembly pageAssembly)
             {
@@ -764,11 +754,11 @@
      * @param parameterName
      * @param containerParameterName
      */
-    private void addInheritedBindingAction(ComponentAssembler assembler,
+    private void addInheritedBindingAction(AssemblerContext context,
                                            final String parameterName,
                                            final String containerParameterName)
     {
-        assembler.add(new PageAssemblyAction()
+        context.add(new PageAssemblyAction()
         {
             public void execute(PageAssembly pageAssembly)
             {
@@ -790,7 +780,8 @@
         });
     }
 
-    private void connectInheritedParameter(ComponentPageElement container, ComponentPageElement embedded,
+    private void connectInheritedParameter(ComponentPageElement container,
+                                           ComponentPageElement embedded,
                                            String parameterName,
                                            String containerParameterName)
     {
@@ -810,20 +801,18 @@
         embedded.bindParameter(parameterName, containerBinding);
     }
 
-    private void addActionForEmbeddedComponent(ComponentAssembler assembler,
+    private void addActionForEmbeddedComponent(AssemblerContext context,
                                                final EmbeddedComponentAssembler embeddedAssembler,
                                                final String embeddedId,
                                                final String elementName,
                                                final String componentClassName)
     {
-        assembler.add(new PageAssemblyAction()
+        context.add(new PageAssemblyAction()
         {
             public void execute(PageAssembly pageAssembly)
             {
                 pageAssembly.checkForRecursion(componentClassName, embeddedAssembler.getLocation());
 
-                pageAssembly.flushComposableRenderCommands();
-
                 Locale locale = pageAssembly.page.getLocale();
 
                 ComponentAssembler assemblerForSubcomponent = getAssembler(componentClassName, locale);
@@ -855,8 +844,10 @@
     }
 
 
-    private void attribute(ComponentAssembler assembler, final AttributeToken token)
+    private void attribute(AssemblerContext context)
     {
+        final AttributeToken token = context.next(AttributeToken.class);
+
         String value = token.getValue();
 
         // No expansion makes this easier, more efficient.
@@ -864,12 +855,12 @@
         {
             RenderCommand command = new RenderAttribute(token);
 
-            addComposableCommand(assembler, command);
+            context.addComposable(command);
 
             return;
         }
 
-        assembler.add(new PageAssemblyAction()
+        context.add(new PageAssemblyAction()
         {
             public void execute(PageAssembly pageAssembly)
             {
@@ -877,16 +868,14 @@
 
                 RenderCommand command = elementFactory.newAttributeElement(resources, token);
 
-                // Still composable, BTW.
-
                 pageAssembly.addRenderCommand(command);
             }
         });
     }
 
-    private void body(ComponentAssembler assembler)
+    private void body(AssemblerContext context)
     {
-        assembler.add(new PageAssemblyAction()
+        context.add(new PageAssemblyAction()
         {
             public void execute(PageAssembly pageAssembly)
             {
@@ -897,16 +886,16 @@
         });
     }
 
-    private void expansion(ComponentAssembler assembler, final ExpansionToken token)
+    private void expansion(AssemblerContext context)
     {
-        assembler.add(new PageAssemblyAction()
+        final ExpansionToken token = context.next(ExpansionToken.class);
+
+        context.add(new PageAssemblyAction()
         {
             public void execute(PageAssembly pageAssembly)
             {
                 ComponentResources resources = pageAssembly.activeElement.peek().getComponentResources();
 
-                // TODO: Add composability
-
                 RenderCommand command = elementFactory.newExpansionElement(resources, token);
 
                 pageAssembly.addRenderCommand(command);
@@ -914,25 +903,11 @@
         });
     }
 
-    private void text(ComponentAssembler assembler, TextToken textToken)
+    private void text(AssemblerContext context)
     {
-        addComposableCommand(assembler, new TextPageElement(textToken.getText()));
-    }
-
-    private void addComposableCommand(ComponentAssembler assembler, final RenderCommand command)
-    {
-        assembler.add(new PageAssemblyAction()
-        {
-            public void execute(PageAssembly pageAssembly)
-            {
-                pageAssembly.addComposableRenderCommand(command);
-            }
-        });
-    }
+        TextToken textToken = context.next(TextToken.class);
 
-    private void addFlushAction(ComponentAssembler assembler)
-    {
-        assembler.add(FLUSH_COMPOSABLE_RENDER_COMMANDS_ACTION);
+        context.addComposable(new TextPageElement(textToken.getText()));
     }
 
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentModelSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentModelSource.java?rev=745195&r1=745194&r2=745195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentModelSource.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentModelSource.java Tue Feb 17 19:12:54 2009
@@ -1,4 +1,4 @@
-// Copyright 2009 ${ORG}
+// Copyright 2009 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.
@@ -19,7 +19,7 @@
 /**
  * Access to component models (as provided via {@link org.apache.tapestry5.internal.services.ComponentInstantiatorSource}).
  * <p/>
- * <p>This is a good candidate to move into the public services package.
+ * This is a good candidate to move into the public services package.
  *
  * @since 5.1.0.0
  */

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentModelSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentModelSourceImpl.java?rev=745195&r1=745194&r2=745195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentModelSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentModelSourceImpl.java Tue Feb 17 19:12:54 2009
@@ -1,4 +1,4 @@
-// Copyright 2009 ${ORG}
+// Copyright 2009 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.

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BadMixinIdDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BadMixinIdDemo.java?rev=745195&r1=745194&r2=745195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BadMixinIdDemo.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BadMixinIdDemo.java Tue Feb 17 19:12:54 2009
@@ -1,4 +1,4 @@
-// Copyright 2009 ${ORG}
+// Copyright 2009 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.

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/DupeMixinDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/DupeMixinDemo.java?rev=745195&r1=745194&r2=745195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/DupeMixinDemo.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/DupeMixinDemo.java Tue Feb 17 19:12:54 2009
@@ -1,4 +1,4 @@
-// Copyright 2009 ${ORG}
+// Copyright 2009 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.

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/UnsupportedParameterBlockDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/UnsupportedParameterBlockDemo.java?rev=745195&r1=745194&r2=745195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/UnsupportedParameterBlockDemo.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/UnsupportedParameterBlockDemo.java Tue Feb 17 19:12:54 2009
@@ -1,4 +1,4 @@
-// Copyright 2009 ${ORG}
+// Copyright 2009 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.