Haven't look at this in detail but (sorry) another nitpick:  New files
shouldn't have copyrights extending back into 2007.

On Sat, Mar 8, 2008 at 12:53 PM,  <[EMAIL PROTECTED]> wrote:
> Author: dadams
>  Date: Sat Mar  8 12:53:25 2008
>  New Revision: 635085
>
>  URL: http://svn.apache.org/viewvc?rev=635085&view=rev
>  Log:
>  TAPESTRY-2244: Add @Once annotation for caching method values
>
>  Added:
>     
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/Once.java
>     
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/OnceWorker.java
>     
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/OncePage.java
>     
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/OncePage2.java
>     
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/OnceWorkerTest.java
>     
> tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/OncePage.tml
>  Modified:
>     
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Unless.java
>     
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/TransformMessages.java
>     
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
>     
> tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/transform/TransformStrings.properties
>     tapestry/tapestry5/trunk/tapestry-core/src/site/apt/index.apt
>     
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
>     
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
>
>  Added: 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/Once.java
>  URL: 
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/Once.java?rev=635085&view=auto
>  
> ==============================================================================
>  --- 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/Once.java
>  (added)
>  +++ 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/Once.java
>  Sat Mar  8 12:53:25 2008
>  @@ -0,0 +1,41 @@
>  +// Copyright 2006, 2007, 2008 The Apache Software Foundation
>  +//
>  +// Licensed under the Apache License, Version 2.0 (the "License");
>  +// you may not use this file except in compliance with the License.
>  +// You may obtain a copy of the License at
>  +//
>  +//     http://www.apache.org/licenses/LICENSE-2.0
>  +//
>  +// Unless required by applicable law or agreed to in writing, software
>  +// distributed under the License is distributed on an "AS IS" BASIS,
>  +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  +// See the License for the specific language governing permissions and
>  +// limitations under the License.
>  +
>  +package org.apache.tapestry.annotations;
>  +
>  +import java.lang.annotation.Documented;
>  +import java.lang.annotation.ElementType;
>  +import java.lang.annotation.Retention;
>  +import java.lang.annotation.RetentionPolicy;
>  +import java.lang.annotation.Target;
>  +
>  +/** Indicates that a method should only be evaluated once and the result 
> cached.
>  + * All further calls to the method will return the cached result. Note that 
> this
>  + * annotation is inheritence-safe; if a subclass calls a superclass method 
> that
>  + * has @Once then the value the subclass method gets is the cached value.
>  + * <p>
>  + * The watch parameter can be passed a binding expression
>  + * which will be evaluated each time the method is called. The method will 
> then
>  + * only be executed the first time it is called and after that only when the
>  + * value of the binding changes. This can be used, for instance, to have the
>  + * method only evaluated once per iteration of a loop by setting watch to
>  + * the value or index of the loop.
>  + */
>  [EMAIL PROTECTED](ElementType.METHOD)
>  [EMAIL PROTECTED](RetentionPolicy.RUNTIME)
>  [EMAIL PROTECTED]
>  +public @interface Once {
>  +       /** The optional binding to watch (default binding prefix is "prop") 
> */
>  +       String watch() default "";
>  +}
>
>  Modified: 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Unless.java
>  URL: 
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Unless.java?rev=635085&r1=635084&r2=635085&view=diff
>  
> ==============================================================================
>  --- 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Unless.java
>  (original)
>  +++ 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Unless.java
>  Sat Mar  8 12:53:25 2008
>  @@ -14,9 +14,8 @@
>
>   package org.apache.tapestry.corelib.components;
>
>  -import org.apache.tapestry.annotations.Parameter;
>  -import org.apache.tapestry.annotations.Component;
>   import org.apache.tapestry.Block;
>  +import org.apache.tapestry.annotations.Parameter;
>
>   /**
>   * A close relative of the [EMAIL PROTECTED] 
> org.apache.tapestry.corelib.components.If} component that inverts the meaning 
> of its
>
>  Added: 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/OnceWorker.java
>  URL: 
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/OnceWorker.java?rev=635085&view=auto
>  
> ==============================================================================
>  --- 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/OnceWorker.java
>  (added)
>  +++ 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/OnceWorker.java
>  Sat Mar  8 12:53:25 2008
>  @@ -0,0 +1,128 @@
>  +// Copyright 2006, 2007, 2008 The Apache Software Foundation
>  +//
>  +// Licensed under the Apache License, Version 2.0 (the "License");
>  +// you may not use this file except in compliance with the License.
>  +// You may obtain a copy of the License at
>  +//
>  +//     http://www.apache.org/licenses/LICENSE-2.0
>  +//
>  +// Unless required by applicable law or agreed to in writing, software
>  +// distributed under the License is distributed on an "AS IS" BASIS,
>  +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  +// See the License for the specific language governing permissions and
>  +// limitations under the License.
>  +
>  +package org.apache.tapestry.internal.transform;
>  +
>  +import static java.lang.reflect.Modifier.PRIVATE;
>  +
>  +import java.util.List;
>  +
>  +import org.apache.tapestry.Binding;
>  +import org.apache.tapestry.TapestryConstants;
>  +import org.apache.tapestry.annotations.Once;
>  +import org.apache.tapestry.ioc.util.BodyBuilder;
>  +import org.apache.tapestry.model.MutableComponentModel;
>  +import org.apache.tapestry.services.BindingSource;
>  +import org.apache.tapestry.services.ClassTransformation;
>  +import org.apache.tapestry.services.ComponentClassTransformWorker;
>  +import org.apache.tapestry.services.TransformConstants;
>  +import org.apache.tapestry.services.TransformMethodSignature;
>  +import org.apache.tapestry.services.TransformUtils;
>  +
>  +/** Caches method return values for methods annotated with [EMAIL 
> PROTECTED] Once}. */
>  +public class OnceWorker implements ComponentClassTransformWorker {
>  +       private final BindingSource _bindingSource;
>  +
>  +       public OnceWorker(BindingSource bindingSource) {
>  +               super();
>  +               this._bindingSource = bindingSource;
>  +       }
>  +
>  +       public void transform(ClassTransformation transformation, 
> MutableComponentModel model) {
>  +               List<TransformMethodSignature> methods = 
> transformation.findMethodsWithAnnotation(Once.class);
>  +               if (methods.isEmpty())
>  +                       return;
>  +
>  +               for(TransformMethodSignature method : methods) {
>  +                       if (method.getReturnType().equals("void"))
>  +                               throw new 
> IllegalArgumentException(TransformMessages.onceMethodMustHaveReturnValue(method));
>  +
>  +                       if (method.getParameterTypes().length != 0)
>  +                               throw new 
> IllegalArgumentException(TransformMessages.onceMethodsHaveNoParameters(method));
>  +
>  +                       String propertyName = method.getMethodName();
>  +
>  +                       // add a property to store whether or not the method 
> has been called
>  +                       String fieldName = transformation.addField(PRIVATE, 
> method.getReturnType(), propertyName);
>  +                       String calledField = 
> transformation.addField(PRIVATE, "boolean", fieldName + "$called");
>  +
>  +                       Once once = 
> transformation.getMethodAnnotation(method, Once.class);
>  +                       String bindingField = null;
>  +                       String bindingValueField = null;
>  +                       boolean watching = once.watch().length() > 0;
>  +                       if (watching) {
>  +                               // add fields to store the binding and the 
> value
>  +                               bindingField = 
> transformation.addField(PRIVATE, Binding.class.getCanonicalName(), fieldName 
> + "$binding");
>  +                               bindingValueField = 
> transformation.addField(PRIVATE, "java.lang.Object", fieldName + 
> "$bindingValue");
>  +
>  +                               String bindingSourceField = 
> transformation.addInjectedField(BindingSource.class, fieldName + 
> "$bindingsource", _bindingSource);
>  +
>  +                               String body = String.format("%s = 
> %s.newBinding(\"Watch expression\", %s, \"%s\", \"%s\");",
>  +                                               bindingField,
>  +                                               bindingSourceField,
>  +                                               
> transformation.getResourcesFieldName(),
>  +                                               
> TapestryConstants.PROP_BINDING_PREFIX,
>  +                                               once.watch());
>  +                               
> transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
>  body);
>  +                       }
>  +
>  +                       BodyBuilder b = new BodyBuilder();
>  +
>  +                       // on cleanup, reset the field values
>  +                       b.begin();
>  +
>  +                       if 
> (!TransformUtils.isPrimitive(method.getReturnType()))
>  +                               b.addln("%s = null;", fieldName);
>  +                       b.addln("%s = false;", calledField);
>  +
>  +                       if (watching)
>  +                               b.addln("%s = null;", bindingValueField);
>  +
>  +                       b.end();
>  +                       
> transformation.extendMethod(TransformConstants.POST_RENDER_CLEANUP_SIGNATURE, 
> b.toString());
>  +
>  +                       // prefix the existing method to cache the result
>  +                       b.clear();
>  +                       b.begin();
>  +
>  +                       // if it has been called and watch is set and the 
> old value is the same as the new value then return
>  +                       // get the old value and cache it
>  +                       /* NOTE: evaluates the binding twice when checking 
> the new value.
>  +                        * this is probably not a problem because in most 
> cases properties
>  +                        * that are being watched are not expensive 
> operations. plus, we
>  +                        * never guaranteed that it would be called exactly 
> once when
>  +                        * watching.
>  +                        */
>  +                       if (watching) {
>  +                               b.addln("if (%s && %s == %s.get()) return 
> %s;",
>  +                                               calledField, 
> bindingValueField, bindingField, fieldName);
>  +                               b.addln("%s = %s.get();", bindingValueField, 
> bindingField);
>  +                       }
>  +                       else {
>  +                               b.addln("if (%s) return %s;", calledField, 
> fieldName);
>  +                       }
>  +
>  +                       b.addln("%s = true;", calledField);
>  +                       b.end();
>  +                       transformation.prefixMethod(method, b.toString());
>  +
>  +                       // cache the return value
>  +                       b.clear();
>  +                       b.begin();
>  +                       b.addln("%s = $_;", fieldName);
>  +                       b.end();
>  +                       transformation.extendExistingMethod(method, 
> b.toString());
>  +               }
>  +       }
>  +}
>
>  Modified: 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/TransformMessages.java
>  URL: 
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/TransformMessages.java?rev=635085&r1=635084&r2=635085&view=diff
>  
> ==============================================================================
>  --- 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/TransformMessages.java
>  (original)
>  +++ 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/TransformMessages.java
>  Sat Mar  8 12:53:25 2008
>  @@ -17,6 +17,7 @@
>   import org.apache.tapestry.ioc.Messages;
>   import org.apache.tapestry.ioc.internal.util.MessagesImpl;
>   import org.apache.tapestry.runtime.Component;
>  +import org.apache.tapestry.services.TransformMethodSignature;
>
>   class TransformMessages
>   {
>  @@ -33,4 +34,11 @@
>                  .getComponentResources().getCompleteId(), fieldName, 
> fieldType);
>      }
>
>  +    static String onceMethodMustHaveReturnValue(TransformMethodSignature 
> method) {
>  +        return MESSAGES.format("once-no-return-value", method);
>  +    }
>  +
>  +    static String onceMethodsHaveNoParameters(TransformMethodSignature 
> method) {
>  +        return MESSAGES.format("once-no-parameters", method);
>  +    }
>   }
>
>  Modified: 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
>  URL: 
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java?rev=635085&r1=635084&r2=635085&view=diff
>  
> ==============================================================================
>  --- 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
>  (original)
>  +++ 
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
>  Sat Mar  8 12:53:25 2008
>  @@ -223,7 +223,7 @@
>       * annotation</dd> <dt>ContentType</dt> <dd>Checks for [EMAIL PROTECTED] 
> org.apache.tapestry.annotations.ContentType}
>       * annotation</dd> <dt>ResponseEncoding</dt> <dd>Checks for the [EMAIL 
> PROTECTED] org.apache.tapestry.annotations.ResponseEncoding}
>       * annotation</dd> <dt>GenerateAccessors</dt> <dd>Generates accessor 
> methods if [EMAIL PROTECTED]
>  -     * org.apache.tapestry.annotations.Property} annotation is present 
> </dd> </dl>
>  +     * org.apache.tapestry.annotations.Property} annotation is present 
> </dd> <dt>Once</dt> <dd>Checks for the [EMAIL PROTECTED] Once} 
> annotation</dd></dl>
>       */
>      public static void contributeComponentClassTransformWorker(
>              OrderedConfiguration<ComponentClassTransformWorker> 
> configuration,
>  @@ -243,6 +243,8 @@
>          // TODO: Proper scheduling of all of this. Since a given field or 
> method should
>          // only have a single annotation, the order doesn't matter so much, 
> as long as
>          // UnclaimedField is last.
>  +
>  +        configuration.add("Once", locator.autobuild(OnceWorker.class));
>
>          configuration.add("Meta", new MetaWorker());
>
>
>  Modified: 
> tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/transform/TransformStrings.properties
>  URL: 
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/transform/TransformStrings.properties?rev=635085&r1=635084&r2=635085&view=diff
>  
> ==============================================================================
>  --- 
> tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/transform/TransformStrings.properties
>  (original)
>  +++ 
> tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/transform/TransformStrings.properties
>  Sat Mar  8 12:53:25 2008
>  @@ -14,3 +14,5 @@
>
>   field-injection-error=Error obtaining injected value for field %s.%s: %s
>   component-not-assignable-to-field=Component %s is not assignable to field 
> %s (of type %s).
>  [EMAIL PROTECTED] may only be used with methods that return values: %s
>  [EMAIL PROTECTED] cannot be used with methods that accept parameters: %s
>  \ No newline at end of file
>
>  Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/index.apt
>  URL: 
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/index.apt?rev=635085&r1=635084&r2=635085&view=diff
>  
> ==============================================================================
>  --- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/index.apt (original)
>  +++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/index.apt Sat Mar  8 
> 12:53:25 2008
>  @@ -10,6 +10,8 @@
>
>   New And Of Note
>
>  +  * The @Once annotation has been added to allowing the caching of method 
> results.
>  +
>    * Tapestry can now generate accessor methods for fields automatically via 
> the @Property annotation.
>
>    * It is now possible to override the built-in display and edit blocks for 
> data types.
>
>  Modified: 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
>  URL: 
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?rev=635085&r1=635084&r2=635085&view=diff
>  
> ==============================================================================
>  --- 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
>  (original)
>  +++ 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
>  Sat Mar  8 12:53:25 2008
>  @@ -1860,6 +1860,26 @@
>                  "Class org.apache.tapestry.integration.app1.pages.Datum 
> contains field(s) (_value) that are not private. You should change these 
> fields to private, and add accessor methods if needed.");
>      }
>
>  +    /** TAPESTRY-2244 */
>  +    @Test
>  +    public void once()
>  +    {
>  +        start("Once Annotation");
>  +
>  +        assertText("//[EMAIL PROTECTED]'value']", "000");
>  +        assertText("//[EMAIL PROTECTED]'value2size']", "111");
>  +
>  +        assertText("//[EMAIL PROTECTED]'watch'][1]", "0");
>  +        assertText("//[EMAIL PROTECTED]'watch'][2]", "0");
>  +        assertText("//[EMAIL PROTECTED]'watch'][3]", "1");
>  +    }
>  +
>  +    /** TAPESTRY-2244 */
>  +    @Test
>  +    public void override_method_with_once() {
>  +        start("Once Annotation2");
>  +        assertText("//[EMAIL PROTECTED]'value']", "111");
>  +    }
>
>      private void sleep(long timeout)
>      {
>
>  Added: 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/OncePage.java
>  URL: 
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/OncePage.java?rev=635085&view=auto
>  
> ==============================================================================
>  --- 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/OncePage.java
>  (added)
>  +++ 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/OncePage.java
>  Sat Mar  8 12:53:25 2008
>  @@ -0,0 +1,50 @@
>  +package org.apache.tapestry.integration.app1.pages;
>  +
>  +import java.util.ArrayList;
>  +import java.util.List;
>  +
>  +import org.apache.tapestry.annotations.Once;
>  +
>  +public class OncePage {
>  +       private int value;
>  +       private List<String> value2;
>  +       private int value3;
>  +
>  +       private Integer watchValue;
>  +
>  +       void beginRender() {
>  +               value = 0;
>  +               value2 = new ArrayList<String>();
>  +               value3 = 0;
>  +               watchValue = 0;
>  +       }
>  +
>  +       @Once
>  +       public int getValue() {
>  +               return value++;
>  +       }
>  +
>  +       @Once
>  +       public List<String> getValue2() {
>  +               value2.add("a");
>  +               return value2;
>  +       }
>  +
>  +       @Once(watch="watchValue")
>  +       public int getValue3() {
>  +               return value3++;
>  +       }
>  +
>  +       public Integer getWatchValue() {
>  +               return watchValue;
>  +       }
>  +
>  +       public void setWatchValue(Integer watchValue) {
>  +               this.watchValue = watchValue;
>  +       }
>  +
>  +       public Object incrWatchValue() {
>  +               watchValue++;
>  +               return null;
>  +       }
>  +}
>
>  Added: 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/OncePage2.java
>  URL: 
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/OncePage2.java?rev=635085&view=auto
>  
> ==============================================================================
>  --- 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/OncePage2.java
>  (added)
>  +++ 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/OncePage2.java
>  Sat Mar  8 12:53:25 2008
>  @@ -0,0 +1,10 @@
>  +package org.apache.tapestry.integration.app1.pages;
>  +
>  +public class OncePage2 extends OncePage {
>  +
>  +       @Override
>  +       public int getValue() {
>  +               return super.getValue()+1;
>  +       }
>  +
>  +}
>
>  Modified: 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
>  URL: 
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java?rev=635085&r1=635084&r2=635085&view=diff
>  
> ==============================================================================
>  --- 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
>  (original)
>  +++ 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
>  Sat Mar  8 12:53:25 2008
>  @@ -247,7 +247,12 @@
>              new Item("IndirectProtectedFields", "Protected Fields Demo", 
> "demo exception when component class contains protected fields"),
>
>              new Item("injectcomponentdemo", "Inject Component Demo",
>  -                     "inject component defined in template"));
>  +                     "inject component defined in template"),
>  +
>  +            new Item("oncepage", "Once Annotation", "Caching method return 
> values"),
>  +
>  +            new Item("oncepage2", "Once Annotation2", "Caching method 
> return values w/ inheritence")
>  +    );
>
>      static
>      {
>
>  Added: 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/OnceWorkerTest.java
>  URL: 
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/OnceWorkerTest.java?rev=635085&view=auto
>  
> ==============================================================================
>  --- 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/OnceWorkerTest.java
>  (added)
>  +++ 
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/OnceWorkerTest.java
>  Sat Mar  8 12:53:25 2008
>  @@ -0,0 +1,57 @@
>  +// Copyright 2006, 2007, 2008 The Apache Software Foundation
>  +//
>  +// Licensed under the Apache License, Version 2.0 (the "License");
>  +// you may not use this file except in compliance with the License.
>  +// You may obtain a copy of the License at
>  +//
>  +//     http://www.apache.org/licenses/LICENSE-2.0
>  +//
>  +// Unless required by applicable law or agreed to in writing, software
>  +// distributed under the License is distributed on an "AS IS" BASIS,
>  +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  +// See the License for the specific language governing permissions and
>  +// limitations under the License.
>  +
>  +package org.apache.tapestry.internal.transform;
>  +
>  +import java.lang.reflect.Modifier;
>  +import java.util.Arrays;
>  +
>  +import org.apache.tapestry.annotations.Once;
>  +import org.apache.tapestry.services.ClassTransformation;
>  +import org.apache.tapestry.services.TransformMethodSignature;
>  +import org.apache.tapestry.test.TapestryTestCase;
>  +import org.testng.annotations.Test;
>  +
>  +/** Mostly just testing error conditions here. Functionality testing in 
> integration tests. */
>  [EMAIL PROTECTED]
>  +public class OnceWorkerTest extends TapestryTestCase
>  +{
>  +    public void must_have_return_type() throws Exception {
>  +        ClassTransformation ct = mockClassTransformation();
>  +        TransformMethodSignature sig = new 
> TransformMethodSignature(Modifier.PUBLIC, "void", "getFoo", new String[0], 
> new String[0]);
>  +
>  +        
> expect(ct.findMethodsWithAnnotation(Once.class)).andReturn(Arrays.asList(sig));
>  +
>  +        replay();
>  +        try {
>  +            new OnceWorker(null).transform(ct, null);
>  +            fail("did not throw");
>  +        } catch (IllegalArgumentException e) {}
>  +        verify();
>  +    }
>  +
>  +    public void must_not_have_parameters() throws Exception {
>  +        ClassTransformation ct = mockClassTransformation();
>  +        TransformMethodSignature sig = new 
> TransformMethodSignature(Modifier.PUBLIC, "java.lang.Object", "getFoo", new 
> String[] { "boolean" }, new String[0]);
>  +
>  +        
> expect(ct.findMethodsWithAnnotation(Once.class)).andReturn(Arrays.asList(sig));
>  +
>  +        replay();
>  +        try {
>  +            new OnceWorker(null).transform(ct, null);
>  +            fail("did not throw");
>  +        } catch (IllegalArgumentException e) {}
>  +        verify();
>  +    }
>  +}
>
>  Added: 
> tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/OncePage.tml
>  URL: 
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/OncePage.tml?rev=635085&view=auto
>  
> ==============================================================================
>  --- 
> tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/OncePage.tml
>  (added)
>  +++ 
> tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/OncePage.tml
>  Sat Mar  8 12:53:25 2008
>  @@ -0,0 +1,13 @@
>  +<html t:type="Border" 
> xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";>
>  +       <h1>@Once tests</h1>
>  +       <p>This page tests the @Once annotation.</p>
>  +
>  +       <span id="value">${value}${value}${value}</span>
>  +       <span 
> id="value2size">${value2.size()}${value2.size()}${value2.size()}</span>
>  +
>  +       ${incrWatchValue()}
>  +       <span class="watch">${value3}</span>
>  +       <span class="watch">${value3}</span>
>  +       ${incrWatchValue()}
>  +       <span class="watch">${value3}</span>
>  +</html>
>
>
>



-- 
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to