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 2006/09/05 05:27:28 UTC

svn commit: r440237 - in /tapestry/tapestry5/tapestry-core/trunk/src: ./ main/java/org/apache/tapestry/ main/java/org/apache/tapestry/internal/services/ main/java/org/apache/tapestry/internal/structure/ main/java/org/apache/tapestry/runtime/ main/java/...

Author: hlship
Date: Mon Sep  4 20:27:27 2006
New Revision: 440237

URL: http://svn.apache.org/viewvc?view=rev&rev=440237
Log:
Remove the MarkupWriter.writeln() method.
Add detailed documentation about component rendering.
Add support for marking a field as read-only during component class transformation.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/rendering.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/resources/images/component-render-states.png   (with props)
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ReadOnlyBean.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/MarkupWriter.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MarkupWriterImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/PageLifecycleListener.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties
    tapestry/tapestry5/tapestry-core/trunk/src/render-states.ygf
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/component-classes.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/dom.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/index.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MarkupWriterImplTest.java

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/MarkupWriter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/MarkupWriter.java?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/MarkupWriter.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/MarkupWriter.java Mon Sep  4 20:27:27 2006
@@ -60,9 +60,6 @@
 
     void write(String text);
 
-    /** Writes a line separator. */
-    void writeln();
-
     /** Writes a formatted string. */
     void writef(String format, Object... args);
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java Mon Sep  4 20:27:27 2006
@@ -792,7 +792,6 @@
         catch (NotFoundException ex)
         {
             throw new RuntimeException(ex);
-
         }
     }
 
@@ -1033,6 +1032,25 @@
         builder.append("]");
 
         return builder.toString();
+    }
+
+    public void makeReadOnly(String fieldName)
+    {
+        String methodName = "_write_" + fieldName;
+
+        String fieldType = getFieldType(fieldName);
+
+        MethodSignature sig = new MethodSignature(Modifier.PRIVATE, "void", methodName,
+                new String[]
+                { fieldType }, null);
+
+        String message = ServicesMessages.readOnlyField(_ctClass.getName(), fieldName);
+
+        String body = format("throw new java.lang.RuntimeException(\"%s\");", message);
+
+        addMethod(sig, body);
+
+        replaceWriteAccess(fieldName, methodName);
     }
 
     public void replaceReadAccess(String fieldName, String methodName)

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MarkupWriterImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MarkupWriterImpl.java?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MarkupWriterImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MarkupWriterImpl.java Mon Sep  4 20:27:27 2006
@@ -64,11 +64,6 @@
         _currentText.writef(format, args);
     }
 
-    public void writeln()
-    {
-        write("\n");
-    }
-
     public void attributes(Object... namesAndValues)
     {
         ensureCurrentElement();

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java Mon Sep  4 20:27:27 2006
@@ -133,4 +133,9 @@
     {
         return MESSAGES.format("render-queue-error", command, cause);
     }
+
+    static String readOnlyField(String className, String fieldName)
+    {
+        return MESSAGES.format("read-only-field", className, fieldName);
+    }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Mon Sep  4 20:27:27 2006
@@ -286,7 +286,7 @@
 
     };
 
