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 2021/11/23 15:37:14 UTC

[isis] branch master updated: ISIS-2877: adds test scenarios for OidDto and Bookmark

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


The following commit(s) were added to refs/heads/master by this push:
     new 91fe91b  ISIS-2877: adds test scenarios for OidDto and Bookmark
91fe91b is described below

commit 91fe91b8ed9fddd7db842363318d576d49340068
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Nov 23 16:37:05 2021 +0100

    ISIS-2877: adds test scenarios for OidDto and Bookmark
---
 .../isis/applib/services/bookmark/Bookmark.java    | 13 ++-
 .../valuesemantics/BookmarkValueSemantics.java     | 58 +++-----------
 .../valuesemantics/OidDtoValueSemantics.java       | 36 +++++++--
 .../runtimeservices/memento/_ObjectMemento.java    |  6 +-
 .../applib/IsisBookmarkConverter.java              |  2 +-
 .../isis/testdomain/value/ValueSemanticsTest.java  | 13 ++-
 .../testdomain/value/ValueSemanticsTester.java     |  9 ++-
 .../testdomain/conf/Configuration_headless.java    |  5 +-
 .../model/valuetypes/ValueTypeExample.java         | 93 ++++++++++++++++++++--
 .../viewer/wicket/model/models/EntityModel.java    |  3 +-
 10 files changed, 162 insertions(+), 76 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/Bookmark.java b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/Bookmark.java
index 76f0363..dc4347d 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/Bookmark.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/Bookmark.java
@@ -28,6 +28,7 @@ import org.apache.isis.applib.IsisModuleApplib;
 import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.codec._UrlDecoderUtil;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.schema.common.v2.OidDto;
 
 import lombok.AccessLevel;
