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/01/30 14:53:20 UTC

[isis] branch master updated: ISIS-2877: even further simplify impl. of SchemaValueMarshaller

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 283e831  ISIS-2877: even further simplify impl. of SchemaValueMarshaller
283e831 is described below

commit 283e831164c19140435bc56cc84e675be993f7e2
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sun Jan 30 15:53:13 2022 +0100

    ISIS-2877: even further simplify impl. of SchemaValueMarshaller
---
 .../services/schema/SchemaValueMarshaller.java     | 16 ++---
 .../schema/SchemaValueMarshallerAbstract.java      | 68 +++++++++-------------
 .../command/CommandDtoFactoryDefault.java          | 10 +---
 .../command/SchemaValueMarshallerDefault.java      | 65 ++++++++++-----------
 .../interaction/InteractionDtoFactoryDefault.java  |  4 +-
 5 files changed, 74 insertions(+), 89 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/schema/SchemaValueMarshaller.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/schema/SchemaValueMarshaller.java
index 4df9f05..236fd27 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/schema/SchemaValueMarshaller.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/schema/SchemaValueMarshaller.java
@@ -22,7 +22,9 @@ import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.value.semantics.ValueSemanticsProvider;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.isis.schema.cmd.v2.ActionDto;
 import org.apache.isis.schema.cmd.v2.ParamDto;
 import org.apache.isis.schema.cmd.v2.PropertyDto;
