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 7427412dcdaf9a90aa16654a7b84fb0f0fa1e2ea Author: danhaywood <[email protected]> AuthorDate: Thu Apr 27 06:42:16 2023 +0100 CAUSEWAY-2485: completes @Collection#typeOf --- .../typeOf/ActionTypeOfPage-description.adoc | 9 ++- .../collections/Collection/CollectionMenu.java | 26 +++++-- .../typeOf/CollectionTypeOfPage-description.adoc | 40 +++++++++- .../Collection/typeOf/CollectionTypeOfPage.java | 44 +++++++---- .../typeOf/CollectionTypeOfPage.layout.xml | 85 +++++++++++----------- .../CollectionTypeOfChildVm-description.adoc} | 6 +- .../CollectionTypeOfChildVm.java} | 65 +++++++++++------ .../CollectionTypeOfChildVm.layout.xml} | 9 +-- 8 files changed, 182 insertions(+), 102 deletions(-) diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/typeOf/ActionTypeOfPage-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/typeOf/ActionTypeOfPage-description.adoc index 557aa31248..1b426bbbe4 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/typeOf/ActionTypeOfPage-description.adoc +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/typeOf/ActionTypeOfPage-description.adoc @@ -2,11 +2,12 @@ CAUTION: this feature is currently broken; see link:https://issues.apache.org/jira/browse/CAUSEWAY-3423[CAUSEWAY-3423]. -Actions that return lists of objects are usually parameterized, for example, returning `List<Customer>` or `List<Order>`. +We use the term "standalone collection" for a list or a set that is returned from an action. +Such collection are usually parameterized, for example, returning `List<Customer>` or `List<Order>`. The framework uses the generic parameter to ensure that the list is rendered appropriately for that element type. -In some rare scenarios though it may be necessary to return only a raw (non-parameterized) `List`. -In these cases the link:https://causeway.apache.org/refguide/2.0.0-RC1/applib/index/annotation/Action.html#typeof[@Action#typeOf] attribute can be used to indicate the element type of the returned `List`. +In some rare scenarios though it may be necessary to return only a raw (non-parameterized) collection type (eg `List` or `Set`). +In these cases the link:https://causeway.apache.org/refguide/2.0.0-RC1/applib/index/annotation/Action.html#typeof[@Action#typeOf] attribute can be used to indicate the element type of the returned collection. == How this demo works @@ -49,5 +50,7 @@ include::ActionTypeOfPage.java[tags=action-returning-raw-list-but-annotated] <.> action defines a raw list + The standalone list returned by this object should show the full details of the child object. ++ +CAUTION: this feature is currently broken - try entering 'M' and only the icons are shown. Tracked with link:https://issues.apache.org/jira/browse/CAUSEWAY-3423[CAUSEWAY-3423]. diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/CollectionMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/CollectionMenu.java index c3dc86488a..652324a1d0 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/CollectionMenu.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/CollectionMenu.java @@ -29,6 +29,12 @@ import org.apache.causeway.applib.annotation.PriorityPrecedence; import org.apache.causeway.applib.annotation.SemanticsOf; import org.apache.causeway.applib.services.factory.FactoryService; +import demoapp.dom._infra.samples.NameSamples; +import demoapp.dom.domain.actions.Action.typeOf.ActionTypeOfPage; +import demoapp.dom.domain.actions.Action.typeOf.child.ActionTypeOfChildVm; + +import demoapp.dom.domain.collections.Collection.typeOf.child.CollectionTypeOfChildVm; + import lombok.RequiredArgsConstructor; import lombok.val; @@ -50,20 +56,26 @@ public class CollectionMenu { @ActionLayout(cssClassFa="fa-asterisk", describedAs = "Class of the domain event emitted when interacting with the collection") public CollectionDomainEventPage domainEvent(){ val page = new CollectionDomainEventPage(); - page.addChild("#1"); - page.addChild("#2"); - page.addChild("#3"); - page.addOtherChild("#1"); - page.addOtherChild("#2"); - page.addOtherChild("#3"); + samples.stream() + .forEach(page::addChild); + samples.stream() + .forEach(page::addOtherChild); return page; } @Action(semantics = SemanticsOf.SAFE) @ActionLayout(cssClassFa="fa-shapes", describedAs = "Element type of collections") public CollectionTypeOfPage typeOf(){ - return new CollectionTypeOfPage(); + val page = new CollectionTypeOfPage(); + samples.stream() + .map(CollectionTypeOfChildVm::new) + .forEach(e -> page.getChildren().add(e)); + samples.stream() + .map(CollectionTypeOfChildVm::new) + .forEach(e -> page.getOtherChildren().add(e)); + return page; } + final NameSamples samples; } diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage-description.adoc index 9d4659634d..b1066d3e58 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage-description.adoc +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage-description.adoc @@ -2,6 +2,40 @@ The `typeOf` attribute ... -WARNING: TODO[CAUSEWAY-3311] -The type-of the elements held within the collection. -This is only provided as a fallback; usually the framework can infer the element type of the collection from the collection method’s generic type. +We use the term "parented collection" for a collection of objects that is "owned" by another object, for example the collection of ``OrderItem``s held by an `Order`. +Such collections when declared are usually parameterized, for example `Set<OrderItem>`. +The framework uses the generic parameter to ensure that the collection is rendered appropriately for that element type. + +In some rare scenarios though it may be necessary to return only a raw (non-parameterized) collection type (eg `Set` or `List`). +In these cases the link:https://causeway.apache.org/refguide/2.0.0-RC1/applib/index/annotation/Collection.html#typeof[@Collection#typeOf] attribute can be used to indicate the element type of the returned collection. + +== How this demo works + +This page object defines two collections, both of which use a raw collection type. +The `children` collection is annotated with `@Collection#typeOf`, and so the framework is able to show the columns of the children. +However, the `otherChildren` collection has no such annotation, meaning that the framework knows only that it is a collection of ``Object``s. +No columns are shown, only an icon. + +In terms of code: + +* the `children` collection is annotated: ++ +[source,java,indent=0] +---- +include::CollectionTypeOfPage.java[tags=class-collections-children] +---- +<.> hint as to the element type. +This results in columns in the table. +<.> the fact that this is a raw collection type does not matter, because of the annotation + +* the `otherChildren` collection is not annotated: ++ +[source,java,indent=0] +---- +include::CollectionTypeOfPage.java[tags=class-collections-other-children] +---- +<.> no hint as to the element type. +<.> also a raw collection type. ++ +As a result, the framework has no information as to the type of element in the collection, and therefore can show only the object icons, no columns. + diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage.java index 6be795630c..fe2df3d88b 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage.java @@ -20,6 +20,7 @@ package demoapp.dom.domain.collections.Collection.typeOf; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import javax.inject.Named; import javax.xml.bind.annotation.XmlAccessType; @@ -28,11 +29,16 @@ import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; +import org.apache.causeway.applib.annotation.Action; import org.apache.causeway.applib.annotation.Collection; +import org.apache.causeway.applib.annotation.CollectionLayout; import org.apache.causeway.applib.annotation.DomainObject; import org.apache.causeway.applib.annotation.Editing; import org.apache.causeway.applib.annotation.Nature; import org.apache.causeway.applib.annotation.ObjectSupport; +import org.apache.causeway.applib.annotation.SemanticsOf; + +import demoapp.dom.domain.collections.Collection.typeOf.child.CollectionTypeOfChildVm; import lombok.Getter; import lombok.NoArgsConstructor; @@ -41,27 +47,37 @@ import lombok.Setter; import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription; import demoapp.dom.domain._entities.DemoEntity; -//tag::class[] -@DomainObject( - nature=Nature.VIEW_MODEL, - editing = Editing.ENABLED) -@Named("demo.CollectionTypeOfVm") +@Named("demo.CollectionTypeOfPage") +@DomainObject(nature=Nature.VIEW_MODEL) @XmlRootElement(name = "root") @XmlType @XmlAccessorType(XmlAccessType.FIELD) @NoArgsConstructor public class CollectionTypeOfPage implements HasAsciiDocDescription { - @ObjectSupport public String title() { + @ObjectSupport + public String title() { return "@Collection#typeOf"; } -//tag::collection[] - @Collection( - typeOf = DemoEntity.class) - @XmlTransient - @Getter @Setter - private List<DemoEntity> collection = new ArrayList<>(); -//end::collection[] +//tag::class-collections-children[] + private List<CollectionTypeOfChildVm> children = new ArrayList<>(); + + @Collection(typeOf = CollectionTypeOfChildVm.class) // <.> + @CollectionLayout() + public List getChildren() { // <.> + return children; + } +//end::class-collections-children[] + +//tag::class-collections-other-children[] + private List<CollectionTypeOfChildVm> otherChildren = new ArrayList<>(); + + @Collection() // <.> + @CollectionLayout() + public List getOtherChildren() { // <.> + return otherChildren; + } +//end::class-collections-other-children[] + } -//end::class[] diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage.layout.xml index e6cee971cc..338082ca0f 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage.layout.xml +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage.layout.xml @@ -15,47 +15,50 @@ xmlns:cpt="https://causeway.apache.org/applib/layout/component" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <bs3:row> + <bs3:col span="10" unreferencedActions="true"> + <cpt:domainObject /> + </bs3:col> + <bs3:col span="2"> + <cpt:fieldSet name="" id="sources" /> + </bs3:col> + </bs3:row> - <bs3:row> - <bs3:col span="10" unreferencedActions="true"> - <cpt:domainObject /> - </bs3:col> - <bs3:col span="2"> - <cpt:fieldSet name="" id="sources" /> - </bs3:col> - </bs3:row> - - <bs3:row> - <bs3:col span="6"> - <cpt:fieldSet name="Annotated" id="annotation"/> - <cpt:fieldSet name="Variants" id="variants"/> - <cpt:fieldSet name="Contributed" id="contributed"/> - <cpt:fieldSet name="Meta-annotated" id="meta-annotated"/> - <cpt:fieldSet name="Meta-annotated Overridden" id="meta-annotated-overridden"/> - <cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/> - <cpt:collection id="children"> - <cpt:action id="returnsChildren"/> - </cpt:collection> - </bs3:col> - <bs3:col span="6"> - <cpt:fieldSet name="Description" id="description" > - <cpt:action id="clearHints" position="PANEL" /> - <cpt:action id="rebuildMetamodel" position="PANEL"/> - <cpt:action id="downloadLayout" position="PANEL_DROPDOWN"/> - <cpt:action id="inspectMetamodel" position="PANEL_DROPDOWN"/> - <cpt:action id="downloadMetamodelXml" position="PANEL_DROPDOWN"/> - <cpt:action id="downloadJdoMetamodel" position="PANEL_DROPDOWN"/> - <cpt:action id="recentCommands" position="PANEL_DROPDOWN"/> - <cpt:action id="recentExecutions" position="PANEL_DROPDOWN"/> - <cpt:action id="recentAuditTrailEntries" position="PANEL_DROPDOWN"/> - <cpt:action id="impersonateWithRoles" position="PANEL_DROPDOWN"/> - <cpt:action id="openRestApi" position="PANEL_DROPDOWN" /> - <cpt:property id="description"/> - </cpt:fieldSet> - </bs3:col> - </bs3:row> - <bs3:row> - <bs3:col span="12" unreferencedCollections="true"/> - </bs3:row> + <bs3:row> + <bs3:col span="6"> + <bs3:row> + <bs3:col span="12"> + <cpt:fieldSet name="Annotated" id="annotation"/> + <cpt:fieldSet name="Contributed" id="contributed"/> + <cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/> + </bs3:col> + </bs3:row> + <bs3:row> + <bs3:col span="12"> + <cpt:collection id="children"/> + <cpt:collection id="otherChildren"/> + </bs3:col> + </bs3:row> + </bs3:col> + <bs3:col span="6"> + <cpt:fieldSet name="Description" id="description" > + <cpt:action id="clearHints" position="PANEL" /> + <cpt:action id="rebuildMetamodel" position="PANEL"/> + <cpt:action id="downloadLayout" position="PANEL_DROPDOWN"/> + <cpt:action id="inspectMetamodel" position="PANEL_DROPDOWN"/> + <cpt:action id="downloadMetamodelXml" position="PANEL_DROPDOWN"/> + <cpt:action id="downloadJdoMetamodel" position="PANEL_DROPDOWN"/> + <cpt:action id="recentCommands" position="PANEL_DROPDOWN"/> + <cpt:action id="recentExecutions" position="PANEL_DROPDOWN"/> + <cpt:action id="recentAuditTrailEntries" position="PANEL_DROPDOWN"/> + <cpt:action id="impersonateWithRoles" position="PANEL_DROPDOWN"/> + <cpt:action id="openRestApi" position="PANEL_DROPDOWN" /> + <cpt:property id="description"/> + </cpt:fieldSet> + </bs3:col> + </bs3:row> + <bs3:row> + <bs3:col span="12" unreferencedCollections="true"/> + </bs3:row> </bs3:grid> diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/child/CollectionTypeOfChildVm-description.adoc similarity index 74% copy from examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage-description.adoc copy to examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/child/CollectionTypeOfChildVm-description.adoc index 9d4659634d..928fcd3c10 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage-description.adoc +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/child/CollectionTypeOfChildVm-description.adoc @@ -1,7 +1,3 @@ :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 `typeOf` attribute ... - -WARNING: TODO[CAUSEWAY-3311] -The type-of the elements held within the collection. -This is only provided as a fallback; usually the framework can infer the element type of the collection from the collection method’s generic type. +This child object exists just to act as the element of the collections of the `CollectionTypeOfPage` demo object. diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/child/CollectionTypeOfChildVm.java similarity index 51% copy from examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage.java copy to examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/child/CollectionTypeOfChildVm.java index 6be795630c..970004afdc 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/child/CollectionTypeOfChildVm.java @@ -16,52 +16,75 @@ * specific language governing permissions and limitations * under the License. */ -package demoapp.dom.domain.collections.Collection.typeOf; - -import java.util.ArrayList; -import java.util.List; +package demoapp.dom.domain.collections.Collection.typeOf.child; import javax.inject.Named; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; -import org.apache.causeway.applib.annotation.Collection; import org.apache.causeway.applib.annotation.DomainObject; -import org.apache.causeway.applib.annotation.Editing; import org.apache.causeway.applib.annotation.Nature; import org.apache.causeway.applib.annotation.ObjectSupport; +import org.apache.causeway.applib.annotation.Property; +import org.apache.causeway.applib.annotation.PropertyLayout; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription; -import demoapp.dom.domain._entities.DemoEntity; //tag::class[] -@DomainObject( - nature=Nature.VIEW_MODEL, - editing = Editing.ENABLED) -@Named("demo.CollectionTypeOfVm") -@XmlRootElement(name = "root") +@Named("demo.CollectionTypeOfChildVm") +@DomainObject(nature=Nature.VIEW_MODEL) +@XmlRootElement(name = "child") @XmlType @XmlAccessorType(XmlAccessType.FIELD) @NoArgsConstructor -public class CollectionTypeOfPage implements HasAsciiDocDescription { +public class CollectionTypeOfChildVm implements HasAsciiDocDescription { + + public CollectionTypeOfChildVm(final String value) { + setValue(value); + setValueUpper(value.toUpperCase()); + setValueLower(value.toLowerCase()); + setValueReversed(reverse(value)); + } @ObjectSupport public String title() { - return "@Collection#typeOf"; + return getValue(); } -//tag::collection[] - @Collection( - typeOf = DemoEntity.class) - @XmlTransient + @Property() + @PropertyLayout(fieldSetId = "annotation", sequence = "1") + @XmlElement(required = false) + @Getter @Setter + private String value; + + @Property() + @PropertyLayout(fieldSetId = "annotation", sequence = "2") + @XmlElement(required = false) + @Getter @Setter + private String valueUpper; + + @Property() + @PropertyLayout(fieldSetId = "annotation", sequence = "3") + @XmlElement(required = false) @Getter @Setter - private List<DemoEntity> collection = new ArrayList<>(); -//end::collection[] + private String valueLower; + + @Property() + @PropertyLayout(fieldSetId = "annotation", sequence = "4") + @XmlElement(required = false) + @Getter @Setter + private String valueReversed; + + private static String reverse(final String value) { + return new StringBuilder(value).reverse().toString(); + } + + } //end::class[] diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/child/CollectionTypeOfChildVm.layout.xml similarity index 86% copy from examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage.layout.xml copy to examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/child/CollectionTypeOfChildVm.layout.xml index e6cee971cc..2441ccf9e7 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/CollectionTypeOfPage.layout.xml +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/typeOf/child/CollectionTypeOfChildVm.layout.xml @@ -27,15 +27,8 @@ <bs3:row> <bs3:col span="6"> - <cpt:fieldSet name="Annotated" id="annotation"/> - <cpt:fieldSet name="Variants" id="variants"/> - <cpt:fieldSet name="Contributed" id="contributed"/> - <cpt:fieldSet name="Meta-annotated" id="meta-annotated"/> - <cpt:fieldSet name="Meta-annotated Overridden" id="meta-annotated-overridden"/> + <cpt:fieldSet name="Annotation" id="variants"/> <cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/> - <cpt:collection id="children"> - <cpt:action id="returnsChildren"/> - </cpt:collection> </bs3:col> <bs3:col span="6"> <cpt:fieldSet name="Description" id="description" >
