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/causeway.git
The following commit(s) were added to refs/heads/master by this push:
new d0da9ee945 CAUSEWAY-3586: adds nullable memento support for the
ViewModel programming model
d0da9ee945 is described below
commit d0da9ee945b61947ae1c0af4a523963fee7fd17a
Author: Andi Huber <[email protected]>
AuthorDate: Thu Sep 28 12:22:57 2023 +0200
CAUSEWAY-3586: adds nullable memento support for the ViewModel
programming model
---
.../ViewModelFacetForViewModelInterface.java | 44 +++++++++++++++++++++-
1 file changed, 42 insertions(+), 2 deletions(-)
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/viewmodel/ViewModelFacetForViewModelInterface.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/viewmodel/ViewModelFacetForViewModelInterface.java
index e2dd9ce65f..264a5f3a50 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/viewmodel/ViewModelFacetForViewModelInterface.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/viewmodel/ViewModelFacetForViewModelInterface.java
@@ -19,6 +19,8 @@
package org.apache.causeway.core.metamodel.facets.object.viewmodel;
import java.lang.reflect.Constructor;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -39,9 +41,12 @@ import
org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
import
org.apache.causeway.core.metamodel.specloader.validator.ValidationFailure;
+import lombok.Getter;
import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.val;
+import lombok.experimental.Accessors;
/**
* Corresponds to {@link ViewModel} interface.
@@ -135,11 +140,46 @@ extends ViewModelFacetAbstract {
@Override
public String serialize(final ManagedObject viewModel) {
final ViewModel viewModelPojo = (ViewModel) viewModel.getPojo();
- return UrlUtils.urlEncodeUtf8(viewModelPojo.viewModelMemento());
+ return SpecialMemento.encode(viewModelPojo.viewModelMemento());
}
// -- HELPER
+ /**
+ * In support of (stateless) {@link ViewModel}s that don't use a memento,
+ * or if an empty memento String is actually considered a valid use-case.
+ * (e.g. a Viewmodel that simply holds a String value for a search say)
+ * @apiNote introduced so we can create valid bookmarks,
+ * that must have a non-empty identifier part
+ * @implNote the pipe character '|' is regarded unsafe,
+ * hence gets processed by {@link URLEncoder} and {@link URLDecoder},
+ * which makes it safe for us to use with special meaning
+ */
+ @Getter @Accessors(fluent=true)
+ @RequiredArgsConstructor
+ enum SpecialMemento {
+ EMPTY("||"),
+ NULL("|");
+ static String encode(final @Nullable String memento) {
+ return memento==null
+ ? NULL.representationInUrl()
+ : memento.isEmpty()
+ ? EMPTY.representationInUrl()
+ : UrlUtils.urlEncodeUtf8(memento);
+ }
+ static String decode(final @Nullable String memento) {
+ return NULL.matches(memento)
+ ? null
+ : EMPTY.matches(memento)
+ ? ""
+ : UrlUtils.urlDecodeUtf8(memento);
+ }
+ final String representationInUrl;
+ boolean matches(final String other) {
+ return representationInUrl.equals(other);
+ }
+ }
+
@SneakyThrows
private Object deserialize(
@NonNull final ObjectSpecification viewmodelSpec,
@@ -148,7 +188,7 @@ extends ViewModelFacetAbstract {
_Assert.assertNotNull(constructorAnyArgs, ()->"framework bug: required
non-null, "
+ "this can only happen, if we try to deserialize an abstract
type");
- val memento = UrlUtils.urlDecodeUtf8(mementoEncoded);
+ val memento = SpecialMemento.decode(mementoEncoded);
val resolvedArgs = resolveArgsForConstructor(constructorAnyArgs,
getServiceRegistry(), memento);
val viewmodelPojo =
constructorAnyArgs.constructor().newInstance(resolvedArgs);
return viewmodelPojo;