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 2022/09/02 08:04:48 UTC
[isis] 01/01: ISIS-3200: ManagedObjects of type VALUE should provide bookmarks themselves
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch 3200_broken-value-choices
in repository https://gitbox.apache.org/repos/asf/isis.git
commit 4174060ff1a11d87e14677bdc7fbf93894934ef0
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Sep 2 10:04:38 2022 +0200
ISIS-3200: ManagedObjects of type VALUE should provide bookmarks
themselves
- also introduce URL_SAFE semantics in the context of value serializers
---
.../isis/applib/services/bookmark/Bookmark.java | 14 +-
.../images/managed-object-diagram.drawio.svg | 2 +-
.../facets/object/entity/EntityFacet.java | 36 ++++++
.../facets/object/value/ValueFacetAbstract.java | 10 +-
.../facets/object/value/ValueSerializer.java | 9 +-
.../object/value/ValueSerializerDefault.java | 32 +++--
.../object/viewmodel/ViewModelFacetAbstract.java | 4 +-
.../isis/core/metamodel/object/ManagedObject.java | 14 +-
.../isis/core/metamodel/object/ManagedObjects.java | 11 +-
.../metamodel/object/_ManagedObjectService.java | 4 +-
.../core/metamodel/object/_ManagedObjectValue.java | 9 +-
.../metamodel/objectmanager/ObjectManager.java | 18 +--
.../objectmanager/identify/ObjectBookmarker.java | 1 +
.../identify/ObjectBookmarker_builtinHandlers.java | 70 +++++-----
.../metamodel/spec/HasObjectSpecification.java | 60 +++++++++
.../core/metamodel/util/snapshot/XmlSnapshot.java | 26 ++--
.../value/JavaTimeValueSemanticsProviderTest.java | 11 +-
.../ValueSemanticsProviderAbstractTestCase.java | 41 +++---
.../isis/core/runtime/IsisModuleCoreRuntime.java | 4 +-
...ervice.java => IdStringifierLookupService.java} | 42 ++----
.../command/CommandDtoFactoryDefault.java | 3 +-
.../interaction/InteractionDtoFactoryDefault.java | 13 +-
.../memento/ObjectMementoServiceDefault.java | 6 +-
.../runtimeservices/memento/_ObjectMemento.java | 144 +++++++++------------
.../entities/DnEntityStateProvider.java | 10 +-
.../metamodel/facets/entity/JdoEntityFacet.java | 41 ++++--
.../jpa/integration/entity/JpaEntityFacet.java | 32 +++--
.../integration/entity/JpaEntityFacetFactory.java | 2 +-
.../JsonValueEncoderServiceDefault.java | 4 +-
.../wicket/model/util/PageParameterUtils.java | 16 ---
30 files changed, 377 insertions(+), 312 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 c23d21eb6c..5d7036628a 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
@@ -75,19 +75,19 @@ public final class Bookmark implements Oid {
public static Bookmark forLogicalTypeNameAndIdentifier(
final @NonNull String logicalTypeName,
- final @NonNull String identifier) {
+ final @NonNull String urlSafeIdentifier) {
return new Bookmark(
logicalTypeName,
- identifier,
+ urlSafeIdentifier,
/*hintId*/null);
}
public static Bookmark forLogicalTypeAndIdentifier(
final @NonNull LogicalType logicalType,
- final @NonNull String identifier) {
+ final @NonNull String urlSafeIdentifier) {
return Bookmark.forLogicalTypeNameAndIdentifier(
logicalType.getLogicalTypeName(),
- identifier);
+ urlSafeIdentifier);
}
public static Bookmark forOidDto(final @NonNull OidDto oidDto) {
@@ -104,12 +104,12 @@ public final class Bookmark implements Oid {
private Bookmark(
final String logicalTypeName,
- final String identifier,
+ final String urlSafeIdentifier,
final String hintId) {
this.logicalTypeName = logicalTypeName;
- this.identifier = identifier;
+ this.identifier = urlSafeIdentifier;
this.hintId = hintId;
- this.hashCode = Objects.hash(logicalTypeName, identifier);
+ this.hashCode = Objects.hash(logicalTypeName, urlSafeIdentifier);
}
// -- PARSE
diff --git a/core/metamodel/src/main/adoc/modules/metamodel/images/managed-object-diagram.drawio.svg b/core/metamodel/src/main/adoc/modules/metamodel/images/managed-object-diagram.drawio.svg
index bd01036df0..55aa26123a 100644
--- a/core/metamodel/src/main/adoc/modules/metamodel/images/managed-object-diagram.drawio.svg
+++ b/core/metamodel/src/main/adoc/modules/metamodel/images/managed-object-diagram.drawio.svg
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than diagrams.net -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1391px" height="591px" viewBox="-0.5 -0.5 1391 591" content="<mxfile host="Electron" modified="2022-09-01T14:29:56.898Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/20.2.3 Chrome/102.0.5005.167 Electron/19.0.11 Safari/537.36" etag="cwu7jfOeW0fUMNdx5SSP" version="20.2.3" type="device&qu [...]
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1391px" height="591px" viewBox="-0.5 -0.5 1391 591" content="<mxfile host="Electron" modified="2022-09-02T03:02:42.988Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/20.2.3 Chrome/102.0.5005.167 Electron/19.0.11 Safari/537.36" etag="lW1AIfm3Z-gm0gO0WKht" version="20.2.3" type="device&qu [...]
\ No newline at end of file
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/EntityFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/EntityFacet.java
index f3537fb078..9daafec0df 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/EntityFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/EntityFacet.java
@@ -20,13 +20,17 @@ package org.apache.isis.core.metamodel.facets.object.entity;
import java.lang.reflect.Method;
import java.util.Optional;
+import java.util.function.Function;
import org.springframework.lang.Nullable;
+import org.springframework.util.ClassUtils;
import org.apache.isis.applib.query.Query;
import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.bookmark.IdStringifier;
import org.apache.isis.applib.services.repository.EntityState;
import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.config.beans.PersistenceStack;
import org.apache.isis.core.metamodel.facetapi.Facet;
@@ -35,12 +39,44 @@ import org.apache.isis.core.metamodel.object.ManagedObject;
import org.apache.isis.core.metamodel.object.MmSpecUtil;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import lombok.NonNull;
+
/**
* Indicates that this class is managed by a persistence context.
* @since 2.0
*/
public interface EntityFacet extends Facet {
+ @lombok.Value(staticConstructor = "of")
+ static class PrimaryKeyType<T> {
+ private final @NonNull Class<?> owningEntityClass;
+ private final @NonNull IdStringifier<T> idStringifier;
+ private final @NonNull Class<T> primaryKeyClass;
+ public String enstring(final T primaryKey) {
+ return idStringifier.enstring(primaryKey);
+ }
+ public String enstringWithCast(final Object primaryKey) {
+ return _Casts.castTo(primaryKeyClass, primaryKey)
+ .map(idStringifier::enstring)
+ .orElseThrow(()->_Exceptions.illegalArgument(
+ "failed to cast primary-key '%s' to expected type %s",
+ ""+primaryKey,
+ primaryKeyClass.getName()));
+ }
+ public T destring(final String stringifiedPrimaryKey) {
+ return idStringifier.destring(owningEntityClass, stringifiedPrimaryKey);
+ }
+ public static <T> PrimaryKeyType<T> getInstance(
+ final @NonNull Class<?> owningEntityClass,
+ final @NonNull Function<Class<T>, IdStringifier<T>> stringifierLookup,
+ final @NonNull Class<T> primaryKeyClass){
+ return of(
+ owningEntityClass,
+ stringifierLookup.apply(primaryKeyClass),
+ _Casts.uncheckedCast(ClassUtils.resolvePrimitiveIfNecessary(primaryKeyClass)));
+ }
+ }
+
/**
* The {@link ObjectSpecification} of the entity type this
* facet is associated with.
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueFacetAbstract.java
index 3c402b246a..9ba54f5acb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueFacetAbstract.java
@@ -132,16 +132,16 @@ implements ValueFacet<T> {
iaProvider.currentInteractionContext().orElse(null));
}
- // -- TO STRING SERIALIZATION
+ // -- TO/FROM STRING SERIALIZATION
@Override
- public T fromEncodedString(final Format format, final String encodedData) {
- return valueSerializer.fromEncodedString(format, encodedData);
+ public final T destring(final Format format, final String encodedData) {
+ return valueSerializer.destring(format, encodedData);
}
@Override
- public String toEncodedString(final Format format, final T value) {
- return valueSerializer.toEncodedString(format, value);
+ public final String enstring(final Format format, final T value) {
+ return valueSerializer.enstring(format, value);
}
// -- ORDER RELATION
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueSerializer.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueSerializer.java
index a3ee0d05fc..772e8d3429 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueSerializer.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueSerializer.java
@@ -18,21 +18,26 @@
*/
package org.apache.isis.core.metamodel.facets.object.value;
+import org.springframework.lang.Nullable;
+
+import lombok.NonNull;
+
public interface ValueSerializer<T> {
public enum Format {
JSON,
+ URL_SAFE,
//XML
}
/**
* Converts a string of provided {@link Format} to an instance of the object.
*/
- T fromEncodedString(Format format, String encodedData);
+ T destring(@NonNull Format format, @NonNull String encodedData);
/**
* Converts the provided object into provided {@link Format}.
*/
- String toEncodedString(Format format, T value);
+ String enstring(@NonNull Format format, @Nullable T value);
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueSerializerDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueSerializerDefault.java
index 8d07fd0212..94f3c644db 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueSerializerDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueSerializerDefault.java
@@ -18,10 +18,13 @@
*/
package org.apache.isis.core.metamodel.facets.object.value;
+import org.springframework.lang.Nullable;
+
import org.apache.isis.applib.value.semantics.ValueDecomposition;
import org.apache.isis.applib.value.semantics.ValueSemanticsProvider;
-import org.apache.isis.commons.internal.assertions._Assert;
import org.apache.isis.commons.internal.base._Casts;
+import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@@ -35,21 +38,34 @@ implements ValueSerializer<T> {
private final @NonNull ValueSemanticsProvider<T> semantics;
@Override
- public T fromEncodedString(final Format format, final String encodedData) {
- _Assert.assertNotNull(encodedData);
+ public T destring(final @NonNull Format format, final @NonNull String encodedData) {
if (ENCODED_NULL.equals(encodedData)) {
return null;
- } else {
+ }
+ switch(format) {
+ case JSON:
return semantics.compose(
ValueDecomposition.fromJson(semantics.getSchemaValueType(), encodedData));
+ case URL_SAFE:
+ //TODO could use IdStringifiers instead
+ return destring(Format.JSON, _Strings.base64UrlDecode(encodedData));
}
+ throw _Exceptions.unmatchedCase(format);
}
@Override
- public String toEncodedString(final Format format, final T value) {
- return value == null
- ? ENCODED_NULL
- : semantics.decompose(_Casts.uncheckedCast(value)).toJson();
+ public String enstring(final @NonNull Format format, final @Nullable T value) {
+ if(value == null) {
+ return ENCODED_NULL;
+ }
+ switch(format) {
+ case JSON:
+ return semantics.decompose(_Casts.uncheckedCast(value)).toJson();
+ case URL_SAFE:
+ //TODO could use IdStringifiers instead
+ return _Strings.base64UrlEncode(enstring(Format.JSON, value));
+ }
+ throw _Exceptions.unmatchedCase(format);
}
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacetAbstract.java
index 8c3c1d8328..32c153b06e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacetAbstract.java
@@ -101,9 +101,7 @@ implements ViewModelFacet {
@Override
public final Bookmark serializeToBookmark(final @NonNull ManagedObject managedObject) {
- return Bookmark.forLogicalTypeAndIdentifier(
- managedObject.getSpecification().getLogicalType(),
- serialize(managedObject));
+ return managedObject.createBookmark(serialize(managedObject));
}
protected abstract @NonNull String serialize(@NonNull ManagedObject managedObject);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java
index 8997ef491a..ef2646d3af 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java
@@ -30,6 +30,7 @@ import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.metamodel.context.HasMetaModelContext;
import org.apache.isis.core.metamodel.facets.object.icon.ObjectIcon;
import org.apache.isis.core.metamodel.object.ManagedObject.Specialization.BookmarkPolicy;
+import org.apache.isis.core.metamodel.spec.HasObjectSpecification;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
@@ -50,7 +51,8 @@ import lombok.extern.log4j.Log4j2;
public interface ManagedObject
extends
Bookmarkable,
- HasMetaModelContext {
+ HasMetaModelContext,
+ HasObjectSpecification {
/**
* ManagedObject specializations have varying contract/behavior.
@@ -316,6 +318,7 @@ extends
/**
* Returns the specification that details the structure (meta-model) of this object.
*/
+ @Override
ObjectSpecification getSpecification();
/**
@@ -351,15 +354,6 @@ extends
*/
String getTitle();
- // -- SHORTCUT - ELEMENT SPECIFICATION
-
- /**
- * As used for the element type of collections.
- */
- default Optional<ObjectSpecification> getElementSpecification() {
- return getSpecification().getElementSpecification();
- }
-
// -- SHORTCUT - ICON
/**
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java
index ee6f7b2be3..f642afe7db 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java
@@ -22,6 +22,7 @@ import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.Objects;
import java.util.Optional;
+import java.util.UUID;
import java.util.function.Supplier;
import org.springframework.lang.Nullable;
@@ -161,6 +162,14 @@ public final class ManagedObjects {
.orElseThrow(()->_Exceptions.illegalArgument("cannot identify %s", managedObject));
}
+ /**
+ * eg. transient entities have no bookmark, so can fallback to UUID
+ */
+ public static Bookmark bookmarkElseUUID(final @Nullable ManagedObject managedObject) {
+ return bookmark(managedObject)
+ .orElseGet(()->managedObject.createBookmark(UUID.randomUUID().toString()));
+ }
+
/**
* @param managedObject
* @return optionally a String representing a reference to the <em>identifiable</em>
@@ -368,7 +377,7 @@ public final class ManagedObjects {
.collect(Can.toCan());
}
-
+
// -- IMPERATIVE TEXT UTILITY
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectService.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectService.java
index fd1f168a9f..57e409f01c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectService.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectService.java
@@ -80,9 +80,7 @@ extends _ManagedObjectSpecified {
// -- HELPER
private Bookmark createBookmark() {
- return Bookmark.forLogicalTypeAndIdentifier(
- getSpecification().getLogicalType(),
- "1");
+ return createBookmark("1");
}
}
\ No newline at end of file
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectValue.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectValue.java
index f6795095af..4bcabc9681 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectValue.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectValue.java
@@ -77,15 +77,12 @@ extends _ManagedObjectSpecified {
// -- HELPER
private ValueFacet<?> valueFacet() {
- return getSpecification().valueFacet().orElseThrow();
+ return getSpecification().valueFacetElseFail();
}
private Bookmark createBookmark() {
- //TODO if value semantics providers are enforced to provide an IdStringifier,
- // we could use that instead (to generate the second argument)!
- return Bookmark.forLogicalTypeAndIdentifier(
- getSpecification().getLogicalType(),
- valueFacet().toEncodedString(Format.JSON, _Casts.uncheckedCast(getPojo())));
+ return createBookmark(
+ valueFacet().enstring(Format.URL_SAFE, _Casts.uncheckedCast(getPojo())));
}
}
\ No newline at end of file
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/ObjectManager.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/ObjectManager.java
index 165b141cfa..bf1229edf1 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/ObjectManager.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/ObjectManager.java
@@ -142,7 +142,7 @@ public interface ObjectManager {
return ManagedObject.unspecified();
}
return spec.isScalar()
- ? managedObjectEagerlyBookmarkedIfRequired(spec, pojo)
+ ? ManagedObject.adaptScalar(spec, pojo)
: ManagedObject.packed(
spec.getElementSpecification().orElseGet(fallbackElementType),
_NullSafe.streamAutodetect(pojo)
@@ -173,25 +173,11 @@ public interface ObjectManager {
|| pojo.getClass().equals(proposedSpec.getCorrespondingClass()))
// if actual type matches spec's, we assume, that we don't need to reload,
// so this is a shortcut for performance reasons
- ? managedObjectEagerlyBookmarkedIfRequired(
- proposedSpec, pojo)
+ ? ManagedObject.adaptScalar(proposedSpec, pojo)
// fallback, ignoring proposedSpec
: adapt(pojo);
return adapter;
}
- // -- HELPER
-
- /**
- * {@link ManagedObject} factory, that in case of given pojo representing an entity
- * and the entityAdaptingMode equals {@link EntityAdaptingMode#isBookmarkable()},
- * then tries to memoize its {@link Bookmark} eagerly
- * (otherwise its {@link Bookmark} is lazily resolved).
- */
- private static ManagedObject managedObjectEagerlyBookmarkedIfRequired(
- final ObjectSpecification spec,
- final Object pojo) {
- return ManagedObject.adaptScalar(spec, pojo);
- }
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker.java
index 1a527d69b0..a3ca1217da 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker.java
@@ -42,6 +42,7 @@ public interface ObjectBookmarker {
"ObjectBookmarker",
_Lists.of(
new ObjectBookmarker_builtinHandlers.GuardAgainstOid(),
+ new ObjectBookmarker_builtinHandlers.BookmarkForNonScalar(),
new ObjectBookmarker_builtinHandlers.BookmarkForServices(),
new ObjectBookmarker_builtinHandlers.BookmarkForValues(),
new ObjectBookmarker_builtinHandlers.BookmarkForViewModels(),
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java
index 9130d1b88d..41a2579403 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java
@@ -18,16 +18,11 @@
*/
package org.apache.isis.core.metamodel.objectmanager.identify;
-import java.nio.charset.StandardCharsets;
import java.util.UUID;
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.applib.services.bookmark.Oid;
-import org.apache.isis.applib.value.semantics.ValueSemanticsProvider;
-import org.apache.isis.commons.internal.base._Bytes;
-import org.apache.isis.commons.internal.base._Strings;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
+import org.apache.isis.commons.internal.assertions._Assert;
import org.apache.isis.core.metamodel.object.ManagedObject;
import org.apache.isis.core.metamodel.object.PackedManagedObject;
import org.apache.isis.core.metamodel.objectmanager.identify.ObjectBookmarker.Handler;
@@ -37,8 +32,6 @@ import lombok.val;
class ObjectBookmarker_builtinHandlers {
- public static final String SERVICE_IDENTIFIER = "1";
-
static class GuardAgainstOid implements Handler {
@Override
@@ -55,6 +48,20 @@ class ObjectBookmarker_builtinHandlers {
}
+ static class BookmarkForNonScalar implements Handler {
+
+ @Override
+ public boolean isHandling(final ManagedObject managedObject) {
+ return managedObject instanceof PackedManagedObject;
+ }
+
+ @Override
+ public Bookmark handle(final ManagedObject managedObject) {
+ return bookmarkWithRandomUUID(managedObject);
+ }
+
+ }
+
static class BookmarkForServices implements Handler {
@Override
@@ -77,7 +84,8 @@ class ObjectBookmarker_builtinHandlers {
@Override
public Bookmark handle(final ManagedObject managedObject) {
- return managedObject.getBookmark().orElseThrow();
+ return managedObject.getBookmark()
+ .orElseGet(()->bookmarkWithRandomUUID(managedObject)); // transient
}
}
@@ -86,33 +94,14 @@ class ObjectBookmarker_builtinHandlers {
@Override
public boolean isHandling(final ManagedObject managedObject) {
- return managedObject.getSpecification().isValue();
+ return managedObject.getSpecialization().isValue();
}
@SneakyThrows
@Override
public Bookmark handle(final ManagedObject managedObject) {
- val spec = managedObject.getSpecification();
- val valuePojo = managedObject.getPojo();
- if(valuePojo==null) {
- return Bookmark.forLogicalTypeAndIdentifier(spec.getLogicalType(), "{}");
- }
-
- val valueFacet = spec.valueFacet().orElse(null);
- ValueSemanticsProvider<Object> composer = (ValueSemanticsProvider) valueFacet.selectDefaultSemantics()
- .orElseThrow(()->_Exceptions.illegalArgument(
- "Cannot create a bookmark for the value type %s, "
- + "as no appropriate ValueSemanticsProvider could be found.",
- managedObject.getSpecification().getCorrespondingClass().getName()));
-
- val valueAsJson = composer.decompose(managedObject.getPojo())
- .toJson();
-
- val identifier = _Strings.ofBytes(
- _Bytes.asUrlBase64.apply(valueAsJson.getBytes()),
- StandardCharsets.UTF_8);
-
- return Bookmark.forLogicalTypeAndIdentifier(spec.getLogicalType(), identifier);
+ _Assert.assertTrue(managedObject.isBookmarkSupported(), ()->"is bookmarkable");
+ return managedObject.getBookmark().orElseThrow();
}
}
@@ -121,9 +110,7 @@ class ObjectBookmarker_builtinHandlers {
@Override
public boolean isHandling(final ManagedObject managedObject) {
- return (managedObject instanceof PackedManagedObject)
- ? false
- : managedObject.getSpecification().containsFacet(ViewModelFacet.class);
+ return managedObject.getSpecialization().isViewmodel();
}
@Override
@@ -134,8 +121,7 @@ class ObjectBookmarker_builtinHandlers {
}
val spec = managedObject.getSpecification();
- val recreatableObjectFacet = spec.getFacet(ViewModelFacet.class);
- return recreatableObjectFacet.serializeToBookmark(managedObject);
+ return spec.viewmodelFacetElseFail().serializeToBookmark(managedObject);
}
}
@@ -149,10 +135,16 @@ class ObjectBookmarker_builtinHandlers {
@Override
public Bookmark handle(final ManagedObject managedObject) {
- val spec = managedObject.getSpecification();
- val identifier = UUID.randomUUID().toString();
- return Bookmark.forLogicalTypeAndIdentifier(spec.getLogicalType(), identifier);
+ return bookmarkWithRandomUUID(managedObject);
}
}
+ // -- HELPER
+
+ private static Bookmark bookmarkWithRandomUUID(final ManagedObject managedObject) {
+ val uuid = UUID.randomUUID().toString();
+ System.err.printf("called bookmarkWithRandomUUID %s [%s]%n", managedObject.getSpecification(), uuid);
+ return managedObject.createBookmark(UUID.randomUUID().toString());
+ }
+
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/HasObjectSpecification.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/HasObjectSpecification.java
new file mode 100644
index 0000000000..c1c33fab84
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/HasObjectSpecification.java
@@ -0,0 +1,60 @@
+/*
+ * 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.isis.core.metamodel.spec;
+
+import java.util.Optional;
+
+import org.apache.isis.applib.id.LogicalType;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+
+import lombok.NonNull;
+
+/**
+ * Introduced as a shortcut provider.
+ */
+public interface HasObjectSpecification {
+
+ ObjectSpecification getSpecification();
+
+ // -- SHORTCUTS
+
+ default Class<?> getCorrespondingClass() {
+ return getSpecification().getCorrespondingClass();
+ }
+
+ default LogicalType getLogicalType() {
+ return getSpecification().getLogicalType();
+ }
+
+ default String getLogicalTypeName() {
+ return getSpecification().getLogicalTypeName();
+ }
+
+ /**
+ * As used for the element type of collections.
+ */
+ default Optional<ObjectSpecification> getElementSpecification() {
+ return getSpecification().getElementSpecification();
+ }
+
+ default Bookmark createBookmark(final @NonNull String urlSafeIdentifier) {
+ return Bookmark.forLogicalTypeAndIdentifier(getLogicalType(), urlSafeIdentifier);
+ }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java
index 93a2ff4cb9..15f5876e44 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java
@@ -41,6 +41,7 @@ import org.apache.isis.applib.ViewModel;
import org.apache.isis.applib.exceptions.UnrecoverableException;
import org.apache.isis.applib.services.xmlsnapshot.XmlSnapshotService.Snapshot;
import org.apache.isis.applib.snapshot.SnapshottableWithInclusions;
+import org.apache.isis.commons.internal.base._Strings;
import org.apache.isis.commons.internal.codec._DocumentFactories;
import org.apache.isis.commons.internal.collections._Maps;
import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -682,12 +683,12 @@ public class XmlSnapshot implements Snapshot {
log.debug("objectToElement(NO): {} is value", log("field", fieldName));
}
- final ObjectSpecification fieldNos = field.getElementType();
+ final ObjectSpecification fieldSpec = field.getElementType();
// skip fields of type XmlValue
- if (fieldNos == null) {
+ if (fieldSpec == null) {
continue eachField;
}
- if (fieldNos.getFullIdentifier() != null && fieldNos.getFullIdentifier().endsWith("XmlValue")) {
+ if (fieldSpec.getFullIdentifier() != null && fieldSpec.getFullIdentifier().endsWith("XmlValue")) {
continue eachField;
}
@@ -701,22 +702,17 @@ public class XmlSnapshot implements Snapshot {
try {
value = valueAssociation.get(adapter, InteractionInitiatedBy.FRAMEWORK);
- final ObjectSpecification valueNos = value.getSpecification();
+ val valueSpec = value.getSpecification();
// XML
- isisMetaModel.setAttributesForValue(xmlValueElement, valueNos.getShortIdentifier());
+ isisMetaModel.setAttributesForValue(xmlValueElement, valueSpec.getShortIdentifier());
- // return encoded string, else title.
- String valueStr;
- val valueFacet = fieldNos.valueFacet().orElse(null);
- if (valueFacet != null) {
- valueStr = valueFacet.toEncodedString(Format.JSON, value.getPojo());
- } else {
- valueStr = value.getTitle();
- }
+ // value as JSON
+ @SuppressWarnings("unchecked")
+ val valueStr = fieldSpec.valueFacetElseFail()
+ .enstring(Format.JSON, value.getPojo());
- final boolean notEmpty = (valueStr.length() > 0);
- if (notEmpty) {
+ if (_Strings.isNotEmpty(valueStr)) {
xmlValueElement.appendChild(getXmlDocument().createTextNode(valueStr));
} else {
isisMetaModel.setIsEmptyAttribute(xmlValueElement, true);
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaTimeValueSemanticsProviderTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaTimeValueSemanticsProviderTest.java
index 694c732de7..bff7dfaa3b 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaTimeValueSemanticsProviderTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/JavaTimeValueSemanticsProviderTest.java
@@ -25,6 +25,9 @@ import java.util.Locale;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
import org.apache.isis.applib.annotation.TimePrecision;
import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
import org.apache.isis.applib.locale.UserLocale;
@@ -35,9 +38,6 @@ import org.apache.isis.applib.value.semantics.ValueSemanticsProvider.Context;
import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateTimeValueSemantics;
import org.apache.isis.core.metamodel.valuesemantics.temporal.legacy.JavaUtilDateValueSemantics;
-import static org.junit.Assert.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
import lombok.NonNull;
import lombok.val;
@@ -146,11 +146,6 @@ extends ValueSemanticsProviderAbstractTestCase<java.util.Date> {
return date;
}
- @Override
- public void testValueSerializer_usingJson() {
- // TODO fails with NPE
- }
-
@Override
protected void assertValueEncodesToJsonAs(final Date a, final String json) {
// TODO
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/ValueSemanticsProviderAbstractTestCase.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/ValueSemanticsProviderAbstractTestCase.java
index 04d5323baa..71581794b1 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/ValueSemanticsProviderAbstractTestCase.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/ValueSemanticsProviderAbstractTestCase.java
@@ -29,6 +29,14 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import org.apache.isis.applib.services.iactn.InteractionProvider;
import org.apache.isis.applib.value.semantics.Parser;
@@ -41,16 +49,10 @@ import org.apache.isis.core.metamodel._testing.MetaModelContext_forTesting;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facets.object.value.ValueSerializer;
import org.apache.isis.core.metamodel.facets.object.value.ValueSerializer.Format;
-import org.apache.isis.core.metamodel.object.ManagedObject;
import org.apache.isis.core.metamodel.facets.object.value.ValueSerializerDefault;
+import org.apache.isis.core.metamodel.object.ManagedObject;
import org.apache.isis.core.metamodel.valuesemantics.StringValueSemantics;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
import lombok.Getter;
public abstract class ValueSemanticsProviderAbstractTestCase<T> {
@@ -135,14 +137,17 @@ public abstract class ValueSemanticsProviderAbstractTestCase<T> {
}
- @Test
- public void testValueSerializer_usingJson() {
+ @ParameterizedTest
+ @EnumSource(Format.class)
+ public void testValueSerializer(final Format format) {
+ assumeValueSemanticsProviderIsSetup();
+
final T value = getSample();
- final String encoded = getValueSerializer().toEncodedString(Format.JSON, value);
+ final String encoded = getValueSerializer().enstring(format, value);
assertValueEncodesToJsonAs(value, encoded);
- T decoded = getValueSerializer().fromEncodedString(Format.JSON, encoded);
+ T decoded = getValueSerializer().destring(format, encoded);
Optional.ofNullable(semantics.getOrderRelation())
.ifPresentOrElse(rel->Assertions.assertTrue(rel.equals(value, decoded)),
@@ -153,21 +158,23 @@ public abstract class ValueSemanticsProviderAbstractTestCase<T> {
protected abstract void assertValueEncodesToJsonAs(T a, String json);
- @Test
- public void testDecodeNULL() throws Exception {
+ @ParameterizedTest
+ @EnumSource(Format.class)
+ public void testDecodeNULL(final Format format) throws Exception {
assumeValueSemanticsProviderIsSetup();
final Object newValue = getValueSerializer()
- .fromEncodedString(Format.JSON, ValueSerializerDefault.ENCODED_NULL);
+ .destring(format, ValueSerializerDefault.ENCODED_NULL);
assertNull(newValue);
}
- @Test
- public void testEmptyEncoding() {
+ @ParameterizedTest
+ @EnumSource(Format.class)
+ public void testEmptyEncoding(final Format format) {
assumeValueSemanticsProviderIsSetup();
assertEquals(ValueSerializerDefault.ENCODED_NULL, getValueSerializer()
- .toEncodedString(Format.JSON, null));
+ .enstring(format, null));
}
@Test
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/IsisModuleCoreRuntime.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/IsisModuleCoreRuntime.java
index dd5a2de831..063ea58bd9 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/IsisModuleCoreRuntime.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/IsisModuleCoreRuntime.java
@@ -25,7 +25,7 @@ import org.apache.isis.core.interaction.IsisModuleCoreInteraction;
import org.apache.isis.core.metamodel.IsisModuleCoreMetamodel;
import org.apache.isis.core.runtime.events.MetamodelEventService;
import org.apache.isis.core.runtime.events.TransactionEventEmitter;
-import org.apache.isis.core.runtime.idstringifier.IdStringifierService;
+import org.apache.isis.core.runtime.idstringifier.IdStringifierLookupService;
import org.apache.isis.core.transaction.IsisModuleCoreTransaction;
import org.apache.isis.valuetypes.jodatime.integration.IsisModuleValJodatimeIntegration;
@@ -42,7 +42,7 @@ import org.apache.isis.valuetypes.jodatime.integration.IsisModuleValJodatimeInte
// @Service's
MetamodelEventService.class,
TransactionEventEmitter.class,
- IdStringifierService.class,
+ IdStringifierLookupService.class,
// @Configuration's
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierService.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierLookupService.java
similarity index 68%
rename from core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierService.java
rename to core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierLookupService.java
index dcece158bf..b5101a87e6 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierService.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierLookupService.java
@@ -35,14 +35,13 @@ import org.springframework.stereotype.Service;
import org.springframework.util.ClassUtils;
import org.apache.isis.applib.annotation.PriorityPrecedence;
-import org.apache.isis.applib.annotation.ValueSemantics;
import org.apache.isis.applib.services.bookmark.IdStringifier;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet.PrimaryKeyType;
import org.apache.isis.core.runtime.IsisModuleCoreRuntime;
-import lombok.NonNull;
import lombok.val;
/**
@@ -51,24 +50,19 @@ import lombok.val;
* <p>
* This is intended for framework use, there is little reason to call it or override it.
*
- * @implNote yet does not support per member ValueSemantics selection;
- * future work would look for {@link ValueSemantics} annotations on primary key members and
- * would then honor {@link ValueSemantics#provider()} attribute,
- * to narrow the {@link IdStringifier} search
- *
* @since 2.0
*/
@Service
-@Named(IsisModuleCoreRuntime.NAMESPACE + ".IdStringifierService")
+@Named(IsisModuleCoreRuntime.NAMESPACE + ".IdStringifierLookupService")
@Priority(PriorityPrecedence.MIDPOINT)
@Qualifier("Default")
-public class IdStringifierService {
+public class IdStringifierLookupService {
private final Can<IdStringifier<?>> idStringifiers;
private final Map<Class<?>, IdStringifier<?>> stringifierByClass = new ConcurrentHashMap<>();
@Inject
- public IdStringifierService(
+ public IdStringifierLookupService(
final List<IdStringifier<?>> idStringifiers,
final Optional<IdStringifier<Serializable>> idStringifierForSerializableIfAny) {
// IdStringifierForSerializable is enforced to go last, so any custom IdStringifier(s)
@@ -82,31 +76,23 @@ public class IdStringifierService {
this.idStringifiers = Can.ofCollection(idStringifiers);
}
- public <T> String enstringPrimaryKey(final @NonNull Class<T> primaryKeyType, final @NonNull Object primaryKey) {
- val idStringifier = lookupElseFail(ClassUtils.resolvePrimitiveIfNecessary(primaryKeyType));
- return idStringifier.enstring(_Casts.uncheckedCast(primaryKey));
- }
-
- public <T> T destringPrimaryKey(
- final @NonNull Class<T> primaryKeyType,
- final @NonNull Class<?> entityClass,
- final @NonNull String stringifiedId) {
- val idStringifier = lookupElseFail(ClassUtils.resolvePrimitiveIfNecessary(primaryKeyType));
- val primaryKey = idStringifier.destring(entityClass, stringifiedId);
- return _Casts.uncheckedCast(primaryKey);
+ public <T> PrimaryKeyType<T> primaryKeyTypeFor(
+ final Class<?> entityClass, final Class<T> primaryKeyType) {
+ return PrimaryKeyType.getInstance(entityClass,
+ this::lookupIdStringifierElseFail,
+ primaryKeyType);
}
- // -- HELPER
-
- private <T> IdStringifier<T> lookupElseFail(final Class<T> candidateValueClass) {
- return lookup(candidateValueClass)
+ public <T> IdStringifier<T> lookupIdStringifierElseFail(final Class<T> candidateValueClass) {
+ return lookupIdStringifier(candidateValueClass)
.orElseThrow(() -> _Exceptions.noSuchElement(
"Could not locate an IdStringifier to handle '%s'",
candidateValueClass));
}
- private <T> Optional<IdStringifier<T>> lookup(final Class<T> candidateValueClass) {
- val idStringifier = stringifierByClass.computeIfAbsent(candidateValueClass, aClass -> {
+ public <T> Optional<IdStringifier<T>> lookupIdStringifier(final Class<T> candidateValueClass) {
+ val idStringifier = stringifierByClass.computeIfAbsent(
+ ClassUtils.resolvePrimitiveIfNecessary(candidateValueClass), aClass -> {
for (val candidateStringifier : idStringifiers) {
if (candidateStringifier.getCorrespondingClass().isAssignableFrom(candidateValueClass)) {
return candidateStringifier;
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandDtoFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandDtoFactoryDefault.java
index 2112294f9c..a11ae430f2 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandDtoFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandDtoFactoryDefault.java
@@ -169,7 +169,8 @@ public class CommandDtoFactoryDefault implements CommandDtoFactory {
dto.setUsername(userService.currentUserNameElseNobody());
dto.setTimestamp(clockService.getClock().nowAsXmlGregorianCalendar());
- final Bookmark bookmark = ManagedObjects.bookmarkElseFail(targetHead.getOwner());
+ // transient entities have no bookmark, so fallback to UUID
+ final Bookmark bookmark = ManagedObjects.bookmarkElseUUID(targetHead.getOwner());
final OidsDto targetOids = CommandDtoUtils.targetsFor(dto);
targetOids.getOid().add(bookmark.toOidDto());
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/interaction/InteractionDtoFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/interaction/InteractionDtoFactoryDefault.java
index a3201a6aac..96816d0ea5 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/interaction/InteractionDtoFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/interaction/InteractionDtoFactoryDefault.java
@@ -28,7 +28,6 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.apache.isis.applib.annotation.PriorityPrecedence;
-import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.applib.services.iactn.Interaction;
import org.apache.isis.applib.services.iactn.InteractionProvider;
import org.apache.isis.applib.services.user.UserService;
@@ -36,7 +35,6 @@ import org.apache.isis.applib.util.schema.CommandDtoUtils;
import org.apache.isis.applib.util.schema.InteractionDtoUtils;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.assertions._Assert;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.metamodel.execution.InteractionInternal;
import org.apache.isis.core.metamodel.interactions.InteractionHead;
import org.apache.isis.core.metamodel.object.ManagedObject;
@@ -86,8 +84,10 @@ public class InteractionDtoFactoryDefault implements InteractionDtoFactory {
final int nextEventSequence = ((InteractionInternal) interaction).getThenIncrementExecutionSequence();
val owner = head.getOwner();
- final Bookmark targetBookmark = owner.getBookmark()
- .orElseThrow(()->_Exceptions.noSuchElement("Object provides no Bookmark: %s", owner));
+
+ // transient entities have no bookmark, so fallback to UUID
+ val targetBookmark = ManagedObjects.bookmarkElseUUID(owner);
+ //.orElseThrow(()->_Exceptions.noSuchElement("Object provides no Bookmark: %s", owner));
final String currentUser = userService.currentUserNameElseNobody();
@@ -132,8 +132,9 @@ public class InteractionDtoFactoryDefault implements InteractionDtoFactory {
final Interaction interaction = interactionProviderProvider.get().currentInteractionElseFail();
final int nextEventSequence = ((InteractionInternal) interaction).getThenIncrementExecutionSequence();
- final Bookmark targetBookmark = targetAdapter.getBookmark()
- .orElseThrow(()->_Exceptions.noSuchElement("Object provides no Bookmark: %s", targetAdapter));
+ // transient entities have no bookmark, so fallback to UUID
+ val targetBookmark = ManagedObjects.bookmarkElseUUID(targetAdapter);
+ //.orElseThrow(()->_Exceptions.noSuchElement("Object provides no Bookmark: %s", owner));
final String currentUser = userService.currentUserNameElseNobody();
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/memento/ObjectMementoServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/memento/ObjectMementoServiceDefault.java
index d398c0e8ed..cc7edb7368 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/memento/ObjectMementoServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/memento/ObjectMementoServiceDefault.java
@@ -82,7 +82,7 @@ public class ObjectMementoServiceDefault implements ObjectMementoService {
if(mementoAdapter==null) {
// sonar-ignore-on (fails to detect this as null guard)
return ManagedObjects.isSpecified(adapter)
- ? new ObjectMementoForEmpty(adapter.getSpecification().getLogicalType())
+ ? new ObjectMementoForEmpty(adapter.getLogicalType())
: null;
// sonar-ignore-on
}
@@ -96,7 +96,7 @@ public class ObjectMementoServiceDefault implements ObjectMementoService {
.collect(Collectors.toCollection(ArrayList::new)); // ArrayList is serializable
return ObjectMementoCollection.of(
listOfMementos,
- packedAdapter.getSpecification().getLogicalType());
+ packedAdapter.getLogicalType());
}
@Override
@@ -106,7 +106,7 @@ public class ObjectMementoServiceDefault implements ObjectMementoService {
}
val mementoAdapter = _ObjectMemento.createOrNull(paramAdapter);
if(mementoAdapter==null) {
- return new ObjectMementoForEmpty(paramAdapter.getSpecification().getLogicalType());
+ return new ObjectMementoForEmpty(paramAdapter.getLogicalType());
}
return ObjectMementoAdapter.of(mementoAdapter);
}
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 4cf1ed7816..80714a4f9b 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
@@ -22,7 +22,6 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;
-import java.util.function.Function;
import org.springframework.lang.Nullable;
@@ -45,9 +44,7 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.core.metamodel.util.Facets;
-import lombok.AccessLevel;
import lombok.Getter;
-import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.val;
import lombok.extern.log4j.Log4j2;
@@ -112,55 +109,56 @@ final class _ObjectMemento implements HasLogicalType, Serializable {
return memento.recreateStrategy.equals(memento, otherMemento);
}
},
- /**
- * represents a list of objects
- */
- VECTOR {
-
- @Override
- public ManagedObject asAdapter(
- final _ObjectMemento memento,
- final MetaModelContext mmc) {
-
- // I believe this code path is no longer reachable
- throw _Exceptions.unexpectedCodeReach();
-
-// final Can<ManagedObject> managedObjects =
-// _NullSafe.stream(memento.list)
-// .map(Functions.toManagedObject(mmc))
-// .collect(Can.toCan());
+// /**
+// * represents a list of objects
+// */
+// VECTOR {
//
-// val commonSpec = ManagedObjects.commonSpecification(managedObjects)
-// .orElseGet(()->mmc.getSpecificationLoader().loadSpecification(Object.class));
+// @Override
+// public ManagedObject asAdapter(
+// final _ObjectMemento memento,
+// final MetaModelContext mmc) {
//
-// return ManagedObject.packed(commonSpec, managedObjects);
- }
-
- @Override
- public Bookmark asPseudoBookmark(final _ObjectMemento memento) {
- return Bookmark.forLogicalTypeNameAndIdentifier(
- memento.getLogicalTypeName(),
- memento.list.toString());
- }
-
- @Override
- public int hashCode(final _ObjectMemento memento) {
- return memento.list.hashCode();
- }
-
- @Override
- public boolean equals(final _ObjectMemento memento, final Object other) {
- if (!(other instanceof _ObjectMemento)) {
- return false;
- }
- final _ObjectMemento otherMemento = (_ObjectMemento) other;
- if(otherMemento.cardinality != VECTOR) {
- return false;
- }
- return memento.list.equals(otherMemento.list);
- }
-
- };
+// // I believe this code path is no longer reachable
+// throw _Exceptions.unexpectedCodeReach();
+//
+//// final Can<ManagedObject> managedObjects =
+//// _NullSafe.stream(memento.list)
+//// .map(Functions.toManagedObject(mmc))
+//// .collect(Can.toCan());
+////
+//// val commonSpec = ManagedObjects.commonSpecification(managedObjects)
+//// .orElseGet(()->mmc.getSpecificationLoader().loadSpecification(Object.class));
+////
+//// return ManagedObject.packed(commonSpec, managedObjects);
+// }
+//
+// @Override
+// public Bookmark asPseudoBookmark(final _ObjectMemento memento) {
+// return Bookmark.forLogicalTypeNameAndIdentifier(
+// memento.getLogicalTypeName(),
+// memento.list.toString());
+// }
+//
+// @Override
+// public int hashCode(final _ObjectMemento memento) {
+// return memento.list.hashCode();
+// }
+//
+// @Override
+// public boolean equals(final _ObjectMemento memento, final Object other) {
+// if (!(other instanceof _ObjectMemento)) {
+// return false;
+// }
+// final _ObjectMemento otherMemento = (_ObjectMemento) other;
+// if(otherMemento.cardinality != VECTOR) {
+// return false;
+// }
+// return memento.list.equals(otherMemento.list);
+// }
+//
+// }
+ ;
void ensure(final Cardinality sort) {
if(this == sort) {
@@ -192,14 +190,17 @@ final class _ObjectMemento implements HasLogicalType, Serializable {
final _ObjectMemento memento,
final MetaModelContext mmc) {
- val valueSerializer = mmc.getSpecificationLoader()
+ val valueSpec = mmc.getSpecificationLoader()
.specForLogicalType(memento.logicalType)
- .flatMap(spec->Facets.valueSerializer(spec, spec.getCorrespondingClass()))
.orElseThrow(()->_Exceptions.unrecoverable(
- "logical type %s is expected to have a ValueFacet", memento.logicalType));
+ "logical type %s is not recognized", memento.logicalType));
- return mmc.getObjectManager().adapt(
- valueSerializer.fromEncodedString(Format.JSON, memento.encodableValue));
+ val valueSerializer = Facets.valueSerializer(valueSpec, valueSpec.getCorrespondingClass())
+ .orElseThrow(()->_Exceptions.unrecoverable(
+ "logical type %s is expected to have a value semantics", memento.logicalType));
+
+ return ManagedObject.value(valueSpec,
+ valueSerializer.destring(Format.URL_SAFE, memento.encodableValue));
}
@Override
@@ -413,9 +414,11 @@ final class _ObjectMemento implements HasLogicalType, Serializable {
final ArrayList<_ObjectMemento> list,
final LogicalType logicalType) {
- this.cardinality = Cardinality.VECTOR;
- this.list = list;
- this.logicalType = logicalType;
+ throw _Exceptions.unexpectedCodeReach();
+
+ //this.cardinality = Cardinality.VECTOR;
+// this.list = list;
+// this.logicalType = logicalType;
}
private _ObjectMemento(final Bookmark bookmark, final SpecificationLoader specificationLoader) {
@@ -482,7 +485,7 @@ final class _ObjectMemento implements HasLogicalType, Serializable {
.orElse(null);
val isEncodable = valueSerializer != null;
if (isEncodable) {
- encodableValue = valueSerializer.toEncodedString(Format.JSON, _Casts.uncheckedCast(adapter.getPojo()));
+ encodableValue = valueSerializer.enstring(Format.URL_SAFE, _Casts.uncheckedCast(adapter.getPojo()));
recreateStrategy = RecreateStrategy.VALUE;
return;
}
@@ -578,29 +581,6 @@ final class _ObjectMemento implements HasLogicalType, Serializable {
return cardinality.equals(this, obj);
}
- // -- FUNCTIONS
-
- @NoArgsConstructor(access = AccessLevel.PRIVATE)
- private static final class Functions {
-
- private static Function<_ObjectMemento, ManagedObject> toManagedObject(
- final MetaModelContext mmc) {
-
- return memento->{
- if(memento == null) {
- return ManagedObject.unspecified();
- }
- val objectAdapter = memento
- .reconstructObject(mmc);
- if(objectAdapter == null) {
- return ManagedObject.unspecified();
- }
- return objectAdapter;
- };
- }
-
- }
-
private void ensureScalar() {
getCardinality().ensure(Cardinality.SCALAR);
}
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/entities/DnEntityStateProvider.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/entities/DnEntityStateProvider.java
index 0e2fa29a70..25a86cc6e3 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/entities/DnEntityStateProvider.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/entities/DnEntityStateProvider.java
@@ -67,7 +67,8 @@ public class DnEntityStateProvider implements JdoFacetContext {
return EntityState.NOT_PERSISTABLE;
}
- if (pojo!=null && pojo instanceof Persistable) {
+ if (pojo!=null
+ && pojo instanceof Persistable) {
val persistable = (Persistable) pojo;
val isDeleted = persistable.dnIsDeleted();
if(isDeleted) {
@@ -75,8 +76,11 @@ public class DnEntityStateProvider implements JdoFacetContext {
}
val isPersistent = persistable.dnIsPersistent();
if(isPersistent) {
- return persistable.dnGetObjectId()!=null
- ? EntityState.PERSISTABLE_ATTACHED
+ val oid = persistable.dnGetObjectId();
+ return oid!=null
+ ? persistable.dnGetStateManager().isNew(persistable)
+ ? EntityState.PERSISTABLE_NEW
+ : EntityState.PERSISTABLE_ATTACHED
: EntityState.PERSISTABLE_NEW;
}
return EntityState.PERSISTABLE_DETACHED;
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
index 6865d76cd1..b86cbe86f1 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
@@ -55,14 +55,17 @@ import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.object.ManagedObject;
import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
import org.apache.isis.core.metamodel.services.objectlifecycle.ObjectLifecyclePublisher;
-import org.apache.isis.core.runtime.idstringifier.IdStringifierService;
+import org.apache.isis.core.runtime.idstringifier.IdStringifierLookupService;
import org.apache.isis.persistence.jdo.datanucleus.entities.DnEntityStateProvider;
import org.apache.isis.persistence.jdo.metamodel.facets.object.persistencecapable.JdoPersistenceCapableFacetFactory;
import org.apache.isis.persistence.jdo.provider.entities.JdoFacetContext;
import org.apache.isis.persistence.jdo.spring.integration.TransactionAwarePersistenceManagerFactoryProxy;
+import lombok.AccessLevel;
+import lombok.Getter;
import lombok.NonNull;
import lombok.val;
+import lombok.experimental.Accessors;
import lombok.extern.log4j.Log4j2;
/**
@@ -80,10 +83,18 @@ implements EntityFacet {
@Inject private ObjectManager objectManager;
@Inject private ExceptionRecognizerService exceptionRecognizerService;
@Inject private JdoFacetContext jdoFacetContext;
- @Inject private IdStringifierService idStringifierService;
+ @Inject private ObjectLifecyclePublisher objectLifecyclePublisher;
+
+ @Getter(value = AccessLevel.PROTECTED) @Accessors(fluent = true)
+ @Inject private IdStringifierLookupService idStringifierLookupService;
private final Class<?> entityClass;
+ // lazily looks up the primaryKeyTypeFor (needs a PersistenceManager)
+ @Getter(lazy=true, value = AccessLevel.PROTECTED) @Accessors(fluent = true)
+ private final PrimaryKeyType<?> primaryKeyTypeForDecoding = idStringifierLookupService()
+ .primaryKeyTypeFor(entityClass, primaryKeyTypeFor(entityClass));
+
public JdoEntityFacet(
final FacetHolder holder, final Class<?> entityClass) {
super(EntityFacet.class, holder);
@@ -95,6 +106,19 @@ implements EntityFacet {
return PersistenceStack.JDO;
}
+ /* OPTIMIZATION
+ * even though the IdStringifierLookupService already holds a lookup map,
+ * for performance reasons,
+ * we define another one local to the context of the associated entity class */
+ private final Map<Class<?>, PrimaryKeyType<?>> primaryKeyTypesForEncoding = new ConcurrentHashMap<>();
+ private final PrimaryKeyType<?> primaryKeyTypeForEncoding(final @NonNull Object oid) {
+ val actualPrimaryKeyClass = oid.getClass();
+ val primaryKeyType = primaryKeyTypesForEncoding.computeIfAbsent(actualPrimaryKeyClass, key->
+ idStringifierLookupService()
+ .primaryKeyTypeFor(entityClass, actualPrimaryKeyClass));
+ return primaryKeyType;
+ }
+
@Override
public Optional<String> identifierFor(final Object pojo) {
@@ -105,9 +129,10 @@ implements EntityFacet {
val pm = getPersistenceManager();
var primaryKeyIfAny = pm.getObjectId(pojo);
- return Optional.ofNullable(primaryKeyIfAny)
+ val idIfAny = Optional.ofNullable(primaryKeyIfAny)
.map(primaryKey->
- idStringifierService.enstringPrimaryKey(primaryKey.getClass(), primaryKey));
+ primaryKeyTypeForEncoding(primaryKey).enstringWithCast(primaryKey));
+ return idIfAny;
}
@Override
@@ -119,8 +144,7 @@ implements EntityFacet {
try {
val persistenceManager = getPersistenceManager();
- val primaryKey = idStringifierService
- .destringPrimaryKey(primaryKeyTypeFor(entityClass), entityClass, bookmark.getIdentifier());
+ val primaryKey = primaryKeyTypeForDecoding().destring(bookmark.getIdentifier());
val fetchPlan = persistenceManager.getFetchPlan();
fetchPlan.addGroup(FetchGroup.DEFAULT);
@@ -364,13 +388,11 @@ implements EntityFacet {
private Can<ManagedObject> fetchWithinTransaction(final Supplier<List<?>> fetcher) {
- val objectLifecyclePublisher = getFacetHolder().getServiceRegistry()
- .lookupServiceElseFail(ObjectLifecyclePublisher.class);
-
return getTransactionalProcessor().callWithinCurrentTransactionElseCreateNew(
()->_NullSafe.stream(fetcher.get())
.map(fetchedObject->adopt(objectLifecyclePublisher, fetchedObject))
.collect(Can.toCan()))
+ .ifFailureFail()
.getValue().orElseThrow();
}
@@ -393,5 +415,4 @@ implements EntityFacet {
}
}
-
}
diff --git a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java b/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java
index 7c764ec931..1eb57800fa 100644
--- a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java
+++ b/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java
@@ -21,6 +21,7 @@ package org.apache.isis.persistence.jpa.integration.entity;
import java.lang.reflect.Method;
import java.util.Optional;
+import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.PersistenceUnitUtil;
@@ -34,7 +35,6 @@ import org.apache.isis.applib.query.AllInstancesQuery;
import org.apache.isis.applib.query.NamedQuery;
import org.apache.isis.applib.query.Query;
import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.registry.ServiceRegistry;
import org.apache.isis.applib.services.repository.EntityState;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.base._Casts;
@@ -45,7 +45,7 @@ import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.object.ManagedObject;
-import org.apache.isis.core.runtime.idstringifier.IdStringifierService;
+import org.apache.isis.core.runtime.idstringifier.IdStringifierLookupService;
import lombok.NonNull;
import lombok.val;
@@ -56,19 +56,22 @@ public class JpaEntityFacet
extends FacetAbstract
implements EntityFacet {
+ // self managed injections via constructor
+ @Inject private JpaContext jpaContext;
+ @Inject private IdStringifierLookupService idStringifierLookupService;
+
private final Class<?> entityClass;
- private final ServiceRegistry serviceRegistry;
- private final IdStringifierService idStringifierService;
+ private PrimaryKeyType<?> primaryKeyType;
protected JpaEntityFacet(
final FacetHolder holder,
- final Class<?> entityClass,
- final @NonNull ServiceRegistry serviceRegistry) {
-
+ final Class<?> entityClass) {
super(EntityFacet.class, holder, Precedence.HIGH);
+ getServiceInjector().injectServicesInto(this);
+
this.entityClass = entityClass;
- this.serviceRegistry = serviceRegistry;
- this.idStringifierService = serviceRegistry.lookupServiceElseFail(IdStringifierService.class);
+ this.primaryKeyType = idStringifierLookupService
+ .primaryKeyTypeFor(entityClass, getPrimaryKeyType());
}
// -- ENTITY FACET
@@ -91,7 +94,7 @@ public class JpaEntityFacet
return Optional.ofNullable(primaryKeyIfAny)
.map(primaryKey->
- idStringifierService.enstringPrimaryKey(getPrimaryKeyType(), primaryKey));
+ primaryKeyType.enstringWithCast(primaryKey));
}
@Override
@@ -99,8 +102,7 @@ public class JpaEntityFacet
log.debug("fetchEntity; bookmark={}", bookmark);
- val primaryKey = idStringifierService
- .destringPrimaryKey(getPrimaryKeyType(), entityClass, bookmark.getIdentifier());
+ val primaryKey = primaryKeyType.destring(bookmark.getIdentifier());
val entityManager = getEntityManager();
val entityPojo = entityManager.find(entityClass, primaryKey);
@@ -311,12 +313,8 @@ public class JpaEntityFacet
// -- DEPENDENCIES
- protected JpaContext getJpaContext() {
- return serviceRegistry.lookupServiceElseFail(JpaContext.class);
- }
-
protected EntityManager getEntityManager() {
- return getJpaContext().getEntityManagerByManagedType(entityClass);
+ return jpaContext.getEntityManagerByManagedType(entityClass);
}
protected PersistenceUnitUtil getPersistenceUnitUtil(final EntityManager entityManager) {
diff --git a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacetFactory.java b/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacetFactory.java
index ca1ed4ed6d..cf482fab56 100644
--- a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacetFactory.java
+++ b/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacetFactory.java
@@ -49,7 +49,7 @@ extends FacetFactoryAbstract {
}
addFacet(
- new JpaEntityFacet(facetHolder, cls, getServiceRegistry()));
+ new JpaEntityFacet(facetHolder, cls));
}
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/valuerender/JsonValueEncoderServiceDefault.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/valuerender/JsonValueEncoderServiceDefault.java
index 6608afeb62..72d006b5d1 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/valuerender/JsonValueEncoderServiceDefault.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/valuerender/JsonValueEncoderServiceDefault.java
@@ -127,7 +127,7 @@ public class JsonValueEncoderServiceDefault implements JsonValueEncoderService {
final ValueSerializer<?> valueSerializer) {
if (valueRepr.isString()) {
val recoveredValue = Try.call(()->
- valueSerializer.fromEncodedString(Format.JSON, valueRepr.asString()))
+ valueSerializer.destring(Format.JSON, valueRepr.asString()))
.mapFailure(ex->_Exceptions
.illegalArgument(ex, "Unable to parse value %s as String", valueRepr))
.ifFailureFail()
@@ -235,7 +235,7 @@ public class JsonValueEncoderServiceDefault implements JsonValueEncoderService {
// else
return Facets.valueSerializerElseFail(objectSpec, cls)
- .toEncodedString(Format.JSON, _Casts.uncheckedCast(adapter.getPojo()));
+ .enstring(Format.JSON, _Casts.uncheckedCast(adapter.getPojo()));
}
/**
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/PageParameterUtils.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/PageParameterUtils.java
index 44075d5f0b..3fe8b00bfe 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/PageParameterUtils.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/PageParameterUtils.java
@@ -33,10 +33,8 @@ import org.springframework.lang.Nullable;
import org.apache.isis.applib.Identifier;
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.commons.internal.base._Strings;
import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.facets.object.value.ValueSerializer.Format;
import org.apache.isis.core.metamodel.object.ManagedObject;
import org.apache.isis.core.metamodel.object.ManagedObjects;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@@ -210,13 +208,6 @@ public class PageParameterUtils {
if(adapter == null) {
return NULL_ARG;
}
-
- final ObjectSpecification objSpec = adapter.getSpecification();
- if(objSpec.isValue()) {
- return Facets.valueSerializerElseFail(objSpec, objSpec.getCorrespondingClass())
- .toEncodedString(Format.JSON, _Casts.uncheckedCast(adapter.getPojo()));
- }
-
return ManagedObjects.stringify(adapter).orElse(null);
}
@@ -227,13 +218,6 @@ public class PageParameterUtils {
if(NULL_ARG.equals(encoded)) {
return null;
}
-
- if(objSpec.isValue()) {
- return ManagedObject.value(objSpec,
- Facets.valueSerializerElseFail(objSpec, objSpec.getCorrespondingClass())
- .fromEncodedString(Format.JSON, encoded));
- }
-
try {
return Bookmark.parseUrlEncoded(encoded)
.flatMap(mmc::loadObject)