1.1. Programming paradigms

1.1.1. MVC and the composite pattern

The brasato webapplication framework has two major implementation concepts:

  1. it implements the Model-View-Controller design pattern. From Wikipedia:

    Model-view-controller (MVC) is an architectural pattern used in software engineering. In complex computer applications that present a large amount of data to the user, a developer often wishes to separate data (model) and user interface (view) concerns, so that changes to the user interface will not affect data handling, and that the data can be reorganized without changing the user interface. The model-view-controller solves this problem by decoupling data access and business logic from data presentation and user interaction, by introducing an intermediate component: the controller.

  2. it implements the composite design pattern for a component based architecutre

Components in brasato are very much like components in Java SWING, in fact, the whole GUI layer in brasato has been inspired by the SWING architecture. In such a component based architecture, the controller and the view elements are decomposed into a hierarchical structure of components and composite objects.

If you are not familiar with MVC and the composite design pattern, please bring yourself up-to-date before you continue reading.

1.1.2. Components

Components are visual elements displayed somewhere on the screen. They are generated by a controller that is responsible for this specific part of the view and who reacts to events generated by those components.

Components are reusable and generic GUI elements. Sometimes, components are also called widgets. In brasato, we have GUI components like tables, forms, menu tree, a link and many others. Note that all this components are completely business independet. The purpose of a component is to provide a certain functionality to display or manipulate data. What kind of data this is or in what greater context the component is used is irrelevant.

Components are basic elements of the brasato framework, it is most likely that you will never have to create a component yourself, it is a stable set of elements provided by the framework that is used by developers to create a rich user interface.

1.1.3. Containers and Component positioning

While the purpose of a component is to display a GUI element, the component itself does not know or tell the framework where exactly on the screen itself should be displayed. This is where the containers come in place. A container has the functionality to contain several components and to position them within the containers area. The position of the container itself is again unknown since the container is a component as well.

There are three important containers in brasato:

  • Window: the first container in the chain that represents the users browser window.

  • Panel: a placeholder container. This is used when you don't know yet what your view will be, but you know that will be something you have to display later

  • VelocityContainer: a HTML based container. Pure HTML is used to position components contained by this container, thus it is very flexibl

We can summarize, that a brasato webapplication GUI is a hierarchical structure or containers and components. In the brasato debug mode this hierarchical structure can be observed well. Each container has a thin dotted line that symbolizes the border of the container area.

1.1.4. Controllers

While the MVC pattern separates the view part from the workflow part of the code, it does not necessary make code component based. In simpler web applications it is very common to have one fat controller that dispatches all the requests and does more or less everything. This is normally the case when you use the servlet development model: for each workflow a dedicated servlet.

What is special about the brasato framework is that it takes care of the whole dispatching process and offers a way to break down a whole business process workflow in manageable controller and view parts. In brasato, developers don't write servlets, they write controllers.

So what is a controller? A controller has the following features:

  • Implementation of workflow logic: controllers react to events that occure due to user a interaction. e.g. a user clicks on a link, the responsible controller decides what the meaning of this action is and what business logic is triggered by this event. A sidenote: the controller should not implement the business logic itself, this should be sone in a so called manager class. The controller is only responsible in controlling the users GUI workflow.

  • Creation of a view. Each controller must have a view, a component that represents the viewable thing that this controller is about. This is done by executing the setInitialComponent() method in the controllers constructor. In most cases the controllers view part is either

    • a Panel: in this case the controler can swap its entire view. Remember, the panel is only a placeholder for a component that is generated later!

    • a VelocityContainer: in this case the controller can use many components and position them together with text elements using plain HTML and CSS code

  • Implementation of the composite pattern. There we have it again: a controller can have many child controllers. We come to this in the next chapter.

  • Managing of the data model: The first element in the MVC is the datamodel. It is initialized by the controller and handed over to the components that use the datamodel to display the data. Important to understand is the fact that whenever something happens, e.g. a user clicks the remove link in a table entry, the remove operation is not performed by the table component. Remember, the component has no business meaning, it is only a GUI element! The table component fires an event to the controller that created this table component, the controler does execute some business logic and removes the table entry from the table data model. When the table component displays itself, it just takes the updated data model and renders the data from the model.

  • Controller can be reusable: The higher up in the controller hierarchy, the less reusable is a controller. E.g. the MainHomeController can really just generate the home area as in the OLAT web application. There is little hope that this is reusable anywhere else. On the other hand the GroupController is used almost anywhere. It is a business context free controller that is very reusable.

