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 2020/04/25 19:36:09 UTC
[isis] 05/08: ISIS-2340: share logic of
ObjectAdapterAccessHelper/UpdateHelper (5)
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
commit 98a2ff1fbcdaea0390ad26344159e5aadcfdae6d
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Apr 24 12:52:25 2020 +0200
ISIS-2340: share logic of ObjectAdapterAccessHelper/UpdateHelper (5)
---
.../isis/core/commons/internal/base/_Either.java | 18 +-
.../ui/components/object/ObjectFormView.java | 136 ++++----
.../common/model/binding/UiComponentFactory.java | 19 +
.../model/binding/interaction/ActionBinding.java | 25 ++
.../binding/interaction/ActionBindingReadonly.java | 19 +
.../binding/interaction/ActionBindingUsable.java | 19 +
.../binding/interaction/ActionInteractor.java | 71 ----
.../binding/interaction/CollectionBinding.java | 25 ++
.../interaction/CollectionBindingEditable.java | 19 +
.../interaction/CollectionBindingReadonly.java | 19 +
.../binding/interaction/CollectionInteractor.java | 70 ----
.../binding/interaction/MemberInteractor.java | 84 -----
.../model/binding/interaction/ObjectBinding.java | 387 +++++++++++++++++++++
.../binding/interaction/ObjectInteractor.java | 150 --------
.../model/binding/interaction/PropertyBinding.java | 31 ++
.../interaction/PropertyBindingEditable.java | 37 ++
.../interaction/PropertyBindingReadonly.java | 27 ++
.../binding/interaction/PropertyInteractor.java | 86 -----
.../resources/DomainObjectResourceServerside.java | 71 ++--
.../viewer/resources/DomainResourceHelper.java | 14 +-
.../resources/InteractionFailureHandler.java | 2 +-
.../resources/ObjectAdapterAccessHelper.java | 38 +-
22 files changed, 785 insertions(+), 582 deletions(-)
diff --git a/core/commons/src/main/java/org/apache/isis/core/commons/internal/base/_Either.java b/core/commons/src/main/java/org/apache/isis/core/commons/internal/base/_Either.java
index 2715b95..74a01b5 100644
--- a/core/commons/src/main/java/org/apache/isis/core/commons/internal/base/_Either.java
+++ b/core/commons/src/main/java/org/apache/isis/core/commons/internal/base/_Either.java
@@ -114,13 +114,25 @@ public final class _Either<L, R> {
public <X, Y> _Either<X, Y> map(Function<L, X> leftMapper, Function<R, Y> rightMapper){
return isLeft()
? left(leftMapper.apply(left))
- : right(rightMapper.apply(right));
+ : right(rightMapper.apply(right));
}
public <X, Y> _Either<X, Y> mapNullable(Function<L, X> leftMapper, Function<R, Y> rightMapper){
return isLeft()
? leftNullable(leftMapper.apply(left))
- : rightNullable(rightMapper.apply(right));
+ : rightNullable(rightMapper.apply(right));
+ }
+
+ public _Either<L, R> leftRemap(Function<L, _Either<L, R>> leftRemapper){
+ return isLeft()
+ ? leftRemapper.apply(left)
+ : this;
+ }
+
+ public _Either<L, R> rightReMap(Function<R, _Either<L, R>> rightRemapper){
+ return isLeft()
+ ? this
+ : rightRemapper.apply(right);
}
// -- REDUCTION
@@ -132,7 +144,7 @@ public final class _Either<L, R> {
public <X> X get(Function<L, X> leftMapper, Function<R, X> rightMapper){
return isLeft()
? leftMapper.apply(left)
- : rightMapper.apply(right);
+ : rightMapper.apply(right);
}
// -- TERMINALS
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/object/ObjectFormView.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/object/ObjectFormView.java
index c771ab9..6333a8f 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/object/ObjectFormView.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/object/ObjectFormView.java
@@ -36,6 +36,7 @@ import com.vaadin.flow.component.tabs.Tab;
import com.vaadin.flow.component.tabs.Tabs;
import com.vaadin.flow.component.textfield.TextField;
+import org.apache.isis.applib.annotation.Where;
import org.apache.isis.applib.layout.component.ActionLayoutData;
import org.apache.isis.applib.layout.component.CollectionLayoutData;
import org.apache.isis.applib.layout.component.DomainObjectLayoutData;
@@ -50,7 +51,8 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
import org.apache.isis.incubator.viewer.vaadin.ui.components.UiComponentFactoryVaa;
import org.apache.isis.incubator.viewer.vaadin.ui.components.collection.TableView;
-import org.apache.isis.viewer.common.model.binding.interaction.ObjectInteractor;
+import org.apache.isis.viewer.common.model.binding.UiComponentFactory;
+import org.apache.isis.viewer.common.model.binding.interaction.ObjectBinding;
import org.apache.isis.viewer.common.model.gridlayout.UiGridLayout;
import lombok.NonNull;
@@ -59,9 +61,9 @@ import lombok.val;
public class ObjectFormView extends VerticalLayout {
private static final long serialVersionUID = 1L;
-
+
private static final String NULL_LITERAL = "<NULL>";
-
+
/**
* Constructs given domain object's view, with all its visible members and actions.
* @param managedObject - domain object
@@ -69,63 +71,63 @@ public class ObjectFormView extends VerticalLayout {
public ObjectFormView(
@NonNull final UiComponentFactoryVaa uiComponentFactory,
@NonNull final ManagedObject managedObject) {
-
-
- val objectInteractor = ObjectInteractor.bind(managedObject);
-
+
+
+ val objectInteractor = ObjectBinding.bind(managedObject);
+
val uiGridLayout = UiGridLayout.bind(managedObject);
-
+
// force new row
//formLayout.getElement().appendChild(ElementFactory.createBr());
-
+
val gridVisistor = new UiGridLayout.Visitor<HasComponents>(this) {
@Override
protected void onObjectTitle(HasComponents container, DomainObjectLayoutData domainObjectData) {
val uiTitle = new H1(objectInteractor.getTitle());
-// uiTitle.addThemeVariants(
-// ButtonVariant.LUMO_LARGE,
-// ButtonVariant.LUMO_TERTIARY_INLINE);
+ // uiTitle.addThemeVariants(
+ // ButtonVariant.LUMO_LARGE,
+ // ButtonVariant.LUMO_TERTIARY_INLINE);
container.add(uiTitle);
}
-
+
@Override
protected HasComponents newRow(HasComponents container, BS3Row bs3Row) {
val uiRow = new FlexLayout();
container.add(uiRow);
uiRow.setWidthFull();
uiRow.setWrapMode(FlexLayout.WrapMode.WRAP); // allow line breaking
-
+
// instead of a FlexLayout we need to convert to a layout where we can control
// the responsive steps
-// val steps = _Lists.of(
-// new ResponsiveStep("0", 1),
-// new ResponsiveStep("50em", 2)
-// );
-
+ // val steps = _Lists.of(
+ // new ResponsiveStep("0", 1),
+ // new ResponsiveStep("50em", 2)
+ // );
+
return uiRow;
}
@Override
protected HasComponents newCol(HasComponents container, BS3Col bs3col) {
-
+
val uiCol = new VerticalLayout();
container.add(uiCol);
-
+
final int span = bs3col.getSpan();
((FlexLayout)container).setFlexGrow(span, uiCol);
val widthEm = String.format("%dem", span * 3); // 1em ~ 16px
uiCol.setWidth(null); // clear preset width style
uiCol.setMinWidth(widthEm);
-
+
return uiCol;
}
-
+
@Override
protected HasComponents newActionPanel(HasComponents container) {
val uiActionPanel = new FlexLayout();
container.add(uiActionPanel);
-
+
uiActionPanel.setWrapMode(FlexLayout.WrapMode.WRAP); // allow line breaking
uiActionPanel.setAlignItems(Alignment.BASELINE);
return uiActionPanel;
@@ -145,22 +147,22 @@ public class ObjectFormView extends VerticalLayout {
container.add(uiTab);
return uiTab;
}
-
+
@Override
protected HasComponents newFieldSet(HasComponents container, FieldSet fieldSetData) {
-
+
container.add(new H2(fieldSetData.getName()));
-
+
val uiFieldSet = new FormLayout();
container.add(uiFieldSet);
-
+
uiFieldSet.setResponsiveSteps(
new ResponsiveStep("0", 1)); // single column only
-
+
return uiFieldSet;
}
-
+
@Override
protected void onClearfix(HasComponents container, BS3ClearFix clearFixData) {
// TODO Auto-generated method stub
@@ -175,16 +177,18 @@ public class ObjectFormView extends VerticalLayout {
uiAction.getStyle().set("margin-left", "0.5em");
uiAction.addThemeVariants(
ButtonVariant.LUMO_SMALL);
-
+
});
}
@Override
protected void onProperty(HasComponents container, PropertyLayoutData propertyData) {
- objectInteractor.lookupProperty(propertyData.getId())
- .ifPresent(property->{
- val uiPropertyCreateRequest = objectInteractor.newUiComponentCreateRequest(property);
- val uiProperty = uiComponentFactory.componentFor(uiPropertyCreateRequest);
+ objectInteractor
+ .getPropertyBinding(propertyData.getId(), Where.OBJECT_FORMS)
+ .left() // if visible
+ .ifPresent(propertyBinding->{
+ val uiProperty = uiComponentFactory
+ .componentFor(UiComponentFactory.Request.of(propertyBinding));
container.add(uiProperty);
});
}
@@ -194,49 +198,49 @@ public class ObjectFormView extends VerticalLayout {
objectInteractor.lookupCollection(collectionData.getId())
.ifPresent(collection->{
container.add(new H3(collection.getName()));
-
+
val collectionValue = Optional.ofNullable(collection.get(managedObject))
.orElse(ManagedObject.of(collection.getSpecification(), null));
container.add(createCollectionComponent(collection, collectionValue));
});
}
-
+
};
-
+
uiGridLayout.visit(gridVisistor);
setWidthFull();
-
+
// -- populate actions
-
-// objectInteractor
-// .streamVisisbleActions()
-// .forEach(action -> {
-//
-// val button = new Button(action.getName());
-// actionsLayout.add(button);
-//
-// Dialog dialog = new Dialog();
-// dialog.add(new Label("Under Construction ... Close me with the esc-key or an outside click"));
-//
-// dialog.setWidth("400px");
-// dialog.setHeight("150px");
-//
-// button.addClickListener(e->{
-// dialog.open();
-// });
-//
-////similar code in menu item ...
-//// val actionModel = (ActionVaa)menuItemModel.getMenuActionUiModel();
-////
-//// subMenu.addItem(
-//// (Component)menuActionModel.getUiComponent(),
-//// e->subMenuEventHandler.accept(menuActionModel));
-//
-// });
+
+ // objectInteractor
+ // .streamVisisbleActions()
+ // .forEach(action -> {
+ //
+ // val button = new Button(action.getName());
+ // actionsLayout.add(button);
+ //
+ // Dialog dialog = new Dialog();
+ // dialog.add(new Label("Under Construction ... Close me with the esc-key or an outside click"));
+ //
+ // dialog.setWidth("400px");
+ // dialog.setHeight("150px");
+ //
+ // button.addClickListener(e->{
+ // dialog.open();
+ // });
+ //
+ ////similar code in menu item ...
+ //// val actionModel = (ActionVaa)menuItemModel.getMenuActionUiModel();
+ ////
+ //// subMenu.addItem(
+ //// (Component)menuActionModel.getUiComponent(),
+ //// e->subMenuEventHandler.accept(menuActionModel));
+ //
+ // });
}
-
+
// -- HELPER
private Component createCollectionComponent(
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/UiComponentFactory.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/UiComponentFactory.java
index 7dffb94..fbff986 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/UiComponentFactory.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/UiComponentFactory.java
@@ -30,6 +30,7 @@ import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacet;
import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
+import org.apache.isis.viewer.common.model.binding.interaction.PropertyBinding;
import lombok.NonNull;
import lombok.Value;
@@ -48,6 +49,22 @@ public interface UiComponentFactory<T> {
@NonNull private final ObjectFeature objectFeature;
@NonNull private final Function<ManagedObject, String> toDomainPropagator;
+ public static Request of(PropertyBinding propertyBinding) {
+ val property = propertyBinding.getProperty();
+ //TODO there is also the aspect of editable or not
+ val propertyValue = propertyBinding.getPropertyValue();
+
+ return of(propertyValue, property, proposedNewValue -> {
+
+ val iResponse = propertyBinding.modifyProperty(proposedNewValue);
+ if (iResponse.isFailure()) {
+ return iResponse.getFailureMessage(); // validation result if any
+ }
+ return null;
+
+ });
+ }
+
// -- SHORTCUTS
/**
@@ -129,6 +146,8 @@ public interface UiComponentFactory<T> {
public boolean isReadOnly() {
return objectFeature.getFacet(DisabledFacet.class)!=null;
}
+
+
}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ActionBinding.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ActionBinding.java
new file mode 100644
index 0000000..45aee47
--- /dev/null
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ActionBinding.java
@@ -0,0 +1,25 @@
+package org.apache.isis.viewer.common.model.binding.interaction;
+
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+
+public interface ActionBinding {
+
+ ManagedObject getManagedObject();
+ ObjectAction getAction();
+
+// InteractionResponse modifyProperty(ManagedObject newProperyValue);
+//
+// default InteractionResponse modifyProperty(
+// @NonNull final Function<OneToOneAssociation, ManagedObject> newProperyValueProvider) {
+// return modifyProperty(newProperyValueProvider.apply(getProperty()));
+// }
+//
+// default ManagedObject getPropertyValue() {
+// val property = getProperty();
+//
+// return Optional.ofNullable(property.get(getManagedObject()))
+// .orElse(ManagedObject.of(property.getSpecification(), null));
+// }
+
+}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ActionBindingReadonly.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ActionBindingReadonly.java
new file mode 100644
index 0000000..09f5b55
--- /dev/null
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ActionBindingReadonly.java
@@ -0,0 +1,19 @@
+package org.apache.isis.viewer.common.model.binding.interaction;
+
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor(staticName = "of")
+public class ActionBindingReadonly implements ActionBinding {
+
+ @Getter(onMethod = @__(@Override))
+ private final ManagedObject managedObject;
+
+ @Getter(onMethod = @__(@Override))
+ private final ObjectAction action;
+
+
+}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ActionBindingUsable.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ActionBindingUsable.java
new file mode 100644
index 0000000..2bdc815
--- /dev/null
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ActionBindingUsable.java
@@ -0,0 +1,19 @@
+package org.apache.isis.viewer.common.model.binding.interaction;
+
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor(staticName = "of")
+public class ActionBindingUsable implements ActionBinding {
+
+ @Getter(onMethod = @__(@Override))
+ private final ManagedObject managedObject;
+
+ @Getter(onMethod = @__(@Override))
+ private final ObjectAction action;
+
+
+}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ActionInteractor.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ActionInteractor.java
deleted file mode 100644
index 3a825cc..0000000
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ActionInteractor.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.viewer.common.model.binding.interaction;
-
-import java.util.function.BiConsumer;
-
-import javax.annotation.Nullable;
-
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.core.commons.internal.base._Either;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.viewer.common.model.binding.interaction.InteractionResponse.Veto;
-import org.apache.isis.viewer.common.model.binding.interaction.ObjectInteractor.AccessIntent;
-
-import lombok.val;
-
-public class ActionInteractor extends MemberInteractor {
-
- private final String actionId;
- private final Where where;
- private final AccessIntent accessIntent;
-
- public ActionInteractor(
- final ObjectInteractor objectInteractor,
- final String actionId,
- final Where where,
- final AccessIntent accessIntent) {
- super(objectInteractor);
- this.actionId = actionId;
- this.where = where;
- this.accessIntent = accessIntent;
- }
-
- public _Either<ObjectAction, InteractionResponse> getActionThatIsVisibleForIntent() {
-
- val managedObject = objectInteractor.getManagedObject();
-
- val spec = managedObject.getSpecification();
- val action = spec.getObjectAction(actionId).orElse(null);
-
- if(action==null) {
- return super.notFound(MemberType.ACTION, actionId, Veto.NOT_FOUND);
- }
-
- return super.memberThatIsVisibleForIntent(
- MemberType.ACTION,
- action, where, accessIntent);
- }
-
- public ActionInteractor onFailure(@Nullable final BiConsumer<InteractionResponse, String> onFailure) {
- super.onFailure = onFailure;
- return this;
- }
-
-}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/CollectionBinding.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/CollectionBinding.java
new file mode 100644
index 0000000..92de7cd
--- /dev/null
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/CollectionBinding.java
@@ -0,0 +1,25 @@
+package org.apache.isis.viewer.common.model.binding.interaction;
+
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+
+public interface CollectionBinding {
+
+ ManagedObject getManagedObject();
+ OneToManyAssociation getCollection();
+
+// InteractionResponse modifyProperty(ManagedObject newProperyValue);
+//
+// default InteractionResponse modifyProperty(
+// @NonNull final Function<OneToOneAssociation, ManagedObject> newProperyValueProvider) {
+// return modifyProperty(newProperyValueProvider.apply(getProperty()));
+// }
+//
+// default ManagedObject getPropertyValue() {
+// val property = getProperty();
+//
+// return Optional.ofNullable(property.get(getManagedObject()))
+// .orElse(ManagedObject.of(property.getSpecification(), null));
+// }
+
+}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/CollectionBindingEditable.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/CollectionBindingEditable.java
new file mode 100644
index 0000000..877e654
--- /dev/null
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/CollectionBindingEditable.java
@@ -0,0 +1,19 @@
+package org.apache.isis.viewer.common.model.binding.interaction;
+
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor(staticName = "of")
+public class CollectionBindingEditable implements CollectionBinding {
+
+ @Getter(onMethod = @__(@Override))
+ private final ManagedObject managedObject;
+
+ @Getter(onMethod = @__(@Override))
+ private final OneToManyAssociation collection;
+
+
+}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/CollectionBindingReadonly.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/CollectionBindingReadonly.java
new file mode 100644
index 0000000..d2a4b03
--- /dev/null
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/CollectionBindingReadonly.java
@@ -0,0 +1,19 @@
+package org.apache.isis.viewer.common.model.binding.interaction;
+
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor(staticName = "of")
+public class CollectionBindingReadonly implements CollectionBinding {
+
+ @Getter(onMethod = @__(@Override))
+ private final ManagedObject managedObject;
+
+ @Getter(onMethod = @__(@Override))
+ private final OneToManyAssociation collection;
+
+
+}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/CollectionInteractor.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/CollectionInteractor.java
deleted file mode 100644
index 488a129..0000000
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/CollectionInteractor.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.viewer.common.model.binding.interaction;
-
-import java.util.function.BiConsumer;
-
-import javax.annotation.Nullable;
-
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.core.commons.internal.base._Either;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-import org.apache.isis.viewer.common.model.binding.interaction.InteractionResponse.Veto;
-import org.apache.isis.viewer.common.model.binding.interaction.ObjectInteractor.AccessIntent;
-
-import lombok.val;
-
-public class CollectionInteractor extends MemberInteractor {
-
- private final String collectionId;
- private final Where where;
- private final AccessIntent accessIntent;
-
- public CollectionInteractor(
- final ObjectInteractor objectInteractor,
- final String collectionId,
- final Where where,
- final AccessIntent accessIntent) {
- super(objectInteractor);
- this.collectionId = collectionId;
- this.where = where;
- this.accessIntent = accessIntent;
- }
-
- public _Either<OneToManyAssociation, InteractionResponse> getCollectionThatIsVisibleForIntent() {
-
- val managedObject = objectInteractor.getManagedObject();
-
- val spec = managedObject.getSpecification();
- val collection = spec.getAssociation(collectionId).orElse(null);
- if(collection==null || !collection.isOneToOneAssociation()) {
- return super.notFound(MemberType.COLLECTION, collectionId, Veto.NOT_FOUND);
- }
-
- return super.memberThatIsVisibleForIntent(
- MemberType.COLLECTION,
- (OneToManyAssociation) collection, where, accessIntent);
- }
-
- public CollectionInteractor onFailure(@Nullable final BiConsumer<InteractionResponse, String> onFailure) {
- super.onFailure = onFailure;
- return this;
- }
-
-}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/MemberInteractor.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/MemberInteractor.java
deleted file mode 100644
index 3177440..0000000
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/MemberInteractor.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.viewer.common.model.binding.interaction;
-
-import java.util.function.BiConsumer;
-
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.core.commons.internal.base._Either;
-import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
-import org.apache.isis.viewer.common.model.binding.interaction.InteractionResponse.Veto;
-import org.apache.isis.viewer.common.model.binding.interaction.ObjectInteractor.AccessIntent;
-
-import lombok.RequiredArgsConstructor;
-import lombok.val;
-
-@RequiredArgsConstructor
-class MemberInteractor {
-
- // only used to create failure messages
- static enum MemberType {
- PROPERTY,
- COLLECTION,
- ACTION
- }
-
- protected final ObjectInteractor objectInteractor;
- protected BiConsumer<InteractionResponse, String> onFailure;
-
- protected <T extends ObjectMember>
- _Either<T, InteractionResponse> memberThatIsVisibleForIntent(
- final MemberType memberType,
- final T objectMember,
- final Where where,
- final AccessIntent intent) {
-
- val managedObject = objectInteractor.getManagedObject();
- val visibilityConsent =
- objectMember.isVisible(
- managedObject, InteractionInitiatedBy.USER, where);
- if (visibilityConsent.isVetoed()) {
- val memberId = objectMember.getId();
- return notFound(memberType, memberId, Veto.HIDDEN);
- }
- if (intent.isMutate()) {
- val usabilityConsent =
- objectMember.isUsable(
- managedObject, InteractionInitiatedBy.USER, where);
- if (usabilityConsent.isVetoed()) {
- return _Either.right(InteractionResponse.failed(
- Veto.FORBIDDEN,
- usabilityConsent.getReason()));
- }
- }
- return _Either.left(objectMember);
- }
-
- protected <T extends ObjectMember>
- _Either<T, InteractionResponse> notFound(MemberType memberType, String memberId, Veto veto) {
- return _Either.right(InteractionResponse.failed(
- veto,
- String.format("%s '%s' either does not exist, is disabled or is not visible",
- memberId,
- memberType.name().toLowerCase())));
- }
-
-
-}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ObjectBinding.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ObjectBinding.java
new file mode 100644
index 0000000..8b1a71d
--- /dev/null
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ObjectBinding.java
@@ -0,0 +1,387 @@
+/*
+ * 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.viewer.common.model.binding.interaction;
+
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.BiFunction;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.commons.internal.base._Either;
+import org.apache.isis.core.commons.internal.exceptions._Exceptions;
+import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.viewer.common.model.binding.interaction.InteractionResponse.Veto;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.val;
+
+@RequiredArgsConstructor(staticName = "bind")
+public class ObjectBinding {
+
+ // only used to create failure messages
+ @RequiredArgsConstructor
+ private static enum MemberType {
+ PROPERTY(OneToOneAssociation.class, (spec, propertyId)->
+ spec.getAssociation(propertyId)
+ .map(property->property.isOneToOneAssociation()?property:null)),
+
+ COLLECTION(OneToManyAssociation.class, (spec, collectionId)->
+ spec.getAssociation(collectionId)
+ .map(collection->collection.isOneToManyAssociation()?collection:null)),
+
+ ACTION(ObjectAction.class, (spec, actionId)->
+ spec.getObjectAction(actionId));
+
+ @Getter private final Class<? extends ObjectMember> memberType;
+ @Getter private final BiFunction<
+ ObjectSpecification, String,
+ Optional<? extends ObjectMember>
+ > memberProvider;
+
+ }
+
+ public static enum AccessIntent {
+ ACCESS, MUTATE;
+
+ public boolean isMutate() {
+ return this == MUTATE;
+ }
+ }
+
+ @Getter
+ private final ManagedObject managedObject;
+
+ public String getTitle() {
+ return managedObject.getSpecification().getTitle(null, managedObject);
+ }
+
+ @Deprecated
+ public Stream<OneToOneAssociation> streamVisisbleProperties() {
+ return managedObject.getSpecification()
+ .streamAssociations(Contributed.INCLUDED)
+ .filter(objMember->objMember.getFeatureType().isProperty())
+ //TODO filter visibility
+ .map(OneToOneAssociation.class::cast);
+ }
+
+ @Deprecated
+ public Stream<OneToManyAssociation> streamVisisbleCollections() {
+ return managedObject.getSpecification()
+ .streamAssociations(Contributed.INCLUDED)
+ .filter(objMember->objMember.getFeatureType().isCollection())
+ //TODO filter visibility
+ .map(OneToManyAssociation.class::cast);
+ }
+
+ @Deprecated
+ public Stream<ObjectAction> streamVisisbleActions() {
+ return managedObject.getSpecification()
+ .streamObjectActions(Contributed.INCLUDED)
+ .filter(objMember->objMember.getFeatureType().isAction())
+ //TODO filter visibility
+ .map(ObjectAction.class::cast);
+ }
+
+ public Optional<ObjectAction> lookupAction(String actionId) {
+ return streamVisisbleActions()
+ .filter(action->Objects.equals(actionId, action.getId()))
+ .findFirst();
+ }
+
+ public Optional<OneToOneAssociation> lookupVisibleProperty(String propertyId) {
+ return streamVisisbleProperties()
+ .filter(property->Objects.equals(propertyId, property.getId()))
+ .findFirst();
+ }
+
+ public Optional<OneToManyAssociation> lookupCollection(String collectionId) {
+ return streamVisisbleCollections()
+ .filter(collection->Objects.equals(collectionId, collection.getId()))
+ .findFirst();
+ }
+
+ /**
+ * @param actionId
+ * @param where
+ * @return either an editable or readonly ActionBinding, based on visibility and usability
+ */
+ public _Either<ActionBinding, InteractionResponse> getActionBinding(String actionId, Where where) {
+ return getActionThatIsVisible(actionId, where)
+ .map(
+ action->
+ checkUsability(action, where).isSuccess()
+ ? ActionBindingUsable.of(managedObject, action)
+ : ActionBindingReadonly.of(managedObject, action),
+ UnaryOperator.identity());
+ }
+
+ /**
+ *
+ * @param actionId
+ * @param where
+ * @param accessIntent
+ * @return either an editable or readonly PropertyBinding, based on visibility and accessIntent
+ */
+ public _Either<ActionBinding, InteractionResponse> getActionBinding(
+ final String actionId,
+ final Where where,
+ final AccessIntent accessIntent) {
+
+ return getActionThatIsVisibleForIntent(actionId, where, accessIntent)
+ .map(
+ action->{
+ switch(accessIntent) {
+ case ACCESS:
+ return ActionBindingReadonly.of(managedObject, action);
+ case MUTATE:
+ return ActionBindingUsable.of(managedObject, action);
+ default:
+ throw _Exceptions.unmatchedCase(accessIntent);
+ }
+ },
+ UnaryOperator.identity());
+
+ }
+
+ /**
+ * @param propertyId
+ * @param where
+ * @return either an editable or readonly PropertyBinding, based on visibility and usability
+ */
+ public _Either<PropertyBinding, InteractionResponse> getPropertyBinding(String propertyId, Where where) {
+ return getPropertyThatIsVisible(propertyId, where)
+ .map(
+ property->
+ checkUsability(property, where).isSuccess()
+ ? PropertyBindingEditable.of(managedObject, property)
+ : PropertyBindingReadonly.of(managedObject, property),
+ UnaryOperator.identity());
+ }
+
+ /**
+ *
+ * @param propertyId
+ * @param where
+ * @param accessIntent
+ * @return either an editable or readonly PropertyBinding, based on visibility and accessIntent
+ */
+ public _Either<PropertyBinding, InteractionResponse> getPropertyBinding(
+ final String propertyId,
+ final Where where,
+ final AccessIntent accessIntent) {
+
+ return getPropertyThatIsVisibleForIntent(propertyId, where, accessIntent)
+ .map(
+ property->{
+ switch(accessIntent) {
+ case ACCESS:
+ return PropertyBindingReadonly.of(managedObject, property);
+ case MUTATE:
+ return PropertyBindingEditable.of(managedObject, property);
+ default:
+ throw _Exceptions.unmatchedCase(accessIntent);
+ }
+ },
+ UnaryOperator.identity());
+
+ }
+
+ /**
+ * @param collectionId
+ * @param where
+ * @return either an editable or readonly CollectionBinding, based on visibility and usability
+ */
+ public _Either<CollectionBinding, InteractionResponse> getCollectionBinding(String collectionId, Where where) {
+ return getCollectionThatIsVisible(collectionId, where)
+ .map(
+ coll->
+ checkUsability(coll, where).isSuccess()
+ ? CollectionBindingEditable.of(managedObject, coll)
+ : CollectionBindingReadonly.of(managedObject, coll),
+ UnaryOperator.identity());
+ }
+
+ /**
+ *
+ * @param collectionId
+ * @param where
+ * @param accessIntent
+ * @return either an editable or readonly CollectionBinding, based on visibility and accessIntent
+ */
+ public _Either<CollectionBinding, InteractionResponse> getCollectionBinding(
+ final String collectionId,
+ final Where where,
+ final AccessIntent accessIntent) {
+
+ return getCollectionThatIsVisibleForIntent(collectionId, where, accessIntent)
+ .map(
+ coll->{
+ switch(accessIntent) {
+ case ACCESS:
+ return CollectionBindingReadonly.of(managedObject, coll);
+ case MUTATE:
+ return CollectionBindingEditable.of(managedObject, coll);
+ default:
+ throw _Exceptions.unmatchedCase(accessIntent);
+ }
+ },
+ UnaryOperator.identity());
+
+ }
+
+ // -- HELPER - TOP LEVEL
+
+ private _Either<ObjectAction, InteractionResponse>
+ getActionThatIsVisible(String actionId, Where where) {
+ val chain = this.<ObjectAction>startChain(MemberType.ACTION, actionId);
+ return checkVisibility(chain, MemberType.ACTION, where);
+ }
+
+ private _Either<OneToOneAssociation, InteractionResponse>
+ getPropertyThatIsVisible(String propertyId, Where where) {
+ val chain = this.<OneToOneAssociation>startChain(MemberType.PROPERTY, propertyId);
+ return checkVisibility(chain, MemberType.PROPERTY, where);
+ }
+
+ private _Either<OneToManyAssociation, InteractionResponse>
+ getCollectionThatIsVisible(String collectionId, Where where) {
+ val chain = this.<OneToManyAssociation>startChain(MemberType.COLLECTION, collectionId);
+ return checkVisibility(chain, MemberType.COLLECTION, where);
+ }
+
+ private _Either<ObjectAction, InteractionResponse> getActionThatIsVisibleForIntent(
+ final String actionId,
+ final Where where,
+ final AccessIntent accessIntent) {
+ return checkUsability(getActionThatIsVisible(actionId, where), where, accessIntent);
+ }
+
+ private _Either<OneToOneAssociation, InteractionResponse> getPropertyThatIsVisibleForIntent(
+ final String propertyId,
+ final Where where,
+ final AccessIntent accessIntent) {
+ return checkUsability(getPropertyThatIsVisible(propertyId, where), where, accessIntent);
+ }
+
+ private _Either<OneToManyAssociation, InteractionResponse> getCollectionThatIsVisibleForIntent(
+ final String propertyId,
+ final Where where,
+ final AccessIntent accessIntent) {
+ return checkUsability(getCollectionThatIsVisible(propertyId, where), where, accessIntent);
+ }
+
+ // HELPER - MID LEVEL
+
+ private <T extends ObjectMember> _Either<T, InteractionResponse> startChain(
+ final MemberType memberType,
+ final String memberId) {
+
+ val spec = managedObject.getSpecification();
+ val member = memberType.getMemberProvider().apply(spec, memberId);
+
+ if(!member.isPresent()) {
+ return _Either.right(InteractionResponse.failed(
+ Veto.NOT_FOUND,
+ notFound(memberType, memberId)));
+ }
+ return _Either.<T, InteractionResponse>left((T)member.get());
+ }
+
+ private <T extends ObjectMember> _Either<T, InteractionResponse> checkVisibility(
+ final _Either<T, InteractionResponse> chain,
+ final MemberType memberType,
+ final Where where) {
+
+ return chain.leftRemap(objectMember->{
+ val visibility = checkVisibility(memberType, objectMember, where);
+ if(visibility.isFailure()) {
+ return _Either.right(visibility);
+ }
+ return _Either.left(objectMember);
+
+ });
+ }
+
+ private <T extends ObjectMember> _Either<T, InteractionResponse> checkUsability(
+ final _Either<T, InteractionResponse> chain,
+ final Where where,
+ final AccessIntent accessIntent) {
+
+ return chain.leftRemap(objectMember->{
+ if(accessIntent.isMutate()) {
+ val usability = checkUsability(objectMember, where);
+ if(usability.isFailure()) {
+ return _Either.right(usability);
+ }
+ }
+ return _Either.left(objectMember);
+
+ });
+ }
+
+ // HELPER - LOWEST LEVEL
+
+ private <T extends ObjectMember> InteractionResponse checkVisibility(
+ final MemberType memberType,
+ final T objectMember,
+ final Where where) {
+
+ val visibilityConsent =
+ objectMember.isVisible(
+ managedObject, InteractionInitiatedBy.USER, where);
+ return visibilityConsent.isVetoed()
+ ? InteractionResponse.failed(
+ Veto.HIDDEN,
+ notFound(memberType, objectMember.getId()))
+ : InteractionResponse.success();
+ }
+
+ private <T extends ObjectMember> InteractionResponse checkUsability(
+ final T objectMember,
+ final Where where) {
+
+ val usabilityConsent =
+ objectMember.isUsable(
+ managedObject, InteractionInitiatedBy.USER, where);
+ return usabilityConsent.isVetoed()
+ ? InteractionResponse.failed(
+ Veto.FORBIDDEN,
+ usabilityConsent.getReason())
+ : InteractionResponse.success();
+ }
+
+ private <T extends ObjectMember> String notFound(
+ MemberType memberType,
+ String memberId) {
+ return String.format("%s '%s' either does not exist, is disabled or is not visible",
+ memberId,
+ memberType.name().toLowerCase());
+ }
+
+}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ObjectInteractor.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ObjectInteractor.java
deleted file mode 100644
index 60b5e89..0000000
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/ObjectInteractor.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * 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.viewer.common.model.binding.interaction;
-
-import java.util.Objects;
-import java.util.Optional;
-import java.util.stream.Stream;
-
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.feature.Contributed;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.isis.viewer.common.model.binding.UiComponentFactory;
-import org.apache.isis.viewer.common.model.binding.interaction.InteractionResponse.Veto;
-
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import lombok.val;
-
-@RequiredArgsConstructor(staticName = "bind")
-public class ObjectInteractor {
-
- public static enum AccessIntent {
- ACCESS, MUTATE;
-
- public boolean isMutate() {
- return this == MUTATE;
- }
- }
-
- @Getter
- private final ManagedObject managedObject;
-
- public String getTitle() {
- return managedObject.getSpecification().getTitle(null, managedObject);
- }
-
- public Stream<OneToOneAssociation> streamVisisbleProperties() {
- return managedObject.getSpecification()
- .streamAssociations(Contributed.INCLUDED)
- .filter(objMember->objMember.getFeatureType().isProperty())
- //TODO filter visibility
- .map(OneToOneAssociation.class::cast);
- }
-
- public Stream<OneToManyAssociation> streamVisisbleCollections() {
- return managedObject.getSpecification()
- .streamAssociations(Contributed.INCLUDED)
- .filter(objMember->objMember.getFeatureType().isCollection())
- //TODO filter visibility
- .map(OneToManyAssociation.class::cast);
- }
-
- public Stream<ObjectAction> streamVisisbleActions() {
- return managedObject.getSpecification()
- .streamObjectActions(Contributed.INCLUDED)
- .filter(objMember->objMember.getFeatureType().isAction())
- //TODO filter visibility
- .map(ObjectAction.class::cast);
- }
-
- public InteractionResponse modifyProperty(
- final OneToOneAssociation property,
- final ManagedObject proposedNewValue) {
-
- val consent = property.isAssociationValid(managedObject, proposedNewValue, InteractionInitiatedBy.USER);
- if (consent.isVetoed()) {
- return InteractionResponse.failed(Veto.UNAUTHORIZED, consent.getReason());
- }
-
- property.set(managedObject, proposedNewValue, InteractionInitiatedBy.USER);
-
- return InteractionResponse.success();
- }
-
- public UiComponentFactory.Request newUiComponentCreateRequest(
- final OneToOneAssociation property) {
-
- val propertyValue = Optional.ofNullable(property.get(managedObject))
- .orElse(ManagedObject.of(property.getSpecification(), null));
-
- return UiComponentFactory.Request
- .of(propertyValue, property, proposedNewValue -> {
-
- val iResponse = modifyProperty(property, proposedNewValue);
- if (iResponse.isFailure()) {
- return iResponse.getFailureMessage(); // validation result if any
- }
- return null;
-
- });
-
- }
-
- public Optional<ObjectAction> lookupAction(String id) {
- return streamVisisbleActions()
- .filter(action->Objects.equals(id, action.getId()))
- .findFirst();
- }
-
- public Optional<OneToOneAssociation> lookupProperty(String id) {
- return streamVisisbleProperties()
- .filter(property->Objects.equals(id, property.getId()))
- .findFirst();
- }
-
- public Optional<OneToManyAssociation> lookupCollection(String id) {
- return streamVisisbleCollections()
- .filter(collection->Objects.equals(id, collection.getId()))
- .findFirst();
- }
-
- public ActionInteractor getActionInteractor(
- String actionId, Where where, AccessIntent accessIntent) {
- return new ActionInteractor(this, actionId, where, accessIntent);
- }
-
- public PropertyInteractor getPropertyInteractor(
- String propertyId, Where where, AccessIntent accessIntent) {
- return new PropertyInteractor(this, propertyId, where, accessIntent);
- }
-
- public CollectionInteractor getCollectionInteractor(
- String collectionId, Where where, AccessIntent accessIntent) {
- return new CollectionInteractor(this, collectionId, where, accessIntent);
- }
-
-
-
-
-}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/PropertyBinding.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/PropertyBinding.java
new file mode 100644
index 0000000..690e8bb
--- /dev/null
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/PropertyBinding.java
@@ -0,0 +1,31 @@
+package org.apache.isis.viewer.common.model.binding.interaction;
+
+import java.util.Optional;
+import java.util.function.Function;
+
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+
+import lombok.NonNull;
+import lombok.val;
+
+public interface PropertyBinding {
+
+ ManagedObject getManagedObject();
+ OneToOneAssociation getProperty();
+
+ InteractionResponse modifyProperty(ManagedObject newProperyValue);
+
+ default InteractionResponse modifyProperty(
+ @NonNull final Function<OneToOneAssociation, ManagedObject> newProperyValueProvider) {
+ return modifyProperty(newProperyValueProvider.apply(getProperty()));
+ }
+
+ default ManagedObject getPropertyValue() {
+ val property = getProperty();
+
+ return Optional.ofNullable(property.get(getManagedObject()))
+ .orElse(ManagedObject.of(property.getSpecification(), null));
+ }
+
+}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/PropertyBindingEditable.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/PropertyBindingEditable.java
new file mode 100644
index 0000000..d7f54e1
--- /dev/null
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/PropertyBindingEditable.java
@@ -0,0 +1,37 @@
+package org.apache.isis.viewer.common.model.binding.interaction;
+
+import javax.annotation.Nullable;
+
+import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.viewer.common.model.binding.interaction.InteractionResponse.Veto;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.val;
+
+@RequiredArgsConstructor(staticName = "of")
+public class PropertyBindingEditable implements PropertyBinding {
+
+ @Getter(onMethod = @__(@Override))
+ private final ManagedObject managedObject;
+
+ @Getter(onMethod = @__(@Override))
+ private final OneToOneAssociation property;
+
+
+ @Override
+ public InteractionResponse modifyProperty(@Nullable ManagedObject proposedNewValue) {
+
+ val consent = property.isAssociationValid(getManagedObject(), proposedNewValue, InteractionInitiatedBy.USER);
+ if (consent.isVetoed()) {
+ return InteractionResponse.failed(Veto.UNAUTHORIZED, consent.getReason());
+ }
+
+ property.set(managedObject, proposedNewValue, InteractionInitiatedBy.USER);
+
+ return InteractionResponse.success();
+ }
+
+}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/PropertyBindingReadonly.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/PropertyBindingReadonly.java
new file mode 100644
index 0000000..3c8ed80
--- /dev/null
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/PropertyBindingReadonly.java
@@ -0,0 +1,27 @@
+package org.apache.isis.viewer.common.model.binding.interaction;
+
+import javax.annotation.Nullable;
+
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.viewer.common.model.binding.interaction.InteractionResponse.Veto;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor(staticName = "of")
+public class PropertyBindingReadonly implements PropertyBinding {
+
+ @Getter(onMethod = @__(@Override))
+ private final ManagedObject managedObject;
+
+ @Getter(onMethod = @__(@Override))
+ private final OneToOneAssociation property;
+
+ @Override
+ public InteractionResponse modifyProperty(@Nullable ManagedObject newProperyValue) {
+ // if this code is ever reached we have wired up something wrong internally
+ return InteractionResponse.failed(Veto.FORBIDDEN);
+ }
+
+}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/PropertyInteractor.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/PropertyInteractor.java
deleted file mode 100644
index 79627bd..0000000
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/PropertyInteractor.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.viewer.common.model.binding.interaction;
-
-import java.util.function.BiConsumer;
-import java.util.function.Function;
-
-import javax.annotation.Nullable;
-
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.core.commons.internal.base._Either;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.isis.viewer.common.model.binding.interaction.InteractionResponse.Veto;
-import org.apache.isis.viewer.common.model.binding.interaction.ObjectInteractor.AccessIntent;
-
-import lombok.val;
-
-public class PropertyInteractor extends MemberInteractor {
-
- private final String propertyId;
- private final Where where;
- private final AccessIntent accessIntent;
-
- public PropertyInteractor(
- final ObjectInteractor objectInteractor,
- final String propertyId,
- final Where where,
- final AccessIntent accessIntent) {
- super(objectInteractor);
- this.propertyId = propertyId;
- this.where = where;
- this.accessIntent = accessIntent;
- }
-
- public _Either<OneToOneAssociation, InteractionResponse> getPropertyThatIsVisibleForIntent() {
-
- val managedObject = objectInteractor.getManagedObject();
-
- val spec = managedObject.getSpecification();
- val property = spec.getAssociation(propertyId).orElse(null);
- if(property==null || !property.isOneToOneAssociation()) {
- return super.notFound(MemberType.PROPERTY, propertyId, Veto.NOT_FOUND);
- }
-
- return super.memberThatIsVisibleForIntent(
- MemberType.PROPERTY, (OneToOneAssociation)property, where, accessIntent);
- }
-
- public PropertyInteractor onFailure(@Nullable final BiConsumer<InteractionResponse, String> onFailure) {
- super.onFailure = onFailure;
- return this;
- }
-
- public InteractionResponse modifyProperty(Function<OneToOneAssociation, ManagedObject> newProperyValueProvider) {
-
- val check = getPropertyThatIsVisibleForIntent();
- if(check.isRight()) {
- return check.rightIfAny();
- }
-
- val property = check.leftIfAny();
- val proposedNewValue = newProperyValueProvider.apply(property);
-
- return objectInteractor.modifyProperty(property, proposedNewValue);
- }
-
-
-
-}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
index cc2748c..3179d0f 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
@@ -47,6 +47,7 @@ import org.apache.isis.applib.layout.grid.Grid;
import org.apache.isis.applib.layout.links.Link;
import org.apache.isis.applib.services.command.Command;
import org.apache.isis.core.commons.internal.base._Bytes;
+import org.apache.isis.core.commons.internal.base._Either;
import org.apache.isis.core.commons.internal.base._Strings;
import org.apache.isis.core.commons.internal.codec._UrlDecoderUtil;
import org.apache.isis.core.commons.internal.resources._Resources;
@@ -60,7 +61,7 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecId;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
import org.apache.isis.core.runtime.iactn.IsisInteractionTracker;
-import org.apache.isis.viewer.common.model.binding.interaction.ObjectInteractor;
+import org.apache.isis.viewer.common.model.binding.interaction.ObjectBinding;
import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.isis.viewer.restfulobjects.applib.Rel;
import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
@@ -450,21 +451,31 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
setCommandExecutor(Command.Executor.USER);
val objectAdapter = getObjectAdapterElseThrowNotFound(domainType, instanceId);
- val propertyInteractor = ObjectInteractor.bind(objectAdapter)
- .getPropertyInteractor(
- propertyId,
- resourceContext.getWhere(),
- ObjectInteractor.AccessIntent.MUTATE);
- propertyInteractor
- .onFailure(InteractionFailureHandler::onFailure)
- .modifyProperty(property->{
+ ObjectBinding.bind(objectAdapter)
+ .getPropertyBinding(
+ propertyId,
+ resourceContext.getWhere(),
+ ObjectBinding.AccessIntent.MUTATE)
+ .leftRemap(propertyBinding->{
- val proposedNewValue = new JsonParserHelper(resourceContext, property.getSpecification())
- .parseAsMapWithSingleValue(Util.asStringUtf8(body));
+ val iResponse = propertyBinding.modifyProperty(property->{
+
+ val proposedNewValue = new JsonParserHelper(resourceContext, property.getSpecification())
+ .parseAsMapWithSingleValue(Util.asStringUtf8(body));
+
+ return proposedNewValue;
+ });
- return proposedNewValue;
- });
+ if(iResponse.isFailure()) {
+ _Either.right(iResponse);
+ }
+
+ return _Either.left(propertyBinding);
+ })
+ .right()
+ .ifPresent(InteractionFailureHandler::onFailure);
+ ;
val domainResourceHelper = DomainResourceHelper.ofObjectResource(resourceContext, objectAdapter);
return domainResourceHelper.propertyDetails(
@@ -489,15 +500,27 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
setCommandExecutor(Command.Executor.USER);
val objectAdapter = getObjectAdapterElseThrowNotFound(domainType, instanceId);
- val propertyInteractor = ObjectInteractor.bind(objectAdapter)
- .getPropertyInteractor(
- propertyId,
- resourceContext.getWhere(),
- ObjectInteractor.AccessIntent.MUTATE);
- propertyInteractor
- .onFailure(InteractionFailureHandler::onFailure)
- .modifyProperty(property->null);
+ ObjectBinding.bind(objectAdapter)
+ .getPropertyBinding(
+ propertyId,
+ resourceContext.getWhere(),
+ ObjectBinding.AccessIntent.MUTATE)
+ .leftRemap(propertyBinding->{
+
+ val iResponse = propertyBinding.modifyProperty(property->{
+ return null;
+ });
+
+ if(iResponse.isFailure()) {
+ _Either.right(iResponse);
+ }
+
+ return _Either.left(propertyBinding);
+ })
+ .right()
+ .ifPresent(InteractionFailureHandler::onFailure);
+ ;
val domainResourceHelper = DomainResourceHelper.ofObjectResource(resourceContext, objectAdapter);
return domainResourceHelper.propertyDetails(
@@ -553,7 +576,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
final ObjectAdapterAccessHelper accessHelper = ObjectAdapterAccessHelper.of(resourceContext, objectAdapter);
final OneToManyAssociation collection = accessHelper.getCollectionThatIsVisibleForIntent(
- collectionId, ObjectInteractor.AccessIntent.MUTATE);
+ collectionId, ObjectBinding.AccessIntent.MUTATE);
if (!collection.getCollectionSemantics().isAnySet()) {
throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.BAD_REQUEST, "Collection '%s' does not have set semantics", collectionId);
@@ -592,7 +615,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
final ObjectAdapterAccessHelper accessHelper = ObjectAdapterAccessHelper.of(resourceContext, objectAdapter);
final OneToManyAssociation collection = accessHelper.getCollectionThatIsVisibleForIntent(
- collectionId, ObjectInteractor.AccessIntent.MUTATE);
+ collectionId, ObjectBinding.AccessIntent.MUTATE);
if (!collection.getCollectionSemantics().isListOrArray()) {
throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.METHOD_NOT_ALLOWED, "Collection '%s' does not have list or array semantics", collectionId);
@@ -631,7 +654,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
final ObjectAdapterAccessHelper accessHelper = ObjectAdapterAccessHelper.of(resourceContext, objectAdapter);
final OneToManyAssociation collection = accessHelper.getCollectionThatIsVisibleForIntent(
- collectionId, ObjectInteractor.AccessIntent.MUTATE);
+ collectionId, ObjectBinding.AccessIntent.MUTATE);
final ObjectSpecification collectionSpec = collection.getSpecification();
final ManagedObject argAdapter = new JsonParserHelper(resourceContext, collectionSpec)
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainResourceHelper.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainResourceHelper.java
index 279e5ab..56dee24 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainResourceHelper.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainResourceHelper.java
@@ -27,7 +27,7 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.isis.viewer.common.model.binding.interaction.ObjectInteractor;
+import org.apache.isis.viewer.common.model.binding.interaction.ObjectBinding;
import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.isis.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.isis.viewer.restfulobjects.rendering.IResourceContext;
@@ -109,7 +109,7 @@ class DomainResourceHelper {
ObjectAdapterAccessHelper accessHelper = ObjectAdapterAccessHelper.of(resourceContext, objectAdapter);
- final OneToOneAssociation property = accessHelper.getPropertyThatIsVisibleForIntent(propertyId, ObjectInteractor.AccessIntent.ACCESS);
+ final OneToOneAssociation property = accessHelper.getPropertyThatIsVisibleForIntent(propertyId, ObjectBinding.AccessIntent.ACCESS);
transactionService.flushTransaction();
return representationService.propertyDetails(resourceContext, new ObjectAndProperty2(objectAdapter, property, memberMode), memberMode);
@@ -127,7 +127,7 @@ class DomainResourceHelper {
ObjectAdapterAccessHelper accessHelper = ObjectAdapterAccessHelper.of(resourceContext, objectAdapter);
- final OneToManyAssociation collection = accessHelper.getCollectionThatIsVisibleForIntent(collectionId, ObjectInteractor.AccessIntent.ACCESS);
+ final OneToManyAssociation collection = accessHelper.getCollectionThatIsVisibleForIntent(collectionId, ObjectBinding.AccessIntent.ACCESS);
transactionService.flushTransaction();
return representationService.collectionDetails(resourceContext, new ObjectAndCollection2(objectAdapter, collection, memberMode), memberMode);
@@ -143,7 +143,7 @@ class DomainResourceHelper {
ObjectAdapterAccessHelper accessHelper = ObjectAdapterAccessHelper.of(resourceContext, objectAdapter);
- final ObjectAction action = accessHelper.getObjectActionThatIsVisibleForIntent(actionId, ObjectInteractor.AccessIntent.ACCESS);
+ final ObjectAction action = accessHelper.getObjectActionThatIsVisibleForIntent(actionId, ObjectBinding.AccessIntent.ACCESS);
transactionService.flushTransaction();
return representationService.actionPrompt(resourceContext, new ObjectAndAction(objectAdapter, action));
@@ -163,7 +163,7 @@ class DomainResourceHelper {
final ObjectAdapterAccessHelper accessHelper = ObjectAdapterAccessHelper.of(resourceContext, objectAdapter);
- final ObjectAction action = accessHelper.getObjectActionThatIsVisibleForIntent(actionId, ObjectInteractor.AccessIntent.MUTATE);
+ final ObjectAction action = accessHelper.getObjectActionThatIsVisibleForIntent(actionId, ObjectBinding.AccessIntent.MUTATE);
final SemanticsOf actionSemantics = action.getSemantics();
if (! actionSemantics.isSafeInNature()) {
@@ -187,7 +187,7 @@ class DomainResourceHelper {
final ObjectAdapterAccessHelper accessHelper = ObjectAdapterAccessHelper.of(resourceContext, objectAdapter);
- final ObjectAction action = accessHelper.getObjectActionThatIsVisibleForIntent(actionId, ObjectInteractor.AccessIntent.MUTATE);
+ final ObjectAction action = accessHelper.getObjectActionThatIsVisibleForIntent(actionId, ObjectBinding.AccessIntent.MUTATE);
final SemanticsOf actionSemantics = action.getSemantics();
if (!actionSemantics.isIdempotentInNature()) {
@@ -205,7 +205,7 @@ class DomainResourceHelper {
ObjectAdapterAccessHelper accessHelper = ObjectAdapterAccessHelper.of(resourceContext, objectAdapter);
- final ObjectAction action = accessHelper.getObjectActionThatIsVisibleForIntent(actionId, ObjectInteractor.AccessIntent.MUTATE);
+ final ObjectAction action = accessHelper.getObjectActionThatIsVisibleForIntent(actionId, ObjectBinding.AccessIntent.MUTATE);
return invokeActionUsingAdapters(action, arguments, ActionResultReprRenderer.SelfLink.EXCLUDED);
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/InteractionFailureHandler.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/InteractionFailureHandler.java
index 1fd0840..4251651 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/InteractionFailureHandler.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/InteractionFailureHandler.java
@@ -24,7 +24,7 @@ import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplication
public class InteractionFailureHandler {
- public static void onFailure(final InteractionResponse failure, final String memberId) {
+ public static void onFailure(final InteractionResponse failure) {
if(failure==null || failure.isSuccess()) {
return;
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectAdapterAccessHelper.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectAdapterAccessHelper.java
index c0fdeb6..cdfae79 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectAdapterAccessHelper.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectAdapterAccessHelper.java
@@ -23,8 +23,8 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.isis.viewer.common.model.binding.interaction.ObjectInteractor;
-import org.apache.isis.viewer.common.model.binding.interaction.ObjectInteractor.AccessIntent;
+import org.apache.isis.viewer.common.model.binding.interaction.ObjectBinding;
+import org.apache.isis.viewer.common.model.binding.interaction.ObjectBinding.AccessIntent;
import org.apache.isis.viewer.restfulobjects.rendering.IResourceContext;
import lombok.RequiredArgsConstructor;
@@ -41,47 +41,45 @@ public class ObjectAdapterAccessHelper {
final IResourceContext resourceContext,
final ManagedObject managedObject) {
return new ObjectAdapterAccessHelper(
- ObjectInteractor.bind(managedObject),
+ ObjectBinding.bind(managedObject),
resourceContext.getWhere());
}
- private final ObjectInteractor objectInteractor;
+ private final ObjectBinding objectInteractor;
private final Where where;
public OneToOneAssociation getPropertyThatIsVisibleForIntent(
final String propertyId, final AccessIntent intent) {
- val propertyInteractor = objectInteractor.getPropertyInteractor(propertyId, where, intent);
+ val propertyBindingOrFailure = objectInteractor.getPropertyBinding(propertyId, where, intent);
- val check = propertyInteractor.getPropertyThatIsVisibleForIntent();
- check.right()
- .ifPresent(failure->InteractionFailureHandler.onFailure(failure, propertyId));
+ propertyBindingOrFailure.right()
+ .ifPresent(InteractionFailureHandler::onFailure);
- return check.leftIfAny();
+ return propertyBindingOrFailure.leftIfAny().getProperty();
}
public OneToManyAssociation getCollectionThatIsVisibleForIntent(
final String collectionId, final AccessIntent intent) {
+
+ val collectionBindingOrFailure = objectInteractor.getCollectionBinding(collectionId, where, intent);
- val collectionInteractor = objectInteractor.getCollectionInteractor(collectionId, where, intent);
+ collectionBindingOrFailure.right()
+ .ifPresent(InteractionFailureHandler::onFailure);
- val check = collectionInteractor.getCollectionThatIsVisibleForIntent();
- check.right()
- .ifPresent(failure->InteractionFailureHandler.onFailure(failure, collectionId));
-
- return check.leftIfAny();
+ return collectionBindingOrFailure.leftIfAny().getCollection();
}
public ObjectAction getObjectActionThatIsVisibleForIntent(
final String actionId, final AccessIntent intent) {
+
+ val actionBindingOrFailure = objectInteractor.getActionBinding(actionId, where, intent);
- val actionInteractor = objectInteractor.getActionInteractor(actionId, where, intent);
+ actionBindingOrFailure.right()
+ .ifPresent(InteractionFailureHandler::onFailure);
- val check = actionInteractor.getActionThatIsVisibleForIntent();
- check.right()
- .ifPresent(failure->InteractionFailureHandler.onFailure(failure, actionId));
+ return actionBindingOrFailure.leftIfAny().getAction();
- return check.leftIfAny();
}