Rich Client Modeling
11 June 2014: Blu Age v5.0.0 - Rich client modeling
Reference Manual version v1.0.1
- 1 Introduction
- 2 Available resources
- 3 Requirements
- 4 Rich client modeling
- 4.1 Modeling project structure
- 4.2 General naming conventions
- 4.3 User Interface modeling
- 4.3.1 The Shell
- 4.3.2 Components and views
- 220.127.116.11 Creating a view or a component
- 18.104.22.168 Filling the component/view with UI elements
- 22.214.171.124 Controls & containments
- 126.96.36.199 Linked controls containments
- 188.8.131.52 Binding controls to domain elements
- 184.108.40.206 Data binding
- 220.127.116.11 Optional Collection Binding for list of choices
- 18.104.22.168 Fixed values set
- 22.214.171.124 Dynamic values set
- 126.96.36.199 Binding DataGrid to domain elements
- 188.8.131.52 Binding the DataGrid
- 184.108.40.206 Binding the DataColumn(s)
- 220.127.116.11 User defined controls
- 18.104.22.168 Handling control visibility and disabling
- 22.214.171.124 Additional UI Elements
- 126.96.36.199 Extending UI component
- 188.8.131.52 Security
- 184.108.40.206 Using the validation
- 220.127.116.11 Reusable components (instantiate components)
- 18.104.22.168 Using a component in a component or a view
- 22.214.171.124 Dealing with events handling
- 4.3.3 Events
- 4.3.4 Forwarding, Navigation
- 4.3.5 Event Bus
- 4.3.6 Instances beans in view and simple controller
- 4.3.7 Transferring instances
- 4.3.8 Dealing with scopes
- 4.3.9 Dealing with zone updates and zone process (Ajax)
- 4.3.10 Miscellaneous settings
- 4.4 Rich User Interfaces Elements
This document is a user guide for Rich UI modeling. It covers the presentation layer. The Rich UI modeling is a UML DSL adapted to produce the view as well as the code managing the view. Rich User Interface or Rich Internet Application is a web term defining modern web applications. It strives toward the development of an interactive, stylized and usable interface.
Business modeling documentation is available here:
- HowTo / Cook Book: (available soon)
- Reference documentation of Blu Age Rich UI profile: (available soon)
- Training slide deck & samples: on request.
- Knowledge of UML modeling is required.
- Existing knowledge about rich/heavy client architecture is not mandatory but is heavily suggested since modeling involves understanding what an event driven application consists of.
Rich client modeling
Modeling project structure
- The project structure is based on the following scheme:
- [Root Package]:
- [Business Domain Package(s)]: containing <<PK_BUSINESS>> stereotype
- [Service Package(s)]: containing <<PK_SERVICE>> stereotype
- [User Interface Package(s)]: holding new <<PK_VIEW>> stereotype
General naming conventions
Most of the names given to model objects will be used 'as-is' for corresponding generated code artifacts. Given that, it is strongly advised to make the model naming conventions match the java naming conventions.
Sample rules to follow for java conventions:
- Package name must start with a lowercase letter
- Class and interface names must start with an uppercase letter
- Operation name must start with a lowercase letter
- Operation parameters must start with a lowercase letter
- Central buffer nodes name must start with a lowercase letter
|If the target is .NET, .NET conventions should be used.|
User Interface modeling
The UI modeling starts by defining a Shell (template page of the application) and a set of views/components.
Here is the composition:
- A Shell
- Views and components containing.
- Controls and components
- EventAction definitions (an EventAction is an application process that specifies the way the application will respond to a fired event)
- UserEvent used to decouple events in reusable components.
(The start view can be defined by applying the stereotype <<START_VIEW>>)
|It’s common usage to split content and the layout. In a simple scenario, the view will only contain layout information (set of panels) and the form controls (label/text box) are contained in a component.|
The shell represents the entry point of the application. It must be unique within the entire model.
Creating the shell is just like creating a view, except that the stereotype to be applied is <<Shell>> instead of <<View>>.
The Shell is composed of presentation elements and compositions. Compositions are defined parts which are redefined by the views. This is done by creating a Structured Activity stereotyped <<Panel>> with the property "type=composition".
Sample view redefining the composition "main":
Components and views
Components are reusable UI parts, intended to be shared by the views. Views are UI parts, designed to be the user interface of a complete application use case; views are built using components and controls.
Components and views are very close in terms of modeling. What can be done for a component, can also be done for a view. Given that, the following paragraphs will mainly focus on components modeling (differences between views and components will be stressed as needed).
Two types of components are available:
- Simple components, which are similar to including a view into another view. They can only be used once per view.
- Instance components, which can take object variables (primitives are not allowed). Instance components must be contained in a package stereotyped <<PK_COMPONENT>>.
Sample instance component:
Creating a view or a component
Views are similar to components. The difference is the applied stereotype: <<View>> instead of <<Component>>.
To create a new component, use the "Diagrams > Custom diagrams > Bluage UIs..." menu entry.
A window like the following will open:
Please note that all existing Blu Age UI diagrams in your project are listed here. To create a new one, click on the [Add] button;
Give a name to the component to be created and select the owning package then click on [Open]. The Blu Age UI diagram list is updated with the newly created component as shown below:
Simply close this window. In the containment tree, the new activity is now visible:
To make it a component, right click on the activity and select the <<Component>> stereotype:
The activity now shows as a component in the containment tree:
When the component is selected in the containment tree, hitting Enter will open the specification window, which will look like this:
Please note that the specification window has been tailored to reflect the Blu Age UI properties.
Filling the component/view with UI elements
The elements can be picked from the Blu Age UI custom palette and dropped into the diagram.
Example pick panel from the palette:
- Drop it in the activity diagram
- Drop a label and a textbox in the panel
- Drop a button in the panel
And so on, until the component is complete...
Controls & containments
There are 3 types of controls:
- Standalone control such as input text or label, these controls cannot contain other controls. They are represented by a UML Central Buffer Node;
- Standard containment controls such as panels or repeater, these are represented by a UML Structured Activity;
- Linked containment controls. See below for linked containment representation.
Linked controls containments
There are 3 types of linked controls: Data Grid, Menu and Tree View.
The container is connected to one or more controls using object flows. The relation is always coming from the control to the container.
Example: The contactDataGrid is connected to 4 DataColumns
Example: Hierarchy representation for a menu
Binding controls to domain elements
|The following sections apply to any control EXCEPT DataGrid; DataGrid binding is covered in a dedicated section further on.|
Aside from position/layout properties settings, controls need to be bound to the application data, a.k.a the business domain. The binding with domain elements can affect:
- The value of the control;
- Optionally, a list of choices for the control (when appropriate);
- The availability of the control.
Regarding value binding, a control can only be bound to a scalar property.
Binding controls to properties is operated through the three following attributes:
- instance: instance of the business object/value object to be bound to;
- colProperty: property of the instance/nested instance to which the control value will be bound;
- nestedProperty: textual binding, used to bound nested property. The user needs to verify the coherence of his binding.
Note, the binding will be generated as: instance.nestedProperty.colProperty
e.g.: In the following sample, the txtMocSearch TextBox control is bound to the searchedRecords property of the meansOfCommunicationScreen instance.
- Using instance and colProperty
Please note that the instance needs to be owned by the owning View/Component of the control. In the sample, the meansOfCommunicationScreen instance is owned by the meansOfCommunication View, which is the owner of the txtMocSearch TextBox.
Example of usage for nestedProperty below:
- Using instance, nestedProperty and colProperty
Optional Collection Binding for list of choices
Some controls are based on the use of a "list of available choices" (typical example is the DropDown control).
The "list of available choices" can be either statically defined within the control or dynamically populated at run time.
Fixed values set
To use a set of fixed values, the Values property can be populated with a list of separated Value-Key couples; the separator is the '/' character.
The Value-Key are built on the "value[tab character]key" pattern.
Dynamic values set
In the other case, the "list of available choices" is dynamically populated at runtime using domain elements. Five properties are used for this purpose:
To bind the list:
- instanceListInstance: instance of the business object or the value object to be bound to;
- listInstance: a collection that will be iterated on, containing the objects whose properties might be used to build the "list of available choices" shown to the end-user;
- nestedPropertyListInstance: textual binding, used to bound nested property. The user needs to verify the coherence of his binding;
To bind the value selected and the value submitted:
- key (optional): the property that will be used to identify the user selection amongst the objects in the listInstance; this property should permit a clear discrimination within objects (no ambiguity). This property is optional in case you need to directly manipulate the underlying object. The identifier is a good natural candidate for this purpose;
- value: the property that will be shown to the user in the "list of available choices"; this should point to a human readable property (a string typed property is a good candidate)
Note the generation pattern is: instanceListInstance.nestedPropertyListInstance.listInstance
e.g.: The userTypeDropDown will display the content of the listUserType list using the key description to display the information. The selected object will be set in the property userType from agentScreen.agentModification.
Binding DataGrid to domain elements
Binding a DataGrid to domain elements is based upon:
- Binding the Datagrid with a collection of business objects/value objects,
- Binding each column of the Datagrid (DataColumn) with a property of the business object/value object of the bound collection.
Binding the DataGrid
The listInstance property is used to specify the collection of business objects to bind the DataGrid to;
- Using listInstance, instanceListInstance and nestedPropertyListInstance to populate the DataGrid
Binding the DataColumn(s)
Every DataColumn of the DataGrid needs to be bound to a business object property, through the colProperty property.
e.g.: The laBusinessUnit DataColumn is bound to the businessUnit property from the RecordUnit business object.
User defined controls
To fit custom application needs, it’s possible to define custom controls or use controls from an external library. A custom control is modeled with a UML class marked with the <<control>> stereotype (from the UML2_RichUI_Bluage_Profile UML profile). This class must be located in the sub-hierarchy of a package handling the <<PK_VIEW>> stereotype. In addition, a control may contain operations reflecting its intended behavior.
Handling control visibility and disabling
The visibility and disabling of any control can be handled by using control operations:
Two operations are available to manage the disabling, isDisabled, setDisabled.
Two operations are available to manage the visibility, isRendered, setRendered.
Additional UI Elements
Panels are containers responsible for organizing the user interface by grouping controls according to their functional role. Blu Age modeling currently supports the following panel types:
To add a Panel to a component or a view, select the proper type from the Blu Age UI palette menu.
All controls that are placed onto the panel will belong to it.
Extending UI component
Each control can be extended to define a specific behavior. Essentially, the control is extended when the basic control does not offer all the properties of the destination domain. The extension mechanism works using inheritance between stereotypes. E.g., if you want to specify an autocomplete tag with properties not offered by default: First create a new stereotype inherited from the original tag.
Apply the Stereotype <<toTag>> to the new created stereotype and define the mandatory properties tagName, tagPrefix, tagImplementation and tagUri.
The tagImplementation corresponds to the class used to manipulate the tag in the controller. For example extending the <<Panel>> tag with <<GridPanel>> will generate by default an OutputPanel. If tagImplementation=”org.primefaces.component.panelgrid.PanelGrid”, the tag declaration will change to:
// UI Components: pnlSelectTeam private PanelGrid pnlSelectTeam;
Specify the additional properties in the new stereotype created and stereotype them <<to>>. The tagged value <<to>> define in which property will be copied the value of the property.
The value of the property "dropDown" will be copied in the tag property "dropdown". Example:
Each project can define its own tags to handle specific behaviors and presentation options. All the available properties can be found on the official PrimeFaces documentation . It is recommended to create a specific profile per project.
Globally, access security is implemented using the same convention proposed for modeling a light web application: login service declaration, roles declaration etc. You can read the Blu Age tutorial to get familiar with that part: http://tutorial.bluage.com/presentation/gettingstarted/uc06_loginlogout/uc06_login.html
Here are the main differences:
The screen model:
Service call model:
All the other settings are the same, put the workflow property "securityFwk" at "spring”, stereotype the operation <<login>>...
Using the validation
The JSF 2 component allows some client validation:
- Required: defines if a field is required or not
- Range: defines the range between the value needs to be validated
- Regex: defines a regular expression which correspond with the validation motif
- Format (date, currency, numeric): defines the format that needs to be verified for the current field
- Example date:
- Example numeric:
- Example currency:
- Run validators and display error messages:
The validation is executed when the tagged value "causeValidation" is set to "true". All the messages returned while executing the validation will be displayed in the CentralBufferNode stereotyped "Messages". Example:
Reusable components (instantiate components)
Each component can be used to instantiate components:
- Create a package stereotyped <<PK_COMPONENT>>,
- Create a component inside that package,
- Stereotype your component <<Component>>
- Drag and drop the component into your "View",
- Name it,
Using a component in a component or a view
To use a component in another component or a view, the following steps must be performed: Drag and drop the desired component from the containment tree to the component/view diagram; give it a name
Dealing with events handling
Some controls are not inert and can trigger events. Those events need to be handled, and this event handling has to be properly modeled. Back to the previous example: it is clear that what occurs when the "clickMe" button is pressed has to be clearly defined. This has to be done through event handling modeling. For every event to be handled, an "EventAction" element has to be created.
General EventAction modeling guide
Modeling the EventAction is done by populating the corresponding activity diagram. At the beginning, the activity diagram is empty; only the EventAction parameters are present:
EventAction modeling is similar to Business Logic Process Operation modeling; Each diagram must contain an Initial Node, a final node, connected by a path on which treatment nodes will be added.
A very simple action event modeling, involving a simple opaque action (only writes to system console):
To get an idea of all modeling possibilities please refer to the Business Logic Process Operation modeling documentation (2); the differences from business logic process operation modeling are listed below:
- The initial node does not need to be followed by a CallOperationAction (as opposed to process operation);
- The existing View/Components UI elements do not need to be declared as Central Buffer Nodes to be used within the diagram;
- It is possible to use CallBehaviorAction in the diagram (cannot be done for process operations);
- It is possible to model Transaction scope handling.
Create an EventAction
Create an activity by using the contextual menu. This activity should be owned by the component.
- The name for the activity should reflect the targeted event : in our example, the activity will be named clickMeClicked:
- Once the activity has been created, make it an EventAction by applying the <<EventAction>> stereotype:
- Add a parameter to the activity, representing the event type that will be triggered:
The parameter type must be chosen from among the existing event types, either in the events part of the Rich UI Blu Age profile:
...or in the custom defined event types of the project.
Now create the corresponding activity diagram (should bear the same name as the activity) using the contextual menu.
A window related to parameter will appear, like this one:
Leave all the boxes ticked and click on [OK] button.
- Forward to an external screen
Each event can forward to an external screen. Simply drag and drop forwarded view in your event description:
- Open a popup
Opening a popup using an event can be done following the instructions bellow.
Use the operation showDialog and hideDialog.
Call the operation using a CentralBufferNode typed CommonDialog and named this.
The name of the dialog to open is needed for the operation showDialog (here it is "dialog001").
This works for the Panel typed "dialog" and "confirmationDialog".
- Specific events and behaviors
- OnLoad (precontroller) and PostBack
An event onload can be describe using the event type EventOnLoad, it is possible to manage the post back using the operation "isPostBack" defined in the stereotype <<View>>.
You must declare a CentralBufferNode typed "View" and named this to call the "isPostBack" operation.
- Calling native client code
The Event Bus allows the user to call generic services with a different implementation for each screen. It is a modularity option proposed to manage contextual behaviors.
Create a new custom event type stereotyped <<UserEvent>> (we will call it "EventItemDetail"): The event can contain its own parameters and methods:
Create a new event in your screen typed "EventItemDetail":
Describe the service in the previous event created:
Create a new component with a standard event, and call the custom event inside:
Set all the properties needed to call the custom event, call the event using the operation "fireEvent" from the <<View>> stereotype:
To recap the use case:
- Create a new event MyCustomTypeEvent,
- Define the specific behavior in an "EventAction" typed MyCustomTypeEvent in the screen which needs a particular behavior,
- Define the custom typed event in a sub-hierarchy of the package stereotyped <<PK_VIEW>> with properties if needed,
- Create an event in a "View" or in a specific "Component",
- Call the custom event in the "EventAction" using the operation "fireEvent",
Using a component calling a specific behavior:
Using the same component with another behavior:
Instances beans in view and simple controller
|An instance can only be a bean containing properties/attributes or associations. Rich UI models do not support independent primitives (such as binding a value on an integer or passing a string to a component.)|
|Important, technology related: JSF only supports java.util.List in Data Table/DataGrid, Drop Down, Repeater and AutoComplete. If you use an instance coming from the persistence layer it will likely have a PersistenceSet or a java.util.Set. The best approach is using a transfer object such as a <<VO>>.|
An instance bean can be declared either as an attribute of an activity or as class stereotyped <<bean>>. If the bean is declared as a Class<<bean>> it must inherits from the BO or VO it represent.
Instances bean and view controllers are separated. Meaning an instance bean (Managed bean) can be used in any views or simple components.
Example for activity attributes (teamVOList, selectTeam and selectedPlayer will be generated as managed beans):
|Declaring an instance in the activity won’t link it with the controller. However, using an instance in an Event will generated the necessary code to copy back and forth the instance from the presentation context to the business context.|
Example for a single Class<<bean>> declaration:
An instance can be transferred from a view to an instantiated component and from a view to another view.
Instantiated component instance transfer
To transfer an instance from the view to an instantiated component, the instance must be passed as a parameter of the component activity.
Example component activity parameter declaration (passing bean team):
Example component usage (here the team passed is the repeater iterator variable):
Instance transfer from view to view
In order to be able to transfer an instance during a view change or navigation, the instance must be stereotyped <<scopeView>> (see below 4.3.7) and <<transferInstance>>. The instance must be updated by an Event every time the transfer is needed. Please note, the instance transfer life span is one transfer or redirection.
Example model bean declaration (transferTeam):
Example event (note here the central buffer node is only present to copy/refresh the bean in the view context):
Dealing with scopes
Each instance declared on a screen has to be scoped correctly to make the application work.
There are four different scopes:
- request: default value, applied when a bean does not use any applied stereotyped;
- view: set when the <<scopeView>> stereotype is applied to the activity attribute;
- session: set when the <<scopeSession>> stereotype is applied to the activity attribute;
- application: set when the <<scopeApplication>> stereotype is applied to the activity attribute.
- Request: a bean in this scope lives as long as the HTTP request-response lives;
- Session: a bean in this scope lives as long as the HTTP session lives;
- Application: a bean in this scope lives as long as the web application lives;
- View: a bean in this scope lives as long as you're interacting with the same JSF view in the browser window/tab.
Note: The same instance can be used in multiple views, in that case, the scope needs to be the same in every screen. If the scopes are different you will find below the generation priority.
In the following case, the View scope will be applied.
In general, the view scope is the most commonly used.
Dealing with zone updates and zone process (Ajax)
There are two main categories to execute an Ajax behavior and refresh specific zones: Update/Process.
- We need to refresh a specific zone, and also execute all the JSF phases (even the validation) for all the controls of the view
- The use of zoneUpdate and zoneUpdateType are used to express that behavior.
Each control can set these properties zoneUpdate: Select a specific zone to refresh (an input text, a panel, etc), multiple controls can be specified zoneUpdateType: Generic selection to refresh specific controls. The allowed values are:
- none: refresh nothing (default),
- all: refresh all the view,
- parent: refresh the parent component and all its content,
- this: refresh the current control,
- form: refresh all the form content.
- We need to process a specific operation in Ajax and do not need to execute the validation phase
- The use of zoneProcess and zoneProcessType allow expressing that behavior.
Each control can set these properties zoneProcess: Select a specific zone to refresh (an input text, a panel, etc), multiple controls can be specified zoneProcessType: Generic selection to refresh specific controls. The allowed values are:
- none: refresh nothing (default),
- all: refresh all the view,
- parent: refresh the parent component and all it is content,
- this: refresh the current control,
- form: refresh all the form content.
- Define a specific encType: use the tagged value "encType" present in the <<Shell>> stereotype,
Rich User Interfaces Elements
The Rich UI offers two types of controls. Controls to define the view which are under the form of stereotype and managed controls to handle view components which are classes stereotyped <<Control>>.
The views controls are used in Activity Diagrams, and are mainly applied on Central Buffer Node and Structured Activity Node.
These controls are used in the view controller to manage UI behaviors. For example it’s possible to set a panel using java code.
Here is a sample usage of Controls in an event: