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/14 03:12:10 UTC

svn commit: r443178 - in /tapestry/tapestry5/tapestry-core/trunk/src: main/java/org/apache/tapestry/ main/java/org/apache/tapestry/internal/ main/java/org/apache/tapestry/internal/services/ main/java/org/apache/tapestry/internal/util/ main/java/org/apa...

Author: hlship
Date: Wed Sep 13 18:12:09 2006
New Revision: 443178

URL: http://svn.apache.org/viewvc?view=rev&rev=443178
Log:
Improve documentation, adding detailed discussion of component parameters.
Add error logging about non-private/non-static fields inside component classes.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/parameters.apt
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/VisibilityBean.java
Removed:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/ResourceTracker.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/ResourceTrackerImpl.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResources.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.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/ServicesMessages.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/site/apt/guide/component-classes.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/conf.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/rendering.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/templates.apt
    tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Loop.java
    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/ParameterWorkerTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ClaimedFields.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ParentClass.java

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResources.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResources.java?view=diff&rev=443178&r1=443177&r2=443178
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResources.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResources.java Wed Sep 13 18:12:09 2006
@@ -54,4 +54,7 @@
      * used to determine if parameter values should be cached.
      */
     boolean isRendering();
+
+    /** Returns true if the named parameter is bound, false if not. */
+    boolean isBound(String parameterName);
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java?view=diff&rev=443178&r1=443177&r2=443178
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java Wed Sep 13 18:12:09 2006
@@ -25,9 +25,6 @@
  */
 public interface InternalComponentResources extends ComponentResources
 {
-    /** Returns true if the parameter is bound, false if not. */
-    boolean isBound(String parameterName);
-
     /**
      * Reads the value of a parameter, via the parameter's {@link org.apache.tapestry.Binding}.
      * 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java?view=diff&rev=443178&r1=443177&r2=443178
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java Wed Sep 13 18:12:09 2006
@@ -90,6 +90,8 @@
             throw new RuntimeException(ex);
         }
 
+        Log log = _logSource.getLog(classname);
+
         // If the parent class is in a controlled package, it will already have been loaded and
         // transformed (that is driven by the ComponentInstantiatorSource).
 
@@ -99,8 +101,9 @@
         // TODO: Check that the name is not already in the map.
 
         InternalClassTransformation transformation = parentTransformation == null ? new InternalClassTransformationImpl(
-                ctClass, classLoader)
-                : new InternalClassTransformationImpl(ctClass, parentTransformation, classLoader);
+                ctClass, classLoader, log)
+                : new InternalClassTransformationImpl(ctClass, parentTransformation, classLoader,
+                        log);
 
         // Not all classes in the packages are components. That's not just sloppy coding by
         // application developers, it also represents inner classes (including anonymous classes).
@@ -111,7 +114,6 @@
         // TODO: child class model should start as deep copy of parent model?
         // Or have pointer to parent model? Or something.
 
-        Log log = _logSource.getLog(classname);
         Resource baseResource = new ClasspathResource(classname.replace(".", "/") + ".class");
 
         MutableComponentModel model = new MutableComponentModelImpl(classname, log, baseResource);

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=443178&r1=443177&r2=443178
==============================================================================
--- 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 Wed Sep 13 18:12:09 2006
@@ -36,6 +36,7 @@
 import javassist.expr.ExprEditor;
 import javassist.expr.FieldAccess;
 
+import org.apache.commons.logging.Log;
 import org.apache.tapestry.ComponentResources;
 import org.apache.tapestry.internal.InternalComponentResources;
 import org.apache.tapestry.internal.annotations.SuppressNullCheck;
@@ -65,6 +66,8 @@
 
     private final CtClass _ctClass;
 
+    private final Log _log;
+
     private ClassPool _classPool;
 
     private final IdAllocator _idAllocator;
@@ -112,8 +115,11 @@
     /**
      * This is a constructor for the root class, the class that directly contains the ComponentClass
      * annotation.
+     * 
+     * @param log
+     *            TODO
      */
-    public InternalClassTransformationImpl(CtClass ctClass, ClassLoader loader)
+    public InternalClassTransformationImpl(CtClass ctClass, ClassLoader loader, Log log)
     {
         _ctClass = ctClass;
         _classPool = _ctClass.getClassPool();
@@ -121,8 +127,12 @@
 
         _idAllocator = new IdAllocator();
 
+        _log = log;
+
         preloadMemberNames();
 
+        verifyFields();
+
         _constructorArgs = newList();
         _constructor.append("{\n");
 
@@ -139,11 +149,12 @@
     }
 
     public InternalClassTransformationImpl(CtClass ctClass,
-            InternalClassTransformation parentTransformation, ClassLoader loader)
+            InternalClassTransformation parentTransformation, ClassLoader loader, Log log)
     {
         _ctClass = ctClass;
         _classPool = _ctClass.getClassPool();
         _loader = loader;
+        _log = log;
 
         _resourcesFieldName = parentTransformation.getResourcesFieldName();
 
@@ -151,6 +162,8 @@
 
         preloadMemberNames();
 
+        verifyFields();
+
         _constructorArgs = parentTransformation.getConstructorArgs();
 
         int count = _constructorArgs.size();
@@ -210,6 +223,28 @@
         addMemberNames(_ctClass.getDeclaredMethods());
     }
 
