You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2023/01/13 18:50:35 UTC

[isis] 02/02: ISIS-3304: fixes regression with DtoMapper

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 558a1ec8342f01d5f60637eb666b8373a8d5b8e3
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Jan 13 19:50:25 2023 +0100

    ISIS-3304: fixes regression with DtoMapper
    
    - which must be created for concrete dto types explicitly
---
 .../applib/util/schema/InteractionDtoUtils.java    |  2 +-
 .../util/schema/MemberExecutionDtoUtils.java       | 22 ++++--
 .../applib/util/JaxbUtilsDtoCloneTest.java         | 84 ++++++++++++++++++++++
 .../plural/DomainObjectLayoutPluralVm.java         | 19 ++++-
 .../subscriber/ExecutionSubscriberForTesting.java  |  6 +-
 5 files changed, 124 insertions(+), 9 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/causeway/applib/util/schema/InteractionDtoUtils.java b/api/applib/src/main/java/org/apache/causeway/applib/util/schema/InteractionDtoUtils.java
index 4c0ae7474b..1b5005f9f9 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/util/schema/InteractionDtoUtils.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/util/schema/InteractionDtoUtils.java
@@ -99,7 +99,7 @@ public final class InteractionDtoUtils {
             }
 
             private MemberExecutionDto clone(final MemberExecutionDto memberExecutionDto) {
-                return MemberExecutionDtoUtils.dtoMapper().clone(memberExecutionDto);
+                return MemberExecutionDtoUtils.dtoMapper(memberExecutionDto.getClass()).clone(memberExecutionDto);
             }
         };
 
diff --git a/api/applib/src/main/java/org/apache/causeway/applib/util/schema/MemberExecutionDtoUtils.java b/api/applib/src/main/java/org/apache/causeway/applib/util/schema/MemberExecutionDtoUtils.java
index e1575aa79f..b39e8ff905 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/util/schema/MemberExecutionDtoUtils.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/util/schema/MemberExecutionDtoUtils.java
@@ -18,14 +18,17 @@
  */
 package org.apache.causeway.applib.util.schema;
 
+import org.apache.causeway.commons.internal.base._Casts;
 import org.apache.causeway.commons.internal.base._Lazy;
 import org.apache.causeway.commons.io.DtoMapper;
 import org.apache.causeway.commons.io.JaxbUtils;
 import org.apache.causeway.schema.common.v2.DifferenceDto;
 import org.apache.causeway.schema.common.v2.PeriodDto;
+import org.apache.causeway.schema.ixn.v2.ActionInvocationDto;
 import org.apache.causeway.schema.ixn.v2.MemberExecutionDto;
 import org.apache.causeway.schema.ixn.v2.MetricsDto;
 import org.apache.causeway.schema.ixn.v2.ObjectCountsDto;
+import org.apache.causeway.schema.ixn.v2.PropertyEditDto;
 
 import lombok.experimental.UtilityClass;
 
