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 2011/10/04 00:05:04 UTC

svn commit: r1178607 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/internal/pageload/ main/java/org/apache/tapestry5/internal/parser/ main/java/org/apache/tapestry5/internal/services/ main/java/org/apache/tapestry5/in...

Author: hlship
Date: Mon Oct  3 22:05:03 2011
New Revision: 1178607

URL: http://svn.apache.org/viewvc?rev=1178607&view=rev
Log:
TAP5-1508: Reduce memory utilization of page instances

Make template tokens directly implement RenderCommand, removing need for extra objects to fill gap
Token will be more liberally shared between page instance than the page element object (now removed)

Removed:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/RenderAttribute.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/CommentPageElement.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/DTDPageElement.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/StartElementPageElement.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/TextPageElement.java
Modified:
    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/parser/AttributeToken.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/CDATAToken.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/CommentToken.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/DTDToken.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/DefineNamespacePrefixToken.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/ParameterToken.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/StartElementToken.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/TextToken.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactoryImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TemplateParserImplTest.java

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=1178607&r1=1178606&r2=1178607&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 Mon Oct  3 22:05:03 2011
@@ -64,19 +64,23 @@ import java.util.Map;
  * <p/>
  * And truly, <em>This is the Tapestry Heart, This is the Tapestry Soul...</em>
  */
