Overview

In this section we run through the main building blocks that make up an Apache Causeway application.

The "big idea" of Apache Causeway is that you write only the domain logic, while the application takes care of the user interface. There’s a bit more to it than that, of course, and lots of interesting consequences, but that’s the main gist.

Type of Domain Objects

From the end-user’s perspective the UI displays a single domain object instance that has state. These will be either a domain entity (persisted state) or a view model (user-specific temporary state). To access them, a menu domain service will be used to find from the database (a repository service) or occasionally to create a new instance (a factory service).

The state managed by entities and view models is expressed in terms of properties and collections, with properties whose value either refers to other domain objects (reference types) or alternatively holds a value directly (value types). Apache Causeway supports a wide variety of value types, including JDK types (primitives, strings or dates) Causeway-specific (eg AsciiDoc, Vega) and 3rd party (eg Jodatime). Moreover it is possible to define your own custom types, and you can teach the framework about other 3rd party libraries you might wish to use, eg JScience.

Actions allow the end-user to invoke business logic. These are either defined as a regular method on a domain object (entity, view model or service), or can be "contributed" as a mixin: an important capability to help keep large applications decoupled.

Annotations

Domain classes are generally recognized using annotations. Apache Causeway defines its own set of annotations, and you can generally recognize an Apache Causeway domain class because it will be probably be annotated using @DomainObject and @DomainService. There are though configuration options that allow you to control to what extent (some) annotations can be inferred implicitly rather than specified explicitly.

The framework also recognises some annotations from the ORM layer (ie JPA/EclipseLink or JDO/DataNucleus) and infers domain semantics from these annotations. Similarly, JAXB annotations are often used for view models.

The framework also defines supplementary annotations, notably @DomainObjectLayout and @DomainServiceLayout. These provide hints relating to the layout of the domain object in the user interface. Alternatively, these UI hints might be defined in a supplementary .layout.xml file.

Title and Icon

To allow the end-user to distinguish one domain object from another, it is rendered with a title and an icon. The icon informally identifies the type of the domain object, while the title identifies the instance.

It’s also possible to customise other aspects of the domain object’s presentation within the user interface.

Properties, Collections and Actions (and Mixins)

Every domain object in Apache Causeway consists of three types of members:

  • properties, such as a Customer's firstName

  • collections, such as a Customer's orders collection of Orders

  • actions, such as a Customer's placeOrder(…​) method.

In small or simple applications these are implemented as public methods on the domain object itself. In larger or more complicated applications, mixins provide an alternative way to implement actions (ie behaviour) and derived (read-only) properties or collections, with the implementation "contributed to" the underlying domain object.

Business Rules

When a domain object is rendered in the UI or the end-user interacts with the domain object through the UI, the framework applies a series of precondition business rules to each object member (property, collection or action).

When the object is being rendered, the framework checks:

  • is the object member visible? - Members that are not visible are simply omitted from the page.

  • if the object member is visible, is the object member enabled (or is it not editable/greyed out)?

  • for enabled object members, are the supplied arguments valid?

One way to remember this is: "see it, use it, do it".

The framework provides a multitude of ways to implement these business rules. The simplest approach is to just implement the business rules imperatively in the domain object, using a supporting method.

Events

When the framework renders a domain object, and as the end-user interacts with the domain object, the framework it emits multiple events using the intra-process event bus. These events enable other domain services (possibly in other modules) to influence how the domain object is rendered, or to perform side-effects or even veto an action invocation.

The framework has several categories of events: domain events, UI events and lifecycle events. Learn more about these in events page.

To receive the events, the domain service should subscribe to the EventBusService, and implement an appropriately annotated method to receive the events.

Modularity

Enabling and ensuring modularity is a key principle for the Apache Causeway framework. Modularity is the only way to ensure that a complex application domain does not over time degenerate into the infamous "big ball of mud", software that is difficult, dangerous and expensive to change.

Modules chunk up the overall application into smaller pieces, usually a pacakge and subpackages. The smaller pieces can be either "horizontal" tiers (presentation / domain / persistence) or "vertial" functional slices (eg customer vs orders vs products vs invoice etc).

Because the framework takes care in large part of the presentation and persistence tiers, modules in an Apache Causeway application are oriented around vertical slices, and determining the dependencies between those modules. These modules will form a directed acyclic graph (DAG)

Both mixins and events are important to enabling modularity. Mixins allow one module to seemingly "contribute" behaviour to a domain object in another module, while events allow modules to interact in a decoupled fashion, either reacting to or vetoing actions originating in some other module.