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
The following commit(s) were added to refs/heads/CAUSEWAY-2485 by this push:
new 10022bb6b6 CAUSEWAY-2485: fleshes out embedded types
10022bb6b6 is described below
commit 10022bb6b656eb3e94543045d16d5c3223367009
Author: danhaywood <[email protected]>
AuthorDate: Wed May 10 06:57:36 2023 +0100
CAUSEWAY-2485: fleshes out embedded types
---
.../embeddedvalues/jdo/ComplexNumberJdo.java | 57 ++---------
.../jdo/ComplexNumberJdoValueSemantics.java | 69 +++++--------
.../embeddedvalues/jdo/EmbeddedTypeMenuJdo.java | 6 +-
.../jdo/EmbeddedTypePageJdo-description.adoc | 114 ++++++---------------
.../jdo/NumberConstantJdo-description.adoc | 20 +++-
.../embeddedvalues/jdo/NumberConstantJdo.java | 9 +-
.../jdo/NumberConstantJdo_updateNumber.java | 50 ---------
.../embeddedvalues/jpa/ComplexNumberJpa.java | 9 +-
.../jpa/ComplexNumberJpaValueSemantics.java | 14 +--
.../jpa/ComplexNumberJpa_default.java | 37 -------
.../embeddedvalues/jpa/EmbeddedTypeMenuJpa.java | 2 +-
.../jpa/EmbeddedTypePageJpa-description.adoc | 103 ++++++-------------
.../embeddedvalues/jpa/EmbeddedTypePageJpa.java | 10 +-
.../jpa/NumberConstantJpa-description.adoc | 26 +++--
.../embeddedvalues/jpa/NumberConstantJpa.java | 9 +-
.../jpa/NumberConstantJpa_updateNumber.java | 50 ---------
.../customvaluetypes/ComplexNumberJdo_Test.java | 45 --------
17 files changed, 150 insertions(+), 480 deletions(-)
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/ComplexNumberJdo.java
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/ComplexNumberJdo.java
index baf3aa7a6f..dfc073118b 100644
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/ComplexNumberJdo.java
+++
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/ComplexNumberJdo.java
@@ -18,68 +18,27 @@
*/
package demoapp.dom.domain.objects.progmodel.embeddedvalues.jdo;
-import java.util.Optional;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.causeway.applib.annotation.ObjectSupport;
import org.apache.causeway.applib.annotation.Value;
import lombok.AccessLevel;
-import lombok.val;
import demoapp.dom.domain.objects.progmodel.embeddedvalues.ComplexNumber;
// tag::class[]
[email protected] // <.>
[email protected] // <.>
-@Value // <.>
[email protected] // <.>
[email protected](AccessLevel.PRIVATE) // <.>
[email protected]
[email protected] // <.>
+@Value // <.>
[email protected] // <.>
[email protected](AccessLevel.PRIVATE) // <.>
@lombok.AllArgsConstructor(staticName = "of")
[email protected] // <4>
public class ComplexNumberJdo
implements ComplexNumber{
@javax.jdo.annotations.Column(allowsNull = "false")
- private double re;
+ private double re; // <.>
@javax.jdo.annotations.Column(allowsNull = "false")
- private double im;
-
-// end::class[]
-
-// tag::title[]
- @ObjectSupport public String title() {
- return im >= 0
- ? "" + re + " + " + im + "i"
- : "" + re + " - " + (-im) + "i";
- }
-// end::title[]
-
-// tag::parse[]
- private static final Pattern PATTERN =
- Pattern.compile("^(?<re>\\S*)\\W*(?<sign>[+-])\\W*(?<im>\\S+)i$");
-
- public static Optional<ComplexNumberJdo> parse(final String parse) {
- val m = PATTERN.matcher(parse);
- return m.matches() ?
- Optional.of(ComplexNumberJdo.of(
- realFrom(m), signFrom(m) * imaginaryFrom(m)))
- : Optional.empty();
- }
-
- private static double realFrom(final Matcher m) {
- return Double.parseDouble(m.group("re"));
- }
- private static double signFrom(final Matcher m) {
- return m.group("sign").equals("-") ? -1.0d : +1.0d;
- }
- private static double imaginaryFrom(final Matcher m) {
- return Double.parseDouble(m.group("im"));
- }
-// end::parse[]
-
-// tag::class[]
- // ...
+ private double im; // <5>
}
// end::class[]
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/ComplexNumberJdoValueSemantics.java
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/ComplexNumberJdoValueSemantics.java
index 0a5a93e652..bcb5e7d0bd 100644
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/ComplexNumberJdoValueSemantics.java
+++
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/ComplexNumberJdoValueSemantics.java
@@ -18,22 +18,24 @@
*/
package demoapp.dom.domain.objects.progmodel.embeddedvalues.jdo;
+import javax.inject.Named;
+
+import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.apache.causeway.applib.util.schema.CommonDtoUtils;
-import org.apache.causeway.applib.value.semantics.DefaultsProvider;
-import org.apache.causeway.applib.value.semantics.Parser;
import org.apache.causeway.applib.value.semantics.Renderer;
import org.apache.causeway.applib.value.semantics.ValueDecomposition;
import org.apache.causeway.applib.value.semantics.ValueSemanticsAbstract;
-import org.apache.causeway.applib.value.semantics.ValueSemanticsProvider;
import org.apache.causeway.schema.common.v2.ValueType;
+@Profile("demo-jdo")
// tag::class[]
+@Named("demo.ComplexNumberJdoValueSemantics")
@Component
public class ComplexNumberJdoValueSemantics
extends ValueSemanticsAbstract<ComplexNumberJdo>{
-
+ // ...
// end::class[]
@Override
@@ -46,38 +48,7 @@ public class ComplexNumberJdoValueSemantics
return ValueType.COMPOSITE;
}
- // tag::getRenderer[]
- @Override
- public Renderer<ComplexNumberJdo> getRenderer() {
- return new Renderer<ComplexNumberJdo>() {
- @Override
- public String titlePresentation(final
ValueSemanticsProvider.Context context, final ComplexNumberJdo object) {
- return object!=null ? object.title() : "NaN";
- }
- };
- }
- // end::getRenderer[]
-// tag::getParser[]
- @Override
- public Parser<ComplexNumberJdo> getParser() {
- return new Parser<ComplexNumberJdo>() {
- @Override
- public ComplexNumberJdo parseTextRepresentation(final
ValueSemanticsProvider.Context context, final String entry) {
- return ComplexNumberJdo.parse(entry).orElse(null);
- }
- @Override
- public int typicalLength() {
- return 30;
- }
- @Override
- public String parseableTextRepresentation(final
ValueSemanticsProvider.Context context, final ComplexNumberJdo existing) {
- return existing!=null ? existing.title() : null;
- }
- };
- }
-// end::getParser[]
-
-// tag::getEncoderDecoder[]
+// tag::compose[]
@Override
public ValueDecomposition decompose(final ComplexNumberJdo value) {
return CommonDtoUtils.typedTupleBuilder(value)
@@ -95,17 +66,23 @@ public class ComplexNumberJdoValueSemantics
(Double)map.get("im")))
.orElse(null);
}
-// end::getEncoderDecoder[]
+// end::compose[]
-// tag::getDefaultsProvider[]
- @Override
- public DefaultsProvider<ComplexNumberJdo> getDefaultsProvider() {
-// end::getDefaultsProvider[]
- // ...
-// tag::getDefaultsProvider[]
- return ()-> ComplexNumberJdo.of(0, 0);
- }
-// end::getDefaultsProvider[]
+// tag::getRenderer[]
+ @Override
+ public Renderer<ComplexNumberJdo> getRenderer() {
+ return (context, object) -> title(object, "NaN");
+ }
+
+ private static String title(ComplexNumberJdo complexNumber, final String
fallbackIfNull) {
+ if (complexNumber == null) return fallbackIfNull;
+ return complexNumber.getRe() +
+ (complexNumber.getIm() >= 0
+ ? (" + " + complexNumber.getIm())
+ : (" - " + (-complexNumber.getIm())))
+ + "i";
+ }
+// end::getRenderer[]
// tag::class[]
}
// end::class[]
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/EmbeddedTypeMenuJdo.java
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/EmbeddedTypeMenuJdo.java
index 8d2902d6a8..a288162043 100644
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/EmbeddedTypeMenuJdo.java
+++
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/EmbeddedTypeMenuJdo.java
@@ -21,6 +21,8 @@ package
demoapp.dom.domain.objects.progmodel.embeddedvalues.jdo;
import javax.inject.Inject;
import javax.inject.Named;
+import org.springframework.context.annotation.Profile;
+
import org.apache.causeway.applib.annotation.Action;
import org.apache.causeway.applib.annotation.ActionLayout;
import org.apache.causeway.applib.annotation.DomainService;
@@ -28,8 +30,6 @@ import org.apache.causeway.applib.annotation.NatureOfService;
import org.apache.causeway.applib.annotation.PriorityPrecedence;
import org.apache.causeway.applib.services.factory.FactoryService;
-import org.springframework.context.annotation.Profile;
-
import lombok.RequiredArgsConstructor;
@Profile("demo-jdo")
@@ -42,7 +42,7 @@ public class EmbeddedTypeMenuJdo {
private final FactoryService factoryService;
@Action
- @ActionLayout(cssClassFa="fa-stop-circle", describedAs = "Experimental
support for embedded types")
+ @ActionLayout(cssClassFa="fa-stop-circle", describedAs = "Embedded (value)
types")
public EmbeddedTypePageJdo embeddedTypes(){
return factoryService.viewModel(new EmbeddedTypePageJdo());
}
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/EmbeddedTypePageJdo-description.adoc
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/EmbeddedTypePageJdo-description.adoc
index da065c18fa..f6e384f796 100644
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/EmbeddedTypePageJdo-description.adoc
+++
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/EmbeddedTypePageJdo-description.adoc
@@ -1,121 +1,69 @@
: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 framework includes _experimental_ support for embedded types.
-These are somewhat similar to value types, in that they have no identity and
are persisted inline within their owning object.
-They can also have custom behaviour.
+Embedded types are a feature of the JDO ORM that an entity to a field of a
composite type which groups several data fields together.
+The values of the composite type are then stored inline within the entity's
table.
+Such embedded types have no identity in and of themselves; they are identified
only by the entity that references them.
+Embedded types themselves can be mutable or immutable.
+When immutable, they are very similar to value types.
However, they are not quite true value types as the ORM needs to update their
fields directly.
To enable that, a mutator method is required, though it can be made `private`
-CAUTION: This is still work in progress, see
link:https://issues.apache.org/jira/browse/CAUSEWAY-1695[CAUSEWAY-1695].
-== View model and collection
+== How this demo works
-The page shows the `EmbeddedTypePage`.
-This simply has a collection of `NumberConstantJdo` entities:
+This page object has a collection `allConstants` that just returns a set of
`NumberConstantJdo` entities.
+The `NumberConstantJdo` entity defines a `name` property (of type `String`)
and a `numberConstant` property (of type `ComplexNumberJdo`).
+It is this second property that we are interested in.
-[source,java]
-.EmbeddedTypeVm.java
-----
-include::EmbeddedTypePageJdo.java[tags=class]
-----
-
-The `NumberConstantJdo` entity in turn declares a `name` property and a
`complexNumber` property of type `ComplexNumberJdo`.
-This latter property is an embedded type:
+In terms of code:
+* the `NumberConstantJdo` entity is defined as:
++
[source,java]
.NumberConstantJdo.java
----
include::NumberConstantJdo.java[tags=class]
----
-<.> JDO `@Embedded` annotation inlines the constituent parts of the value type
as columns of the owning entity
-<.> maps the 'ComplexNumber.re' property to column `number_re`
-<.> maps the 'ComplexNumber.im' property to column `number_im`
-
-== Embedded (value) type
-
-The `ComplexNumberJdo` type must also be annotated as embedded.
-We also annotate it with `@Value`; this instructs the framework how to
interact with the type:
+<.> JDO `@Embedded` annotation indicates that the constituent parts of the
embedded type should be stored as columns of the owning entity
+* the `ComplexNumberJdo` is the embedded type:
++
[source,java]
.ComplexNumberJdo.java
----
include::ComplexNumberJdo.java[tags=class]
----
-<.> Indicates to the ORM that this _is_ persisted data ...
-<.> \... but can only be embedded.
-<.> Indicates how the framework interacts with properties and parameters of
this type.
-This is explained further in the "value semantics provider" section below.
-<.> All fields are accessible ...
-<.> \... but can only be mutated by the ORM (so acts like a value type).
-
-This class defines some behaviour:
+<.> JDO `@EmbeddedOnly` annotation is the companion of `@Embedded` on the
owning object
+<.> Indicates to the framework that this is a value rather than an entity.
+Accordingly, we will also need to provide a `ValueSemanticsProvider`
implementation, discussed below.
+<.> provides access the fields
+<.> allows the ORM to initialize the fields
+<.> these fields of the embedded type are persisted as columns of the owning
entity
-* its title:
+* the `ComplexNumberJdoValueSemantics` class instructs the framework how to
render the `ComplexNumberJdo` as a value.
+
[source,java,indent=0]
-----
-include::ComplexNumberJdo.java[tags=title]
-----
-
-* how to parse a string:
-+
-[source,java]
-----
-include::ComplexNumberJdo.java[tags=parse,indent=0]
-----
-+
-This is used by the "value semantics provider", discussed in the next section.
-
-As well as using this type as a property, it can also be used as a parameter.
-The `NumberConstantJdo_updateNumber` mixin allows the value of the complex
number held by any `NumberConstant` to be updated footnote:[somewhat dubious
code, but this is only an example!]:
-
-[source,java]
-.NumberConstantJdo_updateNumber.java
-----
-include::NumberConstantJdo_updateNumber.java[tags=class]
-----
-
-
-== Value Semantics Provider
-
-As mentioned in the previous section, the framework uses an implementation of
`ValueSemanticsProvider` to know how to interact with properties and parameters
of the type:
-
-[source,java]
.ComplexNumberJdoValueSemantics.java
----
include::ComplexNumberJdoValueSemantics.java[tags=class]
----
-
-where:
-
-* `getRenderer()` is responsible for rendering the value:
-+
-[source,java,indent=0]
-----
-include::ComplexNumberJdoValueSemantics.java[tags=getRenderer]
-----
-
-* `getParser()` is responsible for parsing the entered string (for either an
editable property or a parameter):
+
-[source,java,indent=0]
-----
-include::ComplexNumberJdoValueSemantics.java[tags=getParser]
-----
+In this particular demo, the value is immutable.
+See elsewhere for examples of value types that can be mutated.
+
-In this case the implementation just delegates to the `ComplexNumberJdo` class
itself.
-
-* `getEncoderDecoder()` converts the value into a string for marshalling and
other purposes:
+** the `getRenderer()` method:
+
[source,java,indent=0]
+.ComplexNumberJdoValueSemantics.java
----
-include::ComplexNumberJdoValueSemantics.java[tags=getEncoderDecoder]
+include::ComplexNumberJdoValueSemantics.java[tags=getRenderer]
----
-
-* `getDefaultsProvider()` returns the default value to be used for
non-optional parameters and properties:
++
+** the `compose()`/`decompose()` methods:
+
[source,java,indent=0]
+.ComplexNumberJdoValueSemantics.java
----
-include::ComplexNumberJdoValueSemantics.java[tags=getDefaultsProvider]
+include::ComplexNumberJdoValueSemantics.java[tags=compose]
----
-
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/NumberConstantJdo-description.adoc
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/NumberConstantJdo-description.adoc
index 7c55ddaf6d..8528f34b10 100644
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/NumberConstantJdo-description.adoc
+++
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/NumberConstantJdo-description.adoc
@@ -1,5 +1,6 @@
: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 [...]
+
This class is a parent entity that contains an embedded type as a property:
[source,java]
@@ -7,6 +8,19 @@ This class is a parent entity that contains an embedded type
as a property:
----
include::NumberConstantJdo.java[tags=class]
----
-<.> JDO `@Embedded` annotation inlines the constituent parts of the value type
as columns of the owning entity
-<.> maps the 'ComplexNumber.re' property to column `number_re`
-<.> maps the 'ComplexNumber.im' property to column `number_im`
+<.> JDO `@Embedded` annotation indicates that the constituent parts of the
embedded type should be stored as columns of the owning entity
+
+
+The `ComplexNumberJdo` is the embedded type:
+
+[source,java]
+.ComplexNumberJdo.java
+----
+include::ComplexNumberJdo.java[tags=class]
+----
+<.> JDO `@EmbeddedOnly` annotation is the companion of `@Embedded` on the
owning object
+<.> Indicates to the framework that this is a value rather than an entity.
+Accordingly, we will also need to provide a `ValueSemanticsProvider`
implementation, discussed below.
+<.> provides access the fields
+<.> allows the ORM to initialize the fields
+<.> these fields of the embedded type are persisted as columns of the owning
entity
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/NumberConstantJdo.java
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/NumberConstantJdo.java
index 76da8529fc..ff060ed088 100644
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/NumberConstantJdo.java
+++
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/NumberConstantJdo.java
@@ -46,7 +46,10 @@ import
demoapp.dom.domain.objects.progmodel.embeddedvalues.NumberConstantEntity;
@DatastoreIdentity(strategy = IdGeneratorStrategy.IDENTITY, column = "id")
@DomainObject
public class NumberConstantJdo
- extends NumberConstantEntity {
+//end::class[]
+ extends NumberConstantEntity
+//tag::class[]
+{
// ...
@@ -67,8 +70,8 @@ public class NumberConstantJdo
private String name;
@javax.jdo.annotations.Embedded(members={ // <.>
- @Persistent(name="re", columns=@Column(name="number_re")), // <.>
- @Persistent(name="im", columns=@Column(name="number_im")) // <.>
+ @Persistent(name="re", columns=@Column(name="number_re")), // <1>
+ @Persistent(name="im", columns=@Column(name="number_im")) // <1>
})
@Property(editing = Editing.ENABLED)
@Getter @Setter
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/NumberConstantJdo_updateNumber.java
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/NumberConstantJdo_updateNumber.java
deleted file mode 100644
index 88cd54f0ca..0000000000
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jdo/NumberConstantJdo_updateNumber.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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 agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package demoapp.dom.domain.objects.progmodel.embeddedvalues.jdo;
-
-import org.springframework.context.annotation.Profile;
-
-import org.apache.causeway.applib.annotation.Action;
-import org.apache.causeway.applib.annotation.ActionLayout;
-import org.apache.causeway.applib.annotation.MemberSupport;
-import org.apache.causeway.applib.annotation.PromptStyle;
-
-import lombok.RequiredArgsConstructor;
-
-@Profile("demo-jdo")
-// tag::class[]
-@Action()
-@ActionLayout(
- promptStyle = PromptStyle.DIALOG_SIDEBAR
- , associateWith = "number")
-@RequiredArgsConstructor
-public class NumberConstantJdo_updateNumber {
-
- private final NumberConstantJdo numberConstantJdo;
-
- @MemberSupport public NumberConstantJdo act(final ComplexNumberJdo
complexNumberJdo) {
- numberConstantJdo.setNumber(complexNumberJdo);
- return numberConstantJdo;
- }
-
- @MemberSupport public ComplexNumberJdo default0Act() {
- return numberConstantJdo.getNumber();
- }
-}
-// end::class[]
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/ComplexNumberJpa.java
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/ComplexNumberJpa.java
index 23628d1104..50aa33cd26 100644
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/ComplexNumberJpa.java
+++
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/ComplexNumberJpa.java
@@ -30,7 +30,7 @@ import
demoapp.dom.domain.objects.progmodel.embeddedvalues.ComplexNumber;
@lombok.Getter // <.>
@lombok.Setter(AccessLevel.PRIVATE) // <.>
@lombok.AllArgsConstructor(staticName = "of")
[email protected]
[email protected] // <4>
public class ComplexNumberJpa
implements ComplexNumber {
@@ -38,11 +38,6 @@ public class ComplexNumberJpa
private double re; // <.>
@javax.persistence.Column(nullable = false)
- private double im; // <.>
-
-// end::class[]
-
-// tag::class[]
- // ...
+ private double im; // <5>
}
// end::class[]
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/ComplexNumberJpaValueSemantics.java
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/ComplexNumberJpaValueSemantics.java
index 06ec2cbfbc..f63c3b192e 100644
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/ComplexNumberJpaValueSemantics.java
+++
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/ComplexNumberJpaValueSemantics.java
@@ -20,12 +20,10 @@ package
demoapp.dom.domain.objects.progmodel.embeddedvalues.jpa;
import javax.inject.Named;
-import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.apache.causeway.applib.util.schema.CommonDtoUtils;
-import org.apache.causeway.applib.value.semantics.DefaultsProvider;
import org.apache.causeway.applib.value.semantics.Renderer;
import org.apache.causeway.applib.value.semantics.ValueDecomposition;
import org.apache.causeway.applib.value.semantics.ValueSemanticsAbstract;
@@ -35,11 +33,9 @@ import org.apache.causeway.schema.common.v2.ValueType;
// tag::class[]
@Named("demo.ComplexNumberJpaValueSemantics")
@Component
-@Import({
- ComplexNumberJpa_default.class // <.>
-})
public class ComplexNumberJpaValueSemantics
extends ValueSemanticsAbstract<ComplexNumberJpa> {
+ // ...
// end::class[]
@Override
@@ -52,13 +48,6 @@ public class ComplexNumberJpaValueSemantics
return ValueType.COMPOSITE;
}
-// tag::getDefaultsProvider[]
- @Override
- public DefaultsProvider<ComplexNumberJpa> getDefaultsProvider() {
- return ()-> ComplexNumberJpa.of(0, 0);
- }
-// end::getDefaultsProvider[]
-
// tag::compose[]
@Override
public ValueDecomposition decompose(final ComplexNumberJpa value) {
@@ -93,7 +82,6 @@ public class ComplexNumberJpaValueSemantics
: (" - " + (-complexNumber.getIm())))
+ "i";
}
-
// end::getRenderer[]
// tag::class[]
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/ComplexNumberJpa_default.java
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/ComplexNumberJpa_default.java
deleted file mode 100644
index 5df1befb96..0000000000
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/ComplexNumberJpa_default.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package demoapp.dom.domain.objects.progmodel.embeddedvalues.jpa;
-
-import lombok.RequiredArgsConstructor;
-
-import org.apache.causeway.applib.annotation.Action;
-import org.apache.causeway.applib.annotation.ActionLayout;
-import org.apache.causeway.applib.annotation.MemberSupport;
-import org.apache.causeway.applib.annotation.PromptStyle;
-import org.apache.causeway.applib.annotation.SemanticsOf;
-
-// tag::default-mixin[]
-// ...
-@Action(semantics = SemanticsOf.SAFE)
-@ActionLayout(promptStyle = PromptStyle.INLINE_AS_IF_EDIT)
-@RequiredArgsConstructor
-public class ComplexNumberJpa_default {
-
- private final ComplexNumberJpa mixee;
-
- @MemberSupport
- public ComplexNumberJpa act(
- final double re,
- final double im
- ) {
- return ComplexNumberJpa.of(re, im);
- }
-
- @MemberSupport
- public double defaultRe() {
- return mixee.getRe();
- }
-
- @MemberSupport
- public double defaultIm() {
- return mixee.getIm();
- }
-}
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/EmbeddedTypeMenuJpa.java
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/EmbeddedTypeMenuJpa.java
index 93909953e0..a463c6b093 100644
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/EmbeddedTypeMenuJpa.java
+++
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/EmbeddedTypeMenuJpa.java
@@ -42,7 +42,7 @@ public class EmbeddedTypeMenuJpa {
private final FactoryService factoryService;
@Action
- @ActionLayout(cssClassFa="fa-stop-circle", describedAs = "Experimental
support for embedded types")
+ @ActionLayout(cssClassFa="fa-stop-circle", describedAs = "Embedded (value)
types")
public EmbeddedTypePageJpa embeddedTypes(){
return factoryService.viewModel(new EmbeddedTypePageJpa());
}
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/EmbeddedTypePageJpa-description.adoc
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/EmbeddedTypePageJpa-description.adoc
index 78aac4a6cc..a42c1ab3a6 100644
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/EmbeddedTypePageJpa-description.adoc
+++
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/EmbeddedTypePageJpa-description.adoc
@@ -1,20 +1,25 @@
: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 framework includes _experimental_ support for embedded types.
-These are somewhat similar to value types, in that they have no identity and
are persisted inline within their owning object.
-They can also have custom behaviour.
+Embedded types are a feature of the JPA ORM that an entity to a field of a
composite type which groups several data fields together.
+The values of the composite type are then stored inline within the entity's
table.
+Such embedded types have no identity in and of themselves; they are identified
only by the entity that references them.
+Embedded types themselves can be mutable or immutable.
+When immutable, they are very similar to value types.
However, they are not quite true value types as the ORM needs to update their
fields directly.
To enable that, a mutator method is required, though it can be made `private`
-CAUTION: This is still work in progress, see
link:https://issues.apache.org/jira/browse/CAUSEWAY-1695[CAUSEWAY-1695].
== How this demo works
This page object has a collection `allConstants` that just returns a set of
`NumberConstantJpa` entities.
-The `NumberConstantJpa` entity defines a `name` property (of type `String) and
a `numberConstant` property (of type `ComplexNumberJpa`).
-It is this second property that we are interested in:
+The `NumberConstantJpa` entity defines a `name` property (of type `String`)
and a `numberConstant` property (of type `ComplexNumberJpa`).
+It is this second property that we are interested in.
+In terms of code:
+
+* the `NumberConstantJpa` entity is defined as:
++
[source,java]
.NumberConstantJpa.java
----
@@ -22,91 +27,43 @@ include::NumberConstantJpa.java[tags=class]
----
<.> JPA `@Embedded` annotation indicates that the constituent parts of the
embedded type should be stored as columns of the owning entity
-
-== Embedded type
-
-The `ComplexNumberJpa` type must also be annotated as embedded.
-We also annotate it with `@Value`; this instructs the framework how to
interact with the type:
-
+* the `ComplexNumberJpa` is the embedded type:
++
[source,java]
-.ComplexNumberJdo.java
+.ComplexNumberJpa.java
----
include::ComplexNumberJpa.java[tags=class]
----
-<.> Indicates to the ORM that this _is_ persisted data ...
-<.> \... but can only be embedded.
-<.> Indicates how the framework interacts with properties and parameters of
this type.
-This is explained further in the "value semantics provider" section below.
-<.> All fields are accessible ...
-<.> \... but can only be mutated by the ORM (so acts like a value type).
-
-This class defines some behaviour:
+<.> JPA `@Embeddable` annotation is the companion of `@Embedded` on the owning
object
+<.> Indicates to the framework that this is a value rather than an entity.
+Accordingly, we will also need to provide a `ValueSemanticsProvider`
implementation, discussed below.
+<.> provides access the fields
+<.> allows the ORM to initialize the fields
+<.> these fields of the embedded type are persisted as columns of the owning
entity
-* its title:
+* the `ComplexNumberJpaValueSemantics` class instructs the framework how to
render the `ComplexNumberJpa` as a value.
+
[source,java,indent=0]
+.ComplexNumberJpaValueSemantics.java
----
-include::ComplexNumberJpa.java[tags=title]
+include::ComplexNumberJpaValueSemantics.java[tags=class]
----
-
-* how to parse a string:
+
-[source,java]
-----
-include::ComplexNumberJpa.java[tags=parse,indent=0]
-----
+In this particular demo, the value is immutable.
+See elsewhere for examples of value types that can be mutated.
+
-This is used by the "value semantics provider", discussed in the next section.
-
-As well as using this type as a property, it can also be used as a parameter.
-The `NumberConstantJdo_updateNumber` mixin allows the value of the complex
number held by any `NumberConstant` to be updated footnote:[somewhat dubious
code, but this is only an example!]:
-
-[source,java]
-.NumberConstantJdo_updateNumber.java
-----
-include::NumberConstantJpa_updateNumber.java[tags=class]
-----
-
-
-== Value Semantics Provider
-
-As mentioned in the previous section, the framework uses an implementation of
`ValueSemanticsProvider` to know how to interact with properties and parameters
of the type:
-
-[source,java]
-.ComplexNumberJdoValueSemantics.java
-----
-include::ComplexNumberJpaValueSemantics.java[tags=class]
-----
-
-where:
-
-* `getRenderer()` is responsible for rendering the value:
+** the `getRenderer()` method:
+
[source,java,indent=0]
+.ComplexNumberJpaValueSemantics.java
----
include::ComplexNumberJpaValueSemantics.java[tags=getRenderer]
----
-
-* `getParser()` is responsible for parsing the entered string (for either an
editable property or a parameter):
+
-[source,java,indent=0]
-----
-include::ComplexNumberJpaValueSemantics.java[tags=getParser]
-----
-+
-In this case the implementation just delegates to the `ComplexNumberJdo` class
itself.
-
-* `getEncoderDecoder()` converts the value into a string for marshalling and
other purposes:
+** the `compose()`/`decompose()` methods:
+
[source,java,indent=0]
+.ComplexNumberJpaValueSemantics.java
----
-include::ComplexNumberJpaValueSemantics.java[tags=getEncoderDecoder]
+include::ComplexNumberJpaValueSemantics.java[tags=compose]
----
-
-* `getDefaultsProvider()` returns the default value to be used for
non-optional parameters and properties:
-+
-[source,java,indent=0]
-----
-include::ComplexNumberJpaValueSemantics.java[tags=getDefaultsProvider]
-----
-
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/EmbeddedTypePageJpa.java
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/EmbeddedTypePageJpa.java
index e275ae2c8e..212f44b490 100644
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/EmbeddedTypePageJpa.java
+++
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/EmbeddedTypePageJpa.java
@@ -18,11 +18,6 @@
*/
package demoapp.dom.domain.objects.progmodel.embeddedvalues.jpa;
-import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
-import demoapp.dom._infra.values.ValueHolderRepository;
-import demoapp.dom.domain.objects.progmodel.embeddedvalues.ComplexNumber;
-import
demoapp.dom.domain.objects.progmodel.embeddedvalues.NumberConstantEntity;
-
import java.util.List;
import javax.inject.Inject;
@@ -33,6 +28,11 @@ import org.apache.causeway.applib.annotation.DomainObject;
import org.apache.causeway.applib.annotation.Nature;
import org.apache.causeway.applib.annotation.ObjectSupport;
+import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
+import demoapp.dom._infra.values.ValueHolderRepository;
+import demoapp.dom.domain.objects.progmodel.embeddedvalues.ComplexNumber;
+import
demoapp.dom.domain.objects.progmodel.embeddedvalues.NumberConstantEntity;
+
// tag::class[]
@Named("demo.EmbeddedTypePageJpa")
@DomainObject(nature=Nature.VIEW_MODEL)
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/NumberConstantJpa-description.adoc
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/NumberConstantJpa-description.adoc
index f0cbead135..8885320594 100644
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/NumberConstantJpa-description.adoc
+++
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/NumberConstantJpa-description.adoc
@@ -1,17 +1,27 @@
: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 [...]
-[WARNING]
-====
-TODO this yet is just a copy from JDO
-====
This class is a parent entity that contains an embedded type as a property:
[source,java]
-.NumberConstantJdo.java
+.NumberConstantJpa.java
----
include::NumberConstantJpa.java[tags=class]
----
-<.> JDO `@Embedded` annotation inlines the constituent parts of the value type
as columns of the owning entity
-<.> maps the 'ComplexNumber.re' property to column `number_re`
-<.> maps the 'ComplexNumber.im' property to column `number_im`
+<.> JPA `@Embedded` annotation indicates that the constituent parts of the
embedded type should be stored as columns of the owning entity
+
+
+The `ComplexNumberJpa` is the embedded type:
+
+[source,java]
+.ComplexNumberJpa.java
+----
+include::ComplexNumberJpa.java[tags=class]
+----
+<.> JPA `@Embeddable` annotation is the companion of `@Embedded` on the owning
object
+<.> Indicates to the framework that this is a value rather than an entity.
+Accordingly, we will also need to provide a `ValueSemanticsProvider`
implementation, discussed below.
+<.> provides access the fields
+<.> allows the ORM to initialize the fields
+<.> these fields of the embedded type are persisted as columns of the owning
entity
+
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/NumberConstantJpa.java
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/NumberConstantJpa.java
index 54054882a9..25a16a02d0 100644
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/NumberConstantJpa.java
+++
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/NumberConstantJpa.java
@@ -52,10 +52,11 @@ import
demoapp.dom.domain.objects.progmodel.embeddedvalues.NumberConstantEntity;
@DomainObject
@NoArgsConstructor
public class NumberConstantJpa
- extends NumberConstantEntity {
-
+//end::class[]
+ extends NumberConstantEntity
+//tag::class[]
+{
// ...
-
//end::class[]
@ObjectSupport public String title() {
return getName();
@@ -77,7 +78,7 @@ public class NumberConstantJpa
private String name;
@javax.persistence.Embedded // <.>
- @Property(editing = Editing.ENABLED)
+ @Property(editing = Editing.DISABLED)
@Getter @Setter
private ComplexNumberJpa number;
}
diff --git
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/NumberConstantJpa_updateNumber.java
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/NumberConstantJpa_updateNumber.java
deleted file mode 100644
index 6abcba8512..0000000000
---
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/embeddedvalues/jpa/NumberConstantJpa_updateNumber.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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 agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package demoapp.dom.domain.objects.progmodel.embeddedvalues.jpa;
-
-import org.springframework.context.annotation.Profile;
-
-import org.apache.causeway.applib.annotation.Action;
-import org.apache.causeway.applib.annotation.ActionLayout;
-import org.apache.causeway.applib.annotation.MemberSupport;
-import org.apache.causeway.applib.annotation.PromptStyle;
-
-import lombok.RequiredArgsConstructor;
-
-@Profile("demo-jpa")
-// tag::class[]
-@Action()
-@ActionLayout(
- promptStyle = PromptStyle.DIALOG_SIDEBAR
- , associateWith = "number")
-@RequiredArgsConstructor
-public class NumberConstantJpa_updateNumber {
-
- private final NumberConstantJpa numberConstantJdo;
-
- @MemberSupport public NumberConstantJpa act(final ComplexNumberJpa
complexNumberJdo) {
- numberConstantJdo.setNumber(complexNumberJdo);
- return numberConstantJdo;
- }
-
- @MemberSupport public ComplexNumberJpa default0Act() {
- return numberConstantJdo.getNumber();
- }
-}
-// end::class[]
diff --git
a/examples/demo/domain/src/test/java/demoapp/dom/domain/objects/other/customvaluetypes/ComplexNumberJdo_Test.java
b/examples/demo/domain/src/test/java/demoapp/dom/domain/objects/other/customvaluetypes/ComplexNumberJdo_Test.java
deleted file mode 100644
index 24249929bb..0000000000
---
a/examples/demo/domain/src/test/java/demoapp/dom/domain/objects/other/customvaluetypes/ComplexNumberJdo_Test.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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 agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-package demoapp.dom.domain.objects.other.customvaluetypes;
-
-import org.assertj.core.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import lombok.val;
-
-import
demoapp.dom.domain.objects.progmodel.embeddedvalues.jdo.ComplexNumberJdo;
-
-class ComplexNumberJdo_Test {
-
- @Test
- void title() {
- val cn = ComplexNumberJdo.of(10.0, 5.0);
- Assertions.assertThat(cn.title()).isEqualTo("10.0 + 5.0i");
- }
-
- @Test
- void parse() {
- val cn = ComplexNumberJdo.parse("10.0 + 5.0i");
-
- Assertions.assertThat(cn).isPresent();
- Assertions.assertThat(cn.get().title()).isEqualTo("10.0 + 5.0i");
- }
-}