+    /** Verifies that all non-static fields are private. */
+
+    private void verifyFields()
+    {
+        List<String> names = newList();
+
+        for (CtField field : _ctClass.getDeclaredFields())
+        {
+            int modifiers = field.getModifiers();
+
+            // Fields must be either static or private.
+
+            if (Modifier.isStatic(modifiers) || Modifier.isPrivate(modifiers))
+                continue;
+
+            names.add(field.getName());
+        }
+
+        if (!names.isEmpty())
+            _log.error(ServicesMessages.nonPrivateFields(getClassName(), names));
+    }
+
     private void addMemberNames(CtMember[] members)
     {
         for (CtMember member : members)
@@ -1225,4 +1260,8 @@
         return _ctClass.getName();
     }
 
+    public Log getLog()
+    {
+        return _log;
+    }
 }

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=443178&r1=443177&r2=443178
==============================================================================
--- 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 Wed Sep 13 18:12:09 2006
@@ -15,6 +15,7 @@
 package org.apache.tapestry.internal.services;
 
 import java.util.Collection;
+import java.util.List;
 
 import javassist.CtClass;
 
@@ -142,5 +143,10 @@
     static String noInjectionFound(String className, String fieldName, String fieldType)
     {
         return MESSAGES.format("no-injection-found", className, fieldName, fieldType);
+    }
+
+    static String nonPrivateFields(String className, List<String> names)
+    {
+        return MESSAGES.format("non-private-fields", className, IOCUtilities.joinSorted(names));
     }
 }

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=443178&r1=443177&r2=443178
==============================================================================
--- 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 Wed Sep 13 18:12:09 2006
@@ -17,6 +17,8 @@
 import java.lang.annotation.Annotation;
 import java.util.List;
 
+import org.apache.commons.logging.Log;
+
 /**
  * Contains class-specific information used when transforming an raw class into an executable class.
  * Much of this information is somewhat like ordinary reflection, but applies to a class that has
@@ -247,4 +249,10 @@
      */
 
     Class toClass(String type);
+
+    /**
+     * Returns a log, based on the class name being transformed, to which warnings or errors
+     * concerning the class being transformed may be logged.
+     */
+    Log getLog();
 }

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=443178&r1=443177&r2=443178
==============================================================================
--- 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 Wed Sep 13 18:12:09 2006
@@ -36,4 +36,7 @@
 render-queue-error=Render queue error in %s: %s
 read-only-field=Field %s.%s is read-only.
 no-injection-found=Could not find a suitable object to inject into %s.%s (type %s). \
-  Use the value attribute of the @Inject annotation to identify exactly what should be injected into this field.
\ No newline at end of file
+  Use the value attribute of the @Inject annotation to identify exactly what should be injected into this field.
+non-private-fields=Class %s contains field(s) (%s) that are not private. Tapestry will ignore these fields, even if they \
+  have annotations. Runtime behavior, especially in production, may not be what you expect. \
+  You should change these fields to private, and add accessor methods if needed.  
\ No newline at end of file

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=443178&r1=443177&r2=443178
==============================================================================
--- 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 Wed Sep 13 18:12:09 2006
@@ -51,6 +51,20 @@
   In another departure from Tapestry 4, these methods are not necessarily public; they
   can have any visibility you like.
   
+Pages vs. Components
+
+  The distinction in Tapestry 5 between pages and component is very, very small.  The only
+  real difference is the package name:  <root>.<<pages>>.<PageName> for pages,
+  and <root>.<<components>>.<ComponentType> for components.
+  
+  In Tapestry 4, there was a much greater distinction between pages
+  and components, which showed up as seperate interfaces and a hierarchy of
+  abstract implementations to extend your classes from.
+  
+  In Tapestry 5, the "page" is still somewhat present, but is really
+  an internal Tapestry class. Page components are simply the <root component> of a page's
+  component tree.
+  
 Class Transformation
 
   Tapestry uses your class as a starting point. It <transforms> your class at runtime. This is necessary
@@ -77,14 +91,17 @@
   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
+  <<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.
+  a production application because of how Tapestry pools and reuses pages and components. Tapestry
+  will log an error for each component class that contains fields that are neither static nor private.  
   
   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
@@ -92,20 +109,24 @@
   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?>
+  Tapestry will instantiate your class using the default, no arguments constructor.  Other constructors will
+  be ignored.
   
 Injection
 
-  Injection of dependencies occurs at the field level, via additional annotations.  At runtime,
+  {{{inject.html}Injection}} of dependencies occurs at the field level, via additional annotations.  At runtime,
   fields that contain injections become read-only.
