The overall architecture choice is based on the Java EE specification that provides a framework for n-tier enterprise applications.
General decoupage of the architecture
The detailed design choices focused on a server-side four-layer architecture:
- The presentation layer providing the functions of management of the user interface.
- The service layer providing the interface functions between the business layer and the presentation layer, as well as a set of technical services: cache, XML / XSL transformations to HTML or HTML to XHTML.
- The business layer managing objects that model the business activity.
- The data access layer that ensures the persistence of business objects.
Content rendering scheme
The following diagram shows in a simplified way the process of rendering a Front Office content. The schema reads from left to right and represents the different steps beginning at the client's HTTP request and ending at the server's HTTP response. The diagram is followed by explanations of the different steps and detailed descriptions of the different layers.
The different components are represented by different symbols: those of the presentation layer by simple rectangles, those of the service layer with a gear, those of the business layer and those of the data access layer by a sheet of paper. The colors indicate in white the components of lutece-core, in blue the components of the plugin-document, a standard plugin of lutèce, and in green of the components which could be brought by a new plugin. This diagram gives several examples of architecture that can be inspired when writing new plugins.
As seen earlier, Portal.jsp is the rendoring entry point. Like all JSPs in Lutece, Portal.jsp uses a <jsp: useBean> directive to load a java bean (here PortalJspBean), which makes it possible to write the code in a normal java class to facilitate maintenance. PortalJspBean implements methods that correspond to different user operations, and delegates most functionality to java classes of services: PortalService, ContentService, AppPropertiesService, and so on.
The next step is to use the HTTP settings to select a Content Service. Content Services are java classes that mainly include an isInvoked method that specifies HTTP if this service is requested, and a getPage method that returns HTML content using a cache. Content Services comes from the core of Lutece or plugins. To resume the examples of the previous chapter, here are different Content Services:
- PageContent Lutece-core service, http parameters "page_id = n". This Content Service manages the editorial pages of the site. These pages are configured in back office by organizing portlets. These pages are organized in a tree structure of the site Lutece reflected in the menus and the breadcrumb.
- XPageAppService of lutece-core, http parameters "page = name". This Content Service manages stand-alone pages called XPages that provide specific features. The content is entirely manufactured by the java class called and is generally not as editable as the pages of the PageContentService with their portlets.
- DocumentContentSerivce of plugin-document, http parameters "document_id = n & porlet_id = m". This Content service is provided by the document plugin which offers in Lutece typed contents (for example, article, brief, etc.) organized around a publication workflow (management of collaboration, validation).
On the content rendering scheme, in part 3a), if a PageContentService page is requested, the bean addresses the PageService that will provide the page if it is in its cache or else it will build it. Building a page uses the PageHome class to get an instance of the requested page. Then, the content of each section of the page is retrieved in XML then transformed using the associated XSL stylesheet, and aggregated to constitute the page. The new constructed page is then cached. Here, the important point of architecture is that class services rely on classes of business objects, such as PageHome and Page, which load their data from Data Access Object (DAO) objects, such as PageDAO. Parts 3 (b) and 3 (c) operate on the same principle, relying on different technical services and business objects.
Software architecture by brick: description of the software layers
This layer is made using JSP, Java Beans, possibly servlets. HTML code is produced in two ways:
- For the most dynamic elements of the portal (for example, documents in the plugin-document), HTML is produced by transforming XML content using XSL stylesheets. The XML content may itself contain HTML code for all unstructured content including local pages.
- For items that do not require support for multiple rendition formats (for example the admin module or XPages), files containing HTML representation templates called Templates will be used.
As a reminder, we are talking here about the category to which Portal.jsp belongs, the main point of entry for the content of the Front Office.
In general, the role assigned to JSPs is strictly limited to managing page structure and navigation. The HTML part will be built by beans that will use templates to build the code that will be inserted into the JSP pages.
The JSPs will therefore essentially contain:
- the <jsp: useBean> directive that loads a bean containing most of the code.
- the redirection directive on the error page: <% @ page errorPage = "path / to / ErrorPage.jsp"%>
- inclusion directives for static objects: <jsp: include> (eg HTML code to include a style sheet)
- conditional branching (<jsp: forward>)
All Java and HTML code is forbidden in these pages.
JSPs must all contain a header JSP and end-of-page JSP. This makes it possible to integrate initial and final processing in all pages without having to modify all the pages (eg test session timeout, HTML header and footer, link to a style sheet, adding treatments statistics, ...).
The Front Office primarily uses only Portal.jsp, while the Back Office uses many JSPs. This allows for more consistency in the Front Office and more flexibility in the Back Office.
As a reminder, we are talking here about the category to which PortalJspBean belongs, the bean associated with the JSP Portal.jsp seen in the examples.
These beans are responsible for managing the presentation of information from business objects. In particular, they must produce HTML code that will be inserted into the JSPs. These components are grouped in the package fr.paris.lutece.portal.web for the core of lutece, fr.paris.lutece.plugins. *. Web for plugins. and have a JspBean suffix to differentiate them from business beans.
JSP beans can be used by multiple JSP pages that process the same information, including sharing constants.
The scope of the JSP beans (scope attribute in the declaration of the bean in the JSP) must be either session if it contains instance variables relative to the user's session (conversational state), or request if it does not. has no instance variable. In some cases, the scopes page or applications are also used.
After the templating Freemarker, some additional transformations are performed in this order:
- 1) Processing of multilingual labels introduced in the form. The management of internationalization (i18n) will be described later in a dedicated chapter.
- 2) The treatment of labels in the form DS Value Missing whose values are stored in database (in the datastore of Lutece).
- 3) Treatments of any ContentPostProcessor like those of plugin-extend or plugin-seo plugins.
The advantage of these templates is that they can be shared by several JSPs and can be modified by graphic designers without the risk of impact on the processing. These templates will be stored in the / WEB-INF / templates directory.
XSL style sheets
XSL style sheets are used to transform XML content into HTML. By this mechanism, the content of the form is separated. By simple change of style the same contents can be presented in a very different way.
Services are used to implement features that are not directly related to the creation and modification of a business object and its data. This is often the most important part in terms of distributing features of an application.
It is in this category that Content Services, which implements the framework in which most of the contents of the Front Office are rendered: PageContentService and XPageAppService.
A number of technical services provided by the core are accessible from the components of the application. For example:
|AppTemplateService||Returns an HTML template from its name. This service has an activatable cache that allows you to not replay on disk a model that has already been requested.|
|AppConnectionService||Providing database connections from a pool. This service is configurable to use either the application server pool or a stand-alone connection pool.|
|AppPropertiesService||Returns the values of the variables defined in the properties files of the / WEB-INF / conf / and / WEB-INF / conf / plugins /|
|MailService.java||Allows the sending of mail in text or html format, with management of calendar events.|
|I18nService.java||Manages the translation of strings according to the choice of the user|
|AppLogService.java||Manages logs with different severity levels, different loggers|
|XmlTransformerService.java||Manages the XSL style sheet application to transform XML content.|
It is not a question here of giving an exhaustive list of the various services of the core, because the nature of the services makes that very varied functionalities are implemented there. It is advisable to browse the core code and essential plugins (eg plugin-document, plugin-directory) for examples of features to be grouped into classes of services.
The business layer
The business layer is performed by a set of classes corresponding to business objects.
These classes do not contain any HTML or SQL technical code. These components are grouped in the packages fr.paris.lutece.portal.business. * For the core and fr.paris.lutece.plugins. *. Business. * For the plugins.
The persistence of these objects is provided by Data Access Object (DAO) objects whose interface contains the main data access methods corresponding to the basic SQL operations: load (SELECT), store (UPDATE), create (INSERT) , delete (DELETE).
We decided to have a design close to the Enterprise JavaBeans, and we use a "Home" class for each main business object, that is to say having a CAD, inspired by the EJB Home Interface. The prerogatives of these classes are, as for the EJB, to manage the instances of the business object:
- Creating an instance (create () method)
- Returning an instance from its primary key (findByPrimaryKey () method)
- Return a collection of instances for a given criterion (findByCriteria () methods)
To these methods that appear in the EJB entity Home class interface, we will add the methods that normally correspond to actions handled by the EJB container. Since the Home object is the only object that has access to the DAO, it will be responsible for editing and deleting the entities in the database.
Calls to these methods will be made through the update () and remove () methods at the business object level.
Here is the summary table of the classic interfaces of the different objects. A line represents related methods, their scope, and the existence of this method in the entity EJB programming model:
An important recommendation of EJB entity design is to have a fairly large granularity, ie any business object does not have to be implemented as an entity EJB. All business objects that depend on a primary business object, and especially in the case that it is read-only, must be implemented as a simple class. The reading of this object will then be performed at the DAO level of the main object.
The SQL queries written in the DAO files must be compatible with the SQL92 standard.
SQL queries and column types in database creation scripts must be compatible with MySQL or MariaDB databases. The Lutece system for creating the Ant-based database provides transcription for PostgreSQL, HSQLDB and Oracle DBMS.