Welcome to the cdi-training Wiki!
The intention of this repository is to provide a training for the JakartaEE CDI 2.x specification. This project will be developed under the umbrella of a Gepardec Learning Friday Project.
Developer Guide
This page represents the guide which will help you to setup the project on your local machine and tells you how to contribute to the project.
The project is based on the following listed specifications.
Jakarte-EE-9Jakarta-MVC-2.0.0(JSF as template engine)
The project uses the following client side libraries in form os webjars.
MDB-3.9.0(Based on Bootstrap 5.Final)Fontawesome-5.15.2
System Requirements
This project depends on the following software:
How to set up your environment
Install the depending software, check out the github repository and setup the IDE of your choice. See the repository root README for further details.
How to provide documentation
All of our documentation is available as Github Pages, which relates to the projects repository.
How to use Git Branching
We use the simple Github-Flow because we need no special version handling.
We name our feature branches feature/<ticket_id_or_expresive_name> and merge them via reviewed Merge-Requests.
How to implement (MVC) Controllers
Controllers are JAX-RS endpoint classes with the naming scheme *Controller e.g. InjectController
which provide http based action endpoints and for views to render.
All controller classes need to be annotated with:
@RequestScopedbecause in MVC we are stateless@Controllerwhich enables the MVC framework for all contained methods
If not all contained endpoints return a view, then only those endpoint methods need to be annotated with @Controller
which return a view.
The http endpoint are named either as:
- The http method used e.g.
@GET get() - The action name e.g.
@Path("/action") action()
The endpoints either return
Stringif a view is returned,- or
Responsewhen no view is needed
See the following snippet for an example controller implementation.
import jakarta.ws.rs.core.Response;
@Path("/path")
@RequestScoped
public class MyController {
@Path("/")
@GET
@Controller
public String get() {
return "path/index.xhtml";
}
@Path("/action")
@GET
@Controller
public String action() {
// Do something and return the page
return get();
}
@Path("/post")
@POST
public Response action() {
// Do something and return the response
return Response.ok().build();
}
}
For further learning about Jakarta-MVC controller see the Jakarta MVC 1.1.0 specification.
How to implement (MVC) JSF views
The template engine we have chosen is JSF where we only use the templating part of JSF to provide us with common components, so
that we have consistent views and an easy way to implement views. The rest is actually plain html, css, text and javascript.
The root directory for our views is src/main/webapp/WEB-INF/views where we organize our views with the following structure.
/context
The directory which encapsulates the resources and views of a context which could be for instancebasicoradvanced./index.xhtml
The index page for a context which is the entry point and contains the links to the several views./example-one.xhtml
The view for the example one.
See section for a list of available JSF components for building GUIs.
How to provide static resources
In Jakarta-MVC static resources can be provided when located in the webapp directory. The static resources are referenced via normal links,
no JSF involved.
The main thing to consider is that the @ApplicationPath(...) of the JAX-RS Application must not define the root path, because the rest engine cannot provide the static resources.
The static resource are organized in the root directory src/main/webapp/resources and with the following structure.
/<framework>-<version>
The directory for a framework such asmdbwhich also defines the version.
If a webjar of the used framework exists, then the webjar should be used./css
The directory for all the applications stylings./img
The directory for all the applications images./<context>
The directory holding the images for a context/<view>
The directory holding the images for a context view
All provided images must be PNG files.
How to use javascript
Inline javascript must be avoided, and all javascript for a page is implemented in its own file as a javascript ES-6 module.
The root directory for all javascript files is src/main/webapp/resources/js where the javascript files are structured in subdirectories depending on the
context they are used for.
/The directory for commonly used javascript modules, which can be used in any page and other javascript modules./tags
The directory for javascript modules used by JSF tags./basic/<mp_spec>The directory for all basic examples javascript modules of a specification./advanced/<mp_spec>The directory for all advanced examples javascript modules of a specification.
Javascript modules are implement at least in the following way.
// Optional state object
const state = {
attribute: value,
};
// Optional (e.g.: click event listener registration)
const registerElementClickEventListener = (options) => {
const {
element,
} = options;
element.addEventListener('click', () => console.log('element clicked'));
};
const init = (options) => {
};
export default {
init,
};
Parameters for the javascript module are always provided as an options object. If html elements are used in any ways, then the html element instance itself is provided and never ids.
Javascript modules are used in a xhtml page the following way.
<!-- Inserts the contained tags at the end of the HTML page -->
<ui:define name="bottom">
<!-- The used javascript is a javascript module -->
<script type="module">
// '#{pathHelper.buildResourcePath("/js/mp.js")}' is a EL-Expression which gets resolved to ''/mptraining/resources/js/mp.js''
// Imports your modules
import mp from '#{pathHelper.buildResourcePath("/js/mp.js")}'
import myModule from '#{pathHelper.buildResourcePath("/js/basic/<MP_SPEC>/myModule.js")}'
// Initializes your javascript module once per page load
mp.registerOnLoad(() => myModule.init({
...
}));
</script>
</ui:define>
JSF Components
Tags
The custom JSF tags implement GUI components which are used globally.
xmlns:tag="http://tags.microprofile.training.gepardec.com"
Button
Renders a link acting as a button, for executing GET requests like with a link.
Attributes:
id
The page unique idtext
The text for the buttonpath(Optional, Default=’#’)
The relative path from the rest application path on, or a in-page references via ‘#’rendered(Optional, Default=true)
The rendered flag
<tag:button id="toMyActionOrResource" text="Go to example"/>
<tag:button id="toMyActionOrResource" text="Go to example" path="#otherId"/>
<tag:button id="toMyActionOrResource" text="Go to example" path="/basic/index"/>
Link
Renders an ordinary link with a text for executing GET requests.
The component accepts children, for instance an icon.
Attributes:
id
The page unique idtext(Optional)
The text for the linkpath(Optional, Default=’#’)
The relative path from the rest application path on, or a in-page references via ‘#’.target(Optional, Default=’_self’)
The link targetrendered(Optional, Default=true)
The rendered flag
<tag:link id="toMyActionOrResource" text="Go to example"/>
<tag:link id="toMyActionOrResource" text="Go to example" path="#otherId"/>
<tag:link id="toMyActionOrResource" text="Go to example" path="/basic/index" target="_blank"/>
<tag:link id="toMyActionOrResource" text="Go to example" path="/basic/index" target="_blank">
<i class="fas fa-arrow"/>
</tag:link>
NavLink
Renders a nav link with a text for executing GET requests from the navbar.
The link is marked active if the user is on the current page or if the active flag ist set.
The component accepts children, for instance an icon.
Attributes:
id
The page unique idpath
The relative path from the rest application path ontext(Optional) The text for the linkrendered(Optional, Default=true)
The rendered flagactive(Optional, Default=false)
The active flag marking the nav link active
<tag:navLink id="toMyResource" path="/basic/index" text="Go to example"/>
<tag:navLink id="toMyResource" text="Go to example" path="/basic/index" active="#{pathHelper.isOnSubpage('/basic/config')}">
<i class="fas fa-arrow"/>
</tag:navLink>
Card
Renders a card with a header and button section used for an element in teh index pages.
Attributes:
id
The unique card id within a viewtitle
The card titlerendered(Optional, default true)
The rendered flag
<tag:card id="indexExampleMpHealth" title="First part">
<ui:define name="body">
<p>...</p>
</ui:define>
<ui:define name="buttons">
<tag:button id="toMpHealthExample" text="Go to example" path="/basic/health"/>
</ui:define>
</tag:card>