+  
+Parameters
+
+  {{{parameters.html}Component parameters}} are also identified using private fields of your class, with
+  the {{{.../apidocs/org/apache/tapestry/annotations/Parameter.html}Parameter}} annotation.
+  
   
   
   

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/conf.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/conf.apt?view=diff&rev=443178&r1=443177&r2=443178
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/conf.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/conf.apt Wed Sep 13 18:12:09 2006
@@ -45,8 +45,8 @@
 
   You may name the filter whatever you want, though "app" is a common convention.
   
-  In this example, page classes will be stored in the org.example.myapp.pages package (or in sub-packages below).
-  Likewise, component classes will be stored in the org.example.myapp.components package.
+  In this example, page classes will be stored in the <<<org.example.myapp.pages>>> package (or in sub-packages below).
+  Likewise, component classes will be stored in the <<<org.example.myapp.components>>> package.
   
 * Tapestry IoC Configuration
 

Added: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/parameters.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/parameters.apt?view=auto&rev=443178
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/parameters.apt (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/parameters.apt Wed Sep 13 18:12:09 2006
@@ -0,0 +1,221 @@
+ ---
+  Component Parameters
+ ----
+ 
+Component Parameters
+
+  Component parameters are a critical aspect of Tapestry.  It is not enough that an instance of
+  a component class <exists>, it must be <configured> to do the right thing. Configuration is in
+  terms of the parameters of the component.
+  
+  A component may have any number of parameters.  Each parameter has a specific name,
+  a specific Java type (which may be a primitive value), and may be <optional> or <required>.
+  
+  Parameters are defined by placing a
+  {{{../apidocs/org/apache/tapestry/annotations/Parameter.html}Parameter}} annotation
+  onto a private field.
+  
+  The component listed below is a looping component; it renders its body
+  a number of times, defined by its min and max parameters (which set the boundaries
+  of the loop):
+  
++---+
+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
+    private int _min = 1;
+
+    @Parameter(required = true)
+    private int _max;
+
+    @Parameter
+    private int _value;
+
+    @SetupRender
+    void initializeValue()
+    {
+        _value = _min;
+    }
+
+    @AfterRender
+    boolean increment()
+    {
+        int newValue = _value + 1;
+
+        if (newValue <= _max)
+        {
+            _value = newValue;
+            return true;
+        }
+
+        return false;
+    }
+}
++---+
+  
+  The name of the parameter is derived from the field name (by stripping leading "_" and "$" characters).
+  Here, the parameter names are "min", "max" and "value".  You can override the name of the parameter
+  using the name() attribute of the Parameter annotation.
+  
+Binding Parameters
+
+  The component above can be referenced in another component or page 
+  {{{templates.html}template}}:
+  
++---+
+<t:comp type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <p> Merry Christmas: <t:comp type="Loop" max="3"> Ho! </t:comp>
+    </p>
+</t:comp>
++---+  
+  
+  Inside the \<comp\> element, the max attribute is used to <bind> the max parameter of the
+  Loop component.  Here, it is being bound to the string value "3", which is automatically
+  coerced by Tapestry into the int value, 3.
+    
+  Any number of parameters may be bound this way.
+  
+Binding Expressions
+
+  The value inside the template, "3" in the previous example, is a <binding expression>.
+  
+  This binding expression is the simplest form, a literal string.
+  
+  By placing a prefix in front of the value, you can change how Tapestry interprets the remainder
+  of the expression (the part after the colon):
+  
+*------------+----------------------------------------------------------------------------------+
+| <<Prefix>> | <<Description>>                                                                  |
+*------------+----------------------------------------------------------------------------------+
+| literal:   | A literal string. The default inside a component template.                       |
+*------------+----------------------------------------------------------------------------------+
+| prop:     | The name of a property of the containing component to read or update.            |
+*------------+----------------------------------------------------------------------------------+
+
+  <<Note: More prefixes are forthcoming.>>
+    
+Parameters Are Bi-Directional
+
+  Parameters are not simply variables; each parameter represents a connection, or <binding>, between
+  a component and a property of its container.  When using the prop: binding prefix,
+  the component can force changes <into> a property of its container, just by assigning a value
+  to its own instance variable.
+  
++---+
+<t:comp type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <p> Counting: 
+        <t:comp type="Loop" max="5" value="prop:index"> 
+          #${index} ...  
+        </t:comp>
+    </p>
+</t:comp>
++---+   
+
+  Because the Loop component updates its value parameter (the _value field), the index property
+  of the containing component is updated.  Inside the Loop's body, we output the current
+  value of the index property, using the expansion <<<$\{index\}>>>. The resulting output
+  will look something like:
+  
++---+
+  <p> Counting: 1 ... 2 ... 3 ... 4 ... 5 ... </p>
++---+
+
+  (Though the whitespace will be quite different.)  
+  
+  The relevant part is that components can read fixed values or live properties of their
+  container, and can <change> properties of their container as well.
+  
+Required Parameters
+
+  Parameters that are required <<must>> be bound.  A runtime exception occurs if a component
+  has unbound required parameters.
+  
+Optional Parameters
+
+  Parameters which are not required, are optional.  
+  
+  You may set a default value for optional parameters as you would for any other field. In the Loop component,
+  the min parameter has a default value of 1. That value is used unless the min parameter is bound,
+  in which case, the bound value supercedes the default.
+  
+Unbound Parameters
+
+  If a parameter is not bound (and is optional), then the value may be read or <updated> at any time.
+  
+  Updates to unbound parameters cause no side effects.  In the first example, the value parameter of the Loop
+  component is not bound, and this is perfectly valid.
+  
+  Note: updates to such fields are temporary; when the component finishes rendering, the field
+  will revert to its default value.
+  
+  <<TODO: This seems contradictory. What does it mean to update an unbound component parameter when the component 
+  is not rendering?>>
+  
+Parameter Caching
+
+  Reading a parameter value can be marginally expensive (because of type coercion). Therefore, it makes sense
+  to cache the parameter value, at least while the component is actively rendering itself.
+  
+  In rare cases, it is desirable to defeat the caching; this can be done by setting the cache() attribute
+  of the Parameter annotation to false.
+  
+Parameter Type Cooercion
+
+  Tapestry includes a mechanism for coecing types automatically. Most often, this is used to
+  convert literal strings into appropriate values, but in many cases, more complex conversions
+  will occur.
+
+  <<Not yet implemented.>> 
+  
+Parameter Names
+
+  By default, Tapestry converts from the field name to the parameter name, by stripping off leading
+  "$" and "_" characters.
+  
+  This can be overriden using the name() attribute of the Parameter annotation.
+  
+Determining if Bound
+
+  In rare cases, you may want to take different behaviors based on whether a parameter is bound
+  or not. This can be accomplished by querying the component's resources, which can be 
+  {{{inject.html}injected}}  into the component using the
+  {{{../apidocs/org/apache/tapestry/annotations/Inject.html}Inject}} annotation:
+  
++---+
+public class MyComponent
+{
+  @Parameter
+  private int _myParam;
+  
+  @Inject
+  private ComponentResources _resources;
+  
+  @BeginRender
+  void setup()
+  {
+      if (_resources.isBound("myParam"))
+      {
+        . . .
+      }
+  }
+}
++---+
+
+  The above sketch illustrates the approach.  Because the parameter type is a primitive type, int,
+  it is hard to distinguish between no binding, and binding explicitly to the value 0.
+  
+  The @Inject annotation will inject the
+  {{{../apidocs/org/apache/tapestry/ComponentResources.html}ComponentResources}} for the component.
+  These resources are the linkage between the Java class you provide, and the infrastructure Tapestry
+  builds around your class.  In any case, once the resources are injected,
+  they can be queried.
+  
+  
\ No newline at end of file