Sometimes it is difficult to distinguish between components and controllers: why is something implemented as a controller and why some other things as a component? You will see that there are some components like the table component that have a wrapper controller. Whenever you use a table in the brasato framework you actually use the TableController and not the Table component. The reason is that the table component got too many features and to complex to handle all the configuration options that we wanted like pageing, excel download, table configuration and more. The controller has much more possibilities to deal with all this functionality. E.g. the table configuration feature needs a little data model to know which columns are enabled by this user. The controller can read this information from the database and implement a workflow to change the settings. This can't be done in a component. Remember, a component is only a view element, it does not implement a workflow!

So, sometimes the border between controllers and components is thin. Business context free controllers with a high reusability factor like the GroupController, UserSearchController or TableController behave very much like components.

1.1.5. How components are created: layout and control decomposition

It is important to understand how all those components and containers are created at runtime to get a full picture about the final layout. The following picture shows the most relevant controllers and components. To reduce complexity unimportant elements have been removed.

In this diagramm we focus only on layout relevant parts of the framework and ignore the brasato main seNrvlet and dispatching issues. It is enough to know that at some point the createChiefController method on the BaseChiefControllerCreator is called for a certain user request to create a new user window. First, a new BaseChiefController is created. This is the top of the controller hierarchy. The BaseChiefController creates an instance of the Window component and adds the HTML elements html, head and body in a VelocityContainer to that window. Therefore, the BaseChiefController is mainly responsible to provide framework related HTML fragments as the debug tools, the AJAX back channel and covers the whole issues of JavaScript and CSS inclusion.

Then, a SimpleBaseController is created that has a simple VelocityContainer view to add the GUI messages, modal dialog and a GUI stack feature. The SimpleBaseController wrapps the application specific base controller that handels the applications basic behaviour. In most cases this will be the BaseFullWebappController.

You might wonder how the framework knows which controller it should use as the application specific base controler: the BaseChiefController and the SimpleBaseController are both parts of the framework, but the BaseFullWebappController can be replaced with whatever super controller you like. We talked above about the BaseChiefControllerCreator that factored all this controllers - for this purpose the BaseChiefControllerCreator has a Spring injected ContentCreator that has the ability to create the base controller for the current web app. In this example the AutoCreator with the configuration className=BaseFullWebappController is used to create a BaseFullWebappController at run time.

