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 2005/08/18 23:56:07 UTC

cvs commit: jakarta-tapestry/framework/src/java/org/apache/tapestry AbstractComponent.java

hlship      2005/08/18 14:56:07

  Modified:    framework/src/test/org/apache/tapestry/form/translator
                        TestStringTranslator.java TestNumberTranslator.java
                        TestDateTranslator.java
               .        status.xml
               framework/src/java/org/apache/tapestry/form/translator
                        AbstractTranslator.java StringTranslator.java
                        NumberTranslator.java FormatTranslator.java
                        Translator.java
               framework/src/test/org/apache/tapestry/form
                        TestValidationMessages.java
                        TestTranslatedFieldSupportImpl.java
                        FormComponentContributorTestCase.java
               framework/src/java/org/apache/tapestry/form
                        AbstractFormComponentContributor.java
                        TranslatedFieldSupportImpl.java
                        ValidationMessages.java ValidationMessagesImpl.java
               framework/src/java/org/apache/tapestry
                        AbstractComponent.java
  Log:
  TAPESTRY-563: NumberValidator should allow a special case for rendering zero
  
  Revision  Changes    Path
  1.5       +47 -28    jakarta-tapestry/framework/src/test/org/apache/tapestry/form/translator/TestStringTranslator.java
  
  Index: TestStringTranslator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/form/translator/TestStringTranslator.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- TestStringTranslator.java	18 Jun 2005 12:54:40 -0000	1.4
  +++ TestStringTranslator.java	18 Aug 2005 21:56:06 -0000	1.5
  @@ -14,7 +14,12 @@
   
   package org.apache.tapestry.form.translator;
   
  +import org.apache.tapestry.IMarkupWriter;
  +import org.apache.tapestry.IRequestCycle;
  +import org.apache.tapestry.form.FormComponentContributorContext;
  +import org.apache.tapestry.form.IFormComponent;
   import org.apache.tapestry.valid.ValidatorException;
  +import org.easymock.MockControl;
   
   /**
    * Test case for {@link StringTranslator}.
  @@ -29,9 +34,9 @@
       public void testFormat()
       {
           replay();
  -        
  -        String result = _translator.format(_component, "Test this");
  -        
  +
  +        String result = _translator.format(_component, null, "Test this");
  +
           assertEquals("Test this", result);
   
           verify();
  @@ -40,9 +45,9 @@
       public void testNullFormat()
       {
           replay();
  -        
  -        String result = _translator.format(_component, null);
  -        
  +
  +        String result = _translator.format(_component, null, null);
  +
           assertEquals("", result);
   
           verify();
  @@ -51,10 +56,10 @@
       public void testParse()
       {
           replay();
  -        
  +
           try
           {
  -            String result = (String) _translator.parse(_component, "Test this");
  +            String result = (String) _translator.parse(_component, null, "Test this");
   
               assertEquals("Test this", result);
           }
  @@ -71,12 +76,12 @@
       public void testTrimmedParse()
       {
           _translator.setTrim(true);
  -        
  +
           replay();
  -        
  +
           try
           {
  -            String result = (String) _translator.parse(_component, " Test this ");
  +            String result = (String) _translator.parse(_component, null, " Test this ");
   
               assertEquals("Test this", result);
           }
  @@ -93,10 +98,10 @@
       public void testEmptyParse()
       {
           replay();
  -        
  +
           try
           {
  -            String result = (String) _translator.parse(_component, "");
  +            String result = (String) _translator.parse(_component, null, "");
   
               assertEquals(null, result);
           }
  @@ -113,12 +118,12 @@
       public void testCustomEmptyParse()
       {
           _translator.setEmpty("");
  -        
  +
           replay();
  -        
  +
           try
           {
  -            String result = (String) _translator.parse(_component, "");
  +            String result = (String) _translator.parse(_component, null, "");
   
               assertEquals("", result);
           }
  @@ -131,25 +136,39 @@
               verify();
           }
       }
  -    
  +
       public void testRenderContribution()
       {
           replay();
  -        
  +
           _translator.renderContribution(null, _cycle, null, _component);
  -        
  +
           verify();
       }
  -    
  +
       public void testTrimRenderContribution()
       {
  -        _translator.setTrim(true);
  -        trim();
  -        
  -        replay();
  -        
  -        _translator.renderContribution(null, _cycle, null, _component);
  -        
  -        verify();
  +        IMarkupWriter writer = newWriter();
  +        IRequestCycle cycle = newCycle();
  +
  +        MockControl contextc = newControl(FormComponentContributorContext.class);
  +        FormComponentContributorContext context = (FormComponentContributorContext) contextc
  +                .getMock();
  +
  +        context.getFieldDOM();
  +        contextc.setReturnValue("field_dom");
  +
  +        context.addSubmitListener("trim(field_dom)");
  +
  +        IFormComponent field = newField();
  +
  +        replayControls();
  +
  +        Translator t = new StringTranslator("trim");
  +
  +        t.renderContribution(writer, cycle, context, field);
  +
  +        verifyControls();
       }
  +
   }
  
  
  
  1.9       +197 -184  jakarta-tapestry/framework/src/test/org/apache/tapestry/form/translator/TestNumberTranslator.java
  
  Index: TestNumberTranslator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/form/translator/TestNumberTranslator.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- TestNumberTranslator.java	8 Aug 2005 17:23:14 -0000	1.8
  +++ TestNumberTranslator.java	18 Aug 2005 21:56:06 -0000	1.9
  @@ -16,276 +16,289 @@
   
   import java.util.Locale;
   
  -import org.apache.tapestry.form.FormEventType;
  +import org.apache.tapestry.IMarkupWriter;
  +import org.apache.tapestry.IRequestCycle;
  +import org.apache.tapestry.form.FormComponentContributorContext;
  +import org.apache.tapestry.form.FormComponentContributorTestCase;
  +import org.apache.tapestry.form.IFormComponent;
  +import org.apache.tapestry.form.ValidationMessages;
   import org.apache.tapestry.valid.ValidationConstraint;
  +import org.apache.tapestry.valid.ValidationStrings;
   import org.apache.tapestry.valid.ValidatorException;
  +import org.easymock.MockControl;
   
  -public class TestNumberTranslator extends TranslatorTestCase
  +/**
  + * Tests for {@link org.apache.tapestry.form.translator.NumberTranslator}
  + * 
  + * @author Howard Lewis Ship
  + * @since 4.0
  + */
  +public class TestNumberTranslator extends FormComponentContributorTestCase
   {
       public void testDefaultFormat()
       {
           NumberTranslator translator = new NumberTranslator();
  -        
  +
           testFormat(translator, new Integer(10), "10");
       }
  -    
  +
  +    public void testOmitZero()
  +    {
  +        NumberTranslator translator = new NumberTranslator("pattern=0.00");
  +
  +        testFormat(translator, new Integer(0), "");
  +    }
  +
  +    public void testOmitZeroOff()
  +    {
  +        NumberTranslator translator = new NumberTranslator("!omitZero,pattern=0.00");
  +
  +        testFormat(translator, new Integer(0), "0.00");
  +    }
  +
       public void testCustomFormat()
       {
           NumberTranslator translator = new NumberTranslator();
  -        
  +
           translator.setPattern("$#0.00");
  -        
  +
           testFormat(translator, new Integer(10), "$10.00");
       }
  -    
  +
       public void testInitializerFormat()
       {
           NumberTranslator translator = new NumberTranslator("pattern=#0%");
  -        
  +
           testFormat(translator, new Double(0.10), "10%");
       }
  -    
  +
       public void testFormat(Translator translator, Number number, String expected)
       {
  -        _component.getPage();
  -        _componentControl.setReturnValue(_page);
  -        
  -        _page.getLocale();
  -        _pageControl.setReturnValue(Locale.US);
  -        
  -        replay();
  -        
  -        String result = translator.format(_component, number);
  -        
  -        assertEquals(expected, result);
  +        IFormComponent field = newField();
   
  -        verify();
  +        String result = translator.format(field, Locale.ENGLISH, number);
  +
  +        assertEquals(expected, result);
       }
   
       public void testNullFormat()
       {
           NumberTranslator translator = new NumberTranslator();
  -        
  +
           replay();
  -        
  -        String result = translator.format(_component, null);
  -        
  +
  +        String result = translator.format(_component, null, null);
  +
           assertEquals("", result);
   
           verify();
       }
   
  -    public void testDefaultParse()
  +    public void testDefaultParse() throws Exception
       {
           NumberTranslator translator = new NumberTranslator();
  -        
  +
           testParse(translator, "0.1", new Double(0.1));
       }
  -    
  -    public void testCustomParse()
  +
  +    public void testCustomParse() throws Exception
       {
           NumberTranslator translator = new NumberTranslator();
  -        
  +
           translator.setPattern("#%");
  -        
  +
           testParse(translator, "10%", new Double(0.1));
       }
  -    
  -    public void testTrimmedParse()
  +
  +    public void testTrimmedParse() throws Exception
       {
           NumberTranslator translator = new NumberTranslator();
  -        
  +
           translator.setTrim(true);
  -        
  +
           testParse(translator, " 100 ", new Long(100));
       }
   
  -    private void testParse(Translator translator, String number, Number expected)
  +    private void testParse(Translator translator, String number, Number expected) throws Exception
       {
  -        _component.getPage();
  -        _componentControl.setReturnValue(_page);
  -        
  -        _page.getLocale();
  -        _pageControl.setReturnValue(Locale.US);
  -        
  -        replay();
  -        
  -        try
  -        {
  -            Number result = (Number) translator.parse(_component, number);
  +        IFormComponent field = newField();
  +
  +        MockControl messagesc = newControl(ValidationMessages.class);
  +        ValidationMessages messages = (ValidationMessages) messagesc.getMock();
  +
  +        trainGetLocale(messagesc, messages, Locale.ENGLISH);
  +
  +        replayControls();
  +
  +        Number result = (Number) translator.parse(field, messages, number);
  +
  +        assertEquals(expected, result);
  +
  +        verifyControls();
   
  -            assertEquals(expected, result);
  -        }
  -        catch (ValidatorException e)
  -        {
  -            unreachable();
  -        }
  -        finally
  -        {
  -            verify();
  -        }
       }
  -    
  +
       public void testFailedParseDefaultMessage()
       {
           NumberTranslator translator = new NumberTranslator();
  -        
  -        testFailedParse(translator, "Field Name must be a numeric value.");
  +
  +        testFailedParse(translator, null);
       }
  -    
  +
       public void testFailedParseCustomMessage()
       {
           NumberTranslator translator = new NumberTranslator();
  -        
  +
           String message = "Field Name is an invalid number.";
  -        
  +
           translator.setMessage(message);
  -        
  +
           testFailedParse(translator, message);
       }
   
  -    private void testFailedParse(Translator translator, String message)
  +    private void testFailedParse(Translator translator, String messageOverride)
       {
  -        _component.getPage();
  -        _componentControl.setReturnValue(_page);
  +        IFormComponent field = newField("Number Field");
  +
  +        MockControl messagesc = newControl(ValidationMessages.class);
  +        ValidationMessages messages = (ValidationMessages) messagesc.getMock();
  +
  +        trainGetLocale(messagesc, messages, Locale.ENGLISH);
  +        trainGetLocale(messagesc, messages, Locale.ENGLISH);
  +
  +        trainBuildMessage(
  +                messagesc,
  +                messages,
  +                messageOverride,
  +                ValidationStrings.INVALID_NUMBER,
  +                new Object[]
  +                { "Number Field", "#" },
  +                "invalid number");
  +
  +        replayControls();
   
  -        _page.getLocale();
  -        _pageControl.setReturnValue(Locale.US);
  -        
  -        _component.getPage();
  -        _componentControl.setReturnValue(_page);
  -
  -        _page.getLocale();
  -        _pageControl.setReturnValue(Locale.US);
  -        
  -        _component.getDisplayName();
  -        _componentControl.setReturnValue("Field Name");
  -        
  -        replay();
  -        
           try
           {
  -            System.out.println(translator.parse(_component, "Bad-Number"));
  -            
  +            System.out.println(translator.parse(field, messages, "Bad-Number"));
  +
               unreachable();
           }
           catch (ValidatorException e)
           {
  -            assertEquals(message, e.getMessage());
  +            assertEquals("invalid number", e.getMessage());
               assertEquals(ValidationConstraint.NUMBER_FORMAT, e.getConstraint());
           }
  -        finally
  -        {
  -            verify();
  -        }
  +
  +        verifyControls();
       }
  -    
  +
       public void testRenderContribution()
       {
           NumberTranslator translator = new NumberTranslator();
  -        
  -        addScript("/org/apache/tapestry/form/translator/NumberTranslator.js");
  -        
  -        _component.getPage();
  -        _componentControl.setReturnValue(_page);
  -        
  -        _page.getLocale();
  -        _pageControl.setReturnValue(Locale.US);
  -        
  -        _component.getDisplayName();
  -        _componentControl.setReturnValue("Field Label");
  -        
  -        _component.getForm();
  -        _componentControl.setReturnValue(_form);
  -        
  -        _form.getName();
  -        _formControl.setReturnValue("formName");
  -        
  -        _component.getName();
  -        _componentControl.setReturnValue("fieldName");
  -        
  -        _form.addEventHandler(FormEventType.SUBMIT, "validate_number(event, document.formName.fieldName,'Field Label must be a numeric value.')");
  -        _formControl.setVoidCallable();
  -        
  -        replay();
  -        
  -        translator.renderContribution(null, _cycle, null, _component);
  -        
  -        verify();
  +
  +        IMarkupWriter writer = newWriter();
  +        IRequestCycle cycle = newCycle();
  +
  +        MockControl contextc = newControl(FormComponentContributorContext.class);
  +        FormComponentContributorContext context = (FormComponentContributorContext) contextc
  +                .getMock();
  +
  +        context.includeClasspathScript(translator.defaultScript());
  +
  +        trainGetLocale(contextc, context, Locale.ENGLISH);
  +
  +        trainBuildMessage(contextc, context, null, ValidationStrings.INVALID_NUMBER, new Object[]
  +        { "Number Field", "#" }, "invalid number message");
  +
  +        trainGetFieldDOM(contextc, context, "field_dom");
  +
  +        context.addSubmitListener("validate_number(event, field_dom, 'invalid number message')");
  +
  +        IFormComponent field = newField("Number Field");
  +
  +        replayControls();
  +
  +        translator.renderContribution(writer, cycle, context, field);
  +
  +        verifyControls();
       }
  -    
  +
       public void testMessageRenderContribution()
       {
           NumberTranslator translator = new NumberTranslator();
  -        
  -        // MessageFormat requires that single quotes be doubled if they are to be interpreted.
  -        
  -        translator.setMessage("You entered a bunk value for {0}. I should look like {1}. Watch out for ''this''!");
  -        
  -        addScript("/org/apache/tapestry/form/translator/NumberTranslator.js");
  -        
  -        _component.getPage();
  -        _componentControl.setReturnValue(_page);
  -        
  -        _page.getLocale();
  -        _pageControl.setReturnValue(Locale.US);
  -        
  -        _component.getDisplayName();
  -        _componentControl.setReturnValue("Field Label");
  -        
  -        _component.getForm();
  -        _componentControl.setReturnValue(_form);
  -        
  -        _form.getName();
  -        _formControl.setReturnValue("formName");
  -        
  -        _component.getName();
  -        _componentControl.setReturnValue("fieldName");
  -        
  -        _form.addEventHandler(FormEventType.SUBMIT, "validate_number(event, document.formName.fieldName,'You entered a bunk value for Field Label. I should look like #. Watch out for \\'this\\'!')");
  -        _formControl.setVoidCallable();
  -        
  -        replay();
  -        
  -        translator.renderContribution(null, _cycle, null, _component);
  -        
  -        verify();
  +
  +        String messageOverride = "You entered a bunk value for {0}. I should look like {1}. Watch out for ''this''!";
  +
  +        IMarkupWriter writer = newWriter();
  +        IRequestCycle cycle = newCycle();
  +
  +        MockControl contextc = newControl(FormComponentContributorContext.class);
  +        FormComponentContributorContext context = (FormComponentContributorContext) contextc
  +                .getMock();
  +
  +        context.includeClasspathScript(translator.defaultScript());
  +
  +        trainGetLocale(contextc, context, Locale.ENGLISH);
  +
  +        trainBuildMessage(
  +                contextc,
  +                context,
  +                messageOverride,
  +                ValidationStrings.INVALID_NUMBER,
  +                new Object[]
  +                { "Number Field", "#" },
  +                "Blah Blah 'Field Name' Blah.");
  +
  +        trainGetFieldDOM(contextc, context, "field_dom");
  +
  +        context
  +                .addSubmitListener("validate_number(event, field_dom, 'Blah Blah \\'Field Name\\' Blah.')");
  +
  +        IFormComponent field = newField("Number Field");
  +
  +        replayControls();
  +
  +        translator.setMessage(messageOverride);
  +
  +        translator.renderContribution(writer, cycle, context, field);
  +
  +        verifyControls();
       }
  -    
  +
       public void testTrimRenderContribution()
       {
           NumberTranslator translator = new NumberTranslator();
  -        
  +
  +        IMarkupWriter writer = newWriter();
  +        IRequestCycle cycle = newCycle();
  +
  +        MockControl contextc = newControl(FormComponentContributorContext.class);
  +        FormComponentContributorContext context = (FormComponentContributorContext) contextc
  +                .getMock();
  +
  +        context.includeClasspathScript(translator.defaultScript());
  +
  +        trainGetFieldDOM(contextc, context, "field_dom");
  +
  +        context.addSubmitListener("trim(field_dom)");
  +
  +        trainGetLocale(contextc, context, Locale.ENGLISH);
  +
  +        trainBuildMessage(contextc, context, null, ValidationStrings.INVALID_NUMBER, new Object[]
  +        { "Number Field", "#" }, "invalid number message");
  +
  +        trainGetFieldDOM(contextc, context, "field_dom");
  +
  +        context.addSubmitListener("validate_number(event, field_dom, 'invalid number message')");
  +
  +        IFormComponent field = newField("Number Field");
  +
  +        replayControls();
  +
           translator.setTrim(true);
  -        trim();
  -        
  -        addScript("/org/apache/tapestry/form/translator/NumberTranslator.js");
  -        
  -        _component.getPage();
  -        _componentControl.setReturnValue(_page);
  -        
  -        _page.getLocale();
  -        _pageControl.setReturnValue(Locale.US);
  -        
  -        _component.getDisplayName();
  -        _componentControl.setReturnValue("Field Label");
  -        
  -        _component.getForm();
  -        _componentControl.setReturnValue(_form);
  -        
  -        _form.getName();
  -        _formControl.setReturnValue("formName");
  -        
  -        _component.getName();
  -        _componentControl.setReturnValue("fieldName");
  -        
  -        _form.addEventHandler(FormEventType.SUBMIT, "validate_number(event, document.formName.fieldName,'Field Label must be a numeric value.')");
  -        _formControl.setVoidCallable();
  -        
  -        replay();
  -        
  -        translator.renderContribution(null, _cycle, null, _component);
  -        
  -        verify();
  +
  +        translator.renderContribution(writer, cycle, context, field);
  +
  +        verifyControls();
       }
   }
  
  
  
  1.7       +110 -105  jakarta-tapestry/framework/src/test/org/apache/tapestry/form/translator/TestDateTranslator.java
  
  Index: TestDateTranslator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/form/translator/TestDateTranslator.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- TestDateTranslator.java	5 Aug 2005 04:54:49 -0000	1.6
  +++ TestDateTranslator.java	18 Aug 2005 21:56:06 -0000	1.7
  @@ -18,8 +18,15 @@
   import java.util.Date;
   import java.util.Locale;
   
  +import org.apache.tapestry.IMarkupWriter;
  +import org.apache.tapestry.IRequestCycle;
  +import org.apache.tapestry.form.FormComponentContributorContext;
  +import org.apache.tapestry.form.IFormComponent;
  +import org.apache.tapestry.form.ValidationMessages;
   import org.apache.tapestry.valid.ValidationConstraint;
  +import org.apache.tapestry.valid.ValidationStrings;
   import org.apache.tapestry.valid.ValidatorException;
  +import org.easymock.MockControl;
   
   /**
    * Test case for {@link DateTranslator}.
  @@ -44,96 +51,92 @@
           _calendar.set(Calendar.YEAR, year);
           _calendar.set(Calendar.MONTH, month);
           _calendar.set(Calendar.DATE, day);
  -        
  +
           return _calendar.getTime();
       }
  -    
  +
       public void testDefaultFormat()
       {
           DateTranslator translator = new DateTranslator();
           testFormat(translator, buildDate(1976, Calendar.OCTOBER, 29), "10/29/1976");
       }
  -    
  +
       public void testCustomFormat()
       {
           DateTranslator translator = new DateTranslator();
   
           translator.setPattern("yyyy-MM-dd");
  -        
  +
           testFormat(translator, buildDate(1976, Calendar.OCTOBER, 29), "1976-10-29");
       }
  -    
  +
       public void testInitializerFormat()
       {
           DateTranslator translator = new DateTranslator("pattern=yyyy-MM-dd");
  -        
  +
           testFormat(translator, buildDate(1976, Calendar.OCTOBER, 29), "1976-10-29");
       }
  -    
  +
       public void testFormat(DateTranslator translator, Date date, String expected)
       {
  -        _component.getPage();
  -        _componentControl.setReturnValue(_page);
  -        
  -        _page.getLocale();
  -        _pageControl.setReturnValue(Locale.US);
  -        
  -        replay();
  -        
  -        String result = translator.format(_component, date);
  -        
  +        IFormComponent field = newField();
  +
  +        replayControls();
  +
  +        String result = translator.format(field, Locale.ENGLISH, date);
  +
           assertEquals(expected, result);
   
  -        verify();
  +        verifyControls();
       }
   
       public void testNullFormat()
       {
           DateTranslator translator = new DateTranslator();
  -        
  +
           replay();
  -        
  -        String result = translator.format(_component, null);
  -        
  +
  +        String result = translator.format(_component, null, null);
  +
           assertEquals("", result);
   
           verify();
       }
   
  -    public void testDefaultParse()
  +    public void testDefaultParse() throws Exception
       {
           DateTranslator translator = new DateTranslator();
  -        
  +
           testParse(translator, "10/29/1976", buildDate(1976, Calendar.OCTOBER, 29));
       }
  -    
  -    public void testCustomParse()
  +
  +    public void testCustomParse() throws Exception
       {
           DateTranslator translator = new DateTranslator();
  -        
  +
           translator.setPattern("yyyy-MM-dd");
  -        
  +
           testParse(translator, "1976-10-29", buildDate(1976, Calendar.OCTOBER, 29));
       }
  -    
  -    public void testTrimmedParse()
  +
  +    public void testTrimmedParse() throws Exception
       {
           DateTranslator translator = new DateTranslator();
  -        
  +
           translator.setTrim(true);
  -        
  +
           testParse(translator, " 10/29/1976 ", buildDate(1976, Calendar.OCTOBER, 29));
       }
  -    
  +
       public void testEmptyParse()
       {
           DateTranslator translator = new DateTranslator();
  -        
  +
           replay();
  -        
  +
           try
           {
  -            Date result = (Date) translator.parse(_component, "");
  +            Date result = (Date) translator.parse(_component, null, "");
   
               assertEquals(null, result);
           }
  @@ -147,108 +150,110 @@
           }
       }
   
  -    private void testParse(DateTranslator translator, String date, Date expected)
  +    private void testParse(DateTranslator translator, String date, Date expected) throws Exception
       {
  -        _component.getPage();
  -        _componentControl.setReturnValue(_page);
  -        
  -        _page.getLocale();
  -        _pageControl.setReturnValue(Locale.US);
  -        
  -        replay();
  -        
  -        try
  -        {
  -            Date result = (Date) translator.parse(_component, date);
  +        IFormComponent field = newField();
   
  -            assertEquals(expected, result);
  -        }
  -        catch (ValidatorException e)
  -        {
  -            unreachable();
  -        }
  -        finally
  -        {
  -            verify();
  -        }
  +        ValidationMessages messages = newValidationMessages(Locale.ENGLISH);
  +
  +        replayControls();
  +
  +        Date result = (Date) translator.parse(field, messages, date);
  +
  +        assertEquals(expected, result);
  +
  +        verifyControls();
       }
  -    
  -    public void testFailedParseDefaultMessage()
  +
  +    public void testFailedParseDefaultMessage() throws Exception
       {
           DateTranslator translator = new DateTranslator();
  -        
  -        testFailedParse(translator, "Invalid date format for Field Name.  Format is MM/DD/YYYY.");
  +
  +        testFailedParse(translator, null);
       }
  -    
  -    public void testFailedParseCustomMessage()
  +
  +    public void testFailedParseCustomMessage() throws Exception
       {
           DateTranslator translator = new DateTranslator();
           String message = "Field Name is an invalid date.";
  -        
  +
           translator.setMessage(message);
  -        
  +
           testFailedParse(translator, message);
       }
   
  -    private void testFailedParse(DateTranslator translator, String message)
  +    private void testFailedParse(DateTranslator translator, String overrideMessage)
  +            throws Exception
       {
  -        _component.getPage();
  -        _componentControl.setReturnValue(_page);
  +        IFormComponent field = newField("My Field");
  +
  +        MockControl messagesc = newControl(ValidationMessages.class);
  +        ValidationMessages messages = (ValidationMessages) messagesc.getMock();
  +
  +        trainGetLocale(messagesc, messages, Locale.ENGLISH);
  +        trainGetLocale(messagesc, messages, Locale.ENGLISH);
  +
  +        trainBuildMessage(
  +                messagesc,
  +                messages,
  +                overrideMessage,
  +                ValidationStrings.INVALID_DATE,
  +                new Object[]
  +                { "My Field", "MM/DD/YYYY" },
  +                "final message");
  +
  +        replayControls();
   
  -        _page.getLocale();
  -        _pageControl.setReturnValue(Locale.US);
  -        
  -        _component.getPage();
  -        _componentControl.setReturnValue(_page);
  -
  -        _page.getLocale();
  -        _pageControl.setReturnValue(Locale.US);
  -        
  -        _component.getDisplayName();
  -        _componentControl.setReturnValue("Field Name");
  -        
  -        replay();
  -        
           try
           {
  -            System.out.println(translator.parse(_component, "Bad-Date"));
  -            
  +            System.out.println(translator.parse(field, messages, "Bad-Date"));
  +
               unreachable();
           }
           catch (ValidatorException e)
           {
  -            assertEquals(message, e.getMessage());
  +            assertEquals("final message", e.getMessage());
               assertEquals(ValidationConstraint.DATE_FORMAT, e.getConstraint());
           }
  -        finally
  -        {
  -            verify();
  -        }
  +
  +        verifyControls();
       }
  -    
  +
       public void testRenderContribution()
       {
           DateTranslator translator = new DateTranslator();
  -        
  +
           replay();
  -        
  +
           translator.renderContribution(null, _cycle, null, _component);
  -        
  +
           verify();
       }
  -    
  +
       public void testTrimRenderContribution()
       {
  -        DateTranslator translator = new DateTranslator();
  -        
  -        translator.setTrim(true);
  +        IMarkupWriter writer = newWriter();
  +        IRequestCycle cycle = newCycle();
  +
  +        IFormComponent field = newField();
  +
  +        MockControl contextc = newControl(FormComponentContributorContext.class);
  +        FormComponentContributorContext context = (FormComponentContributorContext) contextc
  +                .getMock();
  +
  +        context.getFieldDOM();
  +        contextc.setReturnValue("field_dom");
  +
  +        context.addSubmitListener("trim(field_dom)");
  +
  +        replayControls();
  +
  +        DateTranslator dt = new DateTranslator();
  +        dt.setTrim(true);
  +
  +        dt.renderContribution(writer, cycle, context, field);
  +
  +        verifyControls();
   
  -        trim();
  -        
  -        replay();
  -        
  -        translator.renderContribution(null, _cycle, null, _component);
  -        
  -        verify();
       }
   }
  
  
  
  1.218     +1 -0      jakarta-tapestry/status.xml
  
  Index: status.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/status.xml,v
  retrieving revision 1.217
  retrieving revision 1.218
  diff -u -r1.217 -r1.218
  --- status.xml	16 Aug 2005 23:51:33 -0000	1.217
  +++ status.xml	18 Aug 2005 21:56:06 -0000	1.218
  @@ -66,6 +66,7 @@
         <action type="fix" dev="HLS" fixes-bug="TAPESTRY-437" due-to="Nick Westgate">Select component exception when used twice on a page</action>
         <action type="fix" dev="HLS" fixes-bug="TAPESTRY-568">Engine services should use getName() when constructing thier parameter maps so that they may be more easily subclassed and extended</action>
         <action type="fix" dev="HLS" fixes-bug="TAPESTRY-566">Annotations jar on classpath breaks Tapestry if not running on JDK 1.5</action>
  +      <action type="fix" dev="HLS" fixes-bug="TAPESTRY-563">NumberValidator should allow a special case for rendering zero</action>
       </release>
       <release version="4.0-beta-4" date="Aug 10 2005">
         <action type="fix" dev="HLS">Add getComponent() method to IComponent.</action>
  
  
  
  1.5       +22 -25    jakarta-tapestry/framework/src/java/org/apache/tapestry/form/translator/AbstractTranslator.java
  
  Index: AbstractTranslator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/translator/AbstractTranslator.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- AbstractTranslator.java	18 Jun 2005 12:54:39 -0000	1.4
  +++ AbstractTranslator.java	18 Aug 2005 21:56:06 -0000	1.5
  @@ -14,17 +14,15 @@
   
   package org.apache.tapestry.form.translator;
   
  -import java.text.MessageFormat;
   import java.util.Locale;
   
   import org.apache.hivemind.HiveMind;
  -import org.apache.tapestry.IForm;
   import org.apache.tapestry.IMarkupWriter;
   import org.apache.tapestry.IRequestCycle;
   import org.apache.tapestry.form.AbstractFormComponentContributor;
   import org.apache.tapestry.form.FormComponentContributorContext;
   import org.apache.tapestry.form.IFormComponent;
  -import org.apache.tapestry.valid.ValidationStrings;
  +import org.apache.tapestry.form.ValidationMessages;
   import org.apache.tapestry.valid.ValidatorException;
   
   /**
  @@ -53,44 +51,45 @@
   
       /**
        * @see org.apache.tapestry.form.translator.Translator#format(org.apache.tapestry.form.IFormComponent,
  -     *      java.lang.Object)
  +     *      Locale, java.lang.Object)
        */
  -    public String format(IFormComponent field, Object object)
  +    public String format(IFormComponent field, Locale locale, Object object)
       {
  -        return (object != null) ? formatObject(field, object) : "";
  +        if (object == null)
  +            return "";
  +
  +        return formatObject(field, locale, object);
       }
   
       /**
        * @see org.apache.tapestry.form.translator.Translator#parse(org.apache.tapestry.form.IFormComponent,
  -     *      java.lang.String)
  +     *      ValidationMessages, java.lang.String)
        */
  -    public Object parse(IFormComponent field, String text) throws ValidatorException
  +    public Object parse(IFormComponent field, ValidationMessages messages, String text)
  +            throws ValidatorException
       {
           String value = _trim ? text.trim() : text;
   
  -        return HiveMind.isBlank(value) ? getEmpty() : parseText(field, value);
  +        return HiveMind.isBlank(value) ? getEmpty() : parseText(field, messages, value);
       }
   
  -    protected abstract String formatObject(IFormComponent field, Object object);
  +    protected abstract String formatObject(IFormComponent field, Locale locale, Object object);
   
  -    protected abstract Object parseText(IFormComponent field, String text)
  -            throws ValidatorException;
  +    protected abstract Object parseText(IFormComponent field, ValidationMessages messages,
  +            String text) throws ValidatorException;
   
       protected Object getEmpty()
       {
           return null;
       }
   
  -    protected String buildMessage(IFormComponent field, String key)
  +    protected String buildMessage(ValidationMessages messages, IFormComponent field, String key)
       {
  -        Locale locale = field.getPage().getLocale();
  -
  -        String pattern = (_message == null) ? ValidationStrings.getMessagePattern(key, locale)
  -                : _message;
  +        String label = field.getDisplayName();
   
  -        String name = field.getDisplayName();
  +        Object[] parameters = getMessageParameters(messages.getLocale(), label);
   
  -        return MessageFormat.format(pattern, getMessageParameters(locale, name));
  +        return messages.formatValidationMessage(_message, key, parameters);
       }
   
       protected Object[] getMessageParameters(Locale locale, String label)
  @@ -103,19 +102,17 @@
        * @see org.apache.tapestry.form.FormComponentContributor#renderContribution(org.apache.tapestry.IRequestCycle,
        *      org.apache.tapestry.form.IFormComponent)
        */
  -    public void renderContribution(IMarkupWriter writer, IRequestCycle cycle, FormComponentContributorContext context, IFormComponent field)
  +    public void renderContribution(IMarkupWriter writer, IRequestCycle cycle,
  +            FormComponentContributorContext context, IFormComponent field)
       {
           super.renderContribution(writer, cycle, context, field);
   
           if (_trim)
  -        {
  -            IForm form = field.getForm();
  -
  -            addSubmitHandler(form, "trim(document." + form.getName() + "." + field.getName() + ")");
  -        }
  +            context.addSubmitListener("trim(" + context.getFieldDOM() + ")");
       }
   
       public boolean isTrim()
  +
       {
           return _trim;
       }
  
  
  
  1.4       +11 -5     jakarta-tapestry/framework/src/java/org/apache/tapestry/form/translator/StringTranslator.java
  
  Index: StringTranslator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/translator/StringTranslator.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- StringTranslator.java	16 Jun 2005 20:57:10 -0000	1.3
  +++ StringTranslator.java	18 Aug 2005 21:56:06 -0000	1.4
  @@ -14,7 +14,11 @@
   
   package org.apache.tapestry.form.translator;
   
  +import java.util.Locale;
  +
  +import org.apache.hivemind.util.PropertyUtils;
   import org.apache.tapestry.form.IFormComponent;
  +import org.apache.tapestry.form.ValidationMessages;
   
   /**
    * A trivial {@link Translator} implementation. By default, empty text submissions are interpretted
  @@ -36,23 +40,25 @@
   
       public StringTranslator(String initializer)
       {
  -        super(initializer);
  +        PropertyUtils.configureProperties(this, initializer);
       }
   
       /**
        * @see org.apache.tapestry.form.translator.AbstractTranslator#parseText(org.apache.tapestry.form.IFormComponent,
  -     *      java.lang.String)
  +     *      ValidationMessages, java.lang.String)
        */
  -    protected Object parseText(IFormComponent field, String text)
  +    protected Object parseText(IFormComponent field, ValidationMessages messages, String text)
       {
  +        // TODO: Do something with _empty here?
  +
           return text;
       }
   
       /**
        * @see org.apache.tapestry.form.translator.AbstractTranslator#formatObject(org.apache.tapestry.form.IFormComponent,
  -     *      java.lang.Object)
  +     *      Locale, java.lang.Object)
        */
  -    protected String formatObject(IFormComponent field, Object object)
  +    protected String formatObject(IFormComponent field, Locale locale, Object object)
       {
           return object.toString();
       }
  
  
  
  1.8       +38 -9     jakarta-tapestry/framework/src/java/org/apache/tapestry/form/translator/NumberTranslator.java
  
  Index: NumberTranslator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/translator/NumberTranslator.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- NumberTranslator.java	8 Aug 2005 17:23:14 -0000	1.7
  +++ NumberTranslator.java	18 Aug 2005 21:56:06 -0000	1.8
  @@ -19,8 +19,8 @@
   import java.text.Format;
   import java.util.Locale;
   
  +import org.apache.hivemind.util.PropertyUtils;
   import org.apache.hivemind.util.StringUtils;
  -import org.apache.tapestry.IForm;
   import org.apache.tapestry.IMarkupWriter;
   import org.apache.tapestry.IRequestCycle;
   import org.apache.tapestry.form.FormComponentContributorContext;
  @@ -36,15 +36,31 @@
    */
   public class NumberTranslator extends FormatTranslator
   {
  +    private boolean _omitZero = true;
   
       public NumberTranslator()
       {
       }
   
  +    @Override
  +    protected String formatObject(IFormComponent field, Locale locale, Object object)
  +    {
  +        Number number = (Number) object;
  +
  +        if (_omitZero)
  +        {
  +            if (number.doubleValue() == 0)
  +
  +                return "";
  +        }
  +
  +        return super.formatObject(field, locale, object);
  +    }
  +
       // Needed until HIVEMIND-134 fix is available
       public NumberTranslator(String initializer)
       {
  -        super(initializer);
  +        PropertyUtils.configureProperties(this, initializer);
       }
   
       /**
  @@ -98,21 +114,22 @@
   
       /**
        * @see org.apache.tapestry.form.FormComponentContributor#renderContribution(org.apache.tapestry.IMarkupWriter,
  -     *      org.apache.tapestry.IRequestCycle, FormComponentContributorContext, org.apache.tapestry.form.IFormComponent)
  +     *      org.apache.tapestry.IRequestCycle, FormComponentContributorContext,
  +     *      org.apache.tapestry.form.IFormComponent)
        */
  -    public void renderContribution(IMarkupWriter writer, IRequestCycle cycle, FormComponentContributorContext context, IFormComponent field)
  +    public void renderContribution(IMarkupWriter writer, IRequestCycle cycle,
  +            FormComponentContributorContext context, IFormComponent field)
       {
           super.renderContribution(writer, cycle, context, field);
   
  -        String message = buildMessage(field, getMessageKey());
  -        IForm form = field.getForm();
  +        String message = buildMessage(context, field, getMessageKey());
   
           // Escape backslashes and single quotes in the message
           message = StringUtils.replace(message, "\\", "\\\\");
           message = StringUtils.replace(message, "'", "\\'");
  -        
  -        addSubmitHandler(form, "validate_number(event, document." + form.getName() + "."
  -                + field.getName() + ",'" + message + "')");
  +
  +        context.addSubmitListener("validate_number(event, " + context.getFieldDOM() + ", '"
  +                + message + "')");
       }
   
       /**
  @@ -122,4 +139,16 @@
       {
           return ValidationConstraint.NUMBER_FORMAT;
       }
  +
  +    /**
  +     * If true (which is the default for the property), then values that are 0 are rendered to an
  +     * empty string, not "0" or "0.00". This is useful in most cases where the field is optional; it
  +     * allow the field to render blank when no value is present.
  +     */
  +
  +    public void setOmitZero(boolean omitZero)
  +    {
  +        _omitZero = omitZero;
  +    }
  +
   }
  
  
  
  1.6       +16 -12    jakarta-tapestry/framework/src/java/org/apache/tapestry/form/translator/FormatTranslator.java
  
  Index: FormatTranslator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/translator/FormatTranslator.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- FormatTranslator.java	5 Aug 2005 04:54:49 -0000	1.5
  +++ FormatTranslator.java	18 Aug 2005 21:56:06 -0000	1.6
  @@ -19,7 +19,9 @@
   import java.util.Locale;
   
   import org.apache.hivemind.HiveMind;
  +import org.apache.hivemind.util.PropertyUtils;
   import org.apache.tapestry.form.IFormComponent;
  +import org.apache.tapestry.form.ValidationMessages;
   import org.apache.tapestry.valid.ValidationConstraint;
   import org.apache.tapestry.valid.ValidatorException;
   
  @@ -37,33 +39,35 @@
   
       /**
        * @see org.apache.tapestry.form.translator.AbstractTranslator#formatObject(org.apache.tapestry.form.IFormComponent,
  -     *      java.lang.Object)
  +     *      Locale, java.lang.Object)
        */
  -    protected String formatObject(IFormComponent field, Object object)
  +    protected String formatObject(IFormComponent field, Locale locale, Object object)
       {
           // Get a new format each time, because (a) have to account for locale and (b) formatters are
           // not thread safe.
   
  -        Format format = getFormat(field.getPage().getLocale());
  +        Format format = getFormat(locale);
   
           return format.format(object);
       }
   
       /**
        * @see org.apache.tapestry.form.translator.AbstractTranslator#parseText(org.apache.tapestry.form.IFormComponent,
  -     *      java.lang.String)
  +     *      ValidationMessages, java.lang.String)
        */
  -    protected Object parseText(IFormComponent field, String text) throws ValidatorException
  +    protected Object parseText(IFormComponent field, ValidationMessages messages, String text)
  +            throws ValidatorException
       {
  -        Format format = getFormat(field.getPage().getLocale());
  +        Format format = getFormat(messages.getLocale());
   
           try
           {
               return format.parseObject(text);
           }
  -        catch (ParseException e)
  +        catch (ParseException ex)
           {
  -            throw new ValidatorException(buildMessage(field, getMessageKey()), getConstraint());
  +            throw new ValidatorException(buildMessage(messages, field, getMessageKey()),
  +                    getConstraint());
           }
       }
   
  @@ -85,17 +89,17 @@
   
       public FormatTranslator()
       {
  -    	_pattern = defaultPattern();
  +        _pattern = defaultPattern();
       }
   
       // Needed until HIVEMIND-134 fix is available
       public FormatTranslator(String initializer)
       {
  -        super(initializer);
  -        
  +        PropertyUtils.configureProperties(this, initializer);
  +
           if (HiveMind.isBlank(_pattern))
           {
  -        	_pattern = defaultPattern();
  +            _pattern = defaultPattern();
           }
       }
   }
  
  
  
  1.4       +7 -2      jakarta-tapestry/framework/src/java/org/apache/tapestry/form/translator/Translator.java
  
  Index: Translator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/translator/Translator.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Translator.java	18 Jun 2005 18:09:14 -0000	1.3
  +++ Translator.java	18 Aug 2005 21:56:06 -0000	1.4
  @@ -14,8 +14,11 @@
   
   package org.apache.tapestry.form.translator;
   
  +import java.util.Locale;
  +
   import org.apache.tapestry.form.IFormComponent;
   import org.apache.tapestry.form.FormComponentContributor;
  +import org.apache.tapestry.form.ValidationMessages;
   import org.apache.tapestry.valid.ValidatorException;
   
   /**
  @@ -30,16 +33,18 @@
       /**
        * Invoked during rendering to format an object (which may be null) into a text value (which
        * should not be null) appropriate for the specified field.
  +     * @param locale TODO
        */
  -    public String format(IFormComponent field, Object object);
  +    public String format(IFormComponent field, Locale locale, Object object);
   
       /**
        * Invoked during rewind to parse a submitted input value into an object suitable for the
        * specified component.
  +     * @param messages TODO
        * 
        * @return the parsed object
        * @throws ValidatorException
        *             if the specified text could not be parsed into an object.
        */
  -    public Object parse(IFormComponent field, String value) throws ValidatorException;
  +    public Object parse(IFormComponent field, ValidationMessages messages, String value) throws ValidatorException;
   }
  
  
  
  1.4       +13 -0     jakarta-tapestry/framework/src/test/org/apache/tapestry/form/TestValidationMessages.java
  
  Index: TestValidationMessages.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/form/TestValidationMessages.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TestValidationMessages.java	10 Aug 2005 06:02:50 -0000	1.3
  +++ TestValidationMessages.java	18 Aug 2005 21:56:06 -0000	1.4
  @@ -60,6 +60,19 @@
           verifyControls();
       }
   
  +    public void testGetLocale()
  +    {
  +        IFormComponent field = newField();
  +
  +        ValidationMessages m = new ValidationMessagesImpl(field, Locale.ENGLISH);
  +
  +        replayControls();
  +
  +        assertSame(Locale.ENGLISH, m.getLocale());
  +
  +        verifyControls();
  +    }
  +
       public void testMessageOverride()
       {
           IFormComponent field = newField();
  
  
  
  1.2       +109 -84   jakarta-tapestry/framework/src/test/org/apache/tapestry/form/TestTranslatedFieldSupportImpl.java
  
  Index: TestTranslatedFieldSupportImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/form/TestTranslatedFieldSupportImpl.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TestTranslatedFieldSupportImpl.java	10 Aug 2005 06:02:50 -0000	1.1
  +++ TestTranslatedFieldSupportImpl.java	18 Aug 2005 21:56:06 -0000	1.2
  @@ -34,6 +34,7 @@
   import org.apache.tapestry.valid.IValidationDelegate;
   import org.apache.tapestry.valid.ValidatorException;
   import org.easymock.MockControl;
  +import org.easymock.internal.AlwaysMatcher;
   
   /**
    * Test case for {@link TranslatedFieldSupportImpl}.
  @@ -53,7 +54,7 @@
   
           return tl;
       }
  -    
  +
       private IRequestCycle newCycle(IComponent component)
       {
           MockControl cyclec = newControl(IRequestCycle.class);
  @@ -80,16 +81,16 @@
       public void testRenderContributionsClientValidationDisabled()
       {
           TranslatedFieldSupportImpl support = new TranslatedFieldSupportImpl();
  -        
  +
           MockControl fieldControl = newControl(TranslatedField.class);
           TranslatedField field = (TranslatedField) fieldControl.getMock();
  -        
  +
           MockControl formControl = newControl(IForm.class);
           IForm form = (IForm) formControl.getMock();
  -        
  +
           IMarkupWriter writer = newWriter();
           IRequestCycle cycle = newCycle();
  -        
  +
           field.getForm();
           fieldControl.setReturnValue(form);
   
  @@ -107,19 +108,19 @@
       {
           TranslatedFieldSupportImpl support = new TranslatedFieldSupportImpl();
           support.setThreadLocale(newThreadLocale());
  -        
  +
           MockControl fieldControl = newControl(TranslatedField.class);
           TranslatedField field = (TranslatedField) fieldControl.getMock();
  -        
  +
           MockControl formControl = newControl(IForm.class);
           IForm form = (IForm) formControl.getMock();
  -        
  +
           IMarkupWriter writer = newWriter();
           IRequestCycle cycle = newCycle(field);
  -        
  +
           MockControl translatorControl = newControl(Translator.class);
           Translator translator = (Translator) translatorControl.getMock();
  -        
  +
           field.getForm();
           fieldControl.setReturnValue(form);
   
  @@ -137,71 +138,84 @@
   
           field.getTranslator();
           fieldControl.setReturnValue(translator);
  -        
  -        translator.renderContribution(writer, cycle, new FormComponentContributorContextImpl(field), field);
  +
  +        translator.renderContribution(
  +                writer,
  +                cycle,
  +                new FormComponentContributorContextImpl(field),
  +                field);
           translatorControl.setMatcher(new AggregateArgumentsMatcher(new ArgumentMatcher[]
           { new EqualsMatcher(), new EqualsMatcher(), new TypeMatcher(), new EqualsMatcher() }));
  -        
  +
           replayControls();
   
           support.renderContributions(field, writer, cycle);
   
           verifyControls();
       }
  -    
  -    public void testFormat()
  +
  +    public void testFormat() throws Exception
       {
           TranslatedFieldSupportImpl support = new TranslatedFieldSupportImpl();
  -        
  +
           MockControl fieldControl = newControl(TranslatedField.class);
           TranslatedField field = (TranslatedField) fieldControl.getMock();
  -        
  +
           MockControl formControl = newControl(IForm.class);
           IForm form = (IForm) formControl.getMock();
  -        
  +
           MockControl delegateControl = newControl(IValidationDelegate.class);
           IValidationDelegate delegate = (IValidationDelegate) delegateControl.getMock();
  -        
  -        MockControl translatorControl = newControl(Translator.class);
  -        Translator translator = (Translator) translatorControl.getMock();
  +
  +        MockControl translatorc = newControl(Translator.class);
  +        Translator translator = (Translator) translatorc.getMock();
   
           Object object = new Object();
           String expected = "result";
   
           field.getForm();
           fieldControl.setReturnValue(form);
  -        
  +
           form.getDelegate();
           formControl.setReturnValue(delegate);
  -        
  +
           delegate.isInError();
           delegateControl.setReturnValue(false);
  -        
  +
           field.getTranslator();
           fieldControl.setReturnValue(translator);
  -        
  -        translator.format(field, object);
  -        translatorControl.setReturnValue(expected);
  -        
  +
  +        trainFormat(translatorc, translator, field, object, expected);
  +
  +        support.setThreadLocale(newThreadLocale());
  +
           replayControls();
  -        
  +
           String result = support.format(field, object);
  -        
  +
           verifyControls();
  -        
  +
           assertSame(expected, result);
       }
  -    
  +
  +    private void trainFormat(MockControl control, Translator translator, TranslatedField field,
  +            Object input, String result)
  +    {
  +
  +        translator.format(field, Locale.ENGLISH, input);
  +        control.setReturnValue(result);
  +    }
  +
       public void testFormatInError()
       {
           TranslatedFieldSupportImpl support = new TranslatedFieldSupportImpl();
  -        
  +
           MockControl fieldControl = newControl(TranslatedField.class);
           TranslatedField field = (TranslatedField) fieldControl.getMock();
  -        
  +
           MockControl formControl = newControl(IForm.class);
           IForm form = (IForm) formControl.getMock();
  -        
  +
           MockControl delegateControl = newControl(IValidationDelegate.class);
           IValidationDelegate delegate = (IValidationDelegate) delegateControl.getMock();
   
  @@ -209,38 +223,38 @@
   
           field.getForm();
           fieldControl.setReturnValue(form);
  -        
  +
           form.getDelegate();
           formControl.setReturnValue(delegate);
  -        
  +
           delegate.isInError();
           delegateControl.setReturnValue(true);
   
           delegate.getFieldInputValue();
           delegateControl.setReturnValue(expected);
  -        
  +
           replayControls();
  -        
  +
           String result = support.format(field, new Object());
  -        
  +
           verifyControls();
  -        
  +
           assertSame(expected, result);
       }
   
  -    public void testParse()
  +    public void testParse() throws Exception
       {
           TranslatedFieldSupportImpl support = new TranslatedFieldSupportImpl();
  -        
  +
           MockControl fieldControl = newControl(TranslatedField.class);
           TranslatedField field = (TranslatedField) fieldControl.getMock();
  -        
  +
           MockControl formControl = newControl(IForm.class);
           IForm form = (IForm) formControl.getMock();
  -        
  +
           MockControl delegateControl = newControl(IValidationDelegate.class);
           IValidationDelegate delegate = (IValidationDelegate) delegateControl.getMock();
  -        
  +
           MockControl translatorControl = newControl(Translator.class);
           Translator translator = (Translator) translatorControl.getMock();
   
  @@ -249,47 +263,55 @@
   
           field.getForm();
           fieldControl.setReturnValue(form);
  -        
  +
           form.getDelegate();
           formControl.setReturnValue(delegate);
  -        
  +
           delegate.recordFieldInputValue(text);
  -        
  +
           field.getTranslator();
           fieldControl.setReturnValue(translator);
  -        
  -        try
  -        {
  -            translator.parse(field, text);
  -            translatorControl.setReturnValue(expected);
  -            
  -            replayControls();
  -            
  -            Object result = support.parse(field, text);
  -            
  -            verifyControls();
  -            
  -            assertSame(expected, result);
  -        }
  -        catch (ValidatorException e)
  -        {
  -            unreachable();
  -        }
  +
  +        support.setThreadLocale(newThreadLocale());
  +
  +        trainParse(translatorControl, translator, field, text, expected);
  +
  +        replayControls();
  +
  +        Object result = support.parse(field, text);
  +
  +        verifyControls();
  +
  +        assertSame(expected, result);
  +
       }
   
  -    public void testParseFailed()
  +    private void trainParse(MockControl control, Translator translator, TranslatedField field,
  +            String text, Object result) throws ValidatorException
  +    {
  +        ValidationMessages messages = new ValidationMessagesImpl(field, Locale.ENGLISH);
  +
  +        translator.parse(field, messages, text);
  +        control.setMatcher(new AggregateArgumentsMatcher(new ArgumentMatcher[]
  +        { null, new TypeMatcher() }));
  +        control.setReturnValue(result);
  +    }
  +
  +    public void testParseFailed() throws Exception
       {
           TranslatedFieldSupportImpl support = new TranslatedFieldSupportImpl();
  -        
  +
  +        support.setThreadLocale(newThreadLocale());
  +
           MockControl fieldControl = newControl(TranslatedField.class);
           TranslatedField field = (TranslatedField) fieldControl.getMock();
  -        
  +
           MockControl formControl = newControl(IForm.class);
           IForm form = (IForm) formControl.getMock();
  -        
  +
           MockControl delegateControl = newControl(IValidationDelegate.class);
           IValidationDelegate delegate = (IValidationDelegate) delegateControl.getMock();
  -        
  +
           MockControl translatorControl = newControl(Translator.class);
           Translator translator = (Translator) translatorControl.getMock();
   
  @@ -297,32 +319,35 @@
   
           field.getForm();
           fieldControl.setReturnValue(form);
  -        
  +
           form.getDelegate();
           formControl.setReturnValue(delegate);
  -        
  +
           delegate.recordFieldInputValue(text);
  -        
  +
           field.getTranslator();
           fieldControl.setReturnValue(translator);
  -        
  +
           ValidatorException expected = new ValidatorException("Failure");
  -        
  +
  +        ValidationMessages messages = new ValidationMessagesImpl(field, Locale.ENGLISH);
  +
  +        translator.parse(field, messages, text);
  +        translatorControl.setMatcher(new AlwaysMatcher());
  +        translatorControl.setThrowable(expected);
  +
  +        replayControls();
  +
           try
           {
  -            translator.parse(field, text);
  -            translatorControl.setThrowable(expected);
  -
  -            replayControls();
  -            
               support.parse(field, text);
  -            
  +
               unreachable();
           }
           catch (ValidatorException e)
           {
               verifyControls();
  -            
  +
               assertSame(expected, e);
           }
       }
  
  
  
  1.5       +84 -13    jakarta-tapestry/framework/src/test/org/apache/tapestry/form/FormComponentContributorTestCase.java
  
  Index: FormComponentContributorTestCase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/form/FormComponentContributorTestCase.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- FormComponentContributorTestCase.java	16 Jun 2005 14:46:18 -0000	1.4
  +++ FormComponentContributorTestCase.java	18 Aug 2005 21:56:06 -0000	1.5
  @@ -14,14 +14,18 @@
   
   package org.apache.tapestry.form;
   
  +import java.util.Locale;
  +
   import org.apache.hivemind.util.ClasspathResource;
   import org.apache.tapestry.IEngine;
   import org.apache.tapestry.IForm;
  +import org.apache.tapestry.IMarkupWriter;
   import org.apache.tapestry.IPage;
   import org.apache.tapestry.IRequestCycle;
   import org.apache.tapestry.PageRenderSupport;
   import org.apache.tapestry.junit.TapestryTestCase;
   import org.easymock.MockControl;
  +import org.easymock.internal.ArrayMatcher;
   
   /**
    * Abstract test case for {@link FormComponentContributor}.
  @@ -34,28 +38,37 @@
       // Paul,
       //
       // Think you missed the newControl() and newMock() methods inherited from HiveMindTestCase.
  -    // Those exist to eliminate the need for all this stuff.  Instead, you create newFoo() methods that
  +    // Those exist to eliminate the need for all this stuff. Instead, you create newFoo() methods
  +    // that
       // create and initialize a Foo instance.
       // -- Howard
  -    
  +
       protected MockControl _componentControl = MockControl.createControl(IFormComponent.class);
  +
       protected IFormComponent _component = (IFormComponent) _componentControl.getMock();
   
       protected MockControl _pageControl = MockControl.createControl(IPage.class);
  +
       protected IPage _page = (IPage) _pageControl.getMock();
   
       protected MockControl _cycleControl = MockControl.createControl(IRequestCycle.class);
  +
       protected IRequestCycle _cycle = (IRequestCycle) _cycleControl.getMock();
  -    
  +
       protected MockControl _formControl = MockControl.createControl(IForm.class);
  +
       protected IForm _form = (IForm) _formControl.getMock();
   
       protected MockControl _engineControl = MockControl.createControl(IEngine.class);
  +
       protected IEngine _engine = (IEngine) _engineControl.getMock();
  -    
  -    protected MockControl _pageRenderSupportControl = MockControl.createControl(PageRenderSupport.class);
  -    protected PageRenderSupport _pageRenderSupport = (PageRenderSupport) _pageRenderSupportControl.getMock();
  -    
  +
  +    protected MockControl _pageRenderSupportControl = MockControl
  +            .createControl(PageRenderSupport.class);
  +
  +    protected PageRenderSupport _pageRenderSupport = (PageRenderSupport) _pageRenderSupportControl
  +            .getMock();
  +
       /**
        * @see org.apache.hivemind.test.HiveMindTestCase#tearDown()
        */
  @@ -67,7 +80,7 @@
           _formControl.reset();
           _engineControl.reset();
           _pageRenderSupportControl.reset();
  -        
  +
           super.tearDown();
       }
   
  @@ -80,7 +93,7 @@
           _engineControl.replay();
           _pageRenderSupportControl.replay();
       }
  -    
  +
       protected void verify()
       {
           _componentControl.verify();
  @@ -90,19 +103,77 @@
           _engineControl.verify();
           _pageRenderSupportControl.verify();
       }
  -    
  +
       protected void addScript(String script)
       {
           _cycle.getEngine();
           _cycleControl.setReturnValue(_engine);
  -        
  +
           _engine.getClassResolver();
           _engineControl.setReturnValue(null);
  -        
  +
           _cycle.getAttribute("org.apache.tapestry.PageRenderSupport");
           _cycleControl.setReturnValue(_pageRenderSupport);
  -        
  +
           _pageRenderSupport.addExternalScript(new ClasspathResource(null, script));
           _pageRenderSupportControl.setVoidCallable();
       }
  +
  +    protected IFormComponent newField(String displayName)
  +    {
  +        MockControl control = newControl(IFormComponent.class);
  +        IFormComponent field = (IFormComponent) control.getMock();
  +
  +        field.getDisplayName();
  +        control.setReturnValue(displayName);
  +
  +        return field;
  +    }
  +
  +    protected void trainGetFieldDOM(MockControl control, FormComponentContributorContext context,
  +            String result)
  +    {
  +        context.getFieldDOM();
  +        control.setReturnValue(result);
  +    }
  +
  +    protected void trainBuildMessage(MockControl control, ValidationMessages messages,
  +            String overrideMessage, String key, Object[] parameters, String result)
  +    {
  +        messages.formatValidationMessage(overrideMessage, key, parameters);
  +        control.setMatcher(new ArrayMatcher());
  +        control.setReturnValue(result);
  +    }
  +
  +    protected void trainGetLocale(MockControl control, ValidationMessages messages, Locale locale)
  +    {
  +        messages.getLocale();
  +        control.setReturnValue(locale);
  +    }
  +
  +    protected IFormComponent newField()
  +    {
  +        return (IFormComponent) newMock(IFormComponent.class);
  +    }
  +
  +    protected IMarkupWriter newWriter()
  +    {
  +        return (IMarkupWriter) newMock(IMarkupWriter.class);
  +    }
  +
  +    protected IRequestCycle newCycle()
  +    {
  +        return (IRequestCycle) newMock(IRequestCycle.class);
  +    }
  +
  +    protected ValidationMessages newValidationMessages(Locale locale)
  +    {
  +        MockControl control = newControl(ValidationMessages.class);
  +        ValidationMessages messages = (ValidationMessages) control.getMock();
  +
  +        messages.getLocale();
  +        control.setReturnValue(locale);
  +
  +        return messages;
  +    }
   }
  
  
  
  1.6       +15 -30    jakarta-tapestry/framework/src/java/org/apache/tapestry/form/AbstractFormComponentContributor.java
  
  Index: AbstractFormComponentContributor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/AbstractFormComponentContributor.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- AbstractFormComponentContributor.java	18 Jun 2005 12:54:39 -0000	1.5
  +++ AbstractFormComponentContributor.java	18 Aug 2005 21:56:06 -0000	1.6
  @@ -14,17 +14,13 @@
   
   package org.apache.tapestry.form;
   
  -import org.apache.hivemind.Resource;
  -import org.apache.hivemind.util.ClasspathResource;
   import org.apache.hivemind.util.PropertyUtils;
  -import org.apache.tapestry.IForm;
   import org.apache.tapestry.IMarkupWriter;
   import org.apache.tapestry.IRequestCycle;
  -import org.apache.tapestry.TapestryUtils;
   
   /**
  - * Abstract {@link FormComponentContributor} implementation that adds an optional static 
  - * javscript method reference to the page.
  + * Abstract {@link FormComponentContributor} implementation that adds an optional static javscript
  + * method reference to the page.
    * 
    * @author Paul Ferraro
    * @since 4.0
  @@ -32,17 +28,17 @@
   public abstract class AbstractFormComponentContributor implements FormComponentContributor
   {
       private String _script = defaultScript();
  -    
  +
       public AbstractFormComponentContributor()
  -    {        
  +    {
       }
  -    
  +
       // Needed until HIVEMIND-134 fix is available
       public AbstractFormComponentContributor(String initializer)
       {
           PropertyUtils.configureProperties(this, initializer);
       }
  -    
  +
       /**
        * Defines the default JavaScript file used by this contributor. Overriden by most subclasses
        * that use JavaScript.
  @@ -51,37 +47,26 @@
       {
           return null;
       }
  -    
  +
       public String getScript()
       {
           return _script;
       }
  -    
  +
       public void setScript(String script)
       {
           _script = script;
       }
  -    
  +
       /**
  -     * @see org.apache.tapestry.form.FormComponentContributor#renderContribution(org.apache.tapestry.IMarkupWriter, org.apache.tapestry.IRequestCycle, FormComponentContributorContext, org.apache.tapestry.form.IFormComponent)
  +     * @see org.apache.tapestry.form.FormComponentContributor#renderContribution(org.apache.tapestry.IMarkupWriter,
  +     *      org.apache.tapestry.IRequestCycle, FormComponentContributorContext,
  +     *      org.apache.tapestry.form.IFormComponent)
        */
  -    public void renderContribution(IMarkupWriter writer, IRequestCycle cycle, FormComponentContributorContext context, IFormComponent field)
  +    public void renderContribution(IMarkupWriter writer, IRequestCycle cycle,
  +            FormComponentContributorContext context, IFormComponent field)
       {
           if (_script != null)
  -        {
  -            // TODO:  cycle.getInfrastructure().getClassResolver()
  -            
  -            Resource script = new ClasspathResource(cycle.getEngine().getClassResolver(), _script);
  -            
  -            TapestryUtils.getPageRenderSupport(cycle, field).addExternalScript(script);
  -        }
  -    }
  -    
  -    /**
  -     * Helper method that adds the specified submit handler to to the specified form.
  -     */
  -    protected void addSubmitHandler(IForm form, String handler)
  -    {
  -        form.addEventHandler(FormEventType.SUBMIT, handler);
  +            context.includeClasspathScript(_script);
       }
   }
  
  
  
  1.2       +15 -8     jakarta-tapestry/framework/src/java/org/apache/tapestry/form/TranslatedFieldSupportImpl.java
  
  Index: TranslatedFieldSupportImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/TranslatedFieldSupportImpl.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TranslatedFieldSupportImpl.java	10 Aug 2005 06:02:48 -0000	1.1
  +++ TranslatedFieldSupportImpl.java	18 Aug 2005 21:56:06 -0000	1.2
  @@ -33,7 +33,8 @@
       }
   
       /**
  -     * @param threadLocale The threadLocale to set.
  +     * @param threadLocale
  +     *            The threadLocale to set.
        */
       public void setThreadLocale(ThreadLocale threadLocale)
       {
  @@ -43,24 +44,30 @@
       public String format(TranslatedField field, Object object)
       {
           IValidationDelegate delegate = field.getForm().getDelegate();
  -        
  -        return delegate.isInError() ? delegate.getFieldInputValue() : field.getTranslator().format(field, object);
  +
  +        return delegate.isInError() ? delegate.getFieldInputValue() : field.getTranslator().format(
  +                field,
  +                _threadLocale.getLocale(),
  +                object);
       }
  -    
  +
       public Object parse(TranslatedField field, String text) throws ValidatorException
       {
           IValidationDelegate delegate = field.getForm().getDelegate();
  -        
  +
           delegate.recordFieldInputValue(text);
  -        
  -        return field.getTranslator().parse(field, text);
  +
  +        ValidationMessages messages = new ValidationMessagesImpl(field, _threadLocale.getLocale());
  +
  +        return field.getTranslator().parse(field, messages, text);
       }
   
       public void renderContributions(TranslatedField field, IMarkupWriter writer, IRequestCycle cycle)
       {
           if (field.getForm().isClientValidationEnabled())
           {
  -            FormComponentContributorContext context = new FormComponentContributorContextImpl(_threadLocale.getLocale(), cycle, field);
  +            FormComponentContributorContext context = new FormComponentContributorContextImpl(
  +                    _threadLocale.getLocale(), cycle, field);
   
               field.getTranslator().renderContribution(writer, cycle, context, field);
           }
  
  
  
  1.2       +8 -0      jakarta-tapestry/framework/src/java/org/apache/tapestry/form/ValidationMessages.java
  
  Index: ValidationMessages.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/ValidationMessages.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ValidationMessages.java	18 Jun 2005 12:54:39 -0000	1.1
  +++ ValidationMessages.java	18 Aug 2005 21:56:06 -0000	1.2
  @@ -14,6 +14,8 @@
   
   package org.apache.tapestry.form;
   
  +import java.util.Locale;
  +
   /**
    * Support interface used to provide access to validation messages. Typically used by
    * {@link org.apache.tapestry.form.validator.Validator}s.
  @@ -37,4 +39,10 @@
   
       public String formatValidationMessage(String messageOverride, String messageKey,
               Object[] arguments);
  +
  +    /**
  +     * Returns the locale for which messages are generated.
  +     */
  +
  +    public Locale getLocale();
   }
  
  
  
  1.3       +6 -0      jakarta-tapestry/framework/src/java/org/apache/tapestry/form/ValidationMessagesImpl.java
  
  Index: ValidationMessagesImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/ValidationMessagesImpl.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ValidationMessagesImpl.java	2 Aug 2005 14:59:41 -0000	1.2
  +++ ValidationMessagesImpl.java	18 Aug 2005 21:56:06 -0000	1.3
  @@ -67,4 +67,10 @@
   
           return messageOverride;
       }
  +
  +    public Locale getLocale()
  +    {
  +        return _locale;
  +    }
  +
   }
  
  
  
  1.22      +2 -1      jakarta-tapestry/framework/src/java/org/apache/tapestry/AbstractComponent.java
  
  Index: AbstractComponent.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/AbstractComponent.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- AbstractComponent.java	25 Jul 2005 13:09:13 -0000	1.21
  +++ AbstractComponent.java	18 Aug 2005 21:56:06 -0000	1.22
  @@ -20,6 +20,7 @@
   import java.util.HashSet;
   import java.util.Iterator;
   import java.util.List;
  +import java.util.Locale;
   import java.util.Map;
   
   import org.apache.hivemind.ApplicationRuntimeException;
  @@ -797,7 +798,7 @@
       }
   
       /**
  -     * Convienience method for invoking {@link IMessages#format(String, Object)}
  +     * Convienience method for invoking {@link IMessages#format(String, Locale, Object)}
        * 
        * @since 3.0
        * @deprecated To be removed in 4.1. Use {@link #getMessages()} instead.
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org