The base idee behind shept is that its pages are composed of segments like the elements in an array.
Rendering the page means that all parts of the page (at least that portion that is controlled by shept) will be rendered in a single request. This is a contrast to todays RIA frameworks which have a tendency to break down page rendering into many fine grained roundtrips to server - often one for each ui component. The shept approach is supposed to be more resource-friendly to your backend although there are exceptions to this of course - autocompletion for one example. There are a couple of other existing implementations with a similar approach - tiles for one example - but shept is better integrated and there is one main difference:
The number of visible elements is controlled by your form backing object and the number of segments it contains. There is no predefined layout and for each segment you can define a collection of follow-up candidates. So the user is aware of his full browsing history.
Hope this abstract concept is more clear with some online showcases.
You have the full freedom to mix shept forms with any other spring supported Controller architecture.
It should be pretty straightforward to add experimental shept support for existing spring mvc applications.
Shepts controllers are inspired by springs MultiActionController. Its base implementation DelegatingController introduces delegates to support handlers for segmented command objects. Request processing involves a WebActionResolver
transforming form submissions into a WebActionToken
which contains submission details. The DelegatingController configures the databindings for all involved segments by delegations to ComponentDataBinder
and their postprocessors ComponentPostprocessor
in a way only the pages dynamic segments contribute to the effective page processing.
Next in shepts controller hierarchy is its own MultiActionController that adds a session form cache to the controller. Well actually today one might imagine other implementations that use session scoped beans - anyway it serves its purpose.
The last controller in the hierarchy and actually the one to be used by default in shept driven pages is the SheptController . The shept controller provides a page with one segment which is build from a TargetConfiguration
. We'll later see what constitues a chain between segments from origin to destination ('target') and a TargetConfiguration
is the simplest form of a ChainConfiguration
without origin (predecessor).
Documentation of the controller hierarchy is sparse but usually you won't bother to dive into details when using shepts higher level abstractions.
While the controller takes care about the whole page the handlers care about an aspect of page handling. There are handlers for pagination and sorting , simple persistence
and list persistence
, filtering
and chaining
. Handlers are located in the component package
and interact with one segments form backing object at a time.
While in general its up to the application to provide its own 'command objects' (or 'form backing objects') this can require quite an effort for anything beyond trivial value holding beans. Shept delivers a couple of beans to interact with its infrastructure that can be found in the support package .
The SubCommandProvider with its single implementation DefaultCommandObject delivers the segments of a page - each wrapped into a CommandWrapper
. The purpose of this additional wrapping is to have a level that can be used for additional information, most important the tagName of the segment but also status information e.g. that can be used to hide/show the segment.
For the datagrids there is a hierarchy of PageListHolder -> ChoiceListHolder
-> FilteredListHolder
.
Note that all handlers don't deal with these concrete implementations but with their interface definitions PageableList , MultiChoice
and Refreshable
preserving your freedom for own implementations of datagrid form backing objects.
The basic PagedListHolder is a modified version of the PageListHolder provided by the spring framework. The modification preserves all of the original characteristics but it was unfortunately necessary to overcome extendibility limitations (aka private definition 'sortUsed' and no accessors defined). ChoiceListHolder extends the PageListHolder with the MultiChoice interface to let the user select one or more items (usually provided with checkboxes on the ui level). FilteredListHolder
is an extension to it implementing Refreshable providing list reloading functionality from a backing datasource. The FilteredListHolder is the 'swiss knife' for backing datagrids and is used in all default configurations.
Viewing is supported through 2 taglibs shept and table. Form fields and random objects are bound in the usual spring style via spring
and form taglibs.
Shept provides a default configuration shept.xml that contains a lot of templates and initializations for a Shept controller and its component handlers. It needs to be included in web.xml along with your segment and chain definitions. There is a naming convention applied to its definitions with suffix template which are defined abstract="true" thus you'll declare concrete definitions by using parent="...template". If you are unhappy with shept.xml predefinitions you always have the freedom to copy and paste it into your projects classpath and apply your individual modifications to it. However this should rarely be necessary as almost everything is extendible through spring bean definitions. Have a look at the demo implementations at github.
. A typical web.xml will look like this:
During app container startup shept.xmls configuration configures resource copy operations to your projects /WEB-INF/images and WEB-INF/includes folder. Resource copying checks for existing resources first and will not override any of your individual settings. While this isn't strictly necessary any more since springs <mvc:resource /> tags there is still the advantage of mixing the provided defaults with your individual settings.
There are a couple of support and utility classes to mention the most important ones: ComponentUtils provides access to command objects, their segments and all sorts of conversions between configurations, segments and pathNames. ModelUtils
contains a couple of model related features as copying, wrapping and template retrieval.