The BaseFullWebappController deals with the main navigation and layout of the web app. We think the approach of a main navigation at the top - we call it Site - is universal and can be used for almost every web application out there. The BaseFullWebappController has a VelocityContainer as the main view part with is devided in to a section for:

  • web app header (#header): you could place a link or logo there. The area is controlled by a Sping configured HeaderController

  • the Site navigation (#nav): navigation for static sites and dynamic tabs, controlled entirely by the BaseFullWebappController

  • a static top navigation element (#topnav): for static links like the logout button, the search field, an imprint. This is controlled by the Sping configured TopNavController

  • the main area (#main): The main application area for the currently active site. The controller that is used in this area must implement the MainController interface. In most cases the Main3ColsController is used which features a 1, 2 or 3 column view.

  • the footer (#footer). use to display some footer information like logged in users or a link to the project homepage. This is controlled by a Sping configured FooterController

Note that the nomenclatura for this elements strictly follows the YAML web layout framework. The BaseFullWebappController layout is based on YAML.

The next level of layout relevant parts are generated by the controller that is responsible for the #main area. As I said, usually this is the Main3ColsController delivered by the brasato framework. More about this later. Within the Main3ColsController the three columns can be filled with whatever the application needs.

1.1.6. Dispatching, event and render phase

When implementing the MVC approach, another fundamental paradign is executed: the separation of the dispatching, event handling and rendering.

When a user request enters the brasato framework it gets automaticall dispatched by the DispatherAction. The framework computes then which component is responsible for dealing with the request and calls the dispatchRequest() method on this component.

There are two types of requests a component can dispatch:

  1. an component internal action: some user action that does only modify a view option of the component. E.g. in the Table component the user could click the table header which then sorts the table ascending or descending in this column. This action does not modify the data model nor does it modify anything in the system at all. It is entirely GUI related and component internal only.

  2. an component provided action: some functionality the component offers to the controller that created the component. E.g. in the Table component, when actually clicks on a link in one of the rows this is not a table interal GUI issue. This is the selection functionality of the table, one of the main features the Table component offers.

When component internal actions occure, the component will handel it and the dispatching phase is finished.

But when the action was a functionality the component offers to its Listeners in the component specification it is a whole differnt story. The Listener is the Controller who created the Component and attached itself as Listener. The listener gets informed whenever some of those functions are executed by the user, we call them Event. So, when the user presses this link in the table row, the Table component will fire an Event to the Controller.

Now we entered the event handling phase. Actually, this is still part of the dispatching phase since it happens during the execution of the dispatchRequest() method of the Component, but from a logical point of view this is not dispatching anymore. Sending events from a component to a controller, from controllers to parent controllers or even from controllers to global event buses implement the Observer design pattern, another fundamental design concept. But I'm not going into details here, it it enough to know that the components will signal controlles that a specific event happend.

In the event() method the Controller catches those events and executes some business logic. For example, the controller could call the UserManager and delete the user associated with the selected row from the database and refresh the data model of the table component. That's it: the controller catches the event from the component and manipulates the datamodel. (In other cases, the controller could fire events to its parent controller to signal that a certain workflow is now finished, and the parent controller could then remove the entire view of the current controller and replace it with another view. But at some point in the hierarchy, a controller will do some business logic and not fire an event anymore since everything has been done that needs to be done.)

Now, when the last event is handeld, the dispatching and event handling phase is finished and the framework continues with the rendering phase. At this point all the business logic has been done, all database transactions have been submitted, all states are set and we could call it a day for this request. Everythig that follows now is just rendering the data and the new state of the application.

The render phase is easy: the framework takes the current Window with the whole hierarchy of Components and Containers and traverses it with the Renderer. You can think of the Renderer as a transformer, it translforms the internal object structure into a HTML page. The Renderer has special implementations for each Component and uses those while traversing the component tree recursively. For example, the MenuRenderer will be used to render a MenuTree, the TableRenderer is used to display a Table component. Each of those Renderer produces a string that represents the rendered component as an HTML fragment.

The sum of all those component HTML fragments is the page as an HTML document. Thats it. In the end, the brasato framework delivers this page to the users browser.

1.1.7. Render phase in the AJAX mode

A very powerfull feature of the brasato framework is the automated AJAX mode. When the AJAX mode is enabled, the dispatching and event phase remain the same, but an importand difference happens during rendering phase.

Instead of applying the rendering to the whole Component tree starting from the Window object, the framework checks for each component in the tree if it actually has a dirty view. Dirty means, that the view of the Component changed since the last call. Only those components that are marked as dirty are rendered (including the components child components) and sent to the browser via a background AJAX channel.

In the browser, some JavaScript code detects the corresponding component in the HTML DOM tree and replaces it with the newly rendered component view it got from the server.

The effect of the AJAX mode is that the basic layout does not need to be redrawn by the browser, only parts in the DOM tree change. This results in a more vivid user experience due to lower network traffic and less computer power needed to draw the HTML page in the browser.

From a programmers perspective nothing special has to be done to support this AJAX mode unless a programmed does some custom dispatching.

1.1.8. General component rendering

Components are rendered programmatically in Java code. The render() method is executed. To understand how a component is mapped to HTML one must read the Java sourcecode. To modify the rendering, the class must be patched and recompiled. Component Renderer are in the same package as the components in org.olat.core.gui.components.* .

1.1.9. VelocityContainer rendering

A special case is the VelocityContainer component. The main feature of this Container is to position contained child components using HTML markup and to add other elements like internationalized text fragments. This is implemented using the Apache Velocity templating engine. When constructing a VelocityContainer instance in a Controller, the path to a velocity template file is one of the main elements of the constructor. The templates are normally stored in a special directory _content on the same level as the controller that constructs the element. During the render phase, the VelocityContainer will use this template to create the HTML fragment.

The advantage of this approach is that it is very simple to write Velocity templates and to position other objects like child components, translated strings or objects that represent parts of the data model. A so called VelocityRenderDecorator offers many helpfull methods in the template like translating, URL generation, child component rendering and much more. The render decorator can be accessed using the $r variable in the templates.

Most elements in a brasato web application are implemented in velocity containers, almost every controllers view is constructed using a VelocityContainer. Therefore, most of the HTML code generated in the render phase is defined in the velocity templates. In most cases you can forget about how other components are rendered, most likely you will never need to modify anything there. But for customizing the brasat web application layout, it might very necessary to modify some of the velocity templates.

See the Velocity User Guide for more information about the possibilites in the velocity engine.

1.1.10.