Note: the documentation is still incomplete, so if you got questions,
feel free to contact me directly
Introduction
This example simulates a kind of role-based user management system.
On left left part, you'll see a list of users. The right part gives a detail
view to the user's properties. You can add new, edit existant oder delete users
from the list.
The following classes/feature of the contrib/sam package are used:
- DataObject
- ErrorModel
- XML based Forms
- DataObjectGateway
Description
DataObject
Any class implementing the DataObject interface might be used. The example
uses a simple class User.java that provides static methods for managing users in
a list. A real world application would hold the info persistant in a database,
but this goes beyond the scope of the example.
ErrorModel
The ErrorModel might be used in conjunction with form validation. The validation
process results in a ValidationException if it fails. The exception might be
passed to the static ErrorModel.create method. The Exceptions are stored in the
EventContext's statemap. This happens during the control phase in MVC
During the view/render phase in MVC the error model is simply instantiated and
"remembers" the error's you passed into. In conjunction with a "Has_Errors"
directive in the html mockup, we are able to suppress some parts of the
document. ErrorModel is a iterative model, so it allows you to should all errors
occured during form validation. For usage, see src_mockups/examples/user.html.
XML based Forms
The next (and IMHO most powerful) piece in the puzzle is a form described by an
XML file. Take a look at WEB-INF/userform.xml.
The file starts with ref-id tags. These refer to id-attributes the mockup html.
In plain words, the line
<ref_id type="text" id="text" label_id="text_label" input_id="text_input"/>
means: For all "text" input elements, use a copy of the node identified by
id="text". The label for the input element is identified by "text_label", the
input element itself by "text_input".
The next line
<appendChild id="parent"/>
means that the copies for each formelement are appended to the node identified
by "parent". Alternatively, you might use "insertBefore".
Each input element is defined by a <element>. Inside this tag, the type
and optionally validators are defined.
For further detail on the syntax of the XML form specification, see
dtd/form.dtd.
DataObjectGateway
The abstract class DataObjectGateway defines a set of methods for registering
event handlers. It is used to create, edit, save and delete instances of
DataObject. Internally it uses DataObjectHandlers to do the dirty work. These
are default implementation, that might be overridden (see the SaveEmail event).
UserGateway subclasses DataObjectGateway.
Putting the pieces together
Okay, you've seen the parts of the puzzle, now try to understand who the pieces
play together.
I know, this could be done more easily and elegant uses UML, but I'm
still missing a good UML tool for Linux.
- Let's start at UserGateway. It implements a Config class. This one defines
the necessary parts,
- how to create a DataObject
- the XML form specification
- the render event
- and some constants
- The UserConfig class is used to create concrete subclasses for all DataObjectHandlers
(new, edit, save). UserSaveHandler takes another step: If the user supplied an
empty password, it will be set to "sample".
- RenderUserHandler is repsonsible for displaying the page. Since it is
derived from DataObjectViewHandler, the only thing to add here is a model that
returns the different sumbit buttons.
- The last part of UserGateway is a simple model to get a list of all users in
the system. This is meant to be displayed on the left side.
Stefan Armbruster