Modified: 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=diff&rev=443178&r1=443177&r2=443178
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/rendering.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/rendering.apt Wed Sep 13 18:12:09 2006
@@ -62,13 +62,13 @@
 @ComponentClass
 public class Loop
 {
-    @Parameter(required = true)
-    private int _min;
+    @Parameter
+    private int _min = 1;
 
     @Parameter(required = true)
     private int _max;
 
-    @Parameter(required = true)
+    @Parameter
     private int _value;
 
     @SetupRender
@@ -78,7 +78,7 @@
     }
 
     @AfterRender
-    boolean incrementLoopCount()
+    boolean increment()
     {
         int newValue = _value + 1;
 
@@ -93,7 +93,7 @@
 }
 +---+
   
-  Returning true from incrementLoopCount() causes Tapestry to re-run the BeginRender phase,
+  Returning true from increment() 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.
   
@@ -155,7 +155,7 @@
   
   <TODO: Perhaps this should be called "FinishRender"?>
   
-  If not methods are annotated with FinishRender, then no special output occurs, and the
+  If no methods are annotated with FinishRender, then no special output occurs, and the
   CleanupRender phase is triggered.
    
 * {{{../apidocs/org/apache/tapestry/annotations/CleanupRender.html}CleanupRender}}
@@ -184,6 +184,7 @@
   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.
+  Most render phase methods should return void, to avoid unintentionally short circuiting
+  other methods for the same phase.
   
   

Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/templates.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/templates.apt?view=diff&rev=443178&r1=443177&r2=443178
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/templates.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/templates.apt Wed Sep 13 18:12:09 2006
@@ -14,12 +14,7 @@
   in the form of a Tapestry namespace.
   
   We'll cover the specific content of templates shortly, first a few details about connecting a component to its template.
-  
-Pages vs. Components
-
-  In Tapestry 5, pages and components are virtually identical, the only real difference is that 
-  pages come from a different Java package. In reality, what we call a "page" is really the page's <root component>.
-  
+    
 Template Location
 
   Component templates are stored with the component class file.  The files have a ".html" extension, and are stored in
@@ -34,6 +29,8 @@
   
   The template and the compiled class will be packaged together in the WEB-INF/classes folder of the application WAR.
   
+  <<TODO: Is the ".html" template still useful? And do we need control over the template extension?>>
+  
 Tapestry Namespace
 
   Component templates should include the Tapestry namespace, defining it in the root element of the template.
@@ -75,7 +72,8 @@
   The type attribute is optional; when not specified, Tapestry will expect the class to define
   the type of the component (with a @Component annotation).  <<Not yet implemented.>>
   