@@ -36,14 +39,21 @@ import lombok.experimental.UtilityClass;
 public final class MemberExecutionDtoUtils {
 
     public void init() {
-        dtoMapper.get();
+        dtoMapperForActionInvocation.get();
+        dtoMapperForPropertyEdit.get();
     }
 
-    private _Lazy<DtoMapper<MemberExecutionDto>> dtoMapper = _Lazy.threadSafe(
-            ()->JaxbUtils.mapperFor(MemberExecutionDto.class, opts->opts.allowMissingRootElement(true)));
+    private _Lazy<DtoMapper<ActionInvocationDto>> dtoMapperForActionInvocation = _Lazy.threadSafe(
+            ()->JaxbUtils.mapperFor(ActionInvocationDto.class, opts->opts.allowMissingRootElement(true)));
 
-    public DtoMapper<MemberExecutionDto> dtoMapper() {
-        return dtoMapper.get();
+    private _Lazy<DtoMapper<PropertyEditDto>> dtoMapperForPropertyEdit = _Lazy.threadSafe(
+            ()->JaxbUtils.mapperFor(PropertyEditDto.class, opts->opts.allowMissingRootElement(true)));
+
+    public static <T extends MemberExecutionDto> DtoMapper<MemberExecutionDto> dtoMapper(final Class<T> dtoClass) {
+        return _Casts.uncheckedCast(
+                ActionInvocationDto.class.equals(dtoClass)
+                    ? dtoMapperForActionInvocation.get()
+                    : dtoMapperForPropertyEdit.get());
     }
 
     public MetricsDto metricsFor(final MemberExecutionDto executionDto) {
@@ -90,4 +100,6 @@ public final class MemberExecutionDtoUtils {
         return differenceDto;
     }
 
+
+
 }
diff --git a/api/applib/src/test/java/org/apache/causeway/applib/util/JaxbUtilsDtoCloneTest.java b/api/applib/src/test/java/org/apache/causeway/applib/util/JaxbUtilsDtoCloneTest.java
new file mode 100644
index 0000000000..7036cf6706
--- /dev/null
+++ b/api/applib/src/test/java/org/apache/causeway/applib/util/JaxbUtilsDtoCloneTest.java
@@ -0,0 +1,84 @@
+/*
+ *  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 org.apache.causeway.applib.util;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import org.apache.causeway.applib.util.schema.MemberExecutionDtoUtils;
+import org.apache.causeway.commons.internal.base._Bytes;
+import org.apache.causeway.commons.io.DataSource;
+import org.apache.causeway.schema.ixn.v2.ActionInvocationDto;
+
+import lombok.val;
+
+class JaxbUtilsDtoCloneTest {
+
+    ActionInvocationDto x;
+
+    @Test
+    void dtoCloning() {
+
+        // ActionInvocationDto hex dump
+
+        val dtoHexDump = "3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 31 2e 30 22 20 65 6e 63 6f 64 69 6e "
+                + "67 3d 22 55 54 46 2d 38 22 20 73 74 61 6e 64 61 6c 6f 6e 65 3d 22 79 65 73 22 3f 3e 3c 41 63 74 "
+                + "69 6f 6e 49 6e 76 6f 63 61 74 69 6f 6e 44 74 6f 20 78 6d 6c 6e 73 3a 69 78 6e 3d 22 68 74 74 70 "
+                + "3a 2f 2f 63 61 75 73 65 77 61 79 2e 61 70 61 63 68 65 2e 6f 72 67 2f 73 63 68 65 6d 61 2f 69 78 "
+                + "6e 22 20 78 6d 6c 6e 73 3a 63 6d 64 3d 22 68 74 74 70 3a 2f 2f 63 61 75 73 65 77 61 79 2e 61 70 "
+                + "61 63 68 65 2e 6f 72 67 2f 73 63 68 65 6d 61 2f 63 6d 64 22 20 78 6d 6c 6e 73 3a 63 6f 6d 3d 22 "
+                + "68 74 74 70 3a 2f 2f 63 61 75 73 65 77 61 79 2e 61 70 61 63 68 65 2e 6f 72 67 2f 73 63 68 65 6d "
+                + "61 2f 63 6f 6d 6d 6f 6e 22 3e 3c 69 78 6e 3a 73 65 71 75 65 6e 63 65 3e 30 3c 2f 69 78 6e 3a 73 "
+                + "65 71 75 65 6e 63 65 3e 3c 69 78 6e 3a 74 61 72 67 65 74 20 74 79 70 65 3d 22 73 69 6d 70 6c 65 "
+                + "2e 53 69 6d 70 6c 65 4f 62 6a 65 63 74 73 22 20 69 64 3d 22 31 22 2f 3e 3c 69 78 6e 3a 6c 6f 67 "
+                + "69 63 61 6c 4d 65 6d 62 65 72 49 64 65 6e 74 69 66 69 65 72 3e 73 69 6d 70 6c 65 2e 53 69 6d 70 "
+                + "6c 65 4f 62 6a 65 63 74 73 23 63 72 65 61 74 65 3c 2f 69 78 6e 3a 6c 6f 67 69 63 61 6c 4d 65 6d "
+                + "62 65 72 49 64 65 6e 74 69 66 69 65 72 3e 3c 69 78 6e 3a 75 73 65 72 6e 61 6d 65 3e 73 76 65 6e "
+                + "3c 2f 69 78 6e 3a 75 73 65 72 6e 61 6d 65 3e 3c 69 78 6e 3a 6d 65 74 72 69 63 73 3e 3c 69 78 6e "
+                + "3a 74 69 6d 69 6e 67 73 3e 3c 63 6f 6d 3a 73 74 61 72 74 65 64 41 74 3e 32 30 32 33 2d 30 31 2d "
+                + "31 33 54 31 38 3a 34 35 3a 34 32 2e 32 39 33 2b 30 31 3a 30 30 3c 2f 63 6f 6d 3a 73 74 61 72 74 "
+                + "65 64 41 74 3e 3c 63 6f 6d 3a 63 6f 6d 70 6c 65 74 65 64 41 74 3e 32 30 32 33 2d 30 31 2d 31 33 "
+                + "54 31 38 3a 34 35 3a 34 32 2e 32 39 34 2b 30 31 3a 30 30 3c 2f 63 6f 6d 3a 63 6f 6d 70 6c 65 74 "
+                + "65 64 41 74 3e 3c 2f 69 78 6e 3a 74 69 6d 69 6e 67 73 3e 3c 69 78 6e 3a 6f 62 6a 65 63 74 43 6f "
+                + "75 6e 74 73 3e 3c 69 78 6e 3a 6c 6f 61 64 65 64 20 62 65 66 6f 72 65 3d 22 32 34 22 20 61 66 74 "
+                + "65 72 3d 22 32 34 22 2f 3e 3c 69 78 6e 3a 64 69 72 74 69 65 64 20 62 65 66 6f 72 65 3d 22 32 34 "
+                + "22 20 61 66 74 65 72 3d 22 30 22 2f 3e 3c 2f 69 78 6e 3a 6f 62 6a 65 63 74 43 6f 75 6e 74 73 3e "
+                + "3c 2f 69 78 6e 3a 6d 65 74 72 69 63 73 3e 3c 69 78 6e 3a 70 61 72 61 6d 65 74 65 72 73 3e 3c 63 "
+                + "6d 64 3a 70 61 72 61 6d 65 74 65 72 20 6e 61 6d 65 3d 22 4e 61 6d 65 22 20 74 79 70 65 3d 22 73 "
+                + "74 72 69 6e 67 22 3e 3c 63 6f 6d 3a 73 74 72 69 6e 67 3e 64 64 3c 2f 63 6f 6d 3a 73 74 72 69 6e "
+                + "67 3e 3c 2f 63 6d 64 3a 70 61 72 61 6d 65 74 65 72 3e 3c 2f 69 78 6e 3a 70 61 72 61 6d 65 74 65 "
+                + "72 73 3e 3c 69 78 6e 3a 72 65 74 75 72 6e 65 64 20 74 79 70 65 3d 22 72 65 66 65 72 65 6e 63 65 "
+                + "22 3e 3c 63 6f 6d 3a 72 65 66 65 72 65 6e 63 65 20 74 79 70 65 3d 22 73 69 6d 70 6c 65 2e 53 69 "
+                + "6d 70 6c 65 4f 62 6a 65 63 74 22 20 69 64 3d 22 32 38 39 22 2f 3e 3c 2f 69 78 6e 3a 72 65 74 75 "
+                + "72 6e 65 64 3e 3c 2f 41 63 74 69 6f 6e 49 6e 76 6f 63 61 74 69 6f 6e 44 74 6f 3e";
+
+        val dtoAsBytes = _Bytes.ofHexDump(dtoHexDump);
+
+        // verify that we can reproduce a byte array from its stringified representation
+        assertEquals(dtoHexDump, _Bytes.hexDump(dtoAsBytes));
+
+        val mapper = MemberExecutionDtoUtils.dtoMapper(ActionInvocationDto.class);
+        val dto = mapper.read(DataSource.ofBytes(dtoAsBytes));
+
+        assertNotNull(dto);
+    }
+
+}
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObjectLayout/plural/DomainObjectLayoutPluralVm.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObjectLayout/plural/DomainObjectLayoutPluralVm.java
index 898328dac6..8a7861fb68 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObjectLayout/plural/DomainObjectLayoutPluralVm.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObjectLayout/plural/DomainObjectLayoutPluralVm.java
@@ -18,6 +18,9 @@
  */
 package demoapp.dom.domain.objects.DomainObjectLayout.plural;
 
+import java.util.List;
+import java.util.UUID;
+
 import javax.inject.Named;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
@@ -25,11 +28,14 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
+import org.apache.causeway.applib.annotation.Action;
 import org.apache.causeway.applib.annotation.DomainObject;
+import org.apache.causeway.applib.annotation.DomainObjectLayout;
 import org.apache.causeway.applib.annotation.Nature;
 import org.apache.causeway.applib.annotation.ObjectSupport;
 import org.apache.causeway.applib.annotation.Optionality;
 import org.apache.causeway.applib.annotation.Property;
+import org.apache.causeway.applib.annotation.TableDecoration;
 
 import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
 import lombok.Getter;
@@ -42,17 +48,26 @@ import lombok.Setter;
 @Named("demo.DomainObjectLayoutPluralVm")
 @DomainObject(
         nature=Nature.VIEW_MODEL)
+@DomainObjectLayout(
+        tableDecoration = TableDecoration.DATATABLES_NET,
+        plural="Example Plural Name")
 public class DomainObjectLayoutPluralVm implements HasAsciiDocDescription {
 
     @ObjectSupport public String title() {
         return "DomainObjectLayout#plural";
     }
 
-    //TODO[ISIS-3309]
+    @Action
+    public List<DomainObjectLayoutPluralVm> standaloneTable() {
+        return List.of(
+                    new DomainObjectLayoutPluralVm(),
+                    new DomainObjectLayoutPluralVm());
+    }
+
     @Property(optionality = Optionality.OPTIONAL)
     @XmlElement(required = false)
     @Getter @Setter
-    private String dummy;
+    private String uuid = UUID.randomUUID().toString();
 
 }
 //end::class[]
diff --git a/regressiontests/stable/src/main/java/org/apache/causeway/testdomain/publishing/subscriber/ExecutionSubscriberForTesting.java b/regressiontests/stable/src/main/java/org/apache/causeway/testdomain/publishing/subscriber/ExecutionSubscriberForTesting.java
index 7b2a5fbb10..1cf011c5bd 100644
--- a/regressiontests/stable/src/main/java/org/apache/causeway/testdomain/publishing/subscriber/ExecutionSubscriberForTesting.java
+++ b/regressiontests/stable/src/main/java/org/apache/causeway/testdomain/publishing/subscriber/ExecutionSubscriberForTesting.java
@@ -30,6 +30,7 @@ import org.apache.causeway.applib.services.iactn.Execution;
 import org.apache.causeway.applib.services.publishing.spi.ExecutionSubscriber;
 import org.apache.causeway.applib.util.schema.MemberExecutionDtoUtils;
 import org.apache.causeway.commons.collections.Can;
+import org.apache.causeway.schema.ixn.v2.MemberExecutionDto;
 import org.apache.causeway.testdomain.util.kv.KVStoreForTesting;
 
 import lombok.val;
@@ -57,7 +58,10 @@ implements ExecutionSubscriber {
         publishedEntries.add(execution);
 
         kvStore.put(this, "publishedExecutions", publishedEntries);
-        log.debug("publish execution {}", ()->MemberExecutionDtoUtils.dtoMapper().toString(execution.getDto()));
+        log.debug("publish execution {}", ()->{
+            final MemberExecutionDto dto = execution.getDto();
+            return MemberExecutionDtoUtils.dtoMapper(dto.getClass()).toString(dto);
+        });
     }
 
     // -- UTILITIES