A ViewParameters object holds a deserialized (from the HttpServletRequest or similar) representation of the location of the view for the current request. In HTTP idiom, ViewParameters is a technology-neutral representation of a URL.
ViewParameters fields#
There are various housekeeping fields defined in the base class of ViewParameters, most of which needn't concern the developer, apart from the core field viewID, which is the central index in RSF that defines the identity of a view.public String viewID;
Each view in RSF is associated with exactly one specific subclass of ViewParameters. Unless the ViewProducer defines otherwise, the class which will be used is SimpleViewParameters, which defines no extra fields, and uses a straightforward URL representation strategy with the viewID parsed from the first component of the URL.
Starting with SimpleViewParameters#
For example, in the LogonTest application, we saw this line:UIInternalLink.make(pane, "waleslink", new SimpleViewParameters(WalesFrameProducer.VIEW_ID));
This indicates that the view walesframe is using the default, SimpleViewParameters, which means that inside the fillComponents method, the object viewparams delivered to it would be of this class. However, since there is no extra information other than the viewID (which we already know, it would have to be our own) inside this params, there would be no reason to inspect them inside the producer.
Defining your own ViewParameters#
Most applications will want to pass user-defined view state from view to view via links - in fact RSF's main strength is its idiomatic and natural support for URL state. In order to define what this extra view state is, the developer will need to derive their own subclass from ViewParameters (one of the few cases where subclasses are used within RSF). In fact it is generally most convenient to derive from SimpleViewParameters rather than ViewParameters itself, since there is special support for setting up a default set of URL parsing rules for SimpleViewParameters subclasses. So, for example, we could write:
public class NavParams extends SimpleViewParameters { public String itemID; public String viewtype; public int pageseq; public String keywords; }
Note that the user really needs to do very little other than list the extra fields one wants in a structure (or Pea) - RSF will take on the rest of the work of implementing the parsing system, as well as the copyBase() method which is essential for getting the full power of RESTful flows. You may want to implement one or more convenience constructors, though.
Now all we need to do is to register with RSF that this ViewParameters class will be the one used for a particular view. This is done by implementing the ViewParamsReporter interface from the view's producer, which for example would look like this:
public class NavFrameProducer implements ViewComponentProducer, ViewParamsReporter { public static final String VIEWID = "nav-frame"; public String getViewID() { return VIEWID; } public void fillComponents(UIContainer tofill, ViewParameters origviewparams, ComponentChecker checker) { NavParams navparams = (NavParams) origviewparams; // use the navparams here when generating the view contents ... } public ViewParameters getViewParameters() { return new NavParams(); }
Note that the getViewParameters() method simply returns an exemplar for the kind of ViewParameters that required - there is no need to initialise any of the fields on it, since RSF is really only interested in its type.
So, finally, any other producer wanting to make a link to this view might for example use code like the following:
NavParams navparams = new NavParams(); navparams.itemID = hit.get("identifier"); navparams.pageseq = Integer.parseInt(pageno); navparams.viewID = NavFrameProducer.VIEWID; navparams.keywords = freetext; UIInternalLink.make(hitrow, "identifier-link", hit .get("identifier"), navparams);
ParseSpecs#
By default, any ViewParameters derived from SimpleViewParameters will have a ParseSpec (or "parse specification") deduced from its fields automatically. The default parseSpec maps every bean property (or public field) into a URL attribute of the same name. To take control of this strategy you can override the getParseSpec method to map the ViewParameters state in a custom way to provide more "cool URLs". If you place more than simple leaf types into viewaparams (that is, other than simple Strings, Strings or numbers) you will need to write a ParseSpec.
ViewParameters theory#
The implementation of the view parameters object is one of the primary responsibilities of the RSF application developer. In theory, the viewparams may be derived from the request in arbitrary ways, although in practice there is particular support for deriving public "leaf-type" fields of the form above from URL attributes of the same names (this will happen automatically if they are reported from the getAttributeFields method of ViewParameters). All Java primitive types are usable, as well as some composite ones, although URL considerations will probably suggest towards the use of simple types.The bulk of the other fields in ViewParameters are required for housekeeping for flow and error state, being the flowtoken and endflow indicator for flows, and the errortoken and errorredirect indicator for errors. The tokens collectively comprise the view tokens, discussed somewhat in another page.
Role of ViewParameters #
ViewParameters is critical in blocking off the last piece of dependence of RSF application code on the servlet infrastructure. To RSF, the ViewParameters are abstract tokens that are passed around and have their viewID field used as indexes to locate the ViewTemplate and ComponentProducer. To code within the ComponentProducer, ViewParameters may well have a much richer structure, encoding many more details of flow and application state.In essence the ViewParameters representations bound the structure and possible flow paths through the application, by defining the unique representation of every view state.
For common links (<a href=" in HTML language), the target of a link is specified by the ComponentProducer when it emits the UILink object peering with the links. For submission links (resulting in POSTs) represented by UICommand components, the resulting ViewParameters is determined by the result of the ActionResultInterpreter registered by the application, which in essence defines the flow of the application by inspecting the result (if any) of the Action invokation as well as any errors that may have occured to compute the required ViewParameters for the client redirect that is (always!) issued.
ViewParameters objects are frequently cloned and modified slightly during the course of the actions of a ComponentProducer, since links leading from pages frequently lead to navigational state closely related to the source page. The copyBase() method is provided for this purpose.
Future of ViewParameters#
ViewParameters are currently capable of dealing with serialisation of a bounded collection of leaf types within its object tree (Strings, Integers, Longs etc.). Before 1.0, the ViewParameters system will be upgraded to support unbounded collections (Lists, Maps, etc.) to allow use cases such as a dynamically sized set of sorting table controls within a view, etc.Potential pitfalls#
- Make sure your producer implements ViewParamsReporter! Defining getViewParameters() will appear to succeed but will never get called unless you implement this interface (naturally). If you are not getting the ViewParameters you expect, this is a good place to check.
- If you override getParseSpec() remember to prepend your string with the return String of the supertype.