-  Additional attributes are used to bind parameters of the component.  When parameters are bound
+  Additional attributes are used to {{{parameters.html}bind parameters of the component}}.  
+  When parameters are bound
   in this way, the values are interpreted as literals unless a specific prefix is given.
   
   The element defines where, within the containing component's template, the embedded component is active.
@@ -129,11 +127,26 @@
 </t:comp >
 +---+    
    
+   When the page renders, the page's template and the Border component's template
+   are merged together:
+   
++---+
+<html>
+  <head>
+    <title>My Tapestry Application</title>
+  </head>
+  <body>
+    My Page Specific Content
+  </body>
+</html>
++---+   
+   
    
 Expansions
 
   Another option for rendering output are <expansions>.  Expansions
-  are special strings that may be emdedded in template bodies, and borrow Ant syntax.
+  are special strings that may be emdedded in template bodies, and borrow some syntax
+  from the {{{http://ant.apache.org}Ant}} build tool.
   
 +---+
   Welcome, ${userId}!
@@ -142,11 +155,13 @@
   Here, <<<$\{userId}>>> is the expansion.  In this example, the userId property of the 
   component is extracted, converted to a string, and streamed into the output.  
   
-  Under the covers, expansions are the same as parameter bindings.  The default
+  Under the covers, expansions are the same as
+  {{{parameters.html}parameter bindings}}.  The default
   binding prefix for expansions is "prop:" (that is, the name of a property), but
-  other binding prefixes are useful.
+  other binding prefixes are useful, especially "message:" (to access a localized
+  message from the component's message catalog).
   
-  Tapestry 4 users will note that expansions are a easy replacement for the
+  Tapestry 4 users will note that expansions are a concise, easy replacement for the
   Insert component, and for the \<span key="..."\> directive.
   
   <<Alas, this is not yet implemented.>>

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=443178&r1=443177&r2=443178
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml Wed Sep 13 18:12:09 2006
@@ -54,6 +54,7 @@
 
         <menu name="User Guide">
             <item name="Component Classes" href="guide/component-classes.html"/>
+            <item name="Component Parameters" href="guide/parameters.html"/>
             <item name="Component Rendering" href="guide/rendering.html"/>
             <item name="Component Templates" href="guide/templates.html"/>
             <item name="Injection" href="guide/inject.html"/>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Loop.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Loop.java?view=diff&rev=443178&r1=443177&r2=443178
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Loop.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Loop.java Wed Sep 13 18:12:09 2006
@@ -14,10 +14,9 @@
 
 package org.apache.tapestry.integration.app1.components;
 
-import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotations.AfterRender;
 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
@@ -26,8 +25,8 @@
     @Parameter
     private int _min = 1;
 
-    @Parameter
-    private int _max = 10;
+    @Parameter(required = true)
+    private int _max;
 
     @Parameter
     private int _value;
@@ -39,7 +38,7 @@
     }
 
     @AfterRender
-    boolean startLoop(MarkupWriter writer)
+    boolean increment()
     {
         int newValue = _value + 1;
 

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=443178&r1=443177&r2=443178
==============================================================================
--- 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 Wed Sep 13 18:12:09 2006
@@ -28,9 +28,10 @@
 import javassist.LoaderClassPath;
 import javassist.NotFoundException;
 
-import org.apache.tapestry.annotations.SetupRender;
+import org.apache.commons.logging.Log;
 import org.apache.tapestry.annotations.ComponentClass;
 import org.apache.tapestry.annotations.Retain;
+import org.apache.tapestry.annotations.SetupRender;
 import org.apache.tapestry.internal.InternalComponentResources;
 import org.apache.tapestry.internal.ioc.services.PropertyAccessImpl;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
@@ -88,13 +89,17 @@
     @Test
     public void new_member_name() throws Exception
     {
-        ClassTransformation ct = createClassTransformation(ParentClass.class);
+        Log log = newLog();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, log);
 
         assertEquals(ct.newMemberName("fred"), "_$fred");
         assertEquals(ct.newMemberName("fred"), "_$fred_0");
 
         // Here we're exposing a bit of the internal algorithm, which strips
-        // of '$' and '_' before tacking "_$" in front.
+        // off '$' and '_' before tacking "_$" in front.
 
         assertEquals(ct.newMemberName("_fred"), "_$fred_1");
         assertEquals(ct.newMemberName("_$fred"), "_$fred_2");
@@ -106,19 +111,26 @@
         assertEquals(ct.newMemberName("_parentField"), "_$parentField");
         assertEquals(ct.newMemberName("conflictField"), "_$conflictField_0");
         assertEquals(ct.newMemberName("conflictMethod"), "_$conflictMethod_0");
+
+        verify();
     }
 
-    private InternalClassTransformation createClassTransformation(Class targetClass)
+    private InternalClassTransformation createClassTransformation(Class targetClass, Log log)
             throws NotFoundException
     {
         CtClass ctClass = findCtClass(targetClass);
-        return new InternalClassTransformationImpl(ctClass, _contextClassLoader);
+
+        return new InternalClassTransformationImpl(ctClass, _contextClassLoader, log);
     }
 
     @Test
     public void find_annotation_on_unknown_field() throws Exception
     {
-        ClassTransformation ct = createClassTransformation(ParentClass.class);
+        Log log = newLog();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, log);
 
         try
         {
@@ -131,55 +143,85 @@
                     ex.getMessage(),
                     "Class org.apache.tapestry.internal.transform.pages.ParentClass does not contain a field named 'unknownField'.");
         }
+
+        verify();
     }
 
     @Test
     public void find_field_annotation() throws Exception
     {
-        ClassTransformation ct = createClassTransformation(ParentClass.class);
+        Log log = newLog();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, log);
 
         Retain retain = ct.getFieldAnnotation("_annotatedField", Retain.class);
 
         assertNotNull(retain);
+
+        verify();
     }
 
     @Test
     public void field_does_not_contain_requested_annotation() throws Exception
     {
-        ClassTransformation ct = createClassTransformation(ParentClass.class);
+        Log log = newLog();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, log);
 
         // Field with annotations, but not that annotation
         assertNull(ct.getFieldAnnotation("_annotatedField", Override.class));
 
         // Field with no annotations
         assertNull(ct.getFieldAnnotation("_parentField", Override.class));