@@ -100,7 +101,7 @@ public final class Bookmark implements Oid {
     /**
      * Round-trip with {@link #stringify()} representation.
      */
-    public static Optional<Bookmark> parse(@Nullable String str) {
+    public static Optional<Bookmark> parse(final @Nullable String str) {
 
         if(str==null) {
             return Optional.empty();
@@ -120,7 +121,13 @@ public final class Bookmark implements Oid {
         return Optional.empty();
     }
 
-    public static Optional<Bookmark> parseUrlEncoded(@Nullable String urlEncodedStr) {
+
+    public static Bookmark parseElseFail(final @Nullable String input) {
+        return parse(input)
+                .orElseThrow(()->_Exceptions.illegalArgument("cannot parse Bookmark %s", input));
+    }
+
+    public static Optional<Bookmark> parseUrlEncoded(@Nullable final String urlEncodedStr) {
         return _Strings.isEmpty(urlEncodedStr)
                 ? Optional.empty()
                 : parse(_UrlDecoderUtil.urlDecode(urlEncodedStr));
@@ -185,7 +192,7 @@ public final class Bookmark implements Oid {
 
     // -- HELPER
 
-    private String stringify(String id) {
+    private String stringify(final String id) {
         return logicalTypeName + SEPARATOR + id;
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BookmarkValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BookmarkValueSemantics.java
index 3877bc3..c07f79f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BookmarkValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BookmarkValueSemantics.java
@@ -18,30 +18,23 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics;
 
+import javax.inject.Inject;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.value.semantics.EncoderDecoder;
-import org.apache.isis.applib.value.semantics.Parser;
-import org.apache.isis.applib.value.semantics.Renderer;
 import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
-import org.apache.isis.applib.value.semantics.ValueSemanticsProvider;
-import org.apache.isis.commons.internal.base._Strings;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
+import org.apache.isis.schema.common.v2.OidDto;
 import org.apache.isis.schema.common.v2.ValueType;
 
-import lombok.val;
-
 @Component
 @Named("isis.val.BookmarkValueSemantics")
 public class BookmarkValueSemantics
-extends ValueSemanticsAbstract<Bookmark>
-implements
-    EncoderDecoder<Bookmark>,
-    Parser<Bookmark>,
-    Renderer<Bookmark> {
+extends ValueSemanticsAdapter<Bookmark, OidDto, Void> {
+
+    @Inject OidDtoValueSemantics oidDtoValueSemantics;
 
     @Override
     public Class<Bookmark> getCorrespondingClass() {
@@ -53,48 +46,21 @@ implements
         return UNREPRESENTED;
     }
 
-    // -- ENCODER DECODER
-
     @Override
-    public String toEncodedString(final Bookmark object) {
-        return object.stringify();
+    public ValueSemanticsAbstract<OidDto> getDelegate() {
+        return oidDtoValueSemantics;
     }
 
     @Override
-    public Bookmark fromEncodedString(final String data) {
-        return Bookmark.parse(data).orElseThrow(()->_Exceptions.illegalArgument("%s", data));
+    public Bookmark fromDelegateValue(final OidDto value) {
+        return value!=null ? Bookmark.forOidDto(value) : null;
     }
 
-    // -- RENDERER
-
     @Override
-    public String simpleTextPresentation(final ValueSemanticsProvider.Context context, final Bookmark value) {
-        return value == null ? "" : value.stringify();
+    public OidDto toDelegateValue(final Bookmark value) {
+        return value!=null ? value.toOidDto() : null;
     }
 
-    // -- PARSER
 
-    @Override
-    public String parseableTextRepresentation(final ValueSemanticsProvider.Context context, final Bookmark value) {
-        return value == null ? null : value.toString();
-    }
-
-    @Override
-    public Bookmark parseTextRepresentation(final ValueSemanticsProvider.Context context, final String text) {
-        val input = _Strings.blankToNullOrTrim(text);
-        return input!=null
-                ? Bookmark.parse(input).orElseThrow(()->_Exceptions.illegalArgument("%s", input))
-                : null;
-    }
-
-    @Override
-    public int typicalLength() {
-        return maxLength();
-    }
-
-    @Override
-    public int maxLength() {
-        return 4048;
-    }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/OidDtoValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/OidDtoValueSemantics.java
index 7f601c3..a9c2f3b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/OidDtoValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/OidDtoValueSemantics.java
@@ -24,12 +24,12 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.value.semantics.EncoderDecoder;
+import org.apache.isis.applib.value.semantics.OrderRelation;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
 import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
 import org.apache.isis.applib.value.semantics.ValueSemanticsProvider;
 import org.apache.isis.commons.internal.base._Strings;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.schema.common.v2.OidDto;
 import org.apache.isis.schema.common.v2.ValueType;
 
@@ -40,6 +40,7 @@ import lombok.val;
 public class OidDtoValueSemantics
 extends ValueSemanticsAbstract<OidDto>
 implements
+    OrderRelation<OidDto, Void>,
     EncoderDecoder<OidDto>,
     Parser<OidDto>,
     Renderer<OidDto> {
@@ -54,6 +55,31 @@ implements
         return UNREPRESENTED;
     }
 
+    // -- ORDER RELATION
+
+    @Override
+    public Void epsilon() {
+        return null; // not used
+    }
+
+    @Override
+    public int compare(final OidDto a, final OidDto b, final Void epsilon) {
+        int c = _Strings.compareNullsFirst(a.getType(), b.getType());
+        if(c!=0) {
+            return c;
+        }
+        c = _Strings.compareNullsFirst(a.getId(), b.getId());
+        if(c!=0) {
+            return c;
+        }
+        return 0;
+    }
+
+    @Override
+    public boolean equals(final OidDto a, final OidDto b, final Void epsilon) {
+        return compare(a, b, epsilon) == 0;
+    }
+
     // -- ENCODER DECODER
 
     @Override
@@ -63,8 +89,7 @@ implements
 
     @Override
     public OidDto fromEncodedString(final String data) {
-        return Bookmark.parse(data)
-                .orElseThrow(()->_Exceptions.illegalArgument("%s", data))
+        return Bookmark.parseElseFail(data)
                 .toOidDto();
     }
 
@@ -79,15 +104,14 @@ implements
 
     @Override
     public String parseableTextRepresentation(final ValueSemanticsProvider.Context context, final OidDto value) {
-        return value == null ? null : value.toString();
+        return value == null ? null : Bookmark.forOidDto(value).stringify();
     }
 
     @Override
     public OidDto parseTextRepresentation(final ValueSemanticsProvider.Context context, final String text) {
         val input = _Strings.blankToNullOrTrim(text);
         return input!=null
-                ? Bookmark.parse(input)
-                        .orElseThrow(()->_Exceptions.illegalArgument("%s", input))
+                ? Bookmark.parseElseFail(input)
                         .toOidDto()
                 : null;
     }
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/memento/_ObjectMemento.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/memento/_ObjectMemento.java
index 2ff5a18..f5e0dbb 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/memento/_ObjectMemento.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/memento/_ObjectMemento.java
@@ -227,10 +227,8 @@ final class _ObjectMemento implements HasLogicalType, Serializable {
                             "need an id to lookup an object, got logical-type %s", memento.logicalType);
                 }
 
-                final Bookmark bookmark = Bookmark.parse(memento.persistentOidStr)
-                        .orElseThrow(()->_Exceptions.illegalArgument(
-                                "cannot parse a bookmark from '%s'",
-                                memento.persistentOidStr));
+                final Bookmark bookmark = Bookmark.parseElseFail(memento.persistentOidStr);
+
                 try {
 
                     log.debug("lookup by oid [{}]", bookmark);
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/typeconverters/applib/IsisBookmarkConverter.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/typeconverters/applib/IsisBookmarkConverter.java
index b9ac392..bb3131b 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/typeconverters/applib/IsisBookmarkConverter.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/typeconverters/applib/IsisBookmarkConverter.java
@@ -40,7 +40,7 @@ public class IsisBookmarkConverter implements TypeConverter<Bookmark, String>{
     public Bookmark toMemberType(final String datastoreValue) {
         return datastoreValue != null
                 ? Bookmark.parse(datastoreValue).orElse(null)
-                        : null;
+                : null;
     }
 
 }
diff --git a/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTest.java b/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTest.java
index 0a0b96e..c4ad889 100644
--- a/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTest.java
+++ b/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTest.java
@@ -31,9 +31,11 @@ import org.junit.jupiter.params.provider.MethodSource;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.TestPropertySource;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.iactnlayer.InteractionContext;
 import org.apache.isis.applib.services.iactnlayer.InteractionService;
 import org.apache.isis.applib.services.inject.ServiceInjector;
@@ -112,18 +114,25 @@ class ValueSemanticsTest {
                 (context, renderer)->{
 
                 },
-                command->{
+                (command, codec)->{
 
                     val propertyDto = (PropertyDto)command.getCommandDto().getMember();
                     val newValueRecordedDto = propertyDto.getNewValue();
 
+                    //TODO needs a codec to recover values that are not directly represented by the schema
                     val newValueRecorded = CommonDtoUtils.getValue(newValueRecordedDto);
 
                     // TODO skip tests, because some value-types are not represented by the schema yet
-                    if(newValueRecorded==null) {
+                    if(newValueRecorded==null
+                            || valueType.equals(Bookmark.class)) {
+                        System.err.printf("skipping command test on %s%n", valueType.getName());
                         return;
                     }
 
+                    assertEquals(valueType, newValueRecorded.getClass(), ()->
+                        String.format("command value parsing type mismatch '%s'",
+                                ValueSemanticsTester.valueDtoToXml(newValueRecordedDto)));
+
                     tester.assertValueEquals(example.getUpdateValue(), newValueRecorded, "command failed");
 
 //                    //debug
diff --git a/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTester.java b/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTester.java
index 088b467..f4b9770 100644
--- a/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTester.java
+++ b/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTester.java
@@ -39,7 +39,6 @@ import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.base._Refs;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.commons.internal.functions._Functions.CheckedBiConsumer;
-import org.apache.isis.commons.internal.functions._Functions.CheckedConsumer;
 import org.apache.isis.commons.internal.resources._Xml;
 import org.apache.isis.commons.internal.resources._Xml.WriteOptions;
 import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
@@ -82,7 +81,7 @@ public class ValueSemanticsTester<T> {
             final @NonNull CheckedBiConsumer<ValueSemanticsProvider.Context, EncoderDecoder<T>> codecCallback,
             final @NonNull CheckedBiConsumer<ValueSemanticsProvider.Context, Parser<T>> parserCallback,
             final @NonNull CheckedBiConsumer<ValueSemanticsProvider.Context, Renderer<T>> renderCallback,
-            final @NonNull CheckedConsumer<Command> commandCallback) {
+            final @NonNull CheckedBiConsumer<Command, EncoderDecoder<T>> commandCallback) {
 
         val objSpec = specLoader.specForTypeElseFail(domainObject.getClass());
         val prop = objSpec.getPropertyElseFail(propertyId);
@@ -90,7 +89,9 @@ public class ValueSemanticsTester<T> {
         val context = valueFacet(prop)
                 .createValueSemanticsContext(prop);
 
-        codecCallback.accept(context, codec(prop));
+        val codec = codec(prop);
+
+        codecCallback.accept(context, codec);
 
         val parserIfAny = parser(prop);
         if(parserIfAny.isPresent()) {
@@ -112,7 +113,7 @@ public class ValueSemanticsTester<T> {
             propInteraction.modifyProperty(managedProp->
                 ManagedObject.of(managedProp.getElementType(), newProperyValueProvider.apply(managedProp)));
 
-            commandCallback.accept(command);
+            commandCallback.accept(command, codec);
         });
     }
 
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/conf/Configuration_headless.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/conf/Configuration_headless.java
index 38fc733..34a1989 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/conf/Configuration_headless.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/conf/Configuration_headless.java
@@ -35,7 +35,6 @@ import org.springframework.transaction.TransactionStatus;
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.services.iactn.Interaction;
 import org.apache.isis.applib.services.metrics.MetricsService;
-import org.apache.isis.commons.internal.debug._Probe;
 import org.apache.isis.core.config.presets.IsisPresets;
 import org.apache.isis.core.interaction.scope.TransactionBoundaryAware;
 import org.apache.isis.core.runtimeservices.IsisModuleCoreRuntimeServices;
@@ -66,13 +65,13 @@ public class Configuration_headless {
 
         @Override
         public void beforeEnteringTransactionalBoundary(final Interaction interaction) {
-            _Probe.errOut("Interaction HAS_STARTED conversationId=%s", interaction.getInteractionId());
+//            _Probe.errOut("Interaction HAS_STARTED conversationId=%s", interaction.getInteractionId());
             setupCommandCreateIfMissing();
         }
 
         @Override
         public void afterLeavingTransactionalBoundary(final Interaction interaction) {
-            _Probe.errOut("Interaction IS_ENDING conversationId=%s", interaction.getInteractionId());
+//            _Probe.errOut("Interaction IS_ENDING conversationId=%s", interaction.getInteractionId());
         }
 
         public void setupCommandCreateIfMissing() {
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/valuetypes/ValueTypeExample.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/valuetypes/ValueTypeExample.java
index 051ba8d..25db966 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/valuetypes/ValueTypeExample.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/valuetypes/ValueTypeExample.java
@@ -30,7 +30,9 @@ import java.time.OffsetDateTime;
 import java.time.OffsetTime;
 import java.time.ZonedDateTime;
 import java.util.List;
+import java.util.Optional;
 import java.util.UUID;
+import java.util.stream.Stream;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.Collection;
@@ -38,12 +40,20 @@ import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.applib.graph.tree.TreeAdapter;
+import org.apache.isis.applib.graph.tree.TreeNode;
+import org.apache.isis.applib.graph.tree.TreeState;
+import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.value.Blob;
 import org.apache.isis.applib.value.Clob;
 import org.apache.isis.applib.value.LocalResourcePath;
 import org.apache.isis.applib.value.Markup;
 import org.apache.isis.applib.value.NamedWithMimeType.CommonMimeType;
 import org.apache.isis.applib.value.Password;
+import org.apache.isis.schema.chg.v2.ChangesDto;
+import org.apache.isis.schema.cmd.v2.CommandDto;
+import org.apache.isis.schema.common.v2.OidDto;
+import org.apache.isis.schema.ixn.v2.InteractionDto;
 
 import lombok.Getter;
 import lombok.Setter;
@@ -451,16 +461,89 @@ public abstract class ValueTypeExample<T> {
         private org.joda.time.LocalTime updateValue = org.joda.time.LocalTime.now().plusSeconds(15);
     }
 
+    // -- EXAMPLES - DATA STRUCTURE
+
+    //TODO    TreeNode
+//    @DomainObject(
+//            logicalTypeName = "isis.testdomain.valuetypes.ValueTypeExampleTreeNode",
+//            nature = Nature.BEAN)
+    public static class ValueTypeExampleTreeNode
+    extends ValueTypeExample<TreeNode<String>> {
+        @Property @Getter @Setter
+        private TreeNode<String> value = TreeNode.of("root", TreeAdapterString.class, TreeState.rootCollapsed());
+        @Getter
+        private TreeNode<String> updateValue = TreeNode.of("anotherRoot", TreeAdapterString.class, TreeState.rootCollapsed());
+
+        private static class TreeAdapterString implements TreeAdapter<String> {
+            @Override public Optional<String> parentOf(final String value) {
+                return null; }
+            @Override public int childCountOf(final String value) {
+                return 0; }
+            @Override public Stream<String> childrenOf(final String value) {
+                return Stream.empty(); }
+        }
+
+    }
+
     // -- EXAMPLES - OTHER
 
-    //TODO    Bookmark
-    //TODO    OidDto
+  //TODO    Bookmark - fails because semantics needs to be adapted from OidDto
+    @DomainObject(
+            logicalTypeName = "isis.testdomain.valuetypes.ValueTypeExampleBookmark",
+            nature = Nature.BEAN)
+    public static class ValueTypeExampleBookmark
+    extends ValueTypeExample<Bookmark> {
+        @Property @Getter @Setter
+        private Bookmark value = Bookmark.parseElseFail("a:b");
+        @Getter
+        private Bookmark updateValue = Bookmark.parseElseFail("c:d");
+    }
+
+    @DomainObject(
+            logicalTypeName = "isis.testdomain.valuetypes.ValueTypeExampleOidDto",
+            nature = Nature.BEAN)
+    public static class ValueTypeExampleOidDto
+    extends ValueTypeExample<OidDto> {
+        @Property @Getter @Setter
+        private OidDto value = Bookmark.parseElseFail("a:b").toOidDto();
+        @Getter
+        private OidDto updateValue = Bookmark.parseElseFail("c:d").toOidDto();
+    }
 
     //TODO    ChangesDto
-    //TODO    CommandDto
-    //TODO    InteractionDto
+//    @DomainObject(
+//            logicalTypeName = "isis.testdomain.valuetypes.ValueTypeExampleChangesDto",
+//            nature = Nature.BEAN)
+    public static class ValueTypeExampleChangesDto
+    extends ValueTypeExample<ChangesDto> {
+        @Property @Getter @Setter
+        private ChangesDto value = new ChangesDto();
+        @Getter
+        private ChangesDto updateValue = new ChangesDto();
+    }
 
-    //TODO    TreeNode
+    //TODO    CommandDto
+//    @DomainObject(
+//            logicalTypeName = "isis.testdomain.valuetypes.ValueTypeExampleCommandDto",
+//            nature = Nature.BEAN)
+    public static class ValueTypeExampleCommandDto
+    extends ValueTypeExample<CommandDto> {
+        @Property @Getter @Setter
+        private CommandDto value = new CommandDto();
+        @Getter
+        private CommandDto updateValue = new CommandDto();
+    }
 
+    //TODO    InteractionDto
+//    @DomainObject(
+//            logicalTypeName = "isis.testdomain.valuetypes.ValueTypeExampleInteractionDto",
+//            nature = Nature.BEAN)
+    public static class ValueTypeExampleInteractionDto
+    extends ValueTypeExample<InteractionDto> {
+        @Property @Getter @Setter
+        private InteractionDto value = new InteractionDto();
+        @Getter
+        private InteractionDto updateValue = new InteractionDto();
+    }
 
 }
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
index f31664a..98f9868 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
@@ -72,8 +72,7 @@ implements
     public static EntityModel ofPageParameters(
             final IsisAppCommonContext commonContext,
             final PageParameters pageParameters) {
-        val bookmark = Bookmark.parse(oidStr(pageParameters))
-                .orElseThrow();
+        val bookmark = Bookmark.parseElseFail(oidStr(pageParameters));
         return ofBookmark(commonContext, bookmark);
     }