- 06 Dec 2010
This chapter introduces the basic concepts necessary to use the XEO framework and learn XEO's approach to development.
XEO's approach to development
XEO was designed from scratch with the purpose of modeling real-world entities using an object oriented approach, as the team felt that that was the most natural way of developing an application. Being able to create an entity, its data model and web pages for listing all instances of that entity (with options such as ordering and grouping), editing single instances and searching a particular instance, while still being able to use customized logic to implement behavior and without dealing with all the low-level complexities was truly the ultimate goal.
Developing starts by defining a set of entities (XEO Object Models) and their properties, using XEO Studio's Object Model editor (a graphic editor for a specific XML language that is used to represent said XEO Object Models). The "XEO Builder" then processed those entities to generate the data model and support classes to interact with instances of said entities. Using the Object Model as a base, web viewers for listing, edit and search instances can be "scaffolded" (think Ruby on Rails) by XEO Studio.
Using XEO is all about modeling business entities as XEO Object Models, which will be used by the framework to create the data model, logic and web layer for each of those entities, which can then be further customized to fit the logic of the business that application is intended to. Let's begin with the basics of a XEO Object Model (to know more about how a XEO Object Model is used to build your application, check the " XEO Model Builder
XEO Object Model
An Object Model is the XEO representation of a business entity. Almost every business entity can be described with a number of "attributes" and relations with other entities (be it relations of extension, 1-1 relation, or 1-N relation). For example, if we're modeling a entity that represents a "Book" in real life, that book would probably have attributes such as the book's title, the book's ISBN, the author's name, the edition number or category list (drama, romance, etc...) of the book. In the following section, you'll learn how more about attributes of a XEO Model.
In a XEO Object Model, attributes modelling the properties of a business entity can be of different types. XEO provides attributes that represent Textual values ( WebXEO.AttributeText
), Numeric Values ( WebXEO.AttributeNumber
), Date and Time values ( WebXEO.AttributeDate
), Sequential Values ( AttributeSequence
), Long textual values ( WebITDS.AttributeLongText
) and Boolean values ( WebXEO.AttributeBoolean
) as well as attributes to make a 1:1 relation (single relation - AttributeObject
) and to make a 1:N relation (a relation to a collection of instances - AttributeObjectCollection
Each of those types of attributes have specific properties which can be set to customize the attribute's behavior, which you'll see further in the documentation. These properties vary with the type of attribute, naturally. For example, a Numeric attribute can have a property maxValue
(which specify maximum and minimum values the attribute can hold) while a collection attribute can have the maximum number of instances to which the first can relate to (or declare the type of Object Models to which the first can relate to).
Each instance of XEO Object Model has a set of predefined attributes which are used by the framework for various operations. Here's a list and description of those attributes.
- BOUI - (Business Object Unique Identifier) - Long, representing the instance's internal identifier. Relations between instance objects are done using the BOUI, security policies are based on the BOUIs, also.
- SYS_DTCREATE - (System Date Creation) - Date where the instance was created
- SYS_DTSAVE - (System Date of Last Update) - Last time where the instance was saved
- PARENT - The BOUI of the parent instance object for this instance.
- CREATOR - The BOUI of the user that created the current instance
Custom Behavior (Logic)
One of the defining features of XEO is the possibility to associate business logic directly to the Object Models, and also with their attributes. By allowing business logic to be "embedded" in the Object Model, instances of a given model become almost like "living entities" which respond to events and have customized actions all without you having to write complex code managing event handling and etc. Custom business logic is defined using the Java Language and interaction with the current instance object (or other objects) can be done by using XEO's Java API. Such logic can influence the viewer layer, because logic can determine whether a given instance/attribute is visible, required, disabled, etc...
Let's take a look at the possibilities for defining business logic in an Object Model.
Attributes themselves can have logic associated. For example, a certain attribute may have a default value that is calculated, or its value may need be validated when it changes (and that validation, may required more or less complicated operations).
Attributes can have logic to define the following:
- Validation (code that will run when the parent instance object is saved, to check if the current value of the attribute is valid)
- Default Value (code that will run when the parent instance object is first saved and the value of the attribute was not set)
- Requirement (code that determines whether or not the value of this attribute must be set before the parent object can be saved)
- Disabled When (code that will determine when the attribute is disabled (i.e. its value cannot be changed))
- Hidden When (code that will determine when the attribute is hidden - this logic is directly associated with the viewers layer.
- Formula (code that will run to determine the value of the attribute, allows to do calculations and such)
Every instance of an Object Model can react (i.e. execute Java code) to certain predefined actions in its life cycle. Each action generates two events (an onBeforeAction
event and an onAfterAction
event) in which you can write your code, the list of actions (and events) is as follows:
- create ( onBeforeCreate and onAfterCreate)
- load ( onBeforeLoad and onAfterCreate)
- save ( onBeforeSave and onAfterSave)
- destroy ( onBeforeDestroy and onAfterDestroy)
Event returns a boolean value. If the returned value is true, the action (load, create, save, destroy) associated with the event is carried on, otherwise the action is not executed (this allows, for example, to control when an object is to be deleted, if all required conditions for that to happen are met)
In figure Concepts.1 is depicted the XEO Events mechanisms and when they are triggered given a certain action performed on an instance object.
Figure Concepts.1 - XEO Events flow
Attributes may also react to events triggered by actions made upon them and there are three groups of events available. The first group of events (regular events) is applicable to all attributes, except collection attributes (AttributeObjectCollection
), the second group is only applicable to collection attributes (collection events) and the last group contains the events that are common to all attributes (common events). The List is as follows:
- OnBeforeGetValue (Triggered before a value is loaded into the attribute)
- OnAfterGetValue (Triggered after the value is loaded into the attribute)
- OnBeforeAdd (Triggered before an object is added to the collection)
- OnBeforeLoadBridge (Triggered before the collection is loaded)
- OnBeforeChangeOrder (Triggered before an object in a collection is moved inside the collection, when it changes the order of the object)
- OnBeforeRemove (Triggered before an object is removed from the collection)
- OnAfterAdd (Triggered after an object is added to the collection)
- OnAfterLoadBridge (Triggered after the collection is loaded)
- OnAfterChangeOrder (Triggered after an object is moved inside the collection, when it changes the order of object)
- OnAfterRemove (Triggered after an element is removed from the bridge)
- OnBeforeChange (Triggered before the attribute is actually changed)
- OnAfterChange (Triggered after the attribute is actually changed)
Using XEO, business logic can be created right along side the model of the entity, in the form of "Methods". Methods are entry-points in a XEO Object Model to declare business logic associated to the entity; those methods will be available in all instance objects and can perform any desired actions.
Imagine, for example we're dealing with Invoices (each Invoice has several "Invoice Lines" and each of those lines has a state indicating whether it has been processed or not). The Invoice entity has a flag (true/false) which determines when that Invoice has been processed (an Invoice is considered processed
when all its items [Invoice Lines] have been processed). At a given point in time in the application, some action occurs and the consequence of that action is that a certain invoice should be considered "processed". Using XEO Methods, we can define a processInvoice
method (which will be available to all instances of the Invoice XEO Model) that will check every Invoice Line of the instance and set its processed
attribute to true and in the end, change the processed
attribute of the Invoice to true.
By declaring a method in a XEO Object Model that behavior becomes available to every instance; furthermore if that Object Model is used in another application that behavior is taken along with the Model definition, there's no need to "hunt down" the code in the application's logic layer.
In figure Concepts.2 is depicted how the process of defining and invoking a XEO Method on an instance object works.
Figure Concepts.2 - XEO Model Methods
One important factor when creating a business application is security (including permissions). XEO has a feature named Object Policy Labeling (OPL) which helps to create a permission system for a specific Object Model Instance or, more broadly, for an Object Model (or an attribute or method of the Model). The first security mechanism is called Object Model Permissions.
Object Model Permissions (Policies)
Object Model Permissions allow you to specify which set of users can read/write/add/remove or execute certain XEO Model Instances, Attributes or Methods. For example, if you have a XEO Model representing your company projects (named Project) and each project has an attribute representing the total income of the project, you may want that value to be only viewable by a manager, as such, you can create a rule that allows only users of the groups "Managers" to read the attribute "Total Income" of any instance of the "Project" XEO Model and that will be a system wide permission.
Object Model Permissions permissions are runtime permissions, i.e. they're defined using XEO's administration interface
. These permissions are also known as Policies.
OPL (Object Policy Labeling - Instance Permissions)
When creating an instance of a XEO Model, we can determine who has the permission to read the instance, change the instance, delete the instance or have full control over the instance, these type of static permission declarations are called AttributeKeys
(there's a more dynamic alternative, called ClassKeys
A note before explaining the OPL mechanism: The XEO framework includes some System XEO Models which represent entities such as Users, Groups and Profiles and those Object Models are required to set the OPL mechanism (worry not, because it's possible to use your own users/groups with OPL)
The main idea is to give read/write/delete/full control permissions to instances of a User/Group/Role XEO Model which means a given XEO Model must declare an AttributeObject
relation to a User/Group/Role and then a read/write/delete/full control permission can be given to the User/Group/Role instance to which the first relates to.
Figure Concepts.3 depicts and example of OPL usage.
Figure Concepts.3 - XEO Object Policy Labeling* *usage
There's also the possibility to create user-defined permissions by implementing specific interfaces. Implementing these interfaces allows great liberty for developers which may define complex permission rules, such as "a given group can only change instances on even days between 13:00 and 15:42", these are known as Class Keys
XEO Interfaces / Extension
Most object-oriented languages have concepts like Inheritance and Interfaces (of some sort). XEO being a Java-based framework makes use of those concepts in its XEO Object Models.
XEO Object Model Extension
When creating a new XEO Object Model you can extend an existing Object Model (and inheriting all of its attributes, events and methods). If needed, all of these can be overridden in the new Object Model. Extension can be seen just like in a regular object oriented programming language (there's no multiple inheritance, like in C++).
A XEO Interface
A XEO Interface is similar in purpose to a Java Interface, meaning that XEO Models that implement the XEO Interface share the same type, but contrary to Java Interfaces
, in XEO Interfaces you can define regular object attributes, events and methods and when an XEO Model implements the XEO interface it will inherit all of the interface's attributes and events (not methods)
In figure Concepts.4 an example of Object Model extension and Interface Implementation is depicted.
Figure Concepts.4 - XEO Model Extension and Interfaces, how inheritance works.
Orphan / Non-Orphan Object Models
In most applications there's a notion of entities that can only exist if another entity exists, or more properly, an instance of an entity can only exist if another instance of an entity exists, frequently this is called a parent-child relationship where the child cannot exist without its parent. XEO mimics this behavior with the Orphan/ Non-Orphan Concepts.
Contrary to what its common in our society, the most common types of XEO Models, are Orphan
. This means that instances of that model can exist without the need for a parent (hence the term "Orphan"). Instances of Non-Orphan Object Models can only exist in the context of a parent instance.
XEO will only allow to create instances of Non-Orphan Object Models, if there's a parent instance and the visual layer will reflect this situation. A good example of Orphan/Non-Orphan relation is the Invoice/Invoice Line example. An Invoice would be an Orphan Object Model and the Invoice Line would be a Non-Orphan Object Model.
XEO Object Models can be logically grouped in XEO Packages, which helps organizing an XEO application. XEO Packages can have sub-packages to further organize the application structure. XEO Packages do not, however, separate Object Models by namespace or package name, this means that if you create two objects with the same name in different XEO Projects, only one will make it your to application.
Along side XEO Object Models, XEO has the concept of a XEO Lov (List of Values). XEO Lovs are basically key/value pairs of identifiers and labels, which can be used as the values for an Object Model Attribute. If a given XEO Model represents a Person and it defines an AttributeText
representing that person's country, you can restrict the values of the Attribute to existing countries by using a XEO Lov. XEO Lovs are statically (at design time) created, but their values are stored in the database, as such, the list of values can be changed overtime.
At the heart of the XEO Framework is the XEO Builder. The XEO Builder is responsible for most the "magic" behind the scenes, which is analyzing all XEO Models and creating the underlying support structures. Each XEO Model is converted to a Java class (which is later compiled for use within your application) and database tables are created to support the current Object Model as well as auxiliary database tables (to support AttributeObjectCollections
with other Object Models).
The XEO framework, includes a set of System Object Models, which are required for the correct functioning of a XEO application (namely Objects representing groups, users, security features, etc...).
When creating a new project, all XEO Models will be "built" by the XEO Builder and all other required structures will also be created. Each new XEO Model added (or changed) to the project, does not require a complete build to the project. The XEO Builder is clever enough to detect changes to existing XEO Models and build only the required ones.
The XEO Builder is integrated in XEO Studio, the primary development environment for XEO application, so that any new Model (or change to an existing model) will be automatically processed.
XEO Web Components
The XEO Framework was created to produce web-applications, as such, it requires a visual layer in the form of web pages so that users can interact with instances of XEO Models, such interaction includes listing instances, editing specific instances or searching a specific instance.
XEO's Visual Layer is a component based layer, in which the combination of components creates the desired layout for the application. The component layer (named XEO Web Components) is based on Java Server Faces (JSF base components are actually usable along with XEO Web Components).
XEO Web Components are used inside a XEO Viewer
, which is essentially a container for the components. In a XEO Application there are four different types of Viewers (you can create custom viewers as well):
- Main Viewer (The viewer that creates the XEO Application's structure)
- List Viewer (A viewer to list instances of a XEO Model)
- Edit Viewer (A viewer to edit an instance of a XEO Model)
- Lookup Viewer (A viewer to search/select a specific instance of a XEO Model)
List, Edit and Lookup Viewers are designed to deal with instances of XEO Models, but are not limited to that
. Most XEO Web Components are independent from XEO Models and can be used to create interfaces that have nothing to do with them, i.e. you can create customized viewers to satisfy your own requirements
Bellow is a set of screenshots of the various types of XEO Viewers in an application:
(Defines the application structure, elements in the tree structure will be open as tabs in the white section of the figure, see examples in the following figures).
Figure Concepts.5 - Main Viewer of a XEO Application
(Viewer to list instances of XEO Models, can list the Model's attributes as columns of the table. Values can be sorted by column, grouped by column, filtered by a specific value, etc.)
" src="http://wiki.itds.pt/pub/WebXEO/XeoPrimerConcepts/ListViewer.png" title="XEO ListViewer
" height="474" />
Figure Concepts.6 - List viewer in a XEO Application
(Viewer to edit a specific XEO Model instance - you can edit simple (text, numeric, date) attributes, relations to other instances (single or multiple) and the layout can be arranged in different ways using XEO's Web Components).
Figure Concepts.7 - Edit viewer in a XEO Application
- Viewer used to search for a specific XEO Model instance (when you want to relate an instance with another instance, or add an instance to an object collection, for example).
Figure Concepts.8 - Lookup Viewer in a XEO Application
XEO Web Components are JSF-based, thus, they're declared using XML syntax, which will translate to a tree-like structure, as depicted in figure Concepts.9 (the content of the figure is a viewer having two tabs, and the first tab having a four different types of form fields ordered in a tabular like layout (two fields per row)
Figure Concepts.9 - Tree-like structure of a XEO Web Viewer (and its components)
The XEO Web Components layer is responsible for the translation between the XML definition of the viewer and its rendering to the web-browser, an example is seen in figure Concepts.10 where the XML definition is converted to the HTML rendering seen on the right of the figure.
Figure Concepts.10 - XML to HTML rendering of a XEO Viewer
In the next chapter you can learn more about XEO's internal architecture