Author: hlship
Date: Tue Jan 23 07:55:28 2007
New Revision: 499061

URL: http://svn.apache.org/viewvc?view=rev&rev=499061
Log:
Extend Validator to describe under what conditions the Validator should be 
invoked.

Added:
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorImpl.java
    
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorImplTest.java
Modified:
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorSourceImpl.java
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/MinLength.java
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/Required.java
    
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorSourceImplTest.java
    
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/validator/MinLengthTest.java

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java?view=diff&rev=499061&r1=499060&r2=499061
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java
 Tue Jan 23 07:55:28 2007
@@ -34,6 +34,13 @@
     Class<C> getConstraintType();
 
     /**
+     * Returns the value type associated with this validator.
+     * [EMAIL PROTECTED] #check(Field, Object, MessageFormatter, Object)} will 
only be invoked when the value
+     * is assignable to the validator's value type.
+     */
+    Class<T> getValueType();
+
+    /**
      * Returns the message key, within the validiation messages, normally used 
by this validator.
      * This is used to provide the [EMAIL PROTECTED] MessageFormatter} passed 
to
      * [EMAIL PROTECTED] #check(Field, Object, MessageFormatter, Object)} 
(unless overridden).
@@ -61,4 +68,10 @@
      */
     void check(Field field, C constraintValue, MessageFormatter formatter, T 
value)
             throws ValidationException;
+
+    /**
+     * Returns true if the validator should be skipped for null or blank 
(empty string) values. This
+     * is generally true.
+     */
+    boolean skipIfBlank();
 }

Added: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorImpl.java?view=auto&rev=499061
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorImpl.java
 (added)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorImpl.java
 Tue Jan 23 07:55:28 2007
@@ -0,0 +1,59 @@
+// 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.tapestry.internal.services;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.Validator;
+import org.apache.tapestry.ioc.MessageFormatter;
+
+public class FieldValidatorImpl implements FieldValidator
+{
+    private final Field _field;
+
+    private final Object _constraintValue;
+
+    private final MessageFormatter _messageFormatter;
+
+    private final Validator _validator;
+
+    public FieldValidatorImpl(Field field, Object constraintValue,
+            MessageFormatter messageFormatter, Validator validator)
+    {
+        _field = field;
+        _constraintValue = constraintValue;
+        _messageFormatter = messageFormatter;
+        _validator = validator;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void check(Object value) throws ValidationException
+    {
+        if (_validator.skipIfBlank() && isBlank(value))
+            return;
+
+        if (value != null && !_validator.getValueType().isInstance(value))
+            return;
+
+        _validator.check(_field, _constraintValue, _messageFormatter, value);
+    }
+
+    private boolean isBlank(Object value)
+    {
+        return value == null || value.equals("");
+    }
+
+}

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorSourceImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorSourceImpl.java?view=diff&rev=499061&r1=499060&r2=499061
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorSourceImpl.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorSourceImpl.java
 Tue Jan 23 07:55:28 2007
@@ -51,13 +51,12 @@
         _validators = validators;
     }
 
-    public FieldValidator createValidator(final Field field, String 
validatorType,
-            String constraintValue)
+    public FieldValidator createValidator(Field field, String validatorType, 
String constraintValue)
     {
         Component component = cast(field, Component.class, "field");
         notBlank(validatorType, "validatorType");
 
-        final Validator validator = _validators.get(validatorType);
+        Validator validator = _validators.get(validatorType);
 
         if (validator == null)
         {
@@ -67,19 +66,12 @@
             throw new IllegalArgumentException(message);
         }
 
-        final Object coercedConstraintValue = 
coerceConstraintValue(constraintValue, validator
+        Object coercedConstraintValue = coerceConstraintValue(constraintValue, 
validator
                 .getConstraintType());
 
-        final MessageFormatter formatter = findMessageFormatter(component, 
validatorType, validator);
+        MessageFormatter formatter = findMessageFormatter(component, 
validatorType, validator);
 
-        return new FieldValidator()
-        {
-            @SuppressWarnings("unchecked")
-            public void check(Object value) throws ValidationException
-            {
-                validator.check(field, coercedConstraintValue, formatter, 
value);
-            }
-        };
+        return new FieldValidatorImpl(field, coercedConstraintValue, 
formatter, validator);
     }
 
     private MessageFormatter findMessageFormatter(Component component, String 
validatorType,
@@ -91,7 +83,7 @@
 
         // So, if you use a TextField on your EditUser page, we want to search 
the messages
         // of the EditUser page (the container), not the TextField (which will 
always be the same).
-        
+
         Messages messages = resources.getContainerResources().getMessages();
 
         if (messages.contains(overrideKey))

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java?view=diff&rev=499061&r1=499060&r2=499061
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
 Tue Jan 23 07:55:28 2007
@@ -710,4 +710,34 @@
     {
         expect(field.getLabel()).andReturn(label).atLeastOnce();
     }
+
+    protected final void train_getContainerResources(ComponentResources 
resources, ComponentResources containerResources)
+    {
+        
expect(resources.getContainerResources()).andReturn(containerResources).atLeastOnce();
+    }
+
+    protected final void train_contains(Messages messages, String key, boolean 
result)
+    {
+        expect(messages.contains(key)).andReturn(result).atLeastOnce();
+    }
+
+    protected final void train_getId(ComponentResources resources, String id)
+    {
+        expect(resources.getId()).andReturn(id).atLeastOnce();
+    }
+
+    protected final void train_getMessages(ComponentResources resources, 
Messages messages)
+    {
+        expect(resources.getMessages()).andReturn(messages).atLeastOnce();
+    }
+
+    protected final void train_getValueType(Validator validator, Class 
valueType)
+    {
+        expect(validator.getValueType()).andReturn(valueType).atLeastOnce();
+    }
+
+    protected final void train_skipIfBlank(Validator validator, boolean 
skipIfBlank)
+    {
+        expect(validator.skipIfBlank()).andReturn(skipIfBlank).atLeastOnce();
+    }
 }

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/MinLength.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/MinLength.java?view=diff&rev=499061&r1=499060&r2=499061
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/MinLength.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/MinLength.java
 Tue Jan 23 07:55:28 2007
