You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by ro...@apache.org on 2009/06/22 14:42:57 UTC

svn commit: r787224 - in /tapestry/tapestry5/trunk: src/site/apt/guide/ tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/ tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ tapestry-core/src/main/java/org/apache/tap...

Author: robertdzeigler
Date: Mon Jun 22 12:42:56 2009
New Revision: 787224

URL: http://svn.apache.org/viewvc?rev=787224&view=rev
Log:
TAP5-692: T5 should pick up validators to be applied to a field from the containing component's .properties file

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/EnvironmentMessages.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/MessagesConstraintGenerator.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/MessageConstraintGeneratorDemo.tml
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/Pet.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/PetType.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/MessageConstraintGeneratorDemo.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/beaneditor/MessagesAnnotationConstraintGeneratorTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/MessageConstraintGeneratorDemo.properties
Modified:
    tapestry/tapestry5/trunk/src/site/apt/guide/beaneditform.apt
    tapestry/tapestry5/trunk/src/site/apt/guide/validation.apt
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/ValidateAnnotationConstraintGenerator.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/FieldValidatorDefaultSourceImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java

Modified: tapestry/tapestry5/trunk/src/site/apt/guide/beaneditform.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/guide/beaneditform.apt?rev=787224&r1=787223&r2=787224&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/guide/beaneditform.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/guide/beaneditform.apt Mon Jun 22 12:42:56 2009
@@ -73,7 +73,9 @@
   Default validation for fields is primary determined by property type.
   
   If desired, additional validation may be specified using the 
-  {{{../apidocs/org/apache/tapestry5/beaneditor/Validate.html}Validate}} annotation.
+  {{{../apidocs/org/apache/tapestry5/beaneditor/Validate.html}Validate}} annotation. 
+
+  * As of 5.2, validation may also be specified via the containing component's property file, using a key in the form of propertyId-validate (eg: name-validate=required).
   
 * Property ordering
 

Modified: tapestry/tapestry5/trunk/src/site/apt/guide/validation.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/guide/validation.apt?rev=787224&r1=787223&r2=787224&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/guide/validation.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/guide/validation.apt Mon Jun 22 12:42:56 2009
@@ -239,7 +239,7 @@
   This is nice and seamless; the same look and feel and behavior for both the built-in validators, and for errors generated based on
   application logic.
 
-Centralizing Validation with @Validate
+Centralizing Validation with @Validate and Property Files
 
   The {{{../apidocs/org/apache/tapestry5/beaneditor/Validate.html}Validate}} annotation can take the place of the
   validate parameter of TextField, PasswordField, TextArea and other components.  When the validate parameter
@@ -247,6 +247,9 @@
 
   The annotation may be placed on the getter or setter method, or on the field itself.
 