-    private RenderCommand _renderCloseTag = new RenderCommand()
+    private RenderCommand _afterRender = new RenderCommand()
     {
         @SuppressNullCheck
         public void render(MarkupWriter writer, RenderQueue queue)
@@ -373,7 +373,7 @@
         // (including the render body directive), we want to
         // give the component a chance to render its close tag.
 
-        queue.push(_renderCloseTag);
+        queue.push(_afterRender);
 
         // Push them in reverse order, so that the first template item
         // it at the head of the queue.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/PageLifecycleListener.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/PageLifecycleListener.java?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/PageLifecycleListener.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/PageLifecycleListener.java Mon Sep  4 20:27:27 2006
@@ -14,6 +14,11 @@
 
 package org.apache.tapestry.runtime;
 
+/**
+ * A set of methods that allow components to know about page-level operations.
+ * 
+ * @author Howard M. Lewis Ship
+ */
 public interface PageLifecycleListener
 {
     /**
@@ -32,6 +37,6 @@
      * Invoked when a page is first attached to the current request, giving components a chance to
      * initialize for the current request.
      */
-    
+
     void containingPageDidAttach();
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java Mon Sep  4 20:27:27 2006
@@ -112,6 +112,15 @@
     void claimField(String fieldName, Object tag);
 
     /**
+     * Changes the field to be read only. Any existing code that changes the field will cause a
+     * runtime exception.
+     * 
+     * @param fieldName
+     *            name of field to so change
+     */
+    void makeReadOnly(String fieldName);
+
+    /**
      * Finds any declared <em>instance</em> fields that have not been claimed (via
      * {@link #claimField(String, Object)}) and returns the names of those fields. May return an
      * empty array.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties Mon Sep  4 20:27:27 2006
@@ -33,4 +33,5 @@
 content-inside-body-not-allowed=Content inside a Tapestry body element is not allowed (at %s). The content has been ignored.
 may-not-nest-elements-inside-body=Element '%s' is nested within a Tapestry body element, which is not allowed.
 method-compile-error=Error compiling method %s (%s): %s
-render-queue-error=Render queue error in %s: %s
\ No newline at end of file
+render-queue-error=Render queue error in %s: %s
+read-only-field=Field %s.%s is read-only.
\ No newline at end of file

Modified: tapestry/tapestry5/tapestry-core/trunk/src/render-states.ygf
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/render-states.ygf?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
Binary files - no diff available.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/component-classes.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/component-classes.apt?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/component-classes.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/component-classes.apt Mon Sep  4 20:27:27 2006
@@ -1,8 +1,8 @@
  ---
- Writing Component Classes
+  Component Classes
  ----
  
-Writing Component Classes
+Component Classes
 
 * Component Class Basics
 
@@ -11,7 +11,9 @@
   Unlike Tapestry 4, in Tapestry 5, component classes are not <abstract>, nor do
   they extend from framework base classes. They are pure POJOs (Plain Old Java Objects).
   
-  There are only two constraints:
+  There are only a few constraints:
+  
+  * The classes must be public.
   
   * The classes must be in the correct package, as per the {{{conf.html}application configuration}}.
   
@@ -28,12 +30,12 @@
 
 import org.apache.tapestry.MarkupWriter;
 import org.apache.tapestry.annotations.ComponentClass;
-import org.apache.tapestry.annotations.RenderTag;
+import org.apache.tapestry.annotations.BeginRender;
 
 @ComponentClass
 public class HelloWorld
 {
-    @RenderTag
+    @BeginRender
     void renderMessage(MarkupWriter writer)
     {
         writer.write("Bonjour from HelloWorld component.");
@@ -42,11 +44,69 @@
 +----+  
   
   This component's only job is to write out a fixed message. The
-  {{{../apidocs/org/apache/tapestry/annotations/RenderTag.html}RenderTag}} annotation is
-  a type of <component lifecycle annotation>, a method annotation that instructs
+  {{{../apidocs/org/apache/tapestry/annotations/BeginRender.html}BeginRender}} annotation is
+  a type of <{{{rendering.html}component lifecycle annotation}}>, a method annotation that instructs
   Tapestry when and under what circumstances to invoke methods of your class.
  
   In another departure from Tapestry 4, these methods are not necessarily public; they
-  can be protected, package private, or private.
+  can have any visibility you like.
+  
+Class Transformation
+
+  Tapestry uses your class as a starting point. It <transforms> your class at runtime. This is necessary
+  for a number of reasons, including to address how Tapestry pools pages between requests.
+  
+  For the most part, these transformations are both sensible and invisible. In a few limited cases, they
+  are maginally {{{http://www.joelonsoftware.com/printerFriendly/articles/LeakyAbstractions.html}leaky}} -- for instance,
+  the requirement that instance variables be private -- but we feel that the programming
+  model in general will support very high levels of developer productivity.
+  
+  Because transformation doesn't occur until <runtime>, the build stage of your application is not
+  affected by the fact that you are creating a Tapestry application. Further, your classes are absolutely
+  simple POJOs during testing.
+  
+Class Reloading
+
+  Component classes are monitored for changes by the framework. 
+  {{{reload.html}Classes are reloaded when changed.}} This allows you to build your application
+  with a speed approaching that of a scripting environment, without sacrificing any of the power
+  of the Java platform.
+  
+Instance Variables
+
+  Tapestry components may have instance variables (unlike Tapestry 4, where you had to 
+  use <abstract properties>). 
+  
+  Instance variables must be private. Tapestry must perform runtime class modifications to
+  support instance variables, and may only do so for private variables. You may have
+  non-private variables in your class, but you may then see unexpected behavior in
+  a production application because of how Tapestry pools and reuses pages and components.
+  
+  Be aware that you will need to provide getter and setter methods to access your classes'
+  instance variables. Tapestry <does not> do this automatically.
+  
+Transient Instance Variables
+
+  Unless an instance variable is decorated with an annotation, it will be a
+  <transient> instance variable. This means that its value resets to its
+  default value
+  at the end of reach request.
+  
+  <<TODO: Setting an initial value with @OnPageLoad>>
+  
+Constructors
+
+  Tapestry adds its own constructors to your class, and doesn't invoke your constructors. You
+  should be careful not to have any logic inside your constructors.
+  
+  <TODO: Can we "convert" the default constructor into a method called by the fabricated
+  constructor?>
+  
+Injection
+
+  Injection of dependencies occurs at the field level, via additional annotations.  At runtime,
+  fields that contain injections become read-only.
+  
+  
   
   

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/dom.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/dom.apt?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/dom.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/dom.apt Mon Sep  4 20:27:27 2006
@@ -133,16 +133,10 @@
 * write()
 
   The write() method writes text inside the current element.  It scans the provided text for XML control characters
-  ('<', '>', and '&') and converts them to their XML entity equivalents ('&lt;', '&gt;', and '&amp;').  The result is correct, safe,
+  ('\<', '\>', and '&') and converts them to their XML entity equivalents ('&lt;', '&gt;', and '&amp;').  The result is correct, safe,
   HTML/XML output even when the content (which may come from a template, or from an external source such as a database)
   contains such problematic characters.
-  
-* writeln()
-
-  Writes a blank line, which is useful for neatness.
-  
-  <<TODO: This may go away in the future, once output pretty-printing and/or compression is implemented.>>
-  
+   
 * writef()
 
   The writef() method formats an number of arguments.  It uses a java.util.Formatter.  It is a convience for formatting that ultimately

Added: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/rendering.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/rendering.apt?view=auto&rev=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/rendering.apt (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/rendering.apt Mon Sep  4 20:27:27 2006
@@ -0,0 +1,189 @@
+ ----
+ Component Rendering
+ ----
+
+Component Rendering
+
+* Tapestry 4 Approach
+ 
+ Rendering was a recursive process. Each component implemented a render() method
+ (inherited from an IRender interface).
+ Component's would invoke render() on the objects in their template, including
+ other components. 
+ 
+ {{{http://blog.rapidred.com/}Bruce Tate}} has said "if you get veritgo, don't
+ stand at the edge of a JavaServer Faces stack trace and look down". The same applies
+ to Tapestry 4. Once you have heavily nested, looping components, the stack trace
+ can get quite deep. 
+ 
+* Tapestry 5 Approach
+
+ Rendering of components is based on a <state machine> and a <queue> instead of tail recursion.
+ This breaks the rendering process up into tiny pieces that can easily be
+ implemented or overriden.  Don't worry, in practice, it is a breathtakingly
+ small amount of code to write.
+ 
+Rendering Phases
+
+ The rendering of  each component is divided into a number of phases, illustrated
+ below.
+ 
+[../images/component-render-states.png] Component Render States
+
+  Each of the orange phases (SetupRender, BeginRender, BeforeRenderBody,
+  AfterRender and CleanupRender) corresponds to an annotation you
+  may place on one or more methods of your class.  The annotation directs
+  Tapestry to invoke your method as part of that phase.
+  
+  Methods marked with these annotations are called <<render phase methods>>.
+  
+  Your methods may be void, or return a boolean value. Returning a value can force
+  phases to be skipped, or re-visited.
+  
+  Render phase methods may take no parameters, or may take
+  a parameter of type {{{dom.html}MarkupWriter}}.  The methods can have any visibility
+  you like ... typically, package private is used, as it
+  makes it possible to test your code without making the methods part of the component's
+  public API.
+  
+  These methods are <<optional>>, a default behavior is associated with each phase.
+ 
+  Here's the source for a looping component that renders its body a number of times,
+  and stores the current index value in a parameter:
+  
++---+
+package org.example.components;
+
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.Parameter;
+import org.apache.tapestry.annotations.AfterRender;
+import org.apache.tapestry.annotations.SetupRender;
+
+@ComponentClass
+public class Loop
+{
+    @Parameter(required = true)
+    private int _min;
+
+    @Parameter(required = true)
+    private int _max;
+
+    @Parameter(required = true)
+    private int _value;
+
+    @SetupRender
+    void initializeValue()
+    {
+        _value = _min;
+    }
+
+    @AfterRender
+    boolean incrementLoopCount()
+    {
+        int newValue = _value + 1;
+
+        if (newValue <= _max)
+        {
+            _value = newValue;
+            return true;
+        }
+
+        return false;
+    }
+}
++---+
+  
+  Returning true from incrementLoopCount() causes Tapestry to re-run the BeginRender phase,
+  and from there, re-render the component's body (this component does not have a template).
+  Returning false transitions to the CleanupRender phase.
+  
+  Notice how Tapestry adapts to your methods, as marked with the annotations. It also
+  adapts in terms of parameters; the two annotated methods here did not perform any
+  output, so they did not need a MarkupWriter.
+  
+  What's really mind blowing is that the template and body of a component will
+  often contain ... more components! That means that many different components will
+  be in different phases of their own state machine.
+  
+  <TODO: Add more phases as needed.  Could phases be extensible?>
+  
+* {{{../apidocs/org/apache/tapestry/annotations/SetupRender.html}SetupRender}}
+
+  This is where you can perform any one-time per-render setup for your component.
+  This is a good place to read component parameters and use them to set temporary instance
+  variables.
+  
+* {{{../apidocs/org/apache/tapestry/annotations/BeginRender.html}BeginRender}}
+
+  For components that render a tag, the start tag is usually rendered here. The component
+  can also prevent the template and/or body from being rendered by returning false.
+  
+  Components may or may not have a template.  If a component has a template,
+  and the template includes a \<render-body\> element, then the BeforeRenderBody phase
+  will be triggered (giving the component the option of rendering its body or not).
+  
+  If a component does not have a \<render-body\> element in its template, then
+  the BeforeRenderBody phase is not triggered.
+  
+  If a component does not have a template, but does have a body, the BeforeRenderBody
+  phase is still triggered.
+  
+  If no methods are annotated with BeginRender, then no special output occurs during
+  this phase, but the template (if present) or body (if no template is present, but
+  the component has a body) will be rendered.
+  
+* {{{../apidocs/org/apache/tapestry/annotations/BeforeRenderBody.html}BeforeRenderBody}}
+
+  Phase associated with a component's body (the portion of its container's template that
+  the component occupies).  The BeforeRenderBody phase allows the component the ability
+  to skip the body, while still rendering the rest of the component's template (if any).
+  
+  If not methods are annotated with BeforeRenderBody, then the body will be rendered by
+  default. Again, this occurs when the \<render-body\> element of the component's template
+  is reached, or automatically if the component has no template (but the component does
+  have a body).
+  
+  <TODO: At some point in the future, we may add a PostRenderBody phase, which would allow
+  the component to wrap the body in additional markup, as desired.>
+  
+* {{{../apidocs/org/apache/tapestry/annotations/AfterRender.html}AfterRender}}
+  
+  This phase complements BeginRender, and is often used to render the close tag
+  that matches the start tag rendered in the BeginRender phase.  In any case, the
+  AfterRender phase can continue on to CleanupRender, or revert back to BeginRender (as
+  in our Loop component example, above).
+  
+  <TODO: Perhaps this should be called "FinishRender"?>
+  
+  If not methods are annotated with FinishRender, then no special output occurs, and the
+  CleanupRender phase is triggered.
+   
+* {{{../apidocs/org/apache/tapestry/annotations/CleanupRender.html}CleanupRender}}
+  
+  The counterpart to SetupRender, this allows final cleanups to occur.
+
+Method Conflicts and Ordering
+
+  It is possible to have multiple methods that are annotated with the
+  same render phase annotation.  This may include methods in the same class, or
+  a mix of method defined in a class and inherited from other classes.
+  
+* Parents before Child
+
+  Ordering is always parent-first.  Methods defined in the parent class are always invoked
+  before methods defined in the child class.
+  
+* Within a Class
+
+  Currently, methods are sorted alphabetically. Methods with the same name are
+  sorted by number of parameters.  Even so, this is not a great idea ... just define
+  one method, and have it call the other methods in the order you desire.
+  
+* Short Circuiting
+
+  If a method returns a true or false value, this will short circuit processing. Other 
+  methods within the phase that would ordinarily be invoked will not be invoked.
+  
+  Most render phase methods should return void.
+  
+  
\ No newline at end of file

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/index.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/index.apt?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/index.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/index.apt Mon Sep  4 20:27:27 2006
@@ -42,15 +42,21 @@
   
   * Components no longer extend from base classes.
   
-  * Components classes are no longer <abstract>.  Components are pure, simple POJOs (<plain old Java
+  * {{{guide/component-classes.html}Components classes are no longer <abstract>}}.  
+     Components are pure, simple POJOs (<plain old Java
     objects>).
   
   * Tapestry no longer uses XML page and component specification files. Information that used to
     be supplied in such files is now supplied directly in the Java class, using Java annotations.
     
-  * Changes to Tapestry component templates <and classes> are now picked up <immediately>, without any kind
+  * {{{guide/reload.html}Changes to Tapestry component templates <and classes> are now picked up <immediately>}}, 
+    without any kind
     of restart. This will even work properly in <production>, not just during development.
     
+  * <<Blazing Speed>>. The new code base operates considerably faster than Tapestry 4. Critical
+  code paths have been simplified, and the use of reflection has been reduced or even eliminated.
+  Tapestry 4 was as fast as an equivalent Servlet/JSP application, Tapestry 5 is much faster.
+    
   []
   
 Adaptive API
@@ -101,8 +107,8 @@
 
   This short snippet demonstrates a bit about how Tapestry operates.  Pages and services
   within the application are injected with the @Inject annotation. The @OnEvent
-  annotation identifies, to Tapestry, when to method is to be invoked
-  (when a form component contained by the page emits a "submit" event). Further the
+  annotation identifies, to Tapestry, when the method is to be invoked
+  (when a form component contained by the page emits a "submit" event). The method's 
   return value directs Tapestry on what to do: jump to another page within the application
   (by returning the injected Start page), or stay on the same page to display the
   error message.

Added: tapestry/tapestry5/tapestry-core/trunk/src/site/resources/images/component-render-states.png
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/resources/images/component-render-states.png?view=auto&rev=440237
==============================================================================
Binary file - no diff available.

Propchange: tapestry/tapestry5/tapestry-core/trunk/src/site/resources/images/component-render-states.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml Mon Sep  4 20:27:27 2006
@@ -50,6 +50,18 @@
             <item name="Upgrade from Tapestry 4" href="/upgrade.html"/>
         </menu> 
         
+
+
+        <menu name="User Guide">
+            <item name="Component Classes" href="guide/component-classes.html"/>
+            <item name="Component Rendering" href="guide/rendering.html"/>
+            <item name="Configuration" href="guide/conf.html"/>
+            <item name="Request Processing" href="guide/request.html"/>
+            <item name="DOM" href="guide/dom.html"/>
+            <item name="Class Reloading" href="guide/reload.html"/>
+        </menu>
+                
+                
         <menu name="IoC Container">
             <item name="Introduction" href="ioc/index.html"/>
             <item name="Modules" href="ioc/module.html"/>
@@ -63,15 +75,7 @@
             <item name="Pipeline" href="ioc/pipeline.html"/>
             <item name="Shadow Services" href="ioc/shadow.html"/>
         </menu>
-
-        <menu name="User Guide">
-            <item name="Component Classes" href="guide/component-classes.html"/>
-            <item name="Configuration" href="guide/conf.html"/>
-            <item name="Request Processing" href="guide/request.html"/>
-            <item name="DOM" href="guide/dom.html"/>
-            <item name="Class Reloading" href="guide/reload.html"/>
-        </menu>
-                
+                        
         <menu ref="reports"/>
         
     </body>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java Mon Sep  4 20:27:27 2006
@@ -417,6 +417,46 @@
         assertNull(getters.getIntArray());
     }
 
+    @Test
+    public void make_field_read_only() throws Exception
+    {
+        InternalComponentResources resources = newInternalComponentResources();
+
+        replay();
+
+        ClassLoader childLoader = newLoader();
+
+        CtClass targetObjectCtClass = findCtClass(ReadOnlyBean.class);
+
+        InternalClassTransformation ct = new InternalClassTransformationImpl(targetObjectCtClass);
+
+        ct.makeReadOnly("_value");
+
+        ct.finish();
+
+        Class transformed = _classPool.toClass(targetObjectCtClass, childLoader);
+
+        Object target = ct.createInstantiator(transformed).newInstance(resources);
+
+        PropertyAccess access = new PropertyAccessImpl();
+
+        try
+        {
+            access.set(target, "value", "anything");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            // The PropertyAccess layer adds a wrapper exception around the real one.
+
+            assertEquals(
+                    ex.getCause().getMessage(),
+                    "Field org.apache.tapestry.internal.services.ReadOnlyBean._value is read-only.");
+        }
+
+        verify();
+    }
+
     /**
      * Tests the basic functionality of overriding read and write; also tests the case for multiple
      * field read/field write substitions.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MarkupWriterImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MarkupWriterImplTest.java?view=diff&rev=440237&r1=440236&r2=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MarkupWriterImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MarkupWriterImplTest.java Mon Sep  4 20:27:27 2006
@@ -104,20 +104,6 @@
     }
 
     @Test
-    public void writeln()
-    {
-        MarkupWriter w = new MarkupWriterImpl();
-
-        w.element("root");
-        w.write("before");
-        w.writeln();
-        w.write("after");
-        w.end();
-
-        assertEquals(w.toString(), "<root>before\nafter</root>");
-    }
-
-    @Test
     public void attributes()
     {
         MarkupWriter w = new MarkupWriterImpl();

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ReadOnlyBean.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ReadOnlyBean.java?view=auto&rev=440237
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ReadOnlyBean.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ReadOnlyBean.java Mon Sep  4 20:27:27 2006
@@ -0,0 +1,23 @@
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.annotations.SuppressNullCheck;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+@SuppressNullCheck
+public class ReadOnlyBean
+{
+    private String _value;
+
+    public String getValue()
+    {
+        return _value;
+    }
+
+    public void setValue(String value)
+    {
+        _value = value;
+    }
+
+}