@@ -1,10 +1,23 @@
+// 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.tapestry.validator;
 
 import org.apache.tapestry.Field;
 import org.apache.tapestry.ValidationException;
 import org.apache.tapestry.Validator;
 import org.apache.tapestry.ioc.MessageFormatter;
-import org.apache.tapestry.ioc.internal.util.InternalUtils;
 
 public class MinLength implements Validator<Integer, String>
 {
@@ -19,7 +32,7 @@
         // Validators should ignore blank/null values.
         // TODO: Could this be externalized so that the Validator doesn't need 
to check?
 
-        if (InternalUtils.isBlank(value))
+        if (value.equals(""))
             return;
 
         if (value.length() < constraintValue)
@@ -31,4 +44,13 @@
         return Integer.class;
     }
 
+    public boolean skipIfBlank()
+    {
+        return true;
+    }
+
+    public Class<String> getValueType()
+    {
+        return String.class;
+    }
 }

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/Required.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/Required.java?view=diff&rev=499061&r1=499060&r2=499061
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/Required.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/Required.java
 Tue Jan 23 07:55:28 2007
@@ -42,4 +42,13 @@
         return null;
     }
 
+    public boolean skipIfBlank()
+    {
+        return false;
+    }
+
+    public Class<Object> getValueType()
+    {
+        return Object.class;
+    }
 }

Added: 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorImplTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorImplTest.java?view=auto&rev=499061
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorImplTest.java
 (added)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorImplTest.java
 Tue Jan 23 07:55:28 2007
