Petclinic

PetClinic is a well-known example app in the JVM space, originally implemented by Spring. This specification uses an alternative implementation provided as a tutorial for Apache Isis.

this implementation does not (currently) show GraphqlObjects viewer; we provide these instructions just so you can become familiar with the domain.

Running the Application

  • Prereqs:

    • Java 11 (JDK)

    • Maven 3.6.x (or later)

    • git

  • Clone the repo, build and run:

    git clone https://github.com/apache/isis-app-demo .       (1)
    git checkout tags/08-03-view-model-projecting-an-entity   (2)
    mvn clean install                                         (3)
    mvn -pl webapp spring-boot:run                            (4)
    1 Clone the repo
    2 Checkout one of the later solutions
    3 Build
    4 Run
  • Navigate to http://localhost:8080.

  • Logon using sven/pass.

  • Once running, use Prototyping > Run Fixture Script to load in some sample data:

    petclinic home page

UML Class Diagram

The diagram shows the effective domain model implemented by the app:

Diagram

Code Snippets

This section shows the domain classes as implemented in Apache Isis:

PetOwners

The pets.PetOwners domain service is defined as:

pets.PetOwners.java
@DomainService(
        logicalTypeName = "pets.PetOwners",
        // ...
)
public class PetOwners {

    @Action(semantics = SemanticsOf.NON_IDEMPOTENT)
    public PetOwner create(
            @LastName final String lastName,
            @FirstName final String firstName) {
        // ...
    }

    @Action(semantics = SemanticsOf.SAFE)
    public List<PetOwner> findByLastNameLike(
            @LastName final String lastName) {
        // ...
    }

    @Action(semantics = SemanticsOf.SAFE)
    @ActionLayout(bookmarking = BookmarkPolicy.AS_ROOT)
    public List<PetOwner> findByLastName(
            @LastName final String lastName
            ) {
        // ...
    }

    @Action(semantics = SemanticsOf.SAFE)
    @ActionLayout(bookmarking = BookmarkPolicy.AS_ROOT)
    public List<PetOwner> listAll() {
        // ...
    }
}

PetOwner

The pets.PetOwner domain object (an entity) is defined as:

PetOwner.java
@DomainObject(
        logicalTypeName = "pets.PetOwner",
        // ...
)
public class PetOwner implements Comparable<PetOwner> {

    private Long id;
    private long version;

    public String title() {
        // ...
    }

    private String lastName;
    private String firstName;
    private String phoneNumber;
    private String emailAddress;
    private String notes;

    @Action(semantics = IDEMPOTENT, commandPublishing = Publishing.ENABLED, executionPublishing = Publishing.ENABLED)
    public PetOwner updateName(
            @LastName final String lastName,
            @FirstName final String firstName) {
        // ...
    }
    public String default0UpdateName() {
        // ...
    }
    public String default1UpdateName() {
        // ...
    }
}

It also has these contributed members:

  • pets collection

    PetOwner_pets.java
    @Collection
    public class PetOwner_pets {
        public List<Pet> coll() {
            // ...
        }
    }
  • addPet action

    PetOwner_addPet.java
    @Action(
            semantics = SemanticsOf.IDEMPOTENT,
            // ...
    )
    public class PetOwner_addPet {
        public PetOwner act(
                @PetName final String name,
                final PetSpecies petSpecies
                ) {
            // ...
        }
        public String validate0Act(final String name) {
            // ...
        }
        public PetSpecies default1Act() {
            // ...
        }
    }
  • removePet action

    PetOwner_removePet.java
    @Action(
            semantics = SemanticsOf.IDEMPOTENT,
            // ...
    )
    public class PetOwner_removePet {
        public PetOwner act(@PetName final String name) {
            // ...
        }
        public String disableAct() {
            // ...
        }
        public List<String> choices0Act() {
            // ...
        }
        public String default0Act() {
            // ...
        }
    }
  • delete action

    PetOwner_delete.java
    @Action(
            semantics = SemanticsOf.NON_IDEMPOTENT_ARE_YOU_SURE,
            // ...
    )
    public class PetOwner_delete {
        public void act() {
            // ...
        }
    }
  • bookVisit action

    Pet_bookVisit.java
    @Action(
            semantics = SemanticsOf.IDEMPOTENT,
            // ...
    )
    public class Pet_bookVisit {
    
        public Visit act(
                LocalDateTime visitAt,
                @Reason final String reason
                ) {
            // ...
        }
        public String validate0Act(LocalDateTime visitAt) {
            // ...
        }
        public LocalDateTime default0Act() {
            // ...
        }
    }
  • visits collection

    Pet_visits.java
    @Collection
    public class Pet_visits {
    
        public List<Visit> coll() {
            // ...
        }
    }

Pet

The pets.Pet domain object (an entity) is defined as:

Pet.java
@DomainObject(
        logicalTypeName = "pets.Pet",
        // ...
)
public class Pet implements Comparable<Pet> {

    private Long id;
    private long version;

    public String title() {
        // ...
    }
    private String name;
    private String notes;
    private PetOwner petOwner;
    private PetSpecies petSpecies;
}

PetSpecies

PetSpecies is an enum, in effect a value type:

PetSpecies.java
public enum PetSpecies {
    Dog,
    Cat,
    Hamster,
    Budgerigar,
}

Visit

The visits.Visit domain object (an entity) is defined as:

Visit.java
@DomainObject(
        logicalTypeName = "visits.Visit",
        // ...
)
public class Visit implements Comparable<Visit> {

    private Long id;
    private long version;

    public String title() {
        // ...
    }

    private Pet pet;
    private LocalDateTime visitAt;
    private String reason;
}