Rushing forward to the backend part of the application. Its quite more interesting hence we spend multiple sub sections for each of the layers. How OpenWMS.org is structured is more important for Project Engineers who assemble the application rather than for Operators and other users. If you are implementing own services or whole Modules than you should join the project and become a developer to access the developer section and read more about the technical internals. In the following sections we explain how the actual layering is set up - less about the design concept and implementation concepts.
As already mentioned in the main concept on the website as well as in the overview section we strongly rely on the traditional layering architecture, splitting the business tier into a service and a data access layer and bundling domain objects together to be used in all layers. Persistent Domain Objects like Users, Modules, TransportUnits or Orders are part of the cross-cutting Business Domain Object layer. Each Module comes with a set of it's own domain classes suitable for the Module's domain. Splitting technical layers into domain Modules is a trade-off between high cohesion and lose coupling, thats why each set of domain classes is specific to it's Module.
Configuration Services on the right side are used in all layers to access global configuration data. A global scope spans all layers in all Modules, not only the Core Framework Module. It is a central service that comes with the framework. Providing an access point to the persistent storage is part of the Infrastructure Service layer that is arranged at the bottom of Figure 3.1, “Architecture - Backend Tier” and exists only once in the whole application - but can be referenced by all other Modules not only the framework.
The Service Layer (on top of Figure 3.1, “Architecture - Backend Tier”) provides functionality regarding the business requirements - corse grained services with transactional behavior. These services interact with other services within the same Module or with the underlying Repository Layer (Data Access Layer) to perform data access operations. A common goal is to minimize dependencies between services, also it is not always possible to eliminate them at all. Services offer their business functionality via a thin interface layer to outer clients (e.g. the web application) and shield the interal implementation. In the past we implemented two different service implementations, one with the Spring Framework and a second in EJB technology. It was quite convenient to switch between both service layer implementations without the need to change something on the client application. Note that Figure 3.1, “Architecture - Backend Tier” does not reflect the deployment concept and does not suggest different Bundles for both parts of the Business Service Layer even if it is so. It is up to you how you structure your new Modules, probably it is more feasable for you to combine service interface and implementation. However it's a good practise to implement against interfaces. No matter how you build your deliverables later on.
The Data Access Layer, or more fashioned the Repository Layer is a so called Integration Layer because it encapsulates the actual data access operations from the Service Layer and thus increases robustness of the implemented business logic. In former days it was essential to cut-off this functionality from the intrinsic business logic. Lately we already have an abstraction with the standardized Java Persistence API, so you could argue to remove this layer. Our suggestion is, if you feel you write duplicated code or code that just delegates to JPA's EntityManager, then you can omit this layer in your own Modules without doubts. Like in the Business Service Layer we code against an interface definition (Repository) to offer data access functionality. The implementation itself (JPA DAO Implementation) is specific to the JPA standard specification and does not depend on y particular JPA provider (like Hibernate or Eclipselink). But at runtime we need to have an underlying JPA provider, that's why there is another part in the Repository Layer - the JPA Provider. This is always a 3rd party library that comes with OpenWMS.org - by default we are using Hibernate as provider. But it shall also be possible to switch to Eclipselink or another JPA compliant implementation.