001    package hirondelle.web4j.request;
002    
003    import hirondelle.web4j.model.DateTime;
004    import java.util.Date;
005    import java.util.Locale;
006    import java.util.TimeZone;
007    
008    /**
009     Convert text into a {@link DateTime} or {@link Date} object, and vice versa.
010     
011     <P>See {@link hirondelle.web4j.BuildImpl} for important information on how this item is configured. 
012     {@link hirondelle.web4j.BuildImpl#forDateConverter()} 
013     returns the configured implementation of this interface.
014     
015     <P>This interface has methods which occur in pairs, one for a {@link DateTime}, and one for a {@link Date}.
016     The term 'date' used below refers to generically to both of these classes. WEB4J recommeds 
017     {@link DateTime} as the preferred class for representing dates. 
018     
019     <P>The application programmer's implementation of this interface is used when WEB4J needs to 
020     build a date from user input, or format an existing date. Here is an  
021     <a href="http://www.javapractices.com/apps/fish/javadoc/src-html/hirondelle/web4j/config/DateConverterImpl.html">example implementation</a>.
022     
023     <P><b><em>Design Notes</em></b><br>
024     Here are some forces concerning dates in Java web applications :
025    <ul>
026     <li>usually, users expect date input formats to be the same for all forms.
027     <li>an application may have only dates, only date-times, or a mixture of the two.
028     <li>user input of a date or date-time may be with a single control, or with many controls. For example, 
029     the date may be entered with one control, and the hours and minutes with a second and third control, respectively.
030     (WEB4J works well with the one-control-only style. Using more than one control is still possible, since the application 
031     programmer always has access to the underlying request parameters. But, when using WEB4J, 
032     that style involves slightly more work for the application programmer.)
033     <li><span class="highlight">the needs of the eye differ from the needs of the hand.</span> That is, a date format 
034     which is easy to <em>read</em> is usually not easy to <em>enter</em> into a control. Thus, applications should support <em>two</em> formats for 
035     dates : a <em>hand-friendly</em> format (used for input), and an <em>eye-friendly</em> format, used for 
036     presentation <em>and</em> for input as well (allowing user input with an eye-friendly format is 
037     important for forms which change existing data).
038     <li>date formats may differ between Locales. For example, <tt>'01-31-2006'</tt> is natural for English speakers 
039     (January 31, 2006), while <tt>'31-01-2006'</tt> is more natural for French speakers (le 31 janvier 2006). 
040     <li>for <em>parsing</em> tasks, {@link java.text.SimpleDateFormat} is mediocre, and perhaps even untrustworthy. It should be used with great care.
041     One should also be aware that it's not thread-safe.
042     <li>if a new {@link Locale} is added to an application, then parsing and formatting of a date should not fail. 
043     Instead, reasonable defaults should be defined for unknown <tt>Locale</tt>s.
044    </ul>
045    */
046    public interface DateConverter {
047    
048      /**
049       Parse textual user input of a "hand-friendly" format into a {@link Date} object.
050       
051       <P>A hand-friendly format might be <tt>'01312006'</tt>, while an eye-friendly format might be 
052       <tt>'Jan 31, 2006'</tt>.
053       <P>The implementation must return <tt>null</tt> when the user input cannot be 
054       successfully parsed into a {@link Date}. It is recommended that the implementation 
055       have reasonable default behaviour for unexpected {@link Locale}s.
056       <P>This method is called by {@link RequestParser}.
057       
058       @param aInputValue user input value, as returned by {@link hirondelle.web4j.model.ConvertParam#filter(String)} 
059       (always has content).
060       @param aLocale is obtained from the configured {@link LocaleSource}, and passed to this method
061       by the framework.
062       @param aTimeZone is obtained from the configured {@link TimeZoneSource}, and passed to this method
063       by the framework.
064      */
065      Date parseHandFriendly(String aInputValue, Locale aLocale, TimeZone aTimeZone);
066      
067      /**
068       Parse textual user input of an "eye-friendly" format into a {@link Date} object.
069       
070       <P>A hand-friendly format might be <tt>'01312006'</tt>, while an eye-friendly format might be 
071       <tt>'Jan 31, 2006'</tt>.
072       <P>The implementation must return <tt>null</tt> when the user input cannot be 
073       successfully parsed into a {@link Date}. It is recommended that the implementation 
074       have reasonable default behaviour for unexpected {@link Locale}s.
075       <P>This method is called by {@link RequestParser}.
076       
077       @param aInputValue user input value, as returned by {@link hirondelle.web4j.model.ConvertParam#filter(String)} 
078       (always has content).
079       @param aLocale is obtained from the configured {@link LocaleSource}, and passed to this method
080       by the framework.
081       @param aTimeZone is obtained from the configured {@link TimeZoneSource}, and passed to this method
082       by the framework.
083      */
084      Date parseEyeFriendly(String aInputValue, Locale aLocale, TimeZone aTimeZone);
085      
086      /**
087       Format a {@link Date} into an eye-friendly, legible format.
088        
089       <P>The implementation must return an empty <tt>String</tt> when the {@link Date} is null.
090       It is recommended that the implementation have reasonable default behaviour for unexpected {@link Locale}s.
091       <P>The framework will call this method when presenting listings using 
092       {@link hirondelle.web4j.database.Report}, and when presenting a Model Object in a form 
093       for a "change" operation.  
094       <P>This method is called by {@link Formats}.
095       
096       @param aDate to be presented to the user in a legible format
097       @param aLocale is obtained from the configured {@link LocaleSource}, and passed to this method
098       by the framework.
099       @param aTimeZone is obtained from the configured {@link TimeZoneSource}, and passed to this method
100       by the framework.
101       @return text compatible with {@link #parseEyeFriendly(String, Locale, TimeZone)}
102      */
103      String formatEyeFriendly(Date aDate, Locale aLocale, TimeZone aTimeZone);
104    
105      /**
106        Parse textual user input of a "hand-friendly" format into a {@link DateTime} object.
107        
108        <P>A hand-friendly format might be <tt>'01312006'</tt>, while an eye-friendly format might be 
109        <tt>'Jan 31, 2006'</tt>.
110        <P>The implementation must return <tt>null</tt> when the user input cannot be 
111        successfully parsed into a {@link DateTime}. It is recommended that the implementation 
112        have reasonable default behaviour for unexpected {@link Locale}s.
113        <P>This method is called by {@link RequestParser}.
114        
115        @param aInputValue user input value, as returned by {@link hirondelle.web4j.model.ConvertParam#filter(String)} 
116        (always has content).
117        @param aLocale is obtained from the configured {@link LocaleSource}, and passed to this method
118        by the framework.
119      */
120      DateTime parseHandFriendlyDateTime(String aInputValue, Locale aLocale);
121      
122      /**
123        Parse textual user input of an "eye-friendly" format into a {@link DateTime} object.
124        
125        <P>A hand-friendly format might be <tt>'01312006'</tt>, while an eye-friendly format might be 
126        <tt>'Jan 31, 2006'</tt>.
127        <P>The implementation must return <tt>null</tt> when the user input cannot be 
128        successfully parsed into a {@link DateTime}. It is recommended that the implementation 
129        have reasonable default behaviour for unexpected {@link Locale}s.
130        <P>This method is called by {@link RequestParser}.
131        
132        @param aInputValue user input value, as returned by {@link hirondelle.web4j.model.ConvertParam#filter(String)} 
133        (always has content).
134        @param aLocale is obtained from the configured {@link LocaleSource}, and passed to this method
135        by the framework.
136      */
137      DateTime parseEyeFriendlyDateTime(String aInputValue, Locale aLocale);
138      
139      /**
140        Format a {@link DateTime} into an eye-friendly, legible format.
141         
142        <P>The implementation must return an empty <tt>String</tt> when the {@link DateTime} is null.
143        It is recommended that the implementation have reasonable default behaviour for unexpected {@link Locale}s.
144        <P>The framework will call this method when presenting listings using 
145        {@link hirondelle.web4j.database.Report}, and when presenting a Model Object in a form 
146        for a "change" operation.  
147        <P>This method is called by {@link Formats}.
148        
149        @param aDateTime to be presented to the user in a legible format
150        @param aLocale is obtained from the configured {@link LocaleSource}, and passed to this method
151        by the framework.
152        @return text compatible with {@link #parseEyeFriendlyDateTime(String, Locale)}
153      */
154      String formatEyeFriendlyDateTime(DateTime aDateTime, Locale aLocale);
155      
156      
157      
158    }