+  Validation constraints can also be specified in the properties file of the containing page or component.
+  The key takes the form <propertyId>-validate.  For example: username-validate=required,minlength=6.
+
 Customizing Validation Messages
 
   Each validator (such as "required" or "minlength") has a default message used (on the client side and the server side)

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/EnvironmentMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/EnvironmentMessages.java?rev=787224&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/EnvironmentMessages.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/EnvironmentMessages.java Mon Jun 22 12:42:56 2009
@@ -0,0 +1,47 @@
+
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.beaneditor;
+
+import org.apache.tapestry5.ioc.Messages;
+
+/**
+ * Holds the current (overrides) Messages object and override id for placemnt into the environment
+ * by FieldValidatorDefaultSourceImpl so ValidationConstraintGenerator implementations have access
+ * to the catalog if necessary.
+ */
+public class EnvironmentMessages
+{
+
+    private final Messages messages;
+    private final String overrideId;
+
+    public EnvironmentMessages(Messages messages, String overrideId)
+    {
+        this.messages = messages;
+        this.overrideId = overrideId;
+    }
+
+    public Messages getMessages()
+    {
+        return messages;
+    }
+
+    public String getOverrideId()
+    {
+        return overrideId;
+    }
+
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/MessagesConstraintGenerator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/MessagesConstraintGenerator.java?rev=787224&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/MessagesConstraintGenerator.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/MessagesConstraintGenerator.java Mon Jun 22 12:42:56 2009
@@ -0,0 +1,66 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.beaneditor;
+
+import org.apache.tapestry5.services.ValidationConstraintGenerator;
+import org.apache.tapestry5.services.Environment;
+import org.apache.tapestry5.services.PropertyEditContext;
+import org.apache.tapestry5.ioc.AnnotationProvider;
+import org.apache.tapestry5.ioc.Messages;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+
+import java.util.List;
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+/**
+ * Generates constraints from the containing component's property file.
+ * Looks for a key in the form: propertyId-validate. 
+ *
+ */
+public class MessagesConstraintGenerator implements ValidationConstraintGenerator
+{
+
+    private final Environment environment;
+    private final String format="%s-validate";
+    private final Pattern splitPattern;
+
+    public MessagesConstraintGenerator(final Environment environment) {
+        this.environment = environment;
+        splitPattern = Pattern.compile(ValidateAnnotationConstraintGenerator.VALIDATOR_PATTERN);
+    }
+
+    public List<String> buildConstraints(Class propertyType, AnnotationProvider annotationProvider)
+    {
+        EnvironmentMessages environmentMessages = environment.peek(EnvironmentMessages.class);
+        if (environmentMessages == null) {
+            return null;
+        }
+
+        String key = String.format(format,environmentMessages.getOverrideId());
+        Messages m = environmentMessages.getMessages();
+        if (!m.contains(key))
+        {
+            return null;
+        }
+
+        String result = m.get(key);
+        if (InternalUtils.isBlank(result))
+        {
+            return null;
+        }
+        return Arrays.asList(splitPattern.split(result));
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/ValidateAnnotationConstraintGenerator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/ValidateAnnotationConstraintGenerator.java?rev=787224&r1=787223&r2=787224&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/ValidateAnnotationConstraintGenerator.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/beaneditor/ValidateAnnotationConstraintGenerator.java Mon Jun 22 12:42:56 2009
@@ -20,6 +20,7 @@
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.regex.Pattern;
 
 /**
  * Checks for the {@link Validate} annotation, and extracts its value to form the result.
@@ -27,6 +28,15 @@
 public class ValidateAnnotationConstraintGenerator implements ValidationConstraintGenerator
 {
 
+    static final String VALIDATOR_PATTERN="(?<!\\\\),(?!([0-9]*\\}))";
+
+    private final Pattern validatorPattern;
+
+    public ValidateAnnotationConstraintGenerator()
+    {
+        validatorPattern = Pattern.compile(VALIDATOR_PATTERN);
+    }
+
     public List<String> buildConstraints(Class propertyType, AnnotationProvider annotationProvider)
     {
         Validate annotation = annotationProvider.getAnnotation(Validate.class);
@@ -38,7 +48,7 @@
         //We use Negative Lookahead to avoid matching the case a\,b .
         //We use Positive Lookahead to avoid matching cases {n,m} and {n,}.
         //http://www.regular-expressions.info/lookaround.html
-        return Arrays.asList(annotation.value().split("(?<!\\\\),(?!([0-9]*\\}))"));
+        return Arrays.asList(validatorPattern.split(annotation.value()));
     }
 
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/FieldValidatorDefaultSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/FieldValidatorDefaultSourceImpl.java?rev=787224&r1=787223&r2=787224&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/FieldValidatorDefaultSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/FieldValidatorDefaultSourceImpl.java Mon Jun 22 12:42:56 2009
@@ -17,12 +17,14 @@
 import org.apache.tapestry5.ComponentResources;
 import org.apache.tapestry5.Field;
 import org.apache.tapestry5.FieldValidator;
+import org.apache.tapestry5.internal.beaneditor.EnvironmentMessages;
 import org.apache.tapestry5.ioc.AnnotationProvider;
 import org.apache.tapestry5.ioc.Messages;
 import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newList;
 import org.apache.tapestry5.services.FieldValidatorDefaultSource;
 import org.apache.tapestry5.services.FieldValidatorSource;
 import org.apache.tapestry5.services.ValidationConstraintGenerator;
+import org.apache.tapestry5.services.Environment;
 
 import java.util.List;
 import java.util.Locale;
@@ -66,7 +68,6 @@
 
             validators.add(validator);
         }
-
         return validators.size() == 1 ? validators.get(0) : new CompositeFieldValidator(validators);
     }
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=787224&r1=787223&r2=787224&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Mon Jun 22 12:42:56 2009
@@ -26,6 +26,8 @@
 import org.apache.tapestry5.internal.*;
 import org.apache.tapestry5.internal.beaneditor.PrimitiveFieldConstraintGenerator;
 import org.apache.tapestry5.internal.beaneditor.ValidateAnnotationConstraintGenerator;
+import org.apache.tapestry5.internal.beaneditor.MessagesConstraintGenerator;
+import org.apache.tapestry5.internal.beaneditor.EnvironmentMessages;
 import org.apache.tapestry5.internal.bindings.*;
 import org.apache.tapestry5.internal.grid.CollectionGridDataSource;
 import org.apache.tapestry5.internal.grid.NullDataSource;
@@ -1001,6 +1003,7 @@
     {
         configuration.add("PrimitiveField", new PrimitiveFieldConstraintGenerator());
         configuration.add("ValidateAnnotation", new ValidateAnnotationConstraintGenerator());
+        configuration.addInstance("Messages", MessagesConstraintGenerator.class);
     }
 
     private static <S, T> void add(Configuration<CoercionTuple> configuration, Class<S> sourceType, Class<T> targetType,
@@ -1396,7 +1399,7 @@
      * Supports an ordered configuration of {@link org.apache.tapestry5.services.PartialMarkupRendererFilter}s.
      *
      * @see #contributePartialMarkupRenderer(org.apache.tapestry5.ioc.OrderedConfiguration, org.apache.tapestry5.Asset,
-     *      org.apache.tapestry5.ioc.services.SymbolSource, AssetSource, ValidationMessagesSource)
+     *      org.apache.tapestry5.ioc.services.SymbolSource, AssetSource)
      */
     public PartialMarkupRenderer buildPartialMarkupRenderer(Logger logger,
                                                             List<PartialMarkupRendererFilter> configuration,
@@ -2405,4 +2408,50 @@
 
     }
 
+    /**
+     * Decorate FieldValidatorDefaultSource to setup the EnvironmentMessages object and place it in the environment.
+     * Although this could have been implemented directly in the default implementation of the service, doing it
+     * as service decoration ensures that the environment will be properly setup even if a user overrides the default
+     * service implementation.
+     * @param defaultSource The serivce to decorate
+     * @param environment
+     * @return
+     */
+    public static FieldValidatorDefaultSource decorateFieldValidatorDefaultSource(
+           final FieldValidatorDefaultSource defaultSource, final Environment environment)
+    {
+        return new FieldValidatorDefaultSource()
+        {
+
+            public FieldValidator createDefaultValidator(
+                    Field field,
+                    String overrideId,
+                    Messages overrideMessages,
+                    Locale locale,
+                    Class propertyType,
+                    AnnotationProvider propertyAnnotations)
+            {
+                environment.push(EnvironmentMessages.class,new EnvironmentMessages(overrideMessages,overrideId));
+                FieldValidator fieldValidator = defaultSource.createDefaultValidator(field,
+                                                                       overrideId,
+                                                                       overrideMessages,
+                                                                       locale,
+                                                                       propertyType,
+                                                                       propertyAnnotations);
+                environment.pop(EnvironmentMessages.class);
+                return fieldValidator;
+            }
+
+            public FieldValidator createDefaultValidator(ComponentResources resources, String parameterName)
+            {
+
+                EnvironmentMessages em = new EnvironmentMessages(resources.getContainerMessages(),resources.getId());
+                environment.push(EnvironmentMessages.class,em);
+                FieldValidator fieldValidator = defaultSource.createDefaultValidator(resources, parameterName);
+                environment.pop(EnvironmentMessages.class);
+                return fieldValidator;
+            }
+        };
+    }
+
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/MessageConstraintGeneratorDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/MessageConstraintGeneratorDemo.tml?rev=787224&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/MessageConstraintGeneratorDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/MessageConstraintGeneratorDemo.tml Mon Jun 22 12:42:56 2009
@@ -0,0 +1,12 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"
+          xmlns:p="tapestry:parameter">
+
+    <h1>Validators specified in message catalog</h1>
+
+    <t:beaneditform t:id="form" object="pet">
+        <p:age>
+            <t:label for="age"/> <t:textfield t:id="age" value="pet.age"/>
+        </p:age>
+    </t:beaneditform>
+
+</t:border>

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java?rev=787224&r1=787223&r2=787224&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java Mon Jun 22 12:42:56 2009
@@ -2930,4 +2930,31 @@
         assertText("prop.middle.bottom", "bound value");
         assertText("literal.middle.bottom", "some text");
     }
+
+    @Test
+    public void validation_constraints_from_messages() throws InterruptedException
+    {
+        start("Validation Constraints From Messages");
+
+        click(SUBMIT);
+
+        assertBubbleMessage("name","You must provide a value for Name.");
+        assertBubbleMessage("age","You must provide a value for Age.");
+
+        type("name","behemoth");
+        type("age","0");
+        select("type","label=Snake");
+
+        click(SUBMIT);
+        assertBubbleMessage("age","Age requires a value of at least 1.");
+
+        type("age","121");
+        click(SUBMIT);
+        assertBubbleMessage("age","Age requires a value no larger than 120.");
+
+        type("age","5");
+        clickAndWait(SUBMIT);
+
+
+    }
 }
\ No newline at end of file

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/Pet.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/Pet.java?rev=787224&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/Pet.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/Pet.java Mon Jun 22 12:42:56 2009
@@ -0,0 +1,54 @@
+// Copyright 2007 The Apache Software Foundation
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+
+package org.apache.tapestry5.integration.app1.data;
+
+public class Pet
+{
+
+    private String name;
+    private Integer age;
+    private PetType type;
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    public Integer getAge()
+    {
+        return age;
+    }
+
+    public void setAge(Integer age)
+    {
+        this.age = age;
+    }
+
+    public PetType getType()
+    {
+        return type;
+    }
+
+    public void setType(PetType type)
+    {
+        this.type = type;
+    }
+
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/PetType.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/PetType.java?rev=787224&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/PetType.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/PetType.java Mon Jun 22 12:42:56 2009
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.integration.app1.data;
+
+public enum PetType
+{
+    DOG,CAT,FISH,SNAKE,TARANTULA;
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java?rev=787224&r1=787223&r2=787224&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java Mon Jun 22 12:42:56 2009
@@ -347,7 +347,11 @@
                      "Nice exception message for common problem of form fields outside forms"),
 
             new Item("SubmitWithContext", "Submit With Context",
-                     "Providing a context for Submit component")
+                     "Providing a context for Submit component"),
+
+            new Item("MessageConstraintGeneratorDemo",
+                     "Validation Constraints From Messages",
+                     "Providing validators to apply from a properties file")
     );
 
     static

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/MessageConstraintGeneratorDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/MessageConstraintGeneratorDemo.java?rev=787224&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/MessageConstraintGeneratorDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/MessageConstraintGeneratorDemo.java Mon Jun 22 12:42:56 2009
@@ -0,0 +1,26 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.integration.app1.data.Pet;
+
+public class MessageConstraintGeneratorDemo
+{
+
+    @Property
+    private Pet pet;
+    
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/beaneditor/MessagesAnnotationConstraintGeneratorTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/beaneditor/MessagesAnnotationConstraintGeneratorTest.java?rev=787224&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/beaneditor/MessagesAnnotationConstraintGeneratorTest.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/beaneditor/MessagesAnnotationConstraintGeneratorTest.java Mon Jun 22 12:42:56 2009
@@ -0,0 +1,107 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.beaneditor;
+
+import org.apache.tapestry5.internal.test.InternalBaseTestCase;
+import org.apache.tapestry5.services.Environment;
+import org.apache.tapestry5.services.PropertyEditContext;
+import org.apache.tapestry5.ioc.Messages;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+
+public class MessagesAnnotationConstraintGeneratorTest extends InternalBaseTestCase
+{
+
+    @Test
+    public void no_environment()
+    {
+        Environment e = getService(Environment.class);
+        MessagesConstraintGenerator gen = new MessagesConstraintGenerator(e);
+        assertNull(gen.buildConstraints(null,null));
+    }
+
+    @Test
+    public void no_property()
+    {
+        Environment e = getService(Environment.class);
+
+        pushAndTrainEnvironmentalObjects(e,false,null);
+
+        MessagesConstraintGenerator gen = new MessagesConstraintGenerator(e);
+        assertNull(gen.buildConstraints(null,null));
+
+        pop(e);
+        verify();
+    }
+
+    @Test
+    public void empty_message()
+    {
+        Environment e = getService(Environment.class);
+
+        pushAndTrainEnvironmentalObjects(e,true,"");
+
+        MessagesConstraintGenerator gen = new MessagesConstraintGenerator(e);
+        assertNull(gen.buildConstraints(null,null));
+
+        pop(e);
+        verify();
+    }
+
+    @Test
+    public void single_constraint()
+    {
+        Environment e = getService(Environment.class);
+
+        pushAndTrainEnvironmentalObjects(e,true,"required");
+
+        MessagesConstraintGenerator gen = new MessagesConstraintGenerator(e);
+
+        assertEquals(gen.buildConstraints(null,null), Arrays.asList("required"));
+    }
+
+    @Test
+    public void multiple_constraints()
+    {
+        Environment e = getService(Environment.class);
+
+        pushAndTrainEnvironmentalObjects(e,true,"required,minlength=3,regexp=^([a-zA-Z0-9]{2,4})+@(\\p{Lower})*$");
+
+        MessagesConstraintGenerator gen = new MessagesConstraintGenerator(e);
+
+        assertEquals(gen.buildConstraints(null,null),
+                Arrays.asList("required","minlength=3","regexp=^([a-zA-Z0-9]{2,4})+@(\\p{Lower})*$"));
+
+    }
+
+    private void pushAndTrainEnvironmentalObjects(Environment e, boolean hasProperty, String propertyValue) {
+        Messages messages = mockMessages();
+        train_contains(messages,"testProperty-validate",hasProperty);
+
+        if (hasProperty) {
+            train_get(messages,"testProperty-validate",propertyValue);
+        }
+
+        EnvironmentMessages em = new EnvironmentMessages(messages,"testProperty");
+        e.push(EnvironmentMessages.class,em);
+        replay();
+    }
+
+    private void pop(Environment e) {
+        e.pop(EnvironmentMessages.class);
+    }
+
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/MessageConstraintGeneratorDemo.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/MessageConstraintGeneratorDemo.properties?rev=787224&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/MessageConstraintGeneratorDemo.properties (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/MessageConstraintGeneratorDemo.properties Mon Jun 22 12:42:56 2009
@@ -0,0 +1,17 @@
+# Copyright 2007 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.
+
+name-validate=required
+age-validate=required,min=1,max=120
+