@@ -84,7 +86,7 @@ public interface SchemaValueMarshaller {
      */
     ActionInvocationDto recordActionResultScalar(
             @NonNull ActionInvocationDto invocationDto,
-            @NonNull ObjectSpecification elementType,
+            @NonNull ObjectAction objectAction,
             @NonNull ManagedObject value);
 
     /**
@@ -93,7 +95,7 @@ public interface SchemaValueMarshaller {
      */
     ActionInvocationDto recordActionResultNonScalar(
             @NonNull ActionInvocationDto invocationDto,
-            @NonNull ObjectSpecification elementType,
+            @NonNull ObjectAction objectAction,
             @NonNull Can<ManagedObject> values);
 
     /**
@@ -102,7 +104,7 @@ public interface SchemaValueMarshaller {
      */
     PropertyDto recordPropertyValue(
             @NonNull PropertyDto propertyDto,
-            @NonNull ObjectSpecification elementType,
+            @NonNull OneToOneAssociation property,
             @NonNull ManagedObject value);
 
     /**
@@ -110,9 +112,8 @@ public interface SchemaValueMarshaller {
      * using {@link ValueSemanticsProvider} for corresponding <i>Action Parameter</i>.
      */
     ParamDto recordParamScalar(
-            @NonNull Identifier paramIdentifier,
             @NonNull ParamDto paramDto,
-            @NonNull ObjectSpecification elementType,
+            @NonNull ObjectActionParameter param,
             @NonNull ManagedObject value);
 
     /**
@@ -120,9 +121,8 @@ public interface SchemaValueMarshaller {
      * using {@link ValueSemanticsProvider} for corresponding <i>Action Parameter</i>.
      */
     ParamDto recordParamNonScalar(
-            @NonNull Identifier paramIdentifier,
             @NonNull ParamDto paramDto,
-            @NonNull ObjectSpecification elementType,
+            @NonNull ObjectActionParameter param,
             @NonNull Can<ManagedObject> values);
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/schema/SchemaValueMarshallerAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/schema/SchemaValueMarshallerAbstract.java
index b1fc26b..d2738c2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/schema/SchemaValueMarshallerAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/schema/SchemaValueMarshallerAbstract.java
@@ -39,6 +39,7 @@ import org.apache.isis.core.metamodel.objectmanager.load.ObjectLoader;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.PackedManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
 import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
@@ -78,7 +79,7 @@ implements SchemaValueMarshaller {
                     && semantics.getSchemaValueType() == ValueType.STRING
                     && !semantics.getCorrespondingClass().equals(String.class);
 
-            return of(correspondingClass, feature, semantics,
+            return of(correspondingClass, feature, Optional.ofNullable(semantics),
                     supportsConversionViaEncoderDecoder
                         ? Optional.ofNullable(semantics.getEncoderDecoder())
                         : Optional.empty(),
@@ -89,7 +90,7 @@ implements SchemaValueMarshaller {
 
         private final @NonNull Class<T> correspondingClass;
         private final @NonNull ObjectFeature feature;
-        private final @NonNull ValueSemanticsProvider<T> semantics;
+        private final @NonNull Optional<ValueSemanticsProvider<T>> semantics;
         private final @NonNull Optional<EncoderDecoder<T>> encoderDecoder;
         private final @NonNull Optional<Converter<T, ?>> converter;
 
@@ -98,7 +99,9 @@ implements SchemaValueMarshaller {
         }
 
         public ValueType getSchemaValueType() {
-            return semantics.getSchemaValueType();
+            return semantics
+                    .map(ValueSemanticsProvider::getSchemaValueType)
+                    .orElse(ValueType.REFERENCE); // fallback
         }
 
     }
@@ -108,12 +111,12 @@ implements SchemaValueMarshaller {
     @Override
     public final ActionInvocationDto recordActionResultScalar(
             final @NonNull ActionInvocationDto invocationDto,
-            final @NonNull ObjectSpecification returnType,
+            final @NonNull ObjectAction objectAction,
             final @NonNull ManagedObject value) {
 
-        val feature = getSpecificationLoader().loadFeatureElseFail(actionIdentifier(invocationDto));
-        val valueCls = feature.getElementType().getCorrespondingClass();
-        val context = newContext(valueCls, feature);
+        val feature = objectAction;
+        val elementTypeAsClass = feature.getElementType().getCorrespondingClass();
+        val context = newContext(elementTypeAsClass, feature);
         invocationDto.setReturned(
                 recordValue(context, new ValueWithTypeDto(), value));
         return invocationDto;
@@ -122,12 +125,12 @@ implements SchemaValueMarshaller {
     @Override
     public final ActionInvocationDto recordActionResultNonScalar(
             final @NonNull ActionInvocationDto invocationDto,
-            final @NonNull ObjectSpecification elementType,
+            final @NonNull ObjectAction objectAction,
             final @NonNull Can<ManagedObject> value) {
 
-        val feature = getSpecificationLoader().loadFeatureElseFail(actionIdentifier(invocationDto));
-        val valueCls = feature.getElementType().getCorrespondingClass();
-        val context = newContext(valueCls, feature);
+        val feature = objectAction;
+        val elementTypeAsClass = feature.getElementType().getCorrespondingClass();
+        val context = newContext(elementTypeAsClass, feature);
         invocationDto.setReturned(
                 recordValues(context, new ValueWithTypeDto(), value));
         return invocationDto;
@@ -136,22 +139,16 @@ implements SchemaValueMarshaller {
     @Override
     public final PropertyDto recordPropertyValue(
             final @NonNull PropertyDto propertyDto,
-            final @NonNull ObjectSpecification propertyType,
+            final @NonNull OneToOneAssociation property,
             final @NonNull ManagedObject value) {
-        final Identifier propertyIdentifier = propertyIdentifier(propertyDto);
 
-        // guard against property not being a scalar
-        {
-            final OneToOneAssociation property =
-                    (OneToOneAssociation)getSpecificationLoader().loadFeatureElseFail(propertyIdentifier);
+        val feature = property;
+        val elementTypeAsClass = feature.getElementType().getCorrespondingClass();
 
-            val elementType = property.getElementType().getCorrespondingClass();
-            _Assert.assertEquals(elementType, propertyType.getCorrespondingClass());
-        }
+        // guard against property not being a scalar
+        _Assert.assertEquals(elementTypeAsClass, property.getElementType().getCorrespondingClass());
 
-        val feature = getSpecificationLoader().loadFeatureElseFail(propertyIdentifier);
-        val valueCls = feature.getElementType().getCorrespondingClass();
-        val context = newContext(valueCls, feature);
+        val context = newContext(elementTypeAsClass, feature);
         propertyDto.setNewValue(
                 recordValue(context, new ValueWithTypeDto(), value));
         return propertyDto;
@@ -159,19 +156,15 @@ implements SchemaValueMarshaller {
 
     @Override
     public final ParamDto recordParamScalar(
-            final @NonNull Identifier paramIdentifier,
             final @NonNull ParamDto paramDto,
-            final @NonNull ObjectSpecification paramType,
+            final @NonNull ObjectActionParameter actionParameter,
             final @NonNull ManagedObject value) {
 
-        final ObjectActionParameter actionParameter =
-                (ObjectActionParameter)getSpecificationLoader().loadFeatureElseFail(paramIdentifier);
-
         _Assert.assertTrue(actionParameter.getFeatureType() == FeatureType.ACTION_PARAMETER_SCALAR);
 
         val feature = actionParameter;
-        val valueCls = feature.getElementType().getCorrespondingClass();
-        val context = newContext(valueCls, feature);
+        val elementTypeAsClass = feature.getElementType().getCorrespondingClass();
+        val context = newContext(elementTypeAsClass, feature);
 
         //          ValueType valueType = valueWrapper.getValueType();
         //
@@ -186,14 +179,10 @@ implements SchemaValueMarshaller {
 
     @Override
     public ParamDto recordParamNonScalar(
-            final @NonNull Identifier paramIdentifier,
             final @NonNull ParamDto paramDto,
-            final @NonNull ObjectSpecification elementType,
+            final @NonNull ObjectActionParameter actionParameter,
             final @NonNull Can<ManagedObject> values) {
 
-        final ObjectActionParameter actionParameter =
-                (ObjectActionParameter)getSpecificationLoader().loadFeatureElseFail(paramIdentifier);
-
         _Assert.assertTrue(actionParameter.getFeatureType() == FeatureType.ACTION_PARAMETER_COLLECTION);
 
         val feature = actionParameter;
@@ -271,10 +260,11 @@ implements SchemaValueMarshaller {
 
     // -- LOW LEVEL IMPLEMENTATION - RECORDING
 
-    protected abstract <D extends ValueDto, T>
-        D recordValue(Context<T> context, D valueDto, ManagedObject value);
-    protected abstract <D extends ValueWithTypeDto, T>
-        D recordValues(Context<T> context, D valueWithTypeDto, Can<ManagedObject> values);
+    protected abstract <T> ValueWithTypeDto
+        recordValue(Context<T> context, ValueWithTypeDto valueDto, ManagedObject value);
+
+    protected abstract <T> ValueWithTypeDto
+        recordValues(Context<T> context, ValueWithTypeDto valueDto, Can<ManagedObject> values);
 
     // -- LOW LEVEL IMPLEMENTATION - RECOVERY
 
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 05bc8e4..e6b752e 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
@@ -131,13 +131,11 @@ public class CommandDtoFactoryDefault implements CommandDtoFactory {
 
             if(actionParameter.getFeatureType() != FeatureType.ACTION_PARAMETER_COLLECTION) {
                 //scalar
-                valueMarshaller.recordParamScalar(
-                        actionParameter.getFeatureIdentifier(), paramDto, elementType, argAdapter);
+                valueMarshaller.recordParamScalar(paramDto, actionParameter, argAdapter);
             } else {
                 //non-scalar
                 val values = ManagedObjects.unpack(elementType, argAdapter);
-                valueMarshaller.recordParamNonScalar(
-                        actionParameter.getFeatureIdentifier(), paramDto, elementType, values);
+                valueMarshaller.recordParamNonScalar(paramDto, actionParameter, values);
             }
 
             CommandDtoUtils.parametersFor(actionDto)
@@ -155,9 +153,7 @@ public class CommandDtoFactoryDefault implements CommandDtoFactory {
         propertyDto.setLogicalMemberIdentifier(IdentifierUtil.logicalMemberIdentifierFor(property));
         propertyDto.setMemberIdentifier(IdentifierUtil.memberIdentifierFor(property));
 
-        val valueSpec = property.getElementType();
-
-        valueMarshaller.recordPropertyValue(propertyDto, valueSpec, valueAdapter);
+        valueMarshaller.recordPropertyValue(propertyDto, property, valueAdapter);
     }
 
     // -- HELPER
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/SchemaValueMarshallerDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/SchemaValueMarshallerDefault.java
index 51ba40d..7e20ca4 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/SchemaValueMarshallerDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/SchemaValueMarshallerDefault.java
@@ -35,7 +35,6 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.schema.common.v2.CollectionDto;
 import org.apache.isis.schema.common.v2.TypedTupleDto;
-import org.apache.isis.schema.common.v2.ValueDto;
 import org.apache.isis.schema.common.v2.ValueType;
 import org.apache.isis.schema.common.v2.ValueWithTypeDto;
 
@@ -54,35 +53,12 @@ extends SchemaValueMarshallerAbstract {
     @Inject private ValueSemanticsResolver valueSemanticsResolver;
     @Inject private SpecificationLoader specLoader;
 
-    // -- RECOVER VALUES FROM DTO
-
-    @Override
-    protected ManagedObject recoverScalarValue(
-            @NonNull final Context<?> context,
-            @NonNull final ValueWithTypeDto valueDto) {
-
-        val valueAsObject = CommonDtoUtils.getValueAsObject(valueDto);
-
-        if(valueAsObject==null) {
-            return ManagedObject.empty(context.getElementType());
-        }
-
-        val elementSpec = context.getElementType();
-
-        val recoveredValueAsPojo = valueDto.getComposite()!=null
-                ? fromTypedTuple(context, valueDto.getComposite())
-                : fromFundamentalValue(context, CommonDtoUtils.getValueAsObject(valueDto));
-
-        val recoveredValue = ManagedObject.of(elementSpec, recoveredValueAsPojo);
-        return recoveredValue;
-    }
-
     // -- RECORD VALUES INTO DTO
 
     @Override
-    protected <D extends ValueDto, T> D recordValue(
+    protected <T> ValueWithTypeDto recordValue(
             final Context<T> context,
-            final D valueDto,
+            final ValueWithTypeDto valueDto,
             final ManagedObject value) {
 
         value.getBookmark()
@@ -91,15 +67,15 @@ extends SchemaValueMarshallerAbstract {
                 ()->CommonDtoUtils.recordFundamentalValue(
                         context.getSchemaValueType(),
                         valueDto,
-                        toFundamentalValue(context, (T)value.getPojo())));
+                        toFundamentalValue(context, _Casts.uncheckedCast(value.getPojo()))));
 
         return valueDto;
     }
 
     @Override
-    protected <D extends ValueWithTypeDto, T> D recordValues(
+    protected <T> ValueWithTypeDto recordValues(
             final Context<T> context,
-            final D valueWithTypeDto,
+            final ValueWithTypeDto valueWithTypeDto,
             final Can<ManagedObject> values) {
 
         valueWithTypeDto.setType(ValueType.COLLECTION);
@@ -108,6 +84,29 @@ extends SchemaValueMarshallerAbstract {
         return valueWithTypeDto;
     }
 
+    // -- RECOVER VALUES FROM DTO
+
+    @Override
+    protected ManagedObject recoverScalarValue(
+            @NonNull final Context<?> context,
+            @NonNull final ValueWithTypeDto valueDto) {
+
+        val valueAsObject = CommonDtoUtils.getValueAsObject(valueDto);
+
+        if(valueAsObject==null) {
+            return ManagedObject.empty(context.getElementType());
+        }
+
+        val elementSpec = context.getElementType();
+
+        val recoveredValueAsPojo = valueDto.getComposite()!=null
+                ? fromTypedTuple(context, valueDto.getComposite())
+                : fromFundamentalValue(context, CommonDtoUtils.getValueAsObject(valueDto));
+
+        val recoveredValue = ManagedObject.of(elementSpec, recoveredValueAsPojo);
+        return recoveredValue;
+    }
+
     // -- HELPER - RECORDING
 
     private <T> CollectionDto asCollectionDto(
@@ -120,7 +119,8 @@ extends SchemaValueMarshallerAbstract {
 
         values.stream()
         .forEach(element->{
-            val valueDto = new ValueDto();
+            val valueDto = new ValueWithTypeDto();
+            valueDto.setType(elementValueType);
             collectionDto.getValue().add(valueDto);
             recordValue(context, valueDto, element);
         });
@@ -128,7 +128,7 @@ extends SchemaValueMarshallerAbstract {
         return collectionDto;
     }
 
-    public <T> Object toFundamentalValue(final Context<T> context, final T valuePojo) {
+    private <T> Object toFundamentalValue(final Context<T> context, final T valuePojo) {
         return context.getEncoderDecoder().isPresent()
                 ? context.getEncoderDecoder().get().toEncodedString(valuePojo)
                 : context.getConverter()
@@ -136,7 +136,6 @@ extends SchemaValueMarshallerAbstract {
                     .orElse(valuePojo);
     }
 
-
     // -- HELPER - RECOVERY
 
     private <T> T fromTypedTuple(final Context<T> context, final TypedTupleDto typedTupleDto) {
@@ -144,7 +143,7 @@ extends SchemaValueMarshallerAbstract {
         return null;
     }
 
-    public <T> T fromFundamentalValue(final Context<T> context, final Object fundamentalValue) {
+    private <T> T fromFundamentalValue(final Context<T> context, final Object fundamentalValue) {
         val valuePojo = context.getEncoderDecoder().isPresent()
                 ? context.getEncoderDecoder().get().fromEncodedString((String)fundamentalValue)
                 : context.getConverter()
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 3027030..670ee94 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
@@ -114,11 +114,11 @@ public class InteractionDtoFactoryDefault implements InteractionDtoFactory {
 
         if(objectAction.getReturnType().isScalar()) {
             //scalar
-            valueMarshaller.recordActionResultScalar(actionInvocationDto, elementSpec, resultObject);
+            valueMarshaller.recordActionResultScalar(actionInvocationDto, objectAction, resultObject);
         } else {
             //non-scalar
             val values = ManagedObjects.unpack(elementSpec, resultObject);
-            valueMarshaller.recordActionResultNonScalar(actionInvocationDto, elementSpec, values);
+            valueMarshaller.recordActionResultNonScalar(actionInvocationDto, objectAction, values);
         }
         return actionInvocationDto;
     }