Getting Started

Prereqs

You’ll need:

  • Java 11

    Apache Causeway should work up to at least Java 15, but stick with Java 11 for now.

  • Maven 3.6.x

    Maven 3.6.x or later is recommended.

  • git

    The tutorial includes worked example/solution, provided in a github-hosted repo. This has multiple tags for the various checkpoints so you can pick up the tutorial at any point.

  • a Java IDE with support for Maven.

    The Apache Causeway website has detailed documentation for setting up to use IntelliJ or Eclipse.

    For this tutorial, make sure that your IDE is configured to support Lombok.

Ex 1.1: Starter apps / clone the repo

Apache Causeway provides a two starter apps, HelloWorld and SimpleApp. These are identical in terms of functionality, but the simpleapp provides more structure and includes example tests.

there are JPA and JDO variants of the starter apps. This tutorial uses JPA as it is the more commonly used persistence mechanism.

We start the tutorial simply with a copy of SimpleApp; in subsequent exercises we’ll refactor and build upon it to morph it into the petclinic domain.

  • Clone the repo:

    git clone https://github.com/apache/causeway-app-petclinic
  • (optional) Load the git repo into a GUI tool such as SourceTree or GitKraken

    This will make it easier to inspect differences between different tags.

  • Checkout the first tag, and build:

    git checkout tags/01-01-starter-app
    mvn clean install
  • run the app:

    mvn -pl webapp spring-boot:run

Ex 1.2: Explore the Simple App

Although we’ll be refactoring the codebase in the next exercise, take a few minutes to familiarize yourself with the functionality of the simpleapp.

Check your understanding by using the app to:

  • create new objects

  • search by name

  • list all objects

  • Use the Prototyping  Fixture Scripts menu to run in the "DomainAppDemo" fixture script.

    This will create some sample data.

Ex 1.3: Running from the IDE

Running from the command line isn’t ideal, so

  • load the project into your IDE as a Maven project, build and run.

  • The app is a Spring boot application, so locate the class with a main, and run.

  • alternatively, your IDE might also have specialised support for Spring Boot apps, so run the app that way if you wish.

  • with the IDE load

If you want to go deeper, open up the page describing the SimpleApp and start to explore the structure of the app files.

Ex 1.4: Naked Objects pattern

Apache Causeway is an implementation of the naked objects pattern, which means that entities (and later, as we’ll see view models) are automatically exposed in the UI.

An ORM such as JPA (EclipseLink or Hibernate) maps domain objects into an RDBMS or other datastore. You can think of Apache Causeway (and naked objects) similarly, but it’s an OIM - an object interface mapper. It maps to the UI layer rather than the persistence layer.

Common to both ORMs and OIMs is an internal metamodel; this is where much of the power comes from.

We can explore this by looking at the classes provided by the starter app:

  • locate the SimpleObjects domain service, and notice the methods annotated with @Action.

    Map these to the "Simple Objects" menu.

  • locate the SimpleObject entity, and notice the methods annotated with @Property and @Action.

    Map these onto the fields of the "simple object" entity, and the action buttons (eg to "change name").

It’s common for each entity (or more precisely, aggregate root) to have a corresponding domain service, acting as its repository. This abstraction hides the details of interacting with the persistence data store. Domain services are automatically injected wherever they are required, using @javax.inject.Inject.

Apache Causeway applications therefore generally follow the hexagonal architecture (aka the ports and adapters architecture).

As well as writing our own domain services, there are also many framework-provided domain services, for example RepositoryService (to persist objects). See the Reference Guide: Domain Services docs for the full list.

Ex 1.5: UI Hints

The framework derives as much of the UI as possible from the domain objects' intrinsic structure and behaviour, but there are some supporting structures and conventions that are there primarily to improve the UI.

Titles

A title is the identifier of a domain object for the end-user.

For SimpleObject, this is defined declaratively:

SimpleObject.java
@Title
// ... other annotations omitted ...
private String name;

It can also be specified imperatively using either the title() or toString() method.

Each domain object is also associated with an icon. Typically this is static and in the same package as the class; see SimpleObject.png.

Mini-Exercise:

(No solution is provided for this exercise).

  • replace the @Title annotation with a title() method:

    SimpleObject.java
    public String title() {
        return getName();
    }

You can learn more about UI Hint Methods in the reference guide, here.

Object layout

Frameworks that implement the naked objects pattern automatically provide a default representation of domain objects. In many cases the details of that representation can be inferred directly from the domain members. For example the label of a field for an object’s property (eg SimpleObject#name) can be derived directly from the name of the object property itself (getName()).

In the absence of other metadata, Apache Causeway will render a domain object with its properties to the left-hand side and its collections (if any) to the right. The order of these properties and collections can be specified using the @PropertyLayout annotation and the @CollectionLayout annotation. There are other annotations to group properties together and to associate action buttons with either properties or collections.

The downside of using annotations is that changing the layout requires that the application be restarted, and certain more complex UIs, such as multi-columns or tab groups are difficult or impossible to express.

Therefore Apache Causeway also allows the layout of domain objects to be specified using a complementary layout file, eg SimpleObject.layout.xml. This is modelled upon bootstrap and so supports arbitrary rows and columns as well as tab groups and tabs.

Mini-Exercise:

  • locate the SimpleObject.layout.xml file

  • compare the structure of the layout file to that of the rendered object

  • change the file, eg the relative widths of the columns

  • use the IDE to copy over the file to the classpath; the new version will be picked up automatically

    • for example, with IntelliJ use Run  Debugging Actions  Reload Changed Classes.

You can learn more about file-based layouts in the fundamentals guide describing at Object Layouts.

It’s also possible to change the order of columns at runtime, using the SimpleObject.columnOrder.txt file. For more on this topic, see the section of the fundamentals guide describing Table Columns.

In a similar fashion, the actions of the various domain services are grouped into menus using the menubars.layout.xml file.

Mini-Exercise:

  • locate the menubars.layout.xml file

  • compare the structure of the layout file to that of the rendered menu bar

  • change the file, eg reorder menu items or create new menus

  • again, use the IDE to copy over the file to the classpath

    • for example, with IntelliJ use Run  Debugging Actions  Reload Changed Classes/

To learn more, see the section of the fundamentals guide describing file-based menu bar layout.