This is an automated email from the ASF dual-hosted git repository. danhaywood pushed a commit to branch CAUSEWAY-2485 in repository https://gitbox.apache.org/repos/asf/causeway.git
commit 0a43c7396a10abf5714800a0a4b136fc7324ce6a Author: danhaywood <[email protected]> AuthorDate: Sun Apr 30 19:06:57 2023 +0100 CAUSEWAY-2485: fleshes out @CollectionLayout#sortedBy --- .../CollectionLayoutPagedPage-description.adoc | 8 +++-- .../CollectionLayoutSortedByPage-description.adoc | 39 ++++++++++++++++++---- .../sortedBy/CollectionLayoutSortedByPage.java | 16 +-------- .../CollectionLayoutSortedByPage.layout.xml | 6 ++-- ...SortedByComparator.java => NameComparator.java} | 27 ++++++++------- .../child/CollectionLayoutSortedByChildVm.java | 6 ++-- .../CollectionLayoutSortedByChildVm.layout.xml | 2 +- 7 files changed, 60 insertions(+), 44 deletions(-) diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/paged/CollectionLayoutPagedPage-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/paged/CollectionLayoutPagedPage-description.adoc index 3cb2e181cb..a922a4b21e 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/paged/CollectionLayoutPagedPage-description.adoc +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/paged/CollectionLayoutPagedPage-description.adoc @@ -2,9 +2,13 @@ If a collection contains many instances, then by default these are paged. The link:https://causeway.apache.org/refguide/2.0.0-RC1/applib/index/annotation/DomainObjectLayout.html#paged[@DomainObjectLayout#paged] is used to specify how many instances of the domain object should be shown for parented collections (those belonging to an object). -This can be overridden on a case-by-case basis using link:https://causeway.apache.org/refguide/2.0.0-RC1/applib/index/annotation/CollectionLayout.html#paged[@CollectionLayout#paged]. +(It is also used for standalone collections (those returned from an action invocation). -NOTE: the link:https://causeway.apache.org/refguide/2.0.0-RC1/applib/index/annotation/DomainObjectLayout.html#paged[@DomainObjectLayout#paged] value is also used for standalone collections (those returned from an action invocation). +The deefault provided by `@DomainObject#paged` can be overridden on a case-by-case basis using link:https://causeway.apache.org/refguide/2.0.0-RC1/applib/index/annotation/CollectionLayout.html#paged[@CollectionLayout#paged]. + +IMPORTANT: the paging that occurs is at the application-layer, not the database layer. +In other words, the framework resolves _all_ of the objects are meet the criteria, and then manages the paging. +There could therefore be performance/memory issues if too many objects are returned by the Kquery. == How this demo works diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByPage-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByPage-description.adoc index ca003f3fbb..5944a5feb1 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByPage-description.adoc +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByPage-description.adoc @@ -1,10 +1,37 @@ :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...] -The `sortedBy` attribute ... +When dealing with collections of entities, most commonly the entity type will implement `Comparable`, (ie to have a natural ordering), and the collection will be defined as a `java.util.SortedSet`. +In such a set up, the collection will be render the objects in this order. + +If a collection is a standalone collection resulting from invoking an action, then the objects by default will be rendered in the order that the action populated the list. +If the action is some sort of finder that ultimately invokes a repository query, then the order will be according to the JPA/JDO/SQL query. + +The purpose of the link:https://causeway.apache.org/refguide/2.0.0-RC1/applib/index/annotation/DomainObjectLayout.html#sortedby[@DomainObjectLayout#sortedBy] `sortedBy` attribute is to override any existing sorting at the application/persistence layer and to instead sort the objects at the presentation layer. + +== How this demo works + +To the left is a collection of objects, where their displayed order is according to alphabetical `name` of these objects. +This is accomplished using the `sortedBy` attribute, passing in a `NameComparator`. + +In terms of code: + +* the `children` collection is defined as: ++ +[source,java,indent=0] +.CollectionLayoutSortedByPage.java +---- +include::CollectionLayoutSortedByPage.java[tags=children] +---- +<.> sort using the `NameComparator` class + +* while the `NameComparator` class is defined by: ++ +[source,java,indent=0] +.NameComparator.java +---- +include::NameComparator.java[tags=comparator] +---- +<.> utility class provided by the framework (provides helpers for compareTo, equals, hashCode and toString) +<.> compare by the `name` property of the child objects -WARNING: TODO[CAUSEWAY-3311] -Indicates that the elements in a ( java.util.SortedSet ) collection should be sorted according to a different order than the natural sort order, as defined by the specified java.util.Comparator . -Whenever there is a collection of type java.util.SortedSet , the domain entity referenced is expected to implement Comparable , ie to have a natural ordering. In effect tis means that all domain entities should provide a natural ordering. -However, in some circumstances the ordering of collection may be different to the entity’s natural ordering. For example, the entity may represent an interval of time sorted by its startDate ascending, but the collection may wish to sort by startDate . -The purpose of this annotation is to provide a java.util.Comparator such that the collection may be sorted in an order more suitable to the context. diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByPage.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByPage.java index 3e27a8a73f..c2a442d2f7 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByPage.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByPage.java @@ -19,7 +19,6 @@ package demoapp.dom.domain.collections.CollectionLayout.sortedBy; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; import javax.inject.Named; @@ -35,9 +34,6 @@ import org.apache.causeway.applib.annotation.CollectionLayout; import org.apache.causeway.applib.annotation.DomainObject; import org.apache.causeway.applib.annotation.Nature; import org.apache.causeway.applib.annotation.ObjectSupport; -import org.apache.causeway.applib.util.ObjectContracts; - -import demoapp.dom.domain.collections.CollectionLayout.sequence.child.CollectionLayoutSequenceChildVm; import demoapp.dom.domain.collections.CollectionLayout.sortedBy.child.CollectionLayoutSortedByChildVm; @@ -58,22 +54,12 @@ public class CollectionLayoutSortedByPage implements HasAsciiDocDescription { return "@CollectionLayout#sortedBy"; } -//tag::comparator[] - public static class ValueComparator implements Comparator<CollectionLayoutSequenceChildVm> { - @Override - public int compare(CollectionLayoutSequenceChildVm o1, CollectionLayoutSequenceChildVm o2) { - return ObjectContracts.contract(CollectionLayoutSequenceChildVm.class) // <.> - .thenUse("value", CollectionLayoutSequenceChildVm::getValue) // <.> - .compare(o1, o2); - } - } -//end::comparator[] //tag::children[] @Collection() @CollectionLayout( - sortedBy = ValueComparator.class // <.> + sortedBy = NameComparator.class // <.> ) @XmlElementWrapper(name = "children") @XmlElement(name = "child") diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByPage.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByPage.layout.xml index e8b09508e4..eeccc12157 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByPage.layout.xml +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByPage.layout.xml @@ -28,13 +28,13 @@ <bs3:col span="6"> <bs3:row> <bs3:col span="12"> - <cpt:collection id="children"/> + <cpt:collection id="children" paged="5"/> </bs3:col> </bs3:row> <bs3:row> <bs3:col span="12"> - <cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/> - </bs3:col> + <cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/> + </bs3:col> </bs3:row> </bs3:col> <bs3:col span="6"> diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByComparator.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/NameComparator.java similarity index 60% rename from examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByComparator.java rename to examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/NameComparator.java index 153c6c8048..5409d9a8c3 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/CollectionLayoutSortedByComparator.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/NameComparator.java @@ -18,23 +18,22 @@ */ package demoapp.dom.domain.collections.CollectionLayout.sortedBy; -import java.util.Comparator; -import java.util.Objects; - -import lombok.val; - -import demoapp.dom.domain._entities.DemoEntity; +import demoapp.dom.domain.collections.CollectionLayout.sortedBy.child.CollectionLayoutSortedByChildVm; -public class CollectionLayoutSortedByComparator -implements Comparator<DemoEntity> { +import java.util.Comparator; - //TODO[CAUSEWAY-3311] perhaps show that we support injection +import org.apache.causeway.applib.util.ObjectContracts; +//tag::comparator[] +public class NameComparator implements Comparator<CollectionLayoutSortedByChildVm> { @Override - public int compare(final DemoEntity o1, final DemoEntity o2) { - val prop1 = o1.getProperty(); - val prop2 = o2.getProperty(); - return Objects.compare(prop1, prop2, Comparator.nullsFirst(Comparator.naturalOrder())); + public int compare( + CollectionLayoutSortedByChildVm o1, + CollectionLayoutSortedByChildVm o2 + ) { + return ObjectContracts.contract(CollectionLayoutSortedByChildVm.class) // <.> + .thenUse("name", CollectionLayoutSortedByChildVm::getName) // <.> + .compare(o1, o2); } - } +//end::comparator[] diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/child/CollectionLayoutSortedByChildVm.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/child/CollectionLayoutSortedByChildVm.java index c416eea810..fd30effbd7 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/child/CollectionLayoutSortedByChildVm.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/child/CollectionLayoutSortedByChildVm.java @@ -46,8 +46,8 @@ import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription; public class CollectionLayoutSortedByChildVm implements HasAsciiDocDescription { //end::class[] - public CollectionLayoutSortedByChildVm(final String value) { - this.value = value; + public CollectionLayoutSortedByChildVm(final String name) { + this.name = name; } //tag::class[] @@ -55,7 +55,7 @@ public class CollectionLayoutSortedByChildVm implements HasAsciiDocDescription { @Property() @XmlElement(required = true) @Getter @Setter - private String value; + private String name; } //end::class[] diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/child/CollectionLayoutSortedByChildVm.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/child/CollectionLayoutSortedByChildVm.layout.xml index a5d295bce2..392d8705e5 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/child/CollectionLayoutSortedByChildVm.layout.xml +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/CollectionLayout/sortedBy/child/CollectionLayoutSortedByChildVm.layout.xml @@ -29,7 +29,7 @@ <bs3:row> <bs3:col span="12"> <cpt:fieldSet name="Properties" id="properties"> - <cpt:property id="value"/> + <cpt:property id="name"/> </cpt:fieldSet> <cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/> </bs3:col>