+
+        verify();
     }
 
     @Test
     public void find_fields_with_annotation() throws Exception
     {
-        ClassTransformation ct = createClassTransformation(ParentClass.class);
+        Log log = newLog();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, log);
 
         List<String> fields = ct.findFieldsWithAnnotation(Retain.class);
 
         assertEquals(fields.size(), 1);
         assertEquals(fields.get(0), "_annotatedField");
+
+        verify();
     }
 
     @Test
     public void no_fields_contain_requested_annotation() throws Exception
     {
-        ClassTransformation ct = createClassTransformation(ParentClass.class);
+        Log log = newLog();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, log);
 
         List<String> fields = ct.findFieldsWithAnnotation(Documented.class);
 
         assertTrue(fields.isEmpty());
+
+        verify();
     }
 
     @Test
     public void claim_fields() throws Exception
     {
-        ClassTransformation ct = createClassTransformation(ClaimedFields.class);
+        Log log = newLog();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ClaimedFields.class, log);
 
         String[] unclaimed = ct.findUnclaimedFields();
 
@@ -203,24 +245,35 @@
                     "Field _field4 of class org.apache.tapestry.internal.transform.pages.ClaimedFields is already claimed by Fred and can not be claimed by Barney.");
         }
 
+        verify();
     }
 
     @Test
     public void added_fields_are_not_listed_as_unclaimed_fields() throws Exception
     {
-        ClassTransformation ct = createClassTransformation(ClaimedFields.class);
+        Log log = newLog();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ClaimedFields.class, log);
 
         ct.addField(Modifier.PRIVATE, "int", "newField");
 
         String[] unclaimed = ct.findUnclaimedFields();
 
         assertEquals(Arrays.asList(unclaimed), asList("_field1", "_field4", "_zzfield"));
+
+        verify();
     }
 
     @Test
     public void find_class_annotations() throws Exception
     {
-        ClassTransformation ct = createClassTransformation(ParentClass.class);
+        Log log = newLog();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, log);
 
         ComponentClass cc = ct.getAnnotation(ComponentClass.class);
 
@@ -232,6 +285,8 @@
         Target t = ct.getAnnotation(Target.class);
 
         assertNull(t);
