1.1. Programming paradigms

MVC and the composite pattern

The OLAT-Core 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 OLAT-Core are very much like components in Java SWING, in fact, the whole GUI layer in OLAT-Core 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.

Note

In previous versions the OLAT-Core framework has been called "Brasato". We changed this Brasato branding back to OLAT-Core to simplify things for developers. Correspondingly, the filename brasato.css has been renamed to core.css since the OLAT 7.0 release.

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 that reacts to events generated by those components.

Components are reusable and generic GUI elements. Sometimes, components are also called widgets. In OLAT-Core, we have GUI components like tables, forms, menu tree, links and many others. Note that all this components are completely business independent. 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 OLAT-Core framework, it is most likely that you will never have to create a component by yourself. There is a stable set of elements provided by the framework that is used by developers to create a rich user interface.

OLAT-Core components displayed in the hierarchy browser

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 it 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 container's area. The position of the container itself is again unknown since the container is a component as well.

There are three important containers in OLAT-Core:

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

  • Panel: a placeholder container. A Panel is used when you don't know yet what your view will be, but you know that there 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 flexible

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

To enable the OLAT-Core debug mode, the property olatcore.debug=true must be set in the olat.properties file. The GUI debug mode is then started in the debug window that you can find at the top left corner of the browser window.

Start the OLAT-Core GUI debugger
A link component in a container in a container in a container ... in a window

Controllers

While the MVC pattern separates the view part of your code from the workflow part, 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 OLAT-Core framework is that it takes care of the whole dispatching process for you and offers a way to break down a whole business process workflow in manageable and reusable controller and view parts. In OLAT-Core, 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 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 done in a so called manager class. The controller is only responsible in controlling the users GUI workflow, the workflow logic.

  • 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 controller 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 controller 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 OLAT-Core framework you actually use the TableController and not the Table component. The reason is that the table component got too many features and is 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.

For your convenience the OLAT-Core framework offers a feature rich BasicController implementation. The BasicController has methods to easily initialize VelocityContainer objects, to show info, warn or error messages, it creates a package translator for you and auto-disposes child controllers when used properly. You should always start by subclassing from the BasicController when you build your own controller!