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/04/06 17:58:06 UTC
[isis] branch master updated: ISIS-2297: have interaction API use its own InteractionRailway
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 a6a49812a5 ISIS-2297: have interaction API use its own InteractionRailway<T>
a6a49812a5 is described below
commit a6a49812a5812b29dc2d28a4669d4ea847bb4954
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Apr 6 19:57:56 2022 +0200
ISIS-2297: have interaction API use its own InteractionRailway<T>
---
.../applib/value/semantics/ValueDecomposition.java | 5 +-
.../org/apache/isis/commons/functional/Either.java | 1 +
.../apache/isis/commons/functional/Railway.java | 1 +
.../interactions/managed/ActionInteraction.java | 12 ++--
.../managed/CollectionInteraction.java | 9 ++-
.../interactions/managed/InteractionRailway.java | 67 ++++++++++++++++++++++
.../interactions/managed/MemberInteraction.java | 9 ++-
.../interactions/managed/PropertyInteraction.java | 11 ++--
.../viewer/resources/ObjectActionArgHelper.java | 46 ++++++++-------
9 files changed, 116 insertions(+), 45 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueDecomposition.java b/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueDecomposition.java
index 44194e5c31..c7d5faa847 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueDecomposition.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueDecomposition.java
@@ -41,9 +41,6 @@ implements
Serializable {
private static final long serialVersionUID = 1L;
- @Getter
- private final Either<ValueWithTypeDto, TypedTupleDto> either;
-
public static ValueDecomposition ofFundamental(final ValueWithTypeDto valueWithTypeDto) {
return new ValueDecomposition(Either.left(valueWithTypeDto));
}
@@ -52,6 +49,8 @@ implements
return new ValueDecomposition(Either.right(typedTupleDto));
}
+ @Getter private final Either<ValueWithTypeDto, TypedTupleDto> either;
+
// used by RO-Viewer to render values
public String toJson() {
return this.<String>fold(
diff --git a/commons/src/main/java/org/apache/isis/commons/functional/Either.java b/commons/src/main/java/org/apache/isis/commons/functional/Either.java
index 60670693ca..5e32430a3d 100644
--- a/commons/src/main/java/org/apache/isis/commons/functional/Either.java
+++ b/commons/src/main/java/org/apache/isis/commons/functional/Either.java
@@ -189,6 +189,7 @@ public interface Either<L, R> {
// -- TYPE COMPOSITION
+ @FunctionalInterface
public static interface HasEither<L, R> extends Either<L, R> {
Either<L, R> getEither();
diff --git a/commons/src/main/java/org/apache/isis/commons/functional/Railway.java b/commons/src/main/java/org/apache/isis/commons/functional/Railway.java
index 5761efe2d1..256dd93088 100644
--- a/commons/src/main/java/org/apache/isis/commons/functional/Railway.java
+++ b/commons/src/main/java/org/apache/isis/commons/functional/Railway.java
@@ -231,6 +231,7 @@ public interface Railway<F, S> {
// -- TYPE COMPOSITION
+ @FunctionalInterface
public static interface HasRailway<F, S> extends Railway<F, S> {
Railway<F, S> getRailway();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java
index 32ae1081b2..750c55d0d8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java
@@ -70,9 +70,9 @@ extends MemberInteraction<ManagedAction, ActionInteraction> {
val managedAction = ManagedAction.lookupActionWithMultiselect(owner, memberId, where, multiselectChoices);
- final Railway<InteractionVeto, ManagedAction> railway = managedAction.isPresent()
- ? Railway.success(managedAction.get())
- : Railway.failure(InteractionVeto.notFound(MemberType.ACTION, memberId));
+ final InteractionRailway<ManagedAction> railway = managedAction.isPresent()
+ ? InteractionRailway.success(managedAction.get())
+ : InteractionRailway.veto(InteractionVeto.notFound(MemberType.ACTION, memberId));
return new ActionInteraction(
managedAction.map(ManagedAction::getAction),
@@ -82,18 +82,18 @@ extends MemberInteraction<ManagedAction, ActionInteraction> {
public static ActionInteraction wrap(final @NonNull ManagedAction managedAction) {
return new ActionInteraction(
Optional.of(managedAction.getAction()),
- Railway.success(managedAction));
+ InteractionRailway.success(managedAction));
}
public static ActionInteraction empty(final String actionId) {
return new ActionInteraction(
Optional.empty(),
- Railway.failure(InteractionVeto.notFound(MemberType.ACTION, actionId)));
+ InteractionRailway.veto(InteractionVeto.notFound(MemberType.ACTION, actionId)));
}
ActionInteraction(
final @NonNull Optional<ObjectAction> metamodel,
- final @NonNull Railway<InteractionVeto, ManagedAction> railway) {
+ final @NonNull InteractionRailway<ManagedAction> railway) {
super(railway);
this.metamodel = metamodel;
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/CollectionInteraction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/CollectionInteraction.java
index 4834806797..09aff8d9bf 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/CollectionInteraction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/CollectionInteraction.java
@@ -22,7 +22,6 @@ import java.util.Optional;
import java.util.function.Function;
import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.commons.functional.Railway;
import org.apache.isis.core.metamodel.interactions.managed.ManagedMember.MemberType;
import org.apache.isis.core.metamodel.spec.ManagedObject;
@@ -39,14 +38,14 @@ extends MemberInteraction<ManagedCollection, CollectionInteraction> {
val managedCollection = ManagedCollection.lookupCollection(owner, memberId, where);
- final Railway<InteractionVeto, ManagedCollection> railway = managedCollection.isPresent()
- ? Railway.success(managedCollection.get())
- : Railway.failure(InteractionVeto.notFound(MemberType.COLLECTION, memberId));
+ final InteractionRailway<ManagedCollection> railway = managedCollection.isPresent()
+ ? InteractionRailway.success(managedCollection.get())
+ : InteractionRailway.veto(InteractionVeto.notFound(MemberType.COLLECTION, memberId));
return new CollectionInteraction(railway);
}
- CollectionInteraction(@NonNull final Railway<InteractionVeto, ManagedCollection> railway) {
+ CollectionInteraction(@NonNull final InteractionRailway<ManagedCollection> railway) {
super(railway);
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/InteractionRailway.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/InteractionRailway.java
new file mode 100644
index 0000000000..79df4b1a0e
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/InteractionRailway.java
@@ -0,0 +1,67 @@
+/*
+ * 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.interactions.managed;
+
+import java.io.Serializable;
+import java.util.function.Function;
+
+import org.apache.isis.commons.functional.Railway;
+import org.apache.isis.commons.functional.Railway.HasRailway;
+
+import lombok.AccessLevel;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+import lombok.val;
+
+/**
+ * Follows the <em>Railway Pattern</em>, that is, once vetoed, stays vetoed.
+ * @see Railway
+ */
+@RequiredArgsConstructor(access=AccessLevel.PROTECTED)
+@ToString @EqualsAndHashCode
+public final class InteractionRailway<T extends ManagedMember>
+implements
+ HasRailway<InteractionVeto, T>,
+ Serializable {
+ private static final long serialVersionUID = 1L;
+
+ public static <T extends ManagedMember> InteractionRailway<T> success(final T managedMember) {
+ return new InteractionRailway<T>(Railway.<InteractionVeto, T>success(managedMember));
+ }
+
+ public static <T extends ManagedMember> InteractionRailway<T> veto(final InteractionVeto veto) {
+ return new InteractionRailway<>(Railway.<InteractionVeto, T>failure(veto));
+ }
+
+ @Getter private final Railway<InteractionVeto, T> railway;
+
+ @Override // type-safe override
+ public InteractionRailway<T> chain(final @NonNull Function<T, Railway<InteractionVeto, T>> chainingFunction) {
+ val railway = HasRailway.super.chain(chainingFunction);
+ return railway instanceof InteractionRailway
+ ? (InteractionRailway<T>) railway
+ : new InteractionRailway<>(railway);
+ }
+
+}
+
+
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/MemberInteraction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/MemberInteraction.java
index 512d9675f1..d720f548b9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/MemberInteraction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/MemberInteraction.java
@@ -21,7 +21,6 @@ package org.apache.isis.core.metamodel.interactions.managed;
import java.util.Optional;
import java.util.function.Function;
-import org.apache.isis.commons.functional.Railway;
import org.apache.isis.commons.internal.base._Casts;
import lombok.NonNull;
@@ -37,9 +36,9 @@ public abstract class MemberInteraction<T extends ManagedMember, H extends Membe
}
}
- @NonNull protected Railway<InteractionVeto, T> railway;
+ @NonNull protected InteractionRailway<T> railway;
- protected MemberInteraction(@NonNull final Railway<InteractionVeto, T> railway) {
+ protected MemberInteraction(@NonNull final InteractionRailway<T> railway) {
this.railway = railway;
}
@@ -106,8 +105,8 @@ public abstract class MemberInteraction<T extends ManagedMember, H extends Membe
return railway.getSuccessElseFail(onFailure);
}
- protected Railway<InteractionVeto, T> vetoRailway(final InteractionVeto veto) {
- return Railway.failure(veto);
+ protected InteractionRailway<T> vetoRailway(final InteractionVeto veto) {
+ return InteractionRailway.veto(veto);
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/PropertyInteraction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/PropertyInteraction.java
index 177e5970ac..f9a74676b0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/PropertyInteraction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/PropertyInteraction.java
@@ -22,7 +22,6 @@ import java.util.Optional;
import java.util.function.Function;
import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.commons.functional.Railway;
import org.apache.isis.core.metamodel.interactions.managed.ManagedMember.MemberType;
import org.apache.isis.core.metamodel.spec.ManagedObject;
@@ -39,18 +38,18 @@ extends MemberInteraction<ManagedProperty, PropertyInteraction> {
val managedProperty = ManagedProperty.lookupProperty(owner, memberId, where);
- final Railway<InteractionVeto, ManagedProperty> railway = managedProperty.isPresent()
- ? Railway.success(managedProperty.get())
- : Railway.failure(InteractionVeto.notFound(MemberType.PROPERTY, memberId));
+ final InteractionRailway<ManagedProperty> railway = managedProperty.isPresent()
+ ? InteractionRailway.success(managedProperty.get())
+ : InteractionRailway.veto(InteractionVeto.notFound(MemberType.PROPERTY, memberId));
return new PropertyInteraction(railway);
}
public static PropertyInteraction wrap(final @NonNull ManagedProperty managedProperty) {
- return new PropertyInteraction(Railway.success(managedProperty));
+ return new PropertyInteraction(InteractionRailway.success(managedProperty));
}
- PropertyInteraction(@NonNull final Railway<InteractionVeto, ManagedProperty> railway) {
+ PropertyInteraction(@NonNull final InteractionRailway<ManagedProperty> railway) {
super(railway);
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java
index 31481ceda0..ee7444504c 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java
@@ -20,6 +20,7 @@ package org.apache.isis.viewer.restfulobjects.viewer.resources;
import java.util.List;
import java.util.Map;
+import java.util.stream.IntStream;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.functional.Railway;
@@ -50,35 +51,36 @@ public class ObjectActionArgHelper {
final JsonRepresentation arguments) {
val jsonArgList = argListFor(action, arguments);
-
- final List<Railway<InteractionVeto, ManagedObject>> argAdapters = _Lists.newArrayList();
val parameters = action.getParameters();
- for (int i = 0; i < jsonArgList.size(); i++) {
- final JsonRepresentation argRepr = jsonArgList.get(i);
- final int argIndex = i;
+
+ return IntStream.range(0, jsonArgList.size())
+ .mapToObj(argIndex->{
+ final JsonRepresentation argRepr = jsonArgList.get(argIndex);
val paramMeta = parameters.getElseFail(argIndex);
val paramSpec = paramMeta.getElementType();
- val objectOrVeto = Try.call(()->
- (paramMeta.isOptional() && argRepr == null)
+ val tryArgument = Try.call(()->
+ (paramMeta.isOptional()
+ && argRepr == null)
? ManagedObject.empty(paramSpec)
: new JsonParserHelper(resourceContext, paramSpec)
- .objectAdapterFor(argRepr))
- .<Railway<InteractionVeto, ManagedObject>>fold(
+ .objectAdapterFor(argRepr));
+
+ val objectOrVeto = tryArgument.<Railway<InteractionVeto, ManagedObject>>fold(
exception->Railway.failure(
InteractionVeto.actionParamInvalid(
String.format("exception when parsing paramNr %d [%s]: %s",
argIndex, argRepr, exception))),
- success->Railway.success(success.orElseThrow()))
- ;
+ success->Railway.success(success.orElseThrow()));
- argAdapters.add(objectOrVeto);
- }
- return Can.ofCollection(argAdapters);
+ return objectOrVeto;
+ })
+ .collect(Can.toCan());
}
- private static List<JsonRepresentation> argListFor(final ObjectAction action, final JsonRepresentation arguments) {
- final List<JsonRepresentation> argList = _Lists.newArrayList();
+ private static List<JsonRepresentation> argListFor(
+ final ObjectAction action,
+ final JsonRepresentation arguments) {
// ensure that we have no arguments that are not parameters
arguments.streamMapEntries()
@@ -88,20 +90,24 @@ public class ObjectActionArgHelper {
if (action.getParameterById(argName) == null) {
String reason = String.format("Argument '%s' found but no such parameter", argName);
arguments.mapPut("x-ro-invalidReason", reason);
- throw RestfulObjectsApplicationException.createWithBody(RestfulResponse.HttpStatusCode.BAD_REQUEST, arguments, reason);
+ throw RestfulObjectsApplicationException
+ .createWithBody(RestfulResponse.HttpStatusCode.BAD_REQUEST, arguments, reason);
}
});
// ensure that an argument value has been provided for all non-optional
// parameters
+ val argList = _Lists.<JsonRepresentation>newArrayList();
val parameters = action.getParameters();
for (final ObjectActionParameter param : parameters) {
final String paramId = param.getId();
final JsonRepresentation argRepr = arguments.getRepresentation(paramId);
- if (argRepr == null && !param.isOptional()) {
- String reason = String.format("No argument found for (mandatory) parameter '%s'", paramId);
+ if (argRepr == null
+ && !param.isOptional()) {
+ val reason = String.format("No argument found for (mandatory) parameter '%s'", paramId);
arguments.mapPut("x-ro-invalidReason", reason);
- throw RestfulObjectsApplicationException.createWithBody(RestfulResponse.HttpStatusCode.BAD_REQUEST, arguments, reason);
+ throw RestfulObjectsApplicationException
+ .createWithBody(RestfulResponse.HttpStatusCode.BAD_REQUEST, arguments, reason);
}
argList.add(argRepr);
}