+
+        verify();
     }
 
     /**
@@ -245,13 +300,19 @@
         // The Java runtime does honor @Inherited
         assertNotNull(ChildClassInheritsAnnotation.class.getAnnotation(ComponentClass.class));
 
-        ClassTransformation ct = createClassTransformation(ChildClassInheritsAnnotation.class);
+        Log log = newLog();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ChildClassInheritsAnnotation.class, log);
 
         ComponentClass cc = ct.getAnnotation(ComponentClass.class);
 
         // Javassist does not, but ClassTransformation patches around that.
 
         assertNotNull(cc);
+
+        verify();
     }
 
     /**
@@ -325,8 +386,12 @@
 
         CtClass targetObjectCtClass = findCtClass(TargetObject.class);
 
+        Log log = newLog();
+
+        replay();
+
         InternalClassTransformation ct = new InternalClassTransformationImpl(targetObjectCtClass,
-                _contextClassLoader);
+                _contextClassLoader, log);
 
         // Default behavior is to add an injected field for the InternalComponentResources object,
         // so we'll just check that.
@@ -340,6 +405,8 @@
         ComponentResourcesAware instance = instantiator.newInstance(resources);
 
         assertSame(instance.getComponentResources(), resources);
+
+        verify();
     }
 
     @Test
@@ -349,8 +416,12 @@
 
         CtClass ctClass = findCtClass(BasicComponent.class);
 
+        Log log = newLog();
+
+        replay();
+
         InternalClassTransformation ct = new InternalClassTransformationImpl(ctClass,
-                _contextClassLoader);
+                _contextClassLoader, log);
 
         _classPool.toClass(ctClass, childLoader);
 
@@ -365,6 +436,8 @@
                     BasicComponent.class.getName(),
                     Boolean.class));
         }
+
+        verify();
     }
 
     private Loader newLoader()
@@ -389,8 +462,12 @@
 
         CtClass targetObjectCtClass = findCtClass(TargetObject.class);
 
+        Log log = newLog();
+
+        replay();
+
         InternalClassTransformation ct = new InternalClassTransformationImpl(targetObjectCtClass,
-                _contextClassLoader);
+                _contextClassLoader, log);
 
         ct.addImplementedInterface(FooInterface.class);
         ct.addImplementedInterface(GetterMethodsInterface.class);
@@ -422,6 +499,8 @@
         assertNull(getters.getString());
         assertNull(getters.getObjectArray());
         assertNull(getters.getIntArray());
+
+        verify();
     }
 
     @Test
@@ -429,6 +508,8 @@
     {
         InternalComponentResources resources = newInternalComponentResources();
 
+        Log log = newLog();
+
         replay();
 
         ClassLoader childLoader = newLoader();
@@ -436,7 +517,7 @@
         CtClass targetObjectCtClass = findCtClass(ReadOnlyBean.class);
 
         InternalClassTransformation ct = new InternalClassTransformationImpl(targetObjectCtClass,
-                _contextClassLoader);
+                _contextClassLoader, log);
 
         ct.makeReadOnly("_value");
 
@@ -470,6 +551,8 @@
     {
         InternalComponentResources resources = newInternalComponentResources();
 
+        Log log = newLog();
+
         replay();
 
         ClassLoader childLoader = newLoader();
@@ -477,7 +560,7 @@
         CtClass targetObjectCtClass = findCtClass(ReadOnlyBean.class);
 
         InternalClassTransformation ct = new InternalClassTransformationImpl(targetObjectCtClass,
-                _contextClassLoader);
+                _contextClassLoader, log);
 
         ct.injectField("_value", "Tapestry");
 
@@ -517,6 +600,8 @@
     {
         InternalComponentResources resources = newInternalComponentResources();
 
+        Log log = newLog();
+
         replay();
 
         ClassLoader childLoader = newLoader();
@@ -524,7 +609,7 @@
         CtClass targetObjectCtClass = findCtClass(FieldAccessBean.class);
 
         InternalClassTransformation ct = new InternalClassTransformationImpl(targetObjectCtClass,
-                _contextClassLoader);
+                _contextClassLoader, log);
 
         replaceAccessToField(ct, "foo");
         replaceAccessToField(ct, "bar");
@@ -603,7 +688,11 @@
     @Test
     public void find_methods_with_annotation() throws Exception
     {
-        ClassTransformation ct = createClassTransformation(AnnotatedPage.class);
+        Log log = newLog();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(AnnotatedPage.class, log);
 
         List<MethodSignature> l = ct.findMethodsWithAnnotation(SetupRender.class);
 
@@ -620,21 +709,64 @@
         // Check up on no match.
 
         assertTrue(ct.findFieldsWithAnnotation(Deprecated.class).isEmpty());
+
+        verify();
     }
 
     @Test
     public void to_class_with_primitive_type() throws Exception
     {
-        ClassTransformation ct = createClassTransformation(AnnotatedPage.class);
+        Log log = newLog();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(AnnotatedPage.class, log);
 
         assertSame(ct.toClass("float"), Float.class);
+
+        verify();
     }
 
     @Test
     public void to_class_with_object_type() throws Exception
     {
-        ClassTransformation ct = createClassTransformation(AnnotatedPage.class);
+        Log log = newLog();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(AnnotatedPage.class, log);
 
         assertSame(ct.toClass("java.util.Map"), Map.class);
+
+        verify();
+    }
+
+    @Test
+    public void non_private_fields_log_an_error() throws Exception
+    {
+        Log log = newLog();
+
+        log.error(ServicesMessages.nonPrivateFields(VisibilityBean.class.getName(), Arrays.asList(
+                "_$myPackagePrivate",
+                "_$myProtected",
+                "_$myPublic")));
+        
+        replay();
+
+        ClassTransformation ct = createClassTransformation(VisibilityBean.class, log);
+
+        List<String> names = ct.findFieldsWithAnnotation(Retain.class);
+
+        // Only _myLong shows up, because its the only private field
+
+        assertEquals(names, Arrays.asList("_$myLong"));
+
+        // However, all the fields are "reserved" via the IdAllocator ...
+
+        assertEquals(ct.newMemberName("_$myLong"), "_$myLong_0");
+        assertEquals(ct.newMemberName("_$myStatic"), "_$myStatic_0");
+        assertEquals(ct.newMemberName("_$myProtected"), "_$myProtected_0");
+
+        verify();
     }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ParameterWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ParameterWorkerTest.java?view=diff&rev=443178&r1=443177&r2=443178
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ParameterWorkerTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ParameterWorkerTest.java Wed Sep 13 18:12:09 2006
@@ -19,6 +19,7 @@
 import javassist.Loader;
 import javassist.LoaderClassPath;
 
+import org.apache.commons.logging.Log;
 import org.apache.tapestry.internal.InternalComponentResources;
 import org.apache.tapestry.internal.ioc.services.PropertyAccessImpl;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
@@ -141,9 +142,12 @@
      * This actually checks several things:
      * <ul>
      * <li>Changing a parameter property before the page loads doesn't update the binding</li>
-     * <li>Changing a parameter property changes the property AND the default value for the property</li>
-     * <li>Unbound parameters to do not attempt to read or update their bindings (they'll be optional)</li>
+     * <li>Changing a parameter property changes the property AND the default value for the
+     * property</li>
+     * <li>Unbound parameters to do not attempt to read or update their bindings (they'll be
+     * optional)</li>
      * </ul>
+     * 
      * @throws Exception
      */
     @Test