-public class PageLoaderImpl implements PageLoader, InvalidationListener, ComponentAssemblerSource {
-    private static final class Key {
+public class PageLoaderImpl implements PageLoader, InvalidationListener, ComponentAssemblerSource
+{
+    private static final class Key
+    {
         private final String className;
 
         private final ComponentResourceSelector selector;
 
-        private Key(String className, ComponentResourceSelector selector) {
+        private Key(String className, ComponentResourceSelector selector)
+        {
             this.className = className;
             this.selector = selector;
         }
 
         @Override
-        public boolean equals(Object o) {
+        public boolean equals(Object o)
+        {
             if (this == o)
                 return true;
             if (o == null || getClass() != o.getClass())
@@ -88,26 +92,32 @@ public class PageLoaderImpl implements P
         }
 
         @Override
-        public int hashCode() {
+        public int hashCode()
+        {
             return 31 * className.hashCode() + selector.hashCode();
         }
     }
 
-    private static final PageAssemblyAction POP_EMBEDDED_COMPONENT_ACTION = new PageAssemblyAction() {
-        public void execute(PageAssembly pageAssembly) {
+    private static final PageAssemblyAction POP_EMBEDDED_COMPONENT_ACTION = new PageAssemblyAction()
+    {
+        public void execute(PageAssembly pageAssembly)
+        {
             pageAssembly.createdElement.pop();
             pageAssembly.bodyElement.pop();
             pageAssembly.embeddedAssembler.pop();
         }
     };
 
-    private static final RenderCommand END_ELEMENT = new RenderCommand() {
-        public void render(MarkupWriter writer, RenderQueue queue) {
+    private static final RenderCommand END_ELEMENT = new RenderCommand()
+    {
+        public void render(MarkupWriter writer, RenderQueue queue)
+        {
             writer.end();
         }
 
         @Override
-        public String toString() {
+        public String toString()
+        {
             return "End";
         }
     };
@@ -140,7 +150,8 @@ public class PageLoaderImpl implements P
                           PageElementFactory elementFactory, ComponentPageElementResourcesSource resourcesSource,
                           ComponentClassResolver componentClassResolver, PersistentFieldManager persistentFieldManager,
                           StringInterner interner, OperationTracker tracker, PerthreadManager perThreadManager, Request request,
-                          SymbolSource symbolSource) {
+                          SymbolSource symbolSource)
+    {
         this.instantiatorSource = instantiatorSource;
         this.templateSource = templateSource;
         this.elementFactory = elementFactory;
@@ -154,15 +165,19 @@ public class PageLoaderImpl implements P
         this.symbolSource = symbolSource;
     }
 
-    public void objectWasInvalidated() {
+    public void objectWasInvalidated()
+    {
         cache.clear();
     }
 
-    public Page loadPage(final String logicalPageName, final ComponentResourceSelector selector) {
+    public Page loadPage(final String logicalPageName, final ComponentResourceSelector selector)
+    {
         final String pageClassName = componentClassResolver.resolvePageNameToClassName(logicalPageName);
 
-        return tracker.invoke("Constructing instance of page class " + pageClassName, new Invokable<Page>() {
-            public Page invoke() {
+        return tracker.invoke("Constructing instance of page class " + pageClassName, new Invokable<Page>()
+        {
+            public Page invoke()
+            {
                 Page page = new PageImpl(logicalPageName, selector, persistentFieldManager, perThreadManager);
 
                 ComponentAssembler assembler = getAssembler(pageClassName, selector);
@@ -182,12 +197,14 @@ public class PageLoaderImpl implements P
         });
     }
 
-    public ComponentAssembler getAssembler(String className, ComponentResourceSelector selector) {
+    public ComponentAssembler getAssembler(String className, ComponentResourceSelector selector)
+    {
         Key key = new Key(className, selector);
 
         ComponentAssembler result = cache.get(key);
 
-        if (result == null) {
+        if (result == null)
+        {
             // There's a window here where two threads may create the same assembler simultaneously;
             // the extra assembler will be discarded.
 
@@ -199,9 +216,12 @@ public class PageLoaderImpl implements P
         return result;
     }
 
-    private ComponentAssembler createAssembler(final String className, final ComponentResourceSelector selector) {
-        return tracker.invoke("Creating ComponentAssembler for " + className, new Invokable<ComponentAssembler>() {
-            public ComponentAssembler invoke() {
+    private ComponentAssembler createAssembler(final String className, final ComponentResourceSelector selector)
+    {
+        return tracker.invoke("Creating ComponentAssembler for " + className, new Invokable<ComponentAssembler>()
+        {
+            public ComponentAssembler invoke()
+            {
                 Instantiator instantiator = instantiatorSource.getInstantiator(className);
 
                 ComponentModel componentModel = instantiator.getModel();
@@ -227,12 +247,14 @@ public class PageLoaderImpl implements P
      * "Programs" the assembler by analyzing the component, its mixins and its embedded components (both in the template
      * and in the Java class), adding new PageAssemblyActions.
      */
-    private void programAssembler(ComponentAssembler assembler, ComponentTemplate template) {
+    private void programAssembler(ComponentAssembler assembler, ComponentTemplate template)
+    {
         TokenStream stream = createTokenStream(assembler, template);
 
         AssemblerContext context = new AssemblerContext(assembler, stream);
 
-        if (template.isMissing()) {
+        if (template.isMissing())
+        {
             // Pretend the template has a single <t:body> element.
 
             body(context);
@@ -240,7 +262,8 @@ public class PageLoaderImpl implements P
             return;
         }
 
-        while (context.more()) {
+        while (context.more())
+        {
             processTemplateToken(context);
         }
 
@@ -252,7 +275,8 @@ public class PageLoaderImpl implements P
      * {@link org.apache.tapestry5.internal.parser.ExtensionPointToken}s
      * and replacing them with appropriate overrides. Also validates that all embedded ids are accounted for.
      */
-    private TokenStream createTokenStream(ComponentAssembler assembler, ComponentTemplate template) {
+    private TokenStream createTokenStream(ComponentAssembler assembler, ComponentTemplate template)
+    {
         List<TemplateToken> tokens = CollectionFactory.newList();
 
         Stack<TemplateToken> queue = CollectionFactory.newStack();
@@ -266,17 +290,20 @@ public class PageLoaderImpl implements P
 
         pushAll(queue, baseTemplate.getTokens());
 
-        while (!queue.isEmpty()) {
+        while (!queue.isEmpty())
+        {
             TemplateToken token = queue.pop();
 
             // When an ExtensionPoint is found, it is replaced with the tokens of its override.
 
-            if (token.getTokenType().equals(TokenType.EXTENSION_POINT)) {
+            if (token.getTokenType().equals(TokenType.EXTENSION_POINT))
+            {
                 ExtensionPointToken extensionPointToken = (ExtensionPointToken) token;
 
                 queueOverrideTokensForExtensionPoint(extensionPointToken, queue, overrideSearch);
 
-            } else {
+            } else
+            {
                 tokens.add(token);
             }
         }
@@ -287,7 +314,8 @@ public class PageLoaderImpl implements P
 
         Map<String, Location> componentIds = CollectionFactory.newCaseInsensitiveMap();
 
-        for (ComponentTemplate ct : overrideSearch) {
+        for (ComponentTemplate ct : overrideSearch)
+        {
             componentIds.putAll(ct.getComponentIds());
         }
 
@@ -299,22 +327,26 @@ public class PageLoaderImpl implements P
         return new TokenStreamImpl(tokens);
     }
 
-    private static <T> T getLast(List<T> list) {
+    private static <T> T getLast(List<T> list)
+    {
         int count = list.size();
 
         return list.get(count - 1);
     }
 
     private void queueOverrideTokensForExtensionPoint(ExtensionPointToken extensionPointToken,
-                                                      Stack<TemplateToken> queue, List<ComponentTemplate> overrideSearch) {
+                                                      Stack<TemplateToken> queue, List<ComponentTemplate> overrideSearch)
+    {
         String extensionPointId = extensionPointToken.getExtensionPointId();
 
         // Work up from the component, through its base classes, towards the last non-extension template.
 
-        for (ComponentTemplate t : overrideSearch) {
+        for (ComponentTemplate t : overrideSearch)
+        {
             List<TemplateToken> tokens = t.getExtensionPointTokens(extensionPointId);
 
-            if (tokens != null) {
+            if (tokens != null)
+            {
                 pushAll(queue, tokens);
                 return;
             }
@@ -327,7 +359,8 @@ public class PageLoaderImpl implements P
                 extensionPointToken.getLocation(), null);
     }
 
-    private List<ComponentTemplate> buildOverrideSearch(ComponentAssembler assembler, ComponentTemplate template) {
+    private List<ComponentTemplate> buildOverrideSearch(ComponentAssembler assembler, ComponentTemplate template)
+    {
         List<ComponentTemplate> result = CollectionFactory.newList();
         result.add(template);
 
@@ -335,10 +368,12 @@ public class PageLoaderImpl implements P
 
         ComponentTemplate lastTemplate = template;
 
-        while (lastTemplate.isExtension()) {
+        while (lastTemplate.isExtension())
+        {
             ComponentModel parentModel = model.getParentModel();
 
-            if (parentModel == null) {
+            if (parentModel == null)
+            {
                 throw new RuntimeException(PageloadMessages.noParentForExtension(model));
             }
 
@@ -358,16 +393,19 @@ public class PageLoaderImpl implements P
      * Push all the tokens onto the stack, in reverse order, so that the last token is deepest and the first token is
      * most shallow (first to come off the queue).
      */
-    private void pushAll(Stack<TemplateToken> queue, List<TemplateToken> tokens) {
+    private void pushAll(Stack<TemplateToken> queue, List<TemplateToken> tokens)
+    {
         for (int i = tokens.size() - 1; i >= 0; i--)
             queue.push(tokens.get(i));
     }
 
-    private void processTemplateToken(AssemblerContext context) {
+    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 (context.peekType()) {
+        switch (context.peekType())
+        {
             case TEXT:
 
                 text(context);
@@ -428,65 +466,50 @@ public class PageLoaderImpl implements P
         }
     }
 
-    private void cdata(AssemblerContext context) {
-        final CDATAToken token = context.next(CDATAToken.class);
+    private void cdata(AssemblerContext context)
+    {
+        CDATAToken token = context.next(CDATAToken.class);
 
-        RenderCommand command = new RenderCommand() {
-            public void render(MarkupWriter writer, RenderQueue queue) {
-                writer.cdata(token.getContent());
-            }
-
-            @Override
-            public String toString() {
-                return String.format("CDATA[%s]", token.getLocation());
-            }
-        };
-
-        context.addComposable(command);
+        context.addComposable(token);
 
     }
 
-    private void defineNamespacePrefix(AssemblerContext context) {
-        final DefineNamespacePrefixToken token = context.next(DefineNamespacePrefixToken.class);
-
-        RenderCommand command = new RenderCommand() {
-            public void render(MarkupWriter writer, RenderQueue queue) {
-                writer.defineNamespace(token.getNamespaceURI(), token.getNamespacePrefix());
-            }
-
-            @Override
-            public String toString() {
-                return String.format("DefineNamespace[%s %s]", token.getNamespacePrefix(), token.getNamespaceURI());
-            }
-        };
+    private void defineNamespacePrefix(AssemblerContext context)
+    {
+        DefineNamespacePrefixToken token = context.next(DefineNamespacePrefixToken.class);
 
-        context.addComposable(command);
+        context.addComposable(token);
     }
 
-    private void dtd(AssemblerContext context) {
+    private void dtd(AssemblerContext context)
+    {
         final DTDToken token = context.next(DTDToken.class);
 
-        context.add(new PageAssemblyAction() {
-            public void execute(PageAssembly pageAssembly) {
-                if (!pageAssembly.checkAndSetFlag("dtd-page-element-added")) {
-                    RenderCommand command = new DTDPageElement(token.getName(), token.getPublicId(), token
-                            .getSystemId());
+        context.add(new PageAssemblyAction()
+        {
+            public void execute(PageAssembly pageAssembly)
+            {
+                if (!pageAssembly.checkAndSetFlag("dtd-page-element-added"))
+                {
 
                     // It doesn't really matter where this ends up in the tree as long as its inside
                     // a portion that always renders.
 
-                    pageAssembly.addRenderCommand(command);
+                    pageAssembly.addRenderCommand(token);
                 }
             }
         });
     }
 
-    private void parameter(AssemblerContext context) {
+    private void parameter(AssemblerContext context)
+    {
         final ParameterToken token = context.next(ParameterToken.class);
 
-        context.add(new PageAssemblyAction() {
-            public void execute(PageAssembly pageAssembly) {
-                String parameterName = token.getName();
+        context.add(new PageAssemblyAction()
+        {
+            public void execute(PageAssembly pageAssembly)
+            {
+                String parameterName = token.name;
 
                 ComponentPageElement element = pageAssembly.createdElement.peek();
 
@@ -501,7 +524,8 @@ public class PageLoaderImpl implements P
 
                 ParameterBinder binder = embeddedAssembler.createParameterBinder(parameterName);
 
-                if (binder == null) {
+                if (binder == null)
+                {
                     throw new UnknownValueException(
                             String.format("Component %s does not include a formal parameter '%s' (and does not support informal parameters).",
                                     element.getCompleteId(), parameterName), location,
@@ -518,11 +542,14 @@ public class PageLoaderImpl implements P
         consumeToEndElementAndPopBodyElement(context);
     }
 
-    private void block(AssemblerContext context) {
+    private void block(AssemblerContext context)
+    {
         final BlockToken token = context.next(BlockToken.class);
 
-        context.add(new PageAssemblyAction() {
-            public void execute(PageAssembly pageAssembly) {
+        context.add(new PageAssemblyAction()
+        {
+            public void execute(PageAssembly pageAssembly)
+            {
                 String blockId = token.getId();
 
                 ComponentPageElement element = pageAssembly.activeElement.peek();
@@ -543,15 +570,20 @@ public class PageLoaderImpl implements P
         consumeToEndElementAndPopBodyElement(context);
     }
 
-    private void consumeToEndElementAndPopBodyElement(AssemblerContext context) {
-        while (true) {
-            switch (context.peekType()) {
+    private void consumeToEndElementAndPopBodyElement(AssemblerContext context)
+    {
+        while (true)
+        {
+            switch (context.peekType())
+            {
                 case END_ELEMENT:
 
                     context.next();
 
-                    context.add(new PageAssemblyAction() {
-                        public void execute(PageAssembly pageAssembly) {
+                    context.add(new PageAssemblyAction()
+                    {
+                        public void execute(PageAssembly pageAssembly)
+                        {
                             pageAssembly.bodyElement.pop();
                         }
                     });
@@ -564,19 +596,21 @@ public class PageLoaderImpl implements P
         }
     }
 
-    private void comment(AssemblerContext context) {
+    private void comment(AssemblerContext context)
+    {
         CommentToken token = context.next(CommentToken.class);
 
-        RenderCommand commentElement = new CommentPageElement(token.getComment());
-
-        context.addComposable(commentElement);
+        context.addComposable(token);
     }
 
-    private void component(AssemblerContext context) {
+    private void component(AssemblerContext context)
+    {
         EmbeddedComponentAssembler embeddedAssembler = startComponent(context);
 
-        while (true) {
-            switch (context.peekType()) {
+        while (true)
+        {
+            switch (context.peekType())
+            {
                 case ATTRIBUTE:
 
                     bindAttributeAsParameter(context, embeddedAssembler);
@@ -597,22 +631,24 @@ public class PageLoaderImpl implements P
         }
     }
 
-    private void bindAttributeAsParameter(AssemblerContext context, EmbeddedComponentAssembler embeddedAssembler) {
+    private void bindAttributeAsParameter(AssemblerContext context, EmbeddedComponentAssembler embeddedAssembler)
+    {
         AttributeToken token = context.next(AttributeToken.class);
 
-        addParameterBindingAction(context, embeddedAssembler, token.getName(), token.getValue(),
+        addParameterBindingAction(context, embeddedAssembler, token.name, token.value,
                 BindingConstants.LITERAL, token.getLocation(), true);
     }
 
-    private void element(AssemblerContext context) {
+    private void element(AssemblerContext context)
+    {
         StartElementToken token = context.next(StartElementToken.class);
 
-        RenderCommand element = new StartElementPageElement(token.getNamespaceURI(), token.getName());
-
-        context.addComposable(element);
+        context.addComposable(token);
 
-        while (true) {
-            switch (context.peekType()) {
+        while (true)
+        {
+            switch (context.peekType())
+            {
                 case ATTRIBUTE:
                     attribute(context);
                     break;
@@ -633,7 +669,8 @@ public class PageLoaderImpl implements P
 
     }
 
-    private EmbeddedComponentAssembler startComponent(AssemblerContext context) {
+    private EmbeddedComponentAssembler startComponent(AssemblerContext context)
+    {
         StartComponentToken token = context.next(StartComponentToken.class);
 
         ComponentAssembler assembler = context.assembler;
@@ -653,10 +690,12 @@ public class PageLoaderImpl implements P
         if (embeddedId == null)
             embeddedId = assembler.generateEmbeddedId(embeddedType);
 
-        if (embeddedModel != null) {
+        if (embeddedModel != null)
+        {
             String modelType = embeddedModel.getComponentType();
 
-            if (InternalUtils.isNonBlank(modelType) && embeddedType != null) {
+            if (InternalUtils.isNonBlank(modelType) && embeddedType != null)
+            {
                 throw new TapestryException(
                         PageloadMessages.redundantEmbeddedComponentTypes(embeddedId, embeddedType, modelType), token, null);
             }
@@ -670,15 +709,18 @@ public class PageLoaderImpl implements P
         // This awkwardness is making me think that the page loader should resolve the component
         // type before invoking this method (we would then remove the componentType parameter).
 
-        if (InternalUtils.isNonBlank(embeddedType)) {
+        if (InternalUtils.isNonBlank(embeddedType))
+        {
             // The type actually overrides the specified class name. The class name is defined
             // by the type of the field. In many scenarios, the field type is a common
             // interface,
             // and the type is used to determine the concrete class to instantiate.
 
-            try {
+            try
+            {
                 componentClassName = componentClassResolver.resolveComponentTypeToClassName(embeddedType);
-            } catch (RuntimeException ex) {
+            } catch (RuntimeException ex)
+            {
                 throw new TapestryException(ex.getMessage(), token, ex);
             }
         }
@@ -692,17 +734,22 @@ public class PageLoaderImpl implements P
 
         addParameterBindingActions(context, embeddedAssembler, embeddedModel);
 
-        if (embeddedModel != null && embeddedModel.getInheritInformalParameters()) {
+        if (embeddedModel != null && embeddedModel.getInheritInformalParameters())
+        {
             // Another two-step: The first "captures" the container and embedded component. The second
             // occurs at the end of the page setup.
 
-            assembler.add(new PageAssemblyAction() {
-                public void execute(PageAssembly pageAssembly) {
+            assembler.add(new PageAssemblyAction()
+            {
+                public void execute(PageAssembly pageAssembly)
+                {
                     final ComponentPageElement container = pageAssembly.activeElement.peek();
                     final ComponentPageElement embedded = pageAssembly.createdElement.peek();
 
-                    pageAssembly.deferred.add(new PageAssemblyAction() {
-                        public void execute(PageAssembly pageAssembly) {
+                    pageAssembly.deferred.add(new PageAssemblyAction()
+                    {
+                        public void execute(PageAssembly pageAssembly)
+                        {
                             copyInformalParameters(container, embedded);
                         }
                     });
@@ -715,7 +762,8 @@ public class PageLoaderImpl implements P
 
     }
 
-    private void copyInformalParameters(ComponentPageElement container, ComponentPageElement embedded) {
+    private void copyInformalParameters(ComponentPageElement container, ComponentPageElement embedded)
+    {
         // TODO: Much more, this is an area where we can make things a bit more efficient by tracking
         // what has and hasn't been bound in the EmbeddedComponentAssembler (and identifying what is
         // and isn't informal).
@@ -724,7 +772,8 @@ public class PageLoaderImpl implements P
 
         Map<String, Binding> informals = container.getInformalParameterBindings();
 
-        for (String name : informals.keySet()) {
+        for (String name : informals.keySet())
+        {
             if (model.getParameterModel(name) != null)
                 continue;
 
@@ -735,11 +784,13 @@ public class PageLoaderImpl implements P
     }
 
     private void addParameterBindingActions(AssemblerContext context, EmbeddedComponentAssembler embeddedAssembler,
-                                            EmbeddedComponentModel embeddedModel) {
+                                            EmbeddedComponentModel embeddedModel)
+    {
         if (embeddedModel == null)
             return;
 
-        for (String parameterName : embeddedModel.getParameterNames()) {
+        for (String parameterName : embeddedModel.getParameterNames())
+        {
             String parameterValue = embeddedModel.getParameterValue(parameterName);
 
             addParameterBindingAction(context, embeddedAssembler, parameterName, parameterValue, BindingConstants.PROP,
@@ -749,21 +800,25 @@ public class PageLoaderImpl implements P
 
     private void addParameterBindingAction(AssemblerContext context,
                                            final EmbeddedComponentAssembler embeddedAssembler, final String parameterName,
-                                           final String parameterValue, final String metaDefaultBindingPrefix, final Location location, final boolean ignoreUnmatchedFormal) {
+                                           final String parameterValue, final String metaDefaultBindingPrefix, final Location location, final boolean ignoreUnmatchedFormal)
+    {
         if (embeddedAssembler.isBound(parameterName))
             return;
 
         embeddedAssembler.setBound(parameterName);
 
-        if (parameterValue.startsWith(InternalConstants.INHERIT_BINDING_PREFIX)) {
+        if (parameterValue.startsWith(InternalConstants.INHERIT_BINDING_PREFIX))
+        {
             String containerParameterName = parameterValue.substring(InternalConstants.INHERIT_BINDING_PREFIX.length());
 
             addInheritedBindingAction(context, parameterName, containerParameterName);
             return;
         }
 
-        context.add(new PageAssemblyAction() {
-            public void execute(PageAssembly pageAssembly) {
+        context.add(new PageAssemblyAction()
+        {
+            public void execute(PageAssembly pageAssembly)
+            {
                 // Because of published parameters, we have to wait until page assembly time to throw out
                 // informal parameters bound to components that don't support informal parameters ...
                 // otherwise we'd throw out (sometimes!) published parameters.
@@ -772,8 +827,10 @@ public class PageLoaderImpl implements P
 
                 // Null meaning an informal parameter and the component (and mixins) doesn't support informals.
 
-                if (binder == null) {
-                    if (ignoreUnmatchedFormal) {
+                if (binder == null)
+                {
+                    if (ignoreUnmatchedFormal)
+                    {
                         return;
                     }
 
@@ -811,9 +868,12 @@ public class PageLoaderImpl implements P
      * @param containerParameterName
      */
     private void addInheritedBindingAction(AssemblerContext context, final String parameterName,
-                                           final String containerParameterName) {
-        context.add(new PageAssemblyAction() {
-            public void execute(PageAssembly pageAssembly) {
+                                           final String containerParameterName)
+    {
+        context.add(new PageAssemblyAction()
+        {
+            public void execute(PageAssembly pageAssembly)
+            {
                 // At the time this action executes, we'll be able to capture the containing and embedded
                 // component. We can then defer the connection logic until after all other construction.
 
@@ -822,8 +882,10 @@ public class PageLoaderImpl implements P
 
                 // Parameters are normally bound bottom to top. Inherited parameters run differently, and should be
                 // top to bottom.
-                pageAssembly.deferred.add(new PageAssemblyAction() {
-                    public void execute(PageAssembly pageAssembly) {
+                pageAssembly.deferred.add(new PageAssemblyAction()
+                {
+                    public void execute(PageAssembly pageAssembly)
+                    {
                         connectInheritedParameter(container, embedded, parameterName, containerParameterName);
                     }
                 });
@@ -832,7 +894,8 @@ public class PageLoaderImpl implements P
     }
 
     private void connectInheritedParameter(ComponentPageElement container, ComponentPageElement embedded,
-                                           String parameterName, String containerParameterName) {
+                                           String parameterName, String containerParameterName)
+    {
         // TODO: This assumes that the two parameters are both on the core component and not on
         // a mixin. I think this could be improved with more static analysis.
 
@@ -852,9 +915,12 @@ public class PageLoaderImpl implements P
 
     private void addActionForEmbeddedComponent(AssemblerContext context,
                                                final EmbeddedComponentAssembler embeddedAssembler, final String embeddedId, final String elementName,
-                                               final String componentClassName) {
-        context.add(new PageAssemblyAction() {
-            public void execute(PageAssembly pageAssembly) {
+                                               final String componentClassName)
+    {
+        context.add(new PageAssemblyAction()
+        {
+            public void execute(PageAssembly pageAssembly)
+            {
                 pageAssembly.checkForRecursion(componentClassName, embeddedAssembler.getLocation());
 
                 ComponentResourceSelector selector = pageAssembly.page.getSelector();
@@ -887,22 +953,25 @@ public class PageLoaderImpl implements P
         });
     }
 
-    private void attribute(AssemblerContext context) {
+    private void attribute(AssemblerContext context)
+    {
         final AttributeToken token = context.next(AttributeToken.class);
 
-        String value = token.getValue();
+        String value = token.value;
 
         // No expansion makes this easier, more efficient.
-        if (value.indexOf(InternalConstants.EXPANSION_START) < 0) {
-            RenderCommand command = new RenderAttribute(token);
+        if (value.indexOf(InternalConstants.EXPANSION_START) < 0)
+        {
 
-            context.addComposable(command);
+            context.addComposable(token);
 
             return;
         }
 
-        context.add(new PageAssemblyAction() {
-            public void execute(PageAssembly pageAssembly) {
+        context.add(new PageAssemblyAction()
+        {
+            public void execute(PageAssembly pageAssembly)
+            {
                 InternalComponentResources resources = pageAssembly.activeElement.peek().getComponentResources();
 
                 RenderCommand command = elementFactory.newAttributeElement(resources, token);
@@ -912,9 +981,12 @@ public class PageLoaderImpl implements P
         });
     }
 
-    private void body(AssemblerContext context) {
-        context.add(new PageAssemblyAction() {
-            public void execute(PageAssembly pageAssembly) {
+    private void body(AssemblerContext context)
+    {
+        context.add(new PageAssemblyAction()
+        {
+            public void execute(PageAssembly pageAssembly)
+            {
                 ComponentPageElement element = pageAssembly.activeElement.peek();
 
                 pageAssembly.addRenderCommand(new RenderBodyElement(element));
@@ -922,11 +994,14 @@ public class PageLoaderImpl implements P
         });
     }
 
-    private void expansion(AssemblerContext context) {
+    private void expansion(AssemblerContext context)
+    {
         final ExpansionToken token = context.next(ExpansionToken.class);
 
-        context.add(new PageAssemblyAction() {
-            public void execute(PageAssembly pageAssembly) {
+        context.add(new PageAssemblyAction()
+        {
+            public void execute(PageAssembly pageAssembly)
+            {
                 ComponentResources resources = pageAssembly.activeElement.peek().getComponentResources();
 
                 RenderCommand command = elementFactory.newExpansionElement(resources, token);
@@ -936,10 +1011,11 @@ public class PageLoaderImpl implements P
         });
     }
 
-    private void text(AssemblerContext context) {
+    private void text(AssemblerContext context)
+    {
         TextToken textToken = context.next(TextToken.class);
 
-        context.addComposable(new TextPageElement(textToken.getText()));
+        context.addComposable(textToken);
     }
 
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/AttributeToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/AttributeToken.java?rev=1178607&r1=1178606&r2=1178607&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/AttributeToken.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/AttributeToken.java Mon Oct  3 22:05:03 2011
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2011 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.
@@ -14,18 +14,21 @@
 
 package org.apache.tapestry5.internal.parser;
 
+import org.apache.tapestry5.MarkupWriter;
 import org.apache.tapestry5.ioc.Location;
+import org.apache.tapestry5.runtime.RenderCommand;
+import org.apache.tapestry5.runtime.RenderQueue;
 
 /**
  * Stores an attribute/value pair (as part of an XML element).
  */
-public class AttributeToken extends TemplateToken
+public class AttributeToken extends TemplateToken implements RenderCommand
 {
-    private final String namespaceURI;
+    public final String namespaceURI;
 
-    private final String name;
+    public final String name;
 
-    private final String value;
+    public final String value;
 
     public AttributeToken(String namespaceURI, String name, String value, Location location)
     {
@@ -36,29 +39,11 @@ public class AttributeToken extends Temp
         this.value = value;
     }
 
-    /**
-     * Returns local name for the attribute.
-     */
-    public String getName()
+    public void render(MarkupWriter writer, RenderQueue queue)
     {
-        return name;
+        writer.attributeNS(namespaceURI, name, value);
     }
 
-    /**
-     * Returns the value for the attribute.
-     */
-    public String getValue()
-    {
-        return value;
-    }
-
-    /**
-     * Returns the namespace URI containing the attribute, or the empty string for the default namespace.
-     */
-    public String getNamespaceURI()
-    {
-        return namespaceURI;
-    }
 
     @Override
     public String toString()

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/CDATAToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/CDATAToken.java?rev=1178607&r1=1178606&r2=1178607&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/CDATAToken.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/CDATAToken.java Mon Oct  3 22:05:03 2011
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2011 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.
@@ -14,14 +14,17 @@
 
 package org.apache.tapestry5.internal.parser;
 
+import org.apache.tapestry5.MarkupWriter;
 import org.apache.tapestry5.ioc.Location;
+import org.apache.tapestry5.runtime.RenderCommand;
+import org.apache.tapestry5.runtime.RenderQueue;
 
 /**
  * Literal text that was enclosed within a !CDATA in the input template (so we should do the same during output).
  */
-public class CDATAToken extends TemplateToken
+public class CDATAToken extends TemplateToken implements RenderCommand
 {
-    private final String content;
+    public final String content;
 
     public CDATAToken(String content, Location location)
     {
@@ -30,9 +33,9 @@ public class CDATAToken extends Template
         this.content = content;
     }
 
-    public String getContent()
+    public void render(MarkupWriter writer, RenderQueue queue)
     {
-        return content;
+        writer.cdata(content);
     }
 
     @Override

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/CommentToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/CommentToken.java?rev=1178607&r1=1178606&r2=1178607&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/CommentToken.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/CommentToken.java Mon Oct  3 22:05:03 2011
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2011 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.
@@ -14,14 +14,17 @@
 
 package org.apache.tapestry5.internal.parser;
 
+import org.apache.tapestry5.MarkupWriter;
 import org.apache.tapestry5.ioc.Location;
+import org.apache.tapestry5.runtime.RenderCommand;
+import org.apache.tapestry5.runtime.RenderQueue;
 
 /**
  * A node representing a comment embedded in the source input.
  */
-public class CommentToken extends TemplateToken
+public class CommentToken extends TemplateToken implements RenderCommand
 {
-    private final String comment;
+    public final String comment;
 
     public CommentToken(String comment, Location location)
     {
@@ -30,9 +33,9 @@ public class CommentToken extends Templa
         this.comment = comment;
     }
 
-    public String getComment()
+    public void render(MarkupWriter writer, RenderQueue queue)
     {
-        return comment;
+        writer.comment(comment);
     }
 
     @Override

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/DTDToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/DTDToken.java?rev=1178607&r1=1178606&r2=1178607&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/DTDToken.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/DTDToken.java Mon Oct  3 22:05:03 2011
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2011 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.
@@ -14,20 +14,24 @@
 
 package org.apache.tapestry5.internal.parser;
 
+import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.dom.Document;
 import org.apache.tapestry5.ioc.Location;
+import org.apache.tapestry5.runtime.RenderCommand;
+import org.apache.tapestry5.runtime.RenderQueue;
 
 /**
  * Represents the presence of a Document Type declaration within a template. The Document type declaration will be
  * output to the client. In the event that multiple declarations are encountered (a page and one or more nested
  * components all declare a document type), the first document type declared will be used.
  */
-public class DTDToken extends TemplateToken
+public class DTDToken extends TemplateToken implements RenderCommand
 {
-    private final String name;
+    public final String name;
 
-    private final String publicId;
+    public final String publicId;
 
-    private final String systemId;
+    public final String systemId;
 
     public DTDToken(String name, String publicId, String systemId, Location location)
     {
@@ -38,28 +42,14 @@ public class DTDToken extends TemplateTo
         this.systemId = systemId;
     }
 
-    /**
-     * Returns the doctype name (the name of the document root element)
-     */
-    public String getName()
+    public void render(MarkupWriter writer, RenderQueue queue)
     {
-        return name;
-    }
+        Document document = writer.getDocument();
 
-    /**
-     * Returns the public identifier of the DTD
-     */
-    public String getPublicId()
-    {
-        return publicId;
-    }
-
-    /**
-     * Returns the system identifier of the DTD
-     */
-    public String getSystemId()
-    {
-        return systemId;
+        if (!document.hasDTD())
+        {
+            document.dtd(name, publicId, systemId);
+        }
     }
 
     @Override

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/DefineNamespacePrefixToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/DefineNamespacePrefixToken.java?rev=1178607&r1=1178606&r2=1178607&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/DefineNamespacePrefixToken.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/DefineNamespacePrefixToken.java Mon Oct  3 22:05:03 2011
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2011 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.
@@ -14,7 +14,10 @@
 
 package org.apache.tapestry5.internal.parser;
 
+import org.apache.tapestry5.MarkupWriter;
 import org.apache.tapestry5.ioc.Location;
+import org.apache.tapestry5.runtime.RenderCommand;
+import org.apache.tapestry5.runtime.RenderQueue;
 
 /**
  * A token from a template that defines a namespace prefix. This will always follow a {@link
@@ -24,10 +27,11 @@ import org.apache.tapestry5.ioc.Location
  *
  * @see org.apache.tapestry5.dom.Element#defineNamespace(String, String)
  */
-public class DefineNamespacePrefixToken extends TemplateToken
+public class DefineNamespacePrefixToken extends TemplateToken implements RenderCommand
 {
-    private final String namespaceURI;
-    private final String namespacePrefix;
+    public final String namespaceURI;
+
+    public final String namespacePrefix;
 
     public DefineNamespacePrefixToken(String namespaceURI, String namespacePrefix, Location location)
     {
@@ -37,19 +41,15 @@ public class DefineNamespacePrefixToken 
         this.namespaceURI = namespaceURI;
     }
 
-    public String getNamespacePrefix()
+    @Override
+    public String toString()
     {
-        return namespacePrefix;
+        return String.format("DefineNamespacePrefix[%s=%s]", namespacePrefix, namespaceURI);
     }
 
-    public String getNamespaceURI()
+    public void render(MarkupWriter writer, RenderQueue queue)
     {
-        return namespaceURI;
+        writer.defineNamespace(namespaceURI, namespacePrefix);
     }
 
-    @Override
-    public String toString()
-    {
-        return String.format("DefineNamespacePrefix[%s=%s]", namespacePrefix, namespaceURI);
-    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/ParameterToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/ParameterToken.java?rev=1178607&r1=1178606&r2=1178607&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/ParameterToken.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/ParameterToken.java Mon Oct  3 22:05:03 2011
@@ -21,7 +21,7 @@ import org.apache.tapestry5.ioc.Location
  */
 public class ParameterToken extends TemplateToken
 {
-    private final String name;
+    public final String name;
 
     /**
      * @param name     the name of the parameter to be bound
@@ -34,11 +34,6 @@ public class ParameterToken extends Temp
         this.name = name;
     }
 
-    public String getName()
-    {
-        return name;
-    }
-
     @Override
     public String toString()
     {

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/StartElementToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/StartElementToken.java?rev=1178607&r1=1178606&r2=1178607&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/StartElementToken.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/StartElementToken.java Mon Oct  3 22:05:03 2011
@@ -1,4 +1,4 @@
-// Copyright 2006, 2009 The Apache Software Foundation
+// Copyright 2006, 2009, 2011 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.
@@ -14,7 +14,10 @@
 
 package org.apache.tapestry5.internal.parser;
 
+import org.apache.tapestry5.MarkupWriter;
 import org.apache.tapestry5.ioc.Location;
+import org.apache.tapestry5.runtime.RenderCommand;
+import org.apache.tapestry5.runtime.RenderQueue;
 
 /**
  * The start of an ordinary element within the template (as opposed to {@link org.apache.tapestry5.internal.parser.StartComponentToken},
@@ -23,11 +26,11 @@ import org.apache.tapestry5.ioc.Location
  * start element token will always be balanced by a {@link org.apache.tapestry5.internal.parser.EndElementToken} (though
  * there will likely be some amount of intermediate tokens).
  */
-public class StartElementToken extends TemplateToken
+public class StartElementToken extends TemplateToken implements RenderCommand
 {
-    private final String namespaceURI;
+    public final String namespaceURI;
 
-    private final String name;
+    public final String name;
 
     public StartElementToken(String namespaceURI, String name, Location location)
     {
@@ -37,22 +40,6 @@ public class StartElementToken extends T
         this.name = name;
     }
 
-    /**
-     * Returns local name for the element.
-     */
-    public String getName()
-    {
-        return name;
-    }
-
-    /**
-     * @return the namespace URI for the element, or the empty string for the default namespace
-     */
-    public String getNamespaceURI()
-    {
-        return namespaceURI;
-    }
-
     @Override
     public String toString()
     {
@@ -64,4 +51,9 @@ public class StartElementToken extends T
 
         return builder.toString();
     }
+
+    public void render(MarkupWriter writer, RenderQueue queue)
+    {
+        writer.elementNS(namespaceURI, name);
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/TextToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/TextToken.java?rev=1178607&r1=1178606&r2=1178607&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/TextToken.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/parser/TextToken.java Mon Oct  3 22:05:03 2011
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2011 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.
@@ -14,14 +14,17 @@
 
 package org.apache.tapestry5.internal.parser;
 
+import org.apache.tapestry5.MarkupWriter;
 import org.apache.tapestry5.ioc.Location;
+import org.apache.tapestry5.runtime.RenderCommand;
+import org.apache.tapestry5.runtime.RenderQueue;
 
 /**
  *
  */
-public class TextToken extends TemplateToken
+public class TextToken extends TemplateToken implements RenderCommand
 {
-    private final String text;
+    public final String text;
 
     public TextToken(String text, Location location)
     {
@@ -30,12 +33,9 @@ public class TextToken extends TemplateT
         this.text = text;
     }
 
-    /**
-     * Returns the text extracted from that part of the template.
-     */
-    public String getText()
+    public void render(MarkupWriter writer, RenderQueue queue)
     {
-        return text;
+        writer.write(text);
     }
 
     @Override

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactoryImpl.java?rev=1178607&r1=1178606&r2=1178607&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactoryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactoryImpl.java Mon Oct  3 22:05:03 2011
@@ -23,7 +23,6 @@ import org.apache.tapestry5.internal.par
 import org.apache.tapestry5.internal.parser.ExpansionToken;
 import org.apache.tapestry5.internal.structure.ExpansionPageElement;
 import org.apache.tapestry5.ioc.Location;
-import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newList;
 import org.apache.tapestry5.ioc.internal.util.TapestryException;
 import org.apache.tapestry5.ioc.services.TypeCoercer;
 import org.apache.tapestry5.runtime.RenderCommand;
@@ -32,6 +31,8 @@ import org.apache.tapestry5.services.Bin
 
 import java.util.List;
 
+import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newList;
+
 public class PageElementFactoryImpl implements PageElementFactory
 {
     private final TypeCoercer typeCoercer;
@@ -61,22 +62,19 @@ public class PageElementFactoryImpl impl
 
     public RenderCommand newAttributeElement(ComponentResources componentResources, final AttributeToken token)
     {
-        final StringProvider provider = parseAttributeExpansionExpression(token.getValue(), componentResources,
-                                                                          token.getLocation());
-
-        final String namespace = token.getNamespaceURI();
-        final String name = token.getName();
+        final StringProvider provider = parseAttributeExpansionExpression(token.value, componentResources,
+                token.getLocation());
 
         return new RenderCommand()
         {
             public void render(MarkupWriter writer, RenderQueue queue)
             {
-                writer.attributeNS(namespace, name, provider.provideString());
+                writer.attributeNS(token.namespaceURI, token.name, provider.provideString());
             }
 
             public String toString()
             {
-                return String.format("AttributeNS[%s %s \"%s\"]", namespace, name, token.getValue());
+                return String.format("AttributeNS[%s %s \"%s\"]", token.namespaceURI, token.name, token.value);
             }
         };
     }
@@ -115,7 +113,7 @@ public class PageElementFactoryImpl impl
             String expansion = expression.substring(expansionx + 2, endx);
 
             final Binding binding = bindingSource.newBinding("attribute expansion", resources, resources,
-                                                             BindingConstants.PROP, expansion, location);
+                    BindingConstants.PROP, expansion, location);
 
             final StringProvider provider = new StringProvider()
             {
@@ -126,8 +124,7 @@ public class PageElementFactoryImpl impl
                         Object raw = binding.get();
 
                         return typeCoercer.coerce(raw, String.class);
-                    }
-                    catch (Exception ex)
+                    } catch (Exception ex)
                     {
                         throw new TapestryException(ex.getMessage(), location, ex);
                     }
@@ -163,7 +160,7 @@ public class PageElementFactoryImpl impl
     public RenderCommand newExpansionElement(ComponentResources componentResources, ExpansionToken token)
     {
         Binding binding = bindingSource.newBinding("expansion", componentResources, componentResources,
-                                                   BindingConstants.PROP, token.getExpression(), token.getLocation());
+                BindingConstants.PROP, token.getExpression(), token.getLocation());
 
         return new ExpansionPageElement(binding, typeCoercer);
     }
@@ -176,12 +173,12 @@ public class PageElementFactoryImpl impl
         if (expression.contains(InternalConstants.EXPANSION_START))
         {
             StringProvider provider = parseAttributeExpansionExpression(expression, loadingComponentResources,
-                                                                        location);
+                    location);
 
             return new AttributeExpansionBinding(location, provider);
         }
 
         return bindingSource.newBinding(parameterName, loadingComponentResources,
-                                        embeddedComponentResources, defaultBindingPrefix, expression, location);
+                embeddedComponentResources, defaultBindingPrefix, expression, location);
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TemplateParserImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TemplateParserImplTest.java?rev=1178607&r1=1178606&r2=1178607&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TemplateParserImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TemplateParserImplTest.java Mon Oct  3 22:05:03 2011
@@ -103,35 +103,35 @@ public class TemplateParserImplTest exte
 
         // Spot check a few things ...
 
-        assertEquals(t0.getName(), "html");
-        assertEquals(t0.getNamespaceURI(), "");
+        assertEquals(t0.name, "html");
+        assertEquals(t0.namespaceURI, "");
         checkLine(t0, 1);
 
         TextToken t1 = get(tokens, 1);
         // Concerned this may not work cross platform.
-        assertEquals(t1.getText(), "\n    ");
+        assertEquals(t1.text, "\n    ");
 
         StartElementToken t2 = get(tokens, 2);
-        assertEquals(t2.getName(), "head");
+        assertEquals(t2.name, "head");
         checkLine(t2, 2);
 
         TextToken t5 = get(tokens, 5);
-        assertEquals(t5.getText(), "title");
+        assertEquals(t5.text, "title");
         checkLine(t5, 3);
 
         get(tokens, 6);
 
         StartElementToken t12 = get(tokens, 12);
-        assertEquals(t12.getName(), "p");
+        assertEquals(t12.name, "p");
 
         AttributeToken t13 = get(tokens, 13);
-        assertEquals(t13.getName(), "class");
-        assertEquals(t13.getValue(), "important");
-        assertEquals(t13.getNamespaceURI(), "");
+        assertEquals(t13.name, "class");
+        assertEquals(t13.value, "important");
+        assertEquals(t13.namespaceURI, "");
 
         TextToken t14 = get(tokens, 14);
         // Simplify the text, converting consecutive whitespace to just a single space.
-        assertEquals(t14.getText().replaceAll("\\s+", " ").trim(), "Tapestry rocks! Line 2");
+        assertEquals(t14.text.replaceAll("\\s+", " ").trim(), "Tapestry rocks! Line 2");
 
         // Line number is the *start* line of the whole text block.
         checkLine(t14, 6);
@@ -156,24 +156,24 @@ public class TemplateParserImplTest exte
 
         String expectedURI = "http://foo.com";
 
-        assertEquals(t0.getNamespaceURI(), expectedURI);
-        assertEquals(t0.getName(), "bar");
+        assertEquals(t0.namespaceURI, expectedURI);
+        assertEquals(t0.name, "bar");
 
         DefineNamespacePrefixToken t1 = get(tokens, 1);
 
-        assertEquals(t1.getNamespacePrefix(), "foo");
-        assertEquals(t1.getNamespaceURI(), expectedURI);
+        assertEquals(t1.namespacePrefix, "foo");
+        assertEquals(t1.namespaceURI, expectedURI);
 
         AttributeToken t2 = get(tokens, 2);
 
-        assertEquals(t2.getName(), "biff");
-        assertEquals(t2.getValue(), "baz");
-        assertEquals(t2.getNamespaceURI(), expectedURI);
+        assertEquals(t2.name, "biff");
+        assertEquals(t2.value, "baz");
+        assertEquals(t2.namespaceURI, expectedURI);
 
         StartElementToken t4 = get(tokens, 4);
 
-        assertEquals(t4.getNamespaceURI(), "");
-        assertEquals(t4.getName(), "gnip");
+        assertEquals(t4.namespaceURI, "");
+        assertEquals(t4.name, "gnip");
 
         // The rest are close tokens
     }
@@ -187,11 +187,11 @@ public class TemplateParserImplTest exte
 
         TextToken t0 = get(tokens, 0);
 
-        assertEquals(t0.getText().trim(), "A bit of text.");
+        assertEquals(t0.text.trim(), "A bit of text.");
 
         StartElementToken t1 = get(tokens, 1);
 
-        assertEquals(t1.getName(), "foo");
+        assertEquals(t1.name, "foo");
 
         EndElementToken t2 = get(tokens, 2);
 
@@ -199,7 +199,7 @@ public class TemplateParserImplTest exte
 
         TextToken t3 = get(tokens, 3);
 
-        assertEquals(t3.getText().trim(), "Some more text.");
+        assertEquals(t3.text.trim(), "Some more text.");
     }
 
     @Test
@@ -214,7 +214,7 @@ public class TemplateParserImplTest exte
         // This is OK because the org.apache.tapestry5.dom.Text will convert the characters back into
         // XML entities.
 
-        assertEquals(t.getText().trim(), "lt:< gt:> amp:&");
+        assertEquals(t.text.trim(), "lt:< gt:> amp:&");
     }
 
     @Test
@@ -228,19 +228,19 @@ public class TemplateParserImplTest exte
 
         DTDToken t0 = get(tokens, 0);
 
-        assertEquals(t0.getName(), "html");
-        assertEquals(t0.getPublicId(), "-//W3C//DTD XHTML 1.0 Transitional//EN");
-        assertEquals(t0.getSystemId(), "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd");
+        assertEquals(t0.name, "html");
+        assertEquals(t0.publicId, "-//W3C//DTD XHTML 1.0 Transitional//EN");
+        assertEquals(t0.systemId, "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd");
 
         StartElementToken t1 = get(tokens, 1);
 
-        assertEquals(t1.getNamespaceURI(), expectedURI);
-        assertEquals(t1.getName(), "html");
+        assertEquals(t1.namespaceURI, expectedURI);
+        assertEquals(t1.name, "html");
 
         DefineNamespacePrefixToken t2 = get(tokens, 2);
 
-        assertEquals(t2.getNamespaceURI(), expectedURI);
-        assertEquals(t2.getNamespacePrefix(), "");
+        assertEquals(t2.namespaceURI, expectedURI);
+        assertEquals(t2.namespacePrefix, "");
 
 
         TextToken t = get(tokens, 3);
@@ -252,7 +252,7 @@ public class TemplateParserImplTest exte
         // You have to have a DOCTYPE just to parse a template that uses
         // an HTML entity.
 
-        assertEquals(t.getText().trim(), "nbsp:[\u00a0]");
+        assertEquals(t.text.trim(), "nbsp:[\u00a0]");
     }
 
     @Test
@@ -266,7 +266,7 @@ public class TemplateParserImplTest exte
 
         CDATAToken t = get(tokens, 2);
 
-        assertEquals(t.getContent(), "CDATA: &lt;foo&gt; &amp; &lt;bar&gt; and <baz>");
+        assertEquals(t.content, "CDATA: &lt;foo&gt; &amp; &lt;bar&gt; and <baz>");
         checkLine(t, 2);
     }
 
@@ -281,7 +281,7 @@ public class TemplateParserImplTest exte
 
         CommentToken token1 = get(tokens, 1);
 
-        assertEquals(token1.getComment(), " Single line comment ");
+        assertEquals(token1.comment, " Single line comment ");
     }
 
     @Test
@@ -295,7 +295,7 @@ public class TemplateParserImplTest exte
 
         CommentToken t = get(tokens, 2);
 
-        String comment = t.getComment().trim().replaceAll("\\s+", " ");
+        String comment = t.comment.trim().replaceAll("\\s+", " ");
 
         assertEquals(comment, "Line one Line two Line three");
     }
@@ -327,7 +327,7 @@ public class TemplateParserImplTest exte
 
         TextToken t = get(tokens, 3);
 
-        assertEquals(t.getText().trim(), "fred's body");
+        assertEquals(t.text.trim(), "fred's body");
 
         get(tokens, 4);
     }
@@ -346,7 +346,7 @@ public class TemplateParserImplTest exte
 
         TextToken t = get(tokens, 3);
 
-        assertEquals(t.getText().trim(), "fred's body");
+        assertEquals(t.text.trim(), "fred's body");
 
         EndElementToken end5 = get(tokens, 5);
         EndElementToken end7 = get(tokens, 7);
@@ -367,8 +367,8 @@ public class TemplateParserImplTest exte
 
         AttributeToken attr = get(tokens, 1);
 
-        assertEquals(attr.getName(), "param");
-        assertEquals(attr.getValue(), "value");
+        assertEquals(attr.name, "param");
+        assertEquals(attr.value, "value");
 
         assertTrue(EndElementToken.class.isInstance(tokens.get(2)));
     }
@@ -389,8 +389,8 @@ public class TemplateParserImplTest exte
 
         AttributeToken attr = get(tokens, 1);
 
-        assertEquals(attr.getName(), "param");
-        assertEquals(attr.getValue(), "value");
+        assertEquals(attr.name, "param");
+        assertEquals(attr.value, "value");
 
         assertTrue(EndElementToken.class.isInstance(tokens.get(2)));
 
@@ -425,18 +425,18 @@ public class TemplateParserImplTest exte
         // TODO: Not sure what order the attributes appear in. Order in the XML? Sorted
         // alphabetically? Random 'cause they're hashed?
 
-        assertEquals(t1.getName(), "cherry");
-        assertEquals(t1.getValue(), "bomb");
+        assertEquals(t1.name, "cherry");
+        assertEquals(t1.value, "bomb");
         assertSame(t1.getLocation(), l);
 
         AttributeToken t2 = get(tokens, 4);
-        assertEquals(t2.getName(), "align");
-        assertEquals(t2.getValue(), "right");
+        assertEquals(t2.name, "align");
+        assertEquals(t2.value, "right");
         assertSame(t2.getLocation(), l);
 
         TextToken t3 = get(tokens, 5);
 
-        assertEquals(t3.getText().trim(), "fred's body");
+        assertEquals(t3.text.trim(), "fred's body");
 
         get(tokens, 6);
     }
@@ -489,19 +489,19 @@ public class TemplateParserImplTest exte
 
         TextToken t1 = get(tokens, 1);
 
-        assertEquals(t1.getText().trim(), "Expansion #1[");
+        assertEquals(t1.text.trim(), "Expansion #1[");
 
         ExpansionToken t2 = get(tokens, 2);
         assertEquals(t2.getExpression(), "expansion1");
 
         TextToken t3 = get(tokens, 3);
-        assertEquals(t3.getText().replaceAll("\\s+", " "), "] Expansion #2[");
+        assertEquals(t3.text.replaceAll("\\s+", " "), "] Expansion #2[");
 
         ExpansionToken t4 = get(tokens, 4);
         assertEquals(t4.getExpression(), "expansion2");
 
         TextToken t5 = get(tokens, 5);
-        assertEquals(t5.getText().trim(), "]");
+        assertEquals(t5.text.trim(), "]");
     }
 
     @Test
@@ -513,7 +513,7 @@ public class TemplateParserImplTest exte
 
         TextToken t1 = get(tokens, 1);
 
-        assertEquals(t1.getText().replaceAll("\\s+", " "), " ${expansions must be on a single line} ");
+        assertEquals(t1.text.replaceAll("\\s+", " "), " ${expansions must be on a single line} ");
     }
 
     @Test
@@ -529,7 +529,7 @@ public class TemplateParserImplTest exte
 
         TextToken token4 = get(tokens, 4);
 
-        assertEquals(token4.getText(), " [");
+        assertEquals(token4.text, " [");
 
         ExpansionToken token5 = get(tokens, 5);
 
@@ -537,7 +537,7 @@ public class TemplateParserImplTest exte
 
         TextToken token6 = get(tokens, 6);
 
-        assertEquals(token6.getText(), "]");
+        assertEquals(token6.text, "]");
     }
 
     @Test
@@ -549,7 +549,7 @@ public class TemplateParserImplTest exte
 
         CDATAToken t2 = get(tokens, 2);
 
-        assertEquals(t2.getContent(), "${not-an-expansion}");
+        assertEquals(t2.content, "${not-an-expansion}");
     }
 
     @Test
@@ -561,8 +561,8 @@ public class TemplateParserImplTest exte
 
         AttributeToken token1 = get(tokens, 1);
 
-        assertEquals(token1.getName(), "exp");
-        assertEquals(token1.getValue(), "${not-an-expansion}");
+        assertEquals(token1.name, "exp");
+        assertEquals(token1.value, "${not-an-expansion}");
     }
 
     @Test
@@ -605,10 +605,10 @@ public class TemplateParserImplTest exte
         List<TemplateToken> tokens = tokens("parameter_element.tml");
 
         ParameterToken token4 = get(tokens, 4);
-        assertEquals(token4.getName(), "fred");
+        assertEquals(token4.name, "fred");
 
         CommentToken token6 = get(tokens, 6);
-        assertEquals(token6.getComment(), " fred content ");
+        assertEquals(token6.comment, " fred content ");
 
         TemplateToken token8 = get(tokens, 8);
 
@@ -624,10 +624,10 @@ public class TemplateParserImplTest exte
         List<TemplateToken> tokens = tokens("parameter_namespace_element.tml");
 
         ParameterToken token4 = get(tokens, 4);
-        assertEquals(token4.getName(), "fred");
+        assertEquals(token4.name, "fred");
 
         CommentToken token6 = get(tokens, 6);
-        assertEquals(token6.getComment(), " fred content ");
+        assertEquals(token6.comment, " fred content ");
 
         TemplateToken token8 = get(tokens, 8);
 
@@ -670,13 +670,13 @@ public class TemplateParserImplTest exte
         assertEquals(token1.getId(), "block0");
 
         CommentToken token2 = get(tokens, 2);
-        assertEquals(token2.getComment(), " block0 content ");
+        assertEquals(token2.comment, " block0 content ");
 
         BlockToken token4 = get(tokens, 4);
         assertNull(token4.getId());
 
         CommentToken token5 = get(tokens, 5);
-        assertEquals(token5.getComment(), " anon block content ");
+        assertEquals(token5.comment, " anon block content ");
     }
 
     @DataProvider
@@ -767,7 +767,7 @@ public class TemplateParserImplTest exte
         List<TemplateToken> tokens = tokens(fileName);
         assertEquals(tokens.size(), 12);
         TextToken t = get(tokens, 9);
-        assertEquals(t.getText().trim(), "<Test>");
+        assertEquals(t.text.trim(), "<Test>");
     }
 
     @DataProvider
@@ -804,9 +804,9 @@ public class TemplateParserImplTest exte
 
         List<TemplateToken> tokens = tokens(fileName);
         DTDToken t0 = get(tokens, 0);
-        assertEquals(t0.getName(), name);
-        assertEquals(t0.getPublicId(), publicId);
-        assertEquals(t0.getSystemId(), systemId);
+        assertEquals(t0.name, name);
+        assertEquals(t0.publicId, publicId);
+        assertEquals(t0.systemId, systemId);
     }
 
     @Test
@@ -845,7 +845,7 @@ public class TemplateParserImplTest exte
 
         TextToken token1 = get(tokens, 1);
 
-        assertEquals(token1.getText(), "\n" + "        line in the middle\n" + "    ");
+        assertEquals(token1.text, "\n" + "        line in the middle\n" + "    ");
     }
 
     /**
@@ -857,10 +857,10 @@ public class TemplateParserImplTest exte
         List<TemplateToken> tokens = tokens("space_preserved_in_container.tml");
 
         TextToken token0 = get(tokens, 0);
-        assertEquals(token0.getText(), "\n" + "    ");
+        assertEquals(token0.text, "\n" + "    ");
 
         TextToken token2 = get(tokens, 2);
-        assertEquals(token2.getText(), "\n" + "        some text\n" + "    ");
+        assertEquals(token2.text, "\n" + "        some text\n" + "    ");
     }
 
     @Test
@@ -872,11 +872,11 @@ public class TemplateParserImplTest exte
         // just a line feed.
 
         TextToken token1 = get(tokens, 1);
-        assertEquals(token1.getText(), "\nWhitespace\n");
+        assertEquals(token1.text, "\nWhitespace\n");
 
 
         TextToken token5 = get(tokens, 5);
-        assertEquals(token5.getText(), "\nis maintained.\n");
+        assertEquals(token5.text, "\nis maintained.\n");
     }
 
     /**
@@ -894,11 +894,11 @@ public class TemplateParserImplTest exte
         assertEquals(token0.getComponentType(), "layout");
 
         StartElementToken token1 = get(tokens, 1);
-        assertEquals(token1.getName(), "p");
+        assertEquals(token1.name, "p");
 
         TextToken token2 = get(tokens, 2);
 
-        assertEquals(token2.getText(), "Page content");
+        assertEquals(token2.text, "Page content");
 
         checkType(tokens, 3, TokenType.END_ELEMENT);
         checkType(tokens, 4, TokenType.END_ELEMENT);
@@ -918,17 +918,17 @@ public class TemplateParserImplTest exte
         assertEquals(alpha.size(), 1);
 
         TextToken alpha0 = get(alpha, 0);
-        assertEquals(alpha0.getText(), "beta");
+        assertEquals(alpha0.text, "beta");
 
         List<TemplateToken> gamma = template.getExtensionPointTokens("gamma");
         assertEquals(gamma.size(), 3);
 
         StartElementToken gamma0 = get(gamma, 0);
-        assertEquals(gamma0.getName(), "p");
+        assertEquals(gamma0.name, "p");
 
         TextToken gamma1 = get(gamma, 1);
 
-        assertEquals(gamma1.getText(), "Hi!");
+        assertEquals(gamma1.text, "Hi!");
 
         checkType(gamma, 2, TokenType.END_ELEMENT);
     }
@@ -947,10 +947,10 @@ public class TemplateParserImplTest exte
         assertEquals(title.size(), 3);
 
         StartElementToken title0 = get(title, 0);
-        assertEquals(title0.getName(), "h1");
+        assertEquals(title0.name, "h1");
 
         TextToken title1 = get(title, 1);
-        assertEquals(title1.getText(), "Default Title");
+        assertEquals(title1.text, "Default Title");
 
         checkType(title, 2, TokenType.END_ELEMENT);
     }
@@ -964,6 +964,6 @@ public class TemplateParserImplTest exte
 
         TextToken token3 = get(tokens, 3);
 
-        assertEquals(token3.getText(), "\u00A92011\u00A0Apache");
+        assertEquals(token3.text, "\u00A92011\u00A0Apache");
     }
 }