001    package hirondelle.web4j.model;
002    
003    import java.util.Locale;
004    import java.util.TimeZone;
005    
006    import hirondelle.web4j.model.ModelCtorException;
007    
008    /**
009     Convert request parameters into common 'building block' objects.
010     
011     <P>See {@link hirondelle.web4j.BuildImpl} for important information on how this item is configured. 
012     {@link hirondelle.web4j.BuildImpl#forConvertParam()} 
013     returns the configured implementation of this interface.
014     
015    <h3> <a name="BuildingBlock"></a>Building Block Classes</h3>
016     Here, a <em>building block</em> class is one of the 'base' objects from which Model
017     Objects can in turn be built - <tt>Integer</tt>, <tt>BigDecimal</tt>, <tt>Date</tt>,
018     and so on. {@link #isSupported(Class)} defines which classes are supported as 
019     building block classes, and {@link #convert(String, Class, Locale, TimeZone)} defines 
020     how to construct them from request parameters.
021     
022     <P>{@link ConvertParamImpl} is provided as a default implementation, and is likely
023     suitable for many applications.
024     
025     <P>
026     In addition, implementations may optionally choose to apply <em>universal pre-processing</em> 
027     for Strings. For example, an implementation may decide to trim all Strings, or to force capitalization for 
028     all Strings. Such policies may be centralized here, by including them in the implementation of 
029     {@link #filter(String)} or {@link #convert(String, Class, Locale, TimeZone)}.
030    */
031    public interface ConvertParam {
032    
033      /**
034       Determine if <tt>aTargetClass</tt> is a supported <a href="#BuildingBlock">building block</a> class.
035       
036       <P>If <tt>aTargetClass</tt> is supported, then an underlying request parameter can be converted into 
037       an object of that class.
038       
039       <P>The framework will always call this method first, before calling the other methods in
040       this interface. 
041      */
042      boolean isSupported(Class<?> aTargetClass);
043    
044      /**
045       Apply a policy for parameter values which are <tt>null</tt>, empty, or equal to
046       <tt>IgnorableParamValue</tt> in <tt>web.xml</tt>.
047       <P>
048       When a 'blank' form is submitted, items are not treated in a
049       uniform manner. For example, a popular browser exhibits this behavior :
050       <ul>
051       <li>blank text area : param submitted, empty <tt>String</tt>
052       <li>radio button, with none selected : no param submitted (<tt>null</tt>)
053       <li>checkbox, unselected : no param submitted (<tt>null</tt>)
054       <li>drop-down selection, with first pre-selected by browser : param submitted, with value
055       </ul>
056       <P>
057       Moreover, the W3C <a href=http://www.w3.org/TR/html4/interact/forms.html#successful-controls>spec</a> seems
058       to allow for some ambiguity in what exactly is posted, so the above behavior may not be
059       seen for all browsers.
060       
061       <P>This method is used to impose uniformity upon all such 'blank' items.
062       
063       <P><span class="highlight">This method can return <tt>null</tt>. Any non-<tt>null</tt> 
064       values returned by this method must have content.</span> (That is, an implementation cannot return a 
065       <tt>String</tt> which, when trimmed, is empty.)
066        
067       @param aRawParamValue the raw, unchanged parameter value, as submitted in the underlying request.
068      */
069      String filter(String aRawParamValue);
070    
071      /**
072       Convert a request parameter value into a <a href="#BuildingBlock">building block</a> object.
073       <P>
074       The value passed to this method is first <em>filtered</em>, using {@link #filter(String)}.
075       <span class="highlight">Implementations must throw a {@link ModelCtorException} when a parsing problem occurs</span>.
076       <P>
077       @param aFilteredParamValue parameter value as returned by {@link #filter(String)}
078       @param aSupportedTargetClass supported target building block class in a Model Object constructor
079       @param aLocale {@link Locale} returned by the implementation of {@link hirondelle.web4j.request.LocaleSource}
080       @param aTimeZone {@link TimeZone} returned by the implementation of {@link hirondelle.web4j.request.TimeZoneSource}
081      */
082      <T> T convert(String aFilteredParamValue, Class<T> aSupportedTargetClass, Locale aLocale, TimeZone aTimeZone) throws ModelCtorException;
083    }