@@ -0,0 +1,108 @@
+// 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.tapestry.internal.services;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.Validator;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.testng.annotations.Test;
+
+/**
+ * Tests a few outlier cases not covered by [EMAIL PROTECTED] 
FieldValidatorSourceImplTest}.
+ */
+public class FieldValidatorImplTest extends InternalBaseTestCase
+{
+    @SuppressWarnings("unchecked")
+    @Test
+    public void null_value_skipped() throws Exception
+    {
+        Field field = newField();
+        MessageFormatter formatter = newMessageFormatter();
+        Validator validator = newValidator();
+
+        train_skipIfBlank(validator, true);
+
+        replay();
+
+        FieldValidator fv = new FieldValidatorImpl(field, null, formatter, 
validator);
+
+        fv.check(null);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void blank_value_skipped() throws Exception
+    {
+        Field field = newField();
+        MessageFormatter formatter = newMessageFormatter();
+        Validator validator = newValidator();
+
+        train_skipIfBlank(validator, true);
+
+        replay();
+
+        FieldValidator fv = new FieldValidatorImpl(field, null, formatter, 
validator);
+
+        fv.check("");
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void nonmatching_value_type_skipped() throws Exception
+    {
+        Field field = newField();
+        MessageFormatter formatter = newMessageFormatter();
+        Validator validator = newValidator();
+        Integer value = 15;
+
+        train_skipIfBlank(validator, true);
+        train_getValueType(validator, String.class);
+
+        replay();
+
+        FieldValidator fv = new FieldValidatorImpl(field, null, formatter, 
validator);
+
+        fv.check(value);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void value_type_check_skipped_for_null_values() throws Exception
+    {
+        Field field = newField();
+        MessageFormatter formatter = newMessageFormatter();
+        Validator validator = newValidator();
+
+        train_skipIfBlank(validator, false);
+
+        validator.check(field, null, formatter, null);
+
+        replay();
+
+        FieldValidator fv = new FieldValidatorImpl(field, null, formatter, 
validator);
+
+        fv.check(null);
+
+        verify();
+    }
+}

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorSourceImplTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorSourceImplTest.java?view=diff&rev=499061&r1=499060&r2=499061
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorSourceImplTest.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorSourceImplTest.java
 Tue Jan 23 07:55:28 2007
@@ -107,6 +107,8 @@
         train_getMessageKey(validator, "key");
         train_getMessageFormatter(messages, "key", formatter);
 
+        train_skipIfBlank(validator, true);
+        train_getValueType(validator, Object.class);
         validator.check(field, null, formatter, inputValue);
 
         replay();
@@ -120,12 +122,6 @@
         verify();
     }
 
-    protected final void train_getContainerResources(ComponentResources 
resources,
-            ComponentResources containerResources)
-    {
-        
expect(resources.getContainerResources()).andReturn(containerResources).atLeastOnce();
-    }
-
     @SuppressWarnings("unchecked")
     @Test
     public void component_messages_overrides_validator_messages() throws 
Exception
@@ -152,6 +148,8 @@
 
         train_getMessageFormatter(componentMessages, "fred-required", 
formatter);
 
+        train_skipIfBlank(validator, true);
+        train_getValueType(validator, Object.class);
         validator.check(field, null, formatter, inputValue);
 
         replay();
@@ -197,6 +195,8 @@
         train_getMessageKey(validator, "key");
         train_getMessageFormatter(messages, "key", formatter);
 
+        train_skipIfBlank(validator, true);
+        train_getValueType(validator, Object.class);
         validator.check(field, null, formatter, inputValue);
 
         replay();
@@ -210,21 +210,6 @@
         verify();
     }
 
-    private void train_contains(Messages messages, String key, boolean result)
-    {
-        expect(messages.contains(key)).andReturn(result).atLeastOnce();
-    }
-
-    protected void train_getId(ComponentResources resources, String id)
-    {
-        expect(resources.getId()).andReturn(id).atLeastOnce();
-    }
-
-    protected final void train_getMessages(ComponentResources resources, 
Messages messages)
-    {
-        expect(resources.getMessages()).andReturn(messages).atLeastOnce();
-    }
-
     @SuppressWarnings("unchecked")
     @Test
     public void multiple_validators_via_specification() throws Exception
@@ -237,7 +222,7 @@
         Messages messages = newMessages();
         MessageFormatter requiredFormatter = newMessageFormatter();
         MessageFormatter minLengthFormatter = newMessageFormatter();
-        Object inputValue = new Object();
+        Object inputValue = "input value";
         ComponentResources resources = newComponentResources();
         ComponentResources containerResources = newComponentResources();
         Messages componentMessages = newMessages();
@@ -271,7 +256,12 @@
 
         train_coerce(coercer, "15", Integer.class, fifteen);
 
+        train_skipIfBlank(required, false);
+        train_getValueType(required, Object.class);
         required.check(field, null, requiredFormatter, inputValue);
+
+        train_skipIfBlank(minLength, true);
+        train_getValueType(minLength, String.class);
         minLength.check(field, fifteen, minLengthFormatter, inputValue);
 
         replay();
@@ -320,6 +310,8 @@
         train_getMessageKey(validator, "key");
         train_getMessageFormatter(messages, "key", formatter);
 
+        train_skipIfBlank(validator, true);
+        train_getValueType(validator, Object.class);
         validator.check(field, five, formatter, inputValue);
 
         replay();

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/validator/MinLengthTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/validator/MinLengthTest.java?view=diff&rev=499061&r1=499060&r2=499061
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/validator/MinLengthTest.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/validator/MinLengthTest.java
 Tue Jan 23 07:55:28 2007
@@ -1,3 +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.
+
 package org.apache.tapestry.validator;
 
 import org.apache.tapestry.Field;
@@ -8,20 +22,6 @@
 
 public class MinLengthTest extends InternalBaseTestCase
 {
-    @Test
-    public void blank_value_is_ignored() throws Exception
-    {
-        Field field = newField();
-        MessageFormatter formatter = newMessageFormatter();
-
-        replay();
-
-        MinLength validator = new MinLength();
-
-        validator.check(field, 5, formatter, "");
-
-        verify();
-    }
 
     @Test
     public void long_enough() throws Exception


Reply via email to