Version 4.10.0

hirondelle.web4j.model
Class ModelFromRequest

Object
  extended by hirondelle.web4j.model.ModelFromRequest

public final class ModelFromRequest
extends Object

Parse a set of request parameters into a Model Object.

Since HTTP is entirely textual, the problem always arises in a web application of building Model Objects (whose constructors may take arguments of any type) out of the text taken from HTTP request parameters. (See the hirondelle.web4j.database package for the similar problem of translating rows of a ResultSet into a Model Object.)

Somewhat surprisingly, some web application frameworks do not assist the programmer in this regard. That is, they leave the programmer to always translate raw HTTP request parameters (Strings) into target types (Integer, Boolean, etc), and then to in turn build complete Model Objects. This usually results in much code repetition.

This class, along with implementations of ConvertParam and RequestParser, help an Action build a Model Object by defining such "type translation" policies in one place.

Example use case of building a 'Visit' Model Object out of four RequestParameter objects (ID, RESTAURANT, etc.):

protected void validateUserInput() {
  try {
    ModelFromRequest builder = new ModelFromRequest(getRequestParser());
    //pass RequestParameters (or any object) using a sequence (varargs)
    fVisit = builder.build(Visit.class, ID, RESTAURANT, LUNCH_DATE, MESSAGE);
  }
  catch (ModelCtorException ex){
    addError(ex);
  }    
}
 

The order of the sequence params passed to build(Class, Object...) must match the order of arguments passed to the Model Object constructor. This mechanism is quite effective and compact.

The sequence parameters passed to build(Class, Object...) need not be a RequestParameter. They can be any object whatsoever. Before calling the Model Object constructor, the sequence parameters are examined and treated as follows :

 if the item is not an instance of RequestParameter
    - do not alter it in any way
    - it will be passed to the MO ctor 'as is'
 else 
   - fetch the corresponding param value from the request
   - attempt to translate its text to the target type required
     by the corresponding MO ctor argument, using policies 
     defined by RequestParser and ConvertParam
     if the translation attempt fails
      - create a ModelCtorException 
 

If no ModelCtorException has been constructed, then the MO constructor is called using reflection. Note that the MO constructor may itself in turn throw a ModelCtorException. In fact, in order for this class to be well-behaved, the MO constructor cannot throw anything other than a ModelCtorException as part of its contract. This includes RuntimeExceptions. For example, if a null is not permitted by a MO constructor, it should not throw a NullPointerException (unchecked). Rather, it should throw a ModelCtorException (checked). This allows the caller to be notified of all faulty user input in a uniform manner. It also makes MO constructors simpler, since all irregular input will result in a ModelCtorException, instead of a mixture of checked and unchecked exceptions.

This unusual policy is related to the unusual character of Model Objects, which attempt to build an object out of arbitrary user input. Unchecked exceptions should be thrown only if a bug is present. However, irregular user input is not a bug.

When converting from a RequestParameter into a building block class, this class supports only the types supported by the implementation of ConvertParam.

In summary, to work with this class, a Model Object must :


Constructor Summary
ModelFromRequest(RequestParser aRequestParser)
          Constructor.
 
Method Summary
<T> T
build(Class<T> aMOClass, Object... aCandidateArgs)
          Return a Model Object constructed out of request parameters (and possibly other Java objects).
 
Methods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ModelFromRequest

public ModelFromRequest(RequestParser aRequestParser)
Constructor.

Parameters:
aRequestParser - translates parameter values into Integer, Date, and so on, using the implementation of ConvertParam.
Method Detail

build

public <T> T build(Class<T> aMOClass,
                   Object... aCandidateArgs)
        throws ModelCtorException
Return a Model Object constructed out of request parameters (and possibly other Java objects).

Parameters:
aMOClass - class of the target Model Object to be built.
aCandidateArgs - represents the ordered list of items to be passed to the Model Object's constructor, and can contain null elements. Usually contains RequestParameter objects, but may contain objects of any type, as long as they are expected by the target Model Object constructor.
Throws:
ModelCtorException - if either an element of aCandidateArgs cannot be translated into the target type, or if all such translations succeed, but the call to the MO constructor itself fails.

Version 4.10.0

Copyright Hirondelle Systems. Published October 19, 2013 - User Guide - All Docs.