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 8d3294ae3a27c48eb89f8119c81e9f323b85b383 Author: danhaywood <[email protected]> AuthorDate: Tue May 9 06:55:49 2023 +0100 CAUSEWAY-2485: fleshes out Composite value type example --- .../progmodel/compositevalues/ComplexNumber.java | 14 ++- .../ComplexNumberValueSemantics.java | 4 +- .../compositevalues/ComplexNumber_default.java | 15 ++-- .../CompositeValueTypePage-description.adoc | 100 ++++++++++++++++++++- .../compositevalues/CompositeValueTypePage.java | 4 +- .../CompositeValueTypePage_addComplexNumber.java | 24 +++-- ...mpositeValueTypePage_subtractComplexNumber.java | 18 ++-- 7 files changed, 128 insertions(+), 51 deletions(-) diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/ComplexNumber.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/ComplexNumber.java index 9d2595f1b0..9afe3f7266 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/ComplexNumber.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/ComplexNumber.java @@ -20,21 +20,19 @@ package demoapp.dom.domain.objects.progmodel.compositevalues; // tag::class[] [email protected] // <.> [email protected] // <.> [email protected] // <.> [email protected] // <.> @lombok.AllArgsConstructor(staticName = "of") public class ComplexNumber { - double re; - double im; + double re; // <.> + double im; // <3> - public ComplexNumber add(ComplexNumber other) { + public ComplexNumber add(ComplexNumber other) { // <.> return ComplexNumber.of(re + other.re, im + other.im); } - - public ComplexNumber subtract(ComplexNumber other) { + public ComplexNumber subtract(ComplexNumber other) { // <4> return ComplexNumber.of(re - other.re, im - other.im); } - } // end::class[] diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/ComplexNumberValueSemantics.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/ComplexNumberValueSemantics.java index 9834e113c5..9a259a458e 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/ComplexNumberValueSemantics.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/ComplexNumberValueSemantics.java @@ -35,10 +35,10 @@ import org.apache.causeway.schema.common.v2.ValueType; @Named("demo.ComplexNumberValueSemantics") @Component @Import({ - ComplexNumber_default.class // <.> + ComplexNumber_default.class // <.> }) public class ComplexNumberValueSemantics - extends ValueSemanticsAbstract<ComplexNumber> { + extends ValueSemanticsAbstract<ComplexNumber> { // <.> // end::class[] @Override diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/ComplexNumber_default.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/ComplexNumber_default.java index 7b53093be3..2ccb6160e9 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/ComplexNumber_default.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/ComplexNumber_default.java @@ -9,29 +9,24 @@ import org.apache.causeway.applib.annotation.SemanticsOf; import lombok.RequiredArgsConstructor; // tag::default-mixin[] -// ... @Action(semantics = SemanticsOf.SAFE) -@ActionLayout(promptStyle = PromptStyle.INLINE_AS_IF_EDIT) +@ActionLayout(promptStyle = PromptStyle.INLINE_AS_IF_EDIT) // <.> @RequiredArgsConstructor public class ComplexNumber_default { private final ComplexNumber mixee; - @MemberSupport - public ComplexNumber act( + @MemberSupport public ComplexNumber act( final double re, final double im ) { return ComplexNumber.of(re, im); } - - @MemberSupport - public double defaultRe() { + @MemberSupport public double defaultRe() { return mixee.getRe(); } - - @MemberSupport - public double defaultIm() { + @MemberSupport public double defaultIm() { return mixee.getIm(); } } +// end::default-mixin[] diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage-description.adoc index 5e068526a2..3411a42181 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage-description.adoc +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage-description.adoc @@ -1,14 +1,108 @@ :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 [...] -TODO +"Value types" represent concepts that have intrinsic value and are immutable. +They are often used to model concepts such as money, dates, addresses, and other types of measurements or quantities that have a specific value. + +Value types are distinct from "entity types," which represent objects with a unique identity that can change over time. +In contrast, value types have no identity of their own, and two value objects with the same values are considered equal. +It's also common for value types to define an algebra, where they can be combined through operations to produce new values. + +A composite value type has more than one data attribute. == How this demo works -TODO +This page object defines a single property whose type is a value type, `ComplexNumber`, intended to model the mathematical concept of link:https://en.wikipedia.org/wiki/Complex_number[complex numbers]. +This is a composite value type, consisting of two `double` values: the _real_ part, and the _imaginary_ part. + +The value held by this page object can be changed using the two actions. +These simply delegate down to the operations defined by the value type itself. + + +In terms of code: +* The `ComplexNumber` type is defined as: ++ [source,java] -.NumberConstantJpa.java +.ComplexNumber.java ---- include::ComplexNumber.java[tags=class] ---- +<.> Defines this as a value type to the framework +<.> Uses lombok to define getters, a `hashCode()`, `equals()`, `toString()` and a constructor. +<.> The two data attributes +<.> Operations that define a simple algebra for this type. + +* this page object defines this as a single property: ++ +[source,java] +.CompositeValueTypePage.java +---- +include::CompositeValueTypePage.java[tags=class] +---- + +* the mixin action to add a value is: ++ +[source,java] +.CompositeValueTypePage_addComplexNumber.java +---- +include::CompositeValueTypePage_addComplexNumber.java[tags=class] +---- +<.> presents two parameters; the first is a read-only copy of the value held by the page object +<.> delegates to the `add` operation on the `ComplexNumber` value type +<.> defaults the first parameter to that held by the page object +<.> makes the first parameter disabled; the end-user can only enter a value for the second parameter. ++ +The action to subtract is similar + + +The framework also needs to know the structure of the value type. +This is done by providing an implementation of a link:https://causeway.apache.org/refguide/2.0.0-RC1/applib/index/value/semantics/ValueSemanticsProvider.html[ValueSemanticsProvider]. + +* the `ValueSemanticsProvider` implementation is: ++ +[source,java] +.ComplexNumberValueSemantics.java +---- +include::ComplexNumberValueSemantics.java[tags=class] +---- +<.> declares a mixin that the framework uses to present an action prompt to set the parts of the value type. +This is discussed in more detail below. +<.> inherits from link:https://causeway.apache.org/refguide/2.0.0-RC1/applib/index/value/semantics/ValueSemanticsAbstract.html[ValueSemanticsAbstract], a convenience adapter. + +* its implementation of `getDefaultsProvider()` is: ++ +[source,java] +.ComplexNumberValueSemantics.java +---- +include::ComplexNumberValueSemantics.java[tags=getDefaultsProvider] +---- + +* its implementation of `compose()` and `decompose()` is: ++ +[source,java] +.ComplexNumberValueSemantics.java +---- +include::ComplexNumberValueSemantics.java[tags=compose] +---- + +* its implementation of `getRenderer()` is: ++ +[source,java] +.ComplexNumberValueSemantics.java +---- +include::ComplexNumberValueSemantics.java[tags=getRenderer] +---- + +* As noted above, the "default" mixin defines an action to set the parts of the value type. ++ +The name "default" in this context is in effect a reserved method name. ++ +[source,java] +.ComplexNumber_default.java +---- +include::ComplexNumber_default.java[tags=default-mixin] +---- +<.> should always specify the `INLINE_AS_IF_EDIT` prompt style, because the prompt may be "nested" within an outer action prompt (e.g. the `addComplexNumber` action of the page object iself) + + diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage.java index a1ea560684..f93b2915a4 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage.java @@ -35,7 +35,6 @@ import org.apache.causeway.applib.annotation.PropertyLayout; @Named("demo.CompositeValuesPage") @DomainObject(nature=Nature.VIEW_MODEL) public class CompositeValueTypePage implements HasAsciiDocDescription { - // ... // end::class[] @ObjectSupport public String title() { @@ -43,10 +42,9 @@ public class CompositeValueTypePage implements HasAsciiDocDescription { } +// tag::class[] @Property @Getter @Setter private ComplexNumber complexNumber; - -// tag::class[] } // end::class[] diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage_addComplexNumber.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage_addComplexNumber.java index 3aa17a501f..3b5c27abec 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage_addComplexNumber.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage_addComplexNumber.java @@ -4,38 +4,34 @@ import lombok.RequiredArgsConstructor; import org.apache.causeway.applib.annotation.*; -// tag::default-mixin[] -// ... +// tag::class[] @Action(semantics = SemanticsOf.NON_IDEMPOTENT) @ActionLayout( associateWith = "complexNumber", - promptStyle = PromptStyle.DIALOG_SIDEBAR + sequence = "1", + promptStyle = PromptStyle.DIALOG ) @RequiredArgsConstructor public class CompositeValueTypePage_addComplexNumber { private final CompositeValueTypePage mixee; - @MemberSupport - public CompositeValueTypePage act( - final ComplexNumber current, + @MemberSupport public CompositeValueTypePage act( + final ComplexNumber current, // <.> final ComplexNumber other ) { - mixee.setComplexNumber(current.add(other)); // <.> + ComplexNumber result = current.add(other); // <.> + mixee.setComplexNumber(result); return mixee; } - - @MemberSupport public ComplexNumber defaultCurrent() { // <.> + @MemberSupport public ComplexNumber defaultCurrent() { // <.> return mixee.getComplexNumber(); } - - @MemberSupport public String disableCurrent() { // <.> + @MemberSupport public String disableCurrent() { // <.> return "Number being added to"; } - - @MemberSupport public ComplexNumber defaultOther() { return ComplexNumber.of(0,0); } - } +// end::class[] diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage_subtractComplexNumber.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage_subtractComplexNumber.java index 39a53e9945..470737be02 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage_subtractComplexNumber.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/compositevalues/CompositeValueTypePage_subtractComplexNumber.java @@ -4,11 +4,11 @@ import lombok.RequiredArgsConstructor; import org.apache.causeway.applib.annotation.*; -// tag::default-mixin[] -// ... +// tag::class[] @Action(semantics = SemanticsOf.NON_IDEMPOTENT) @ActionLayout( associateWith = "complexNumber", + sequence = "2", promptStyle = PromptStyle.DIALOG_SIDEBAR ) @RequiredArgsConstructor @@ -16,26 +16,22 @@ public class CompositeValueTypePage_subtractComplexNumber { private final CompositeValueTypePage mixee; - @MemberSupport - public CompositeValueTypePage act( + @MemberSupport public CompositeValueTypePage act( final ComplexNumber current, final ComplexNumber other ) { - mixee.setComplexNumber(current.subtract(other)); + ComplexNumber result = current.subtract(other); + mixee.setComplexNumber(result); return mixee; } - @MemberSupport public ComplexNumber defaultCurrent() { return mixee.getComplexNumber(); } - @MemberSupport public String disableCurrent() { - return "Number being added to"; + return "Number being subtracted from"; } - - @MemberSupport public ComplexNumber defaultOther() { return ComplexNumber.of(0,0); } - } +// end::class[]