@@ -466,6 +470,7 @@
     private ComponentLifecycle setupForIntegrationTest(InternalComponentResources resources)
             throws Exception
     {
+        Log log = newLog();
         ClassPool pool = new ClassPool();
         ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
         pool.appendClassPath(new LoaderClassPath(contextLoader));
@@ -476,7 +481,7 @@
 
         CtClass ctClass = pool.get(ParameterComponent.class.getName());
         InternalClassTransformation transformation = new InternalClassTransformationImpl(ctClass,
-                _contextClassLoader);
+                _contextClassLoader, log);
 
         MutableComponentModel model = newMutableComponentModel();
 

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/VisibilityBean.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/VisibilityBean.java?view=auto&rev=443178
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/VisibilityBean.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/VisibilityBean.java Wed Sep 13 18:12:09 2006
@@ -0,0 +1,39 @@
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.annotations.Retain;
+
+/**
+ * Used to test some issues related to visibility.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public class VisibilityBean
+{
+    // Got to some real effort to provoke some name collisions!
+    
+    @Retain
+    public static int _$myStatic;
+
+    @Retain
+    protected String _$myProtected;
+
+    @Retain
+    String _$myPackagePrivate;
+
+    @Retain
+    public String _$myPublic;
+
+    @Retain
+    private long _$myLong;
+
+    public long getMyLong()
+    {
+        return _$myLong;
+    }
+
+    public void setMyLong(long myLong)
+    {
+        _$myLong = myLong;
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ClaimedFields.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ClaimedFields.java?view=diff&rev=443178&r1=443177&r2=443178
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ClaimedFields.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ClaimedFields.java Wed Sep 13 18:12:09 2006
@@ -23,26 +23,8 @@
 
     private int _field1;
 
-    private static int _field2;
-
-    public int _field3;
-
     private String _field4;
 
-    protected boolean _field5;
-
-    long _field6;
-
-    public static final int get_field2()
-    {
-        return _field2;
-    }
-
-    public static final void set_field2(int field2)
-    {
-        _field2 = field2;
-    }
-
     public final int getField1()
     {
         return _field1;
@@ -53,16 +35,6 @@
         _field1 = field1;
     }
 
-    public final int getField3()
-    {
-        return _field3;
-    }
-
-    public final void setField3(int field3)
-    {
-        _field3 = field3;
-    }
-
     public final String getField4()
     {
         return _field4;
@@ -71,26 +43,6 @@
     public final void setField4(String field4)
     {
         _field4 = field4;
-    }
-
-    public final boolean isField5()
-    {
-        return _field5;
-    }
-
-    public final void setField5(boolean field5)
-    {
-        _field5 = field5;
-    }
-
-    public final long getField6()
-    {
-        return _field6;
-    }
-
-    public final void setField6(long field6)
-    {
-        _field6 = field6;
     }
 
     public final int getZzfield()

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ParentClass.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ParentClass.java?view=diff&rev=443178&r1=443177&r2=443178
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ParentClass.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ParentClass.java Wed Sep 13 18:12:09 2006
@@ -26,21 +26,15 @@
 @ComponentClass
 public class ParentClass
 {
-    public int _parentField;
+    private int _parentField;
 
     // Named so that we can force a name conflict
 
-    public String _$conflictField;
+    private String _$conflictField;
 
     @Retain
     private boolean _annotatedField;
 
-    @Retain
-    public String _public_field_annotation_ignored;
-    
-    @Retain
-    private static String _static_field_annotation_ignored;
-    
     public void doNothingParentMethod()
     {
 
@@ -49,6 +43,36 @@
     public void _$conflictMethod()
     {
 
+    }
+
+    public String get$conflictField()
+    {
+        return _$conflictField;
+    }
+
+    public void set$conflictField(String field)
+    {
+        _$conflictField = field;
+    }
+
+    public boolean isAnnotatedField()
+    {
+        return _annotatedField;
+    }
+
+    public void setAnnotatedField(boolean annotatedField)
+    {
+        _annotatedField = annotatedField;
+    }
+
+    public int getParentField()
+    {
+        return _parentField;
+    }
+
+    public void setParentField(int parentField)
+    {
+        _parentField = parentField;
     }
 
 }