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 2e508c8143ff0c306a84c165b4f4bfdcb89e7ab6 Author: Andi Huber <ahu...@apache.org> AuthorDate: Fri Apr 24 08:11:22 2020 +0200 ISIS-2340: share logic of ObjectAdapterAccessHelper/UpdateHelper (4) --- .../binding/interaction/ActionInteractor.java | 29 +++++++++--- .../binding/interaction/CollectionInteractor.java | 29 +++++++++--- .../binding/interaction/MemberInteractor.java | 7 ++- .../binding/interaction/ObjectInteractor.java | 22 +++++---- .../binding/interaction/PropertyInteractor.java | 46 +++++++++++++++--- .../resources/DomainObjectResourceServerside.java | 55 ++++++++++------------ .../resources/InteractionFailureHandler.java | 47 ++++++++++++++++++ .../resources/ObjectAdapterAccessHelper.java | 36 ++++---------- 8 files changed, 185 insertions(+), 86 deletions(-) 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 index 60f5ae4..3a825cc 100644 --- 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 @@ -18,6 +18,10 @@ */ 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; @@ -28,14 +32,22 @@ import lombok.val; public class ActionInteractor extends MemberInteractor { - public ActionInteractor(ObjectInteractor objectInteractor) { + 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( - final String actionId, - final Where where, - final AccessIntent intent) { + public _Either<ObjectAction, InteractionResponse> getActionThatIsVisibleForIntent() { val managedObject = objectInteractor.getManagedObject(); @@ -48,7 +60,12 @@ public class ActionInteractor extends MemberInteractor { return super.memberThatIsVisibleForIntent( MemberType.ACTION, - action, where, intent); + 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/CollectionInteractor.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/CollectionInteractor.java index b30f0a8..488a129 100644 --- 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 @@ -18,6 +18,10 @@ */ 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; @@ -28,14 +32,22 @@ import lombok.val; public class CollectionInteractor extends MemberInteractor { - public CollectionInteractor(ObjectInteractor objectInteractor) { + 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> getPropertyThatIsVisibleForIntent( - final String collectionId, - final Where where, - final AccessIntent intent) { + public _Either<OneToManyAssociation, InteractionResponse> getCollectionThatIsVisibleForIntent() { val managedObject = objectInteractor.getManagedObject(); @@ -47,7 +59,12 @@ public class CollectionInteractor extends MemberInteractor { return super.memberThatIsVisibleForIntent( MemberType.COLLECTION, - (OneToManyAssociation) collection, where, intent); + (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 index 7651891..3177440 100644 --- 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 @@ -18,9 +18,10 @@ */ 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.Consent; 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; @@ -40,6 +41,7 @@ class MemberInteractor { } protected final ObjectInteractor objectInteractor; + protected BiConsumer<InteractionResponse, String> onFailure; protected <T extends ObjectMember> _Either<T, InteractionResponse> memberThatIsVisibleForIntent( @@ -57,7 +59,8 @@ class MemberInteractor { return notFound(memberType, memberId, Veto.HIDDEN); } if (intent.isMutate()) { - final Consent usabilityConsent = objectMember.isUsable( + val usabilityConsent = + objectMember.isUsable( managedObject, InteractionInitiatedBy.USER, where); if (usabilityConsent.isVetoed()) { return _Either.right(InteractionResponse.failed( 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 index 105a4db..60b5e89 100644 --- 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 @@ -22,6 +22,7 @@ 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; @@ -128,21 +129,22 @@ public class ObjectInteractor { .findFirst(); } - public MemberInteractor getMemberInteractor() { - return new MemberInteractor(this); - } - - public ActionInteractor getActionInteractor() { - return new ActionInteractor(this); + public ActionInteractor getActionInteractor( + String actionId, Where where, AccessIntent accessIntent) { + return new ActionInteractor(this, actionId, where, accessIntent); } - public PropertyInteractor getPropertyInteractor() { - return new PropertyInteractor(this); + public PropertyInteractor getPropertyInteractor( + String propertyId, Where where, AccessIntent accessIntent) { + return new PropertyInteractor(this, propertyId, where, accessIntent); } - public CollectionInteractor getCollectionInteractor() { - return new CollectionInteractor(this); + 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/PropertyInteractor.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/interaction/PropertyInteractor.java index 853be97..79627bd 100644 --- 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 @@ -18,8 +18,14 @@ */ 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; @@ -28,14 +34,22 @@ import lombok.val; public class PropertyInteractor extends MemberInteractor { - public PropertyInteractor(ObjectInteractor objectInteractor) { + 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( - final String propertyId, - final Where where, - final AccessIntent intent) { + public _Either<OneToOneAssociation, InteractionResponse> getPropertyThatIsVisibleForIntent() { val managedObject = objectInteractor.getManagedObject(); @@ -46,7 +60,27 @@ public class PropertyInteractor extends MemberInteractor { } return super.memberThatIsVisibleForIntent( - MemberType.PROPERTY, (OneToOneAssociation)property, where, intent); + 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 daf605e..cc2748c 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 @@ -450,24 +450,23 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements setCommandExecutor(Command.Executor.USER); val objectAdapter = getObjectAdapterElseThrowNotFound(domainType, instanceId); - val domainResourceHelper = DomainResourceHelper.ofObjectResource(resourceContext, objectAdapter); - val accessHelper = ObjectAdapterAccessHelper.of(resourceContext, objectAdapter); - - val property = accessHelper.getPropertyThatIsVisibleForIntent(propertyId, - ObjectInteractor.AccessIntent.MUTATE); - - val proposedNewValue = new JsonParserHelper(resourceContext, property.getSpecification()) - .parseAsMapWithSingleValue(Util.asStringUtf8(body)); - - val objectInteractor = ObjectInteractor.bind(objectAdapter); + val propertyInteractor = ObjectInteractor.bind(objectAdapter) + .getPropertyInteractor( + propertyId, + resourceContext.getWhere(), + ObjectInteractor.AccessIntent.MUTATE); - - val iResponse = objectInteractor.modifyProperty(property, proposedNewValue); - if (iResponse.isFailure()) { - throw RestfulObjectsApplicationException - .createWithMessage(HttpStatusCode.UNAUTHORIZED, iResponse.getFailureMessage()); - } + propertyInteractor + .onFailure(InteractionFailureHandler::onFailure) + .modifyProperty(property->{ + + val proposedNewValue = new JsonParserHelper(resourceContext, property.getSpecification()) + .parseAsMapWithSingleValue(Util.asStringUtf8(body)); + + return proposedNewValue; + }); + val domainResourceHelper = DomainResourceHelper.ofObjectResource(resourceContext, objectAdapter); return domainResourceHelper.propertyDetails( propertyId, MemberReprMode.WRITE @@ -488,21 +487,19 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements ResourceDescriptor.generic(Where.OBJECT_FORMS, RepresentationService.Intent.NOT_APPLICABLE)); setCommandExecutor(Command.Executor.USER); - + val objectAdapter = getObjectAdapterElseThrowNotFound(domainType, instanceId); - val domainResourceHelper = DomainResourceHelper.ofObjectResource(resourceContext, objectAdapter); - val accessHelper = ObjectAdapterAccessHelper.of(resourceContext, objectAdapter); - - val property = accessHelper.getPropertyThatIsVisibleForIntent( - propertyId, ObjectInteractor.AccessIntent.MUTATE); - - val objectInteractor = ObjectInteractor.bind(objectAdapter); - val iResponse = objectInteractor.modifyProperty(property, null); - if (iResponse.isFailure()) { - throw RestfulObjectsApplicationException - .createWithMessage(HttpStatusCode.UNAUTHORIZED, iResponse.getFailureMessage()); - } + val propertyInteractor = ObjectInteractor.bind(objectAdapter) + .getPropertyInteractor( + propertyId, + resourceContext.getWhere(), + ObjectInteractor.AccessIntent.MUTATE); + + propertyInteractor + .onFailure(InteractionFailureHandler::onFailure) + .modifyProperty(property->null); + val domainResourceHelper = DomainResourceHelper.ofObjectResource(resourceContext, objectAdapter); return domainResourceHelper.propertyDetails( propertyId, MemberReprMode.WRITE 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 new file mode 100644 index 0000000..1fd0840 --- /dev/null +++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/InteractionFailureHandler.java @@ -0,0 +1,47 @@ +/* + * 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.restfulobjects.viewer.resources; + +import org.apache.isis.viewer.common.model.binding.interaction.InteractionResponse; +import org.apache.isis.viewer.restfulobjects.applib.RestfulResponse; +import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException; + +public class InteractionFailureHandler { + + public static void onFailure(final InteractionResponse failure, final String memberId) { + + if(failure==null || failure.isSuccess()) { + return; + } + + switch(failure.getVeto()) { + case NOT_FOUND: + case HIDDEN: + throw RestfulObjectsApplicationException + .createWithMessage(RestfulResponse.HttpStatusCode.NOT_FOUND, + failure.getFailureMessage()); + case UNAUTHORIZED: + case FORBIDDEN: + throw RestfulObjectsApplicationException + .createWithMessage(RestfulResponse.HttpStatusCode.FORBIDDEN, + failure.getFailureMessage()); + } + } + +} 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 e77e859..c0fdeb6 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,13 +23,9 @@ 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.InteractionResponse; 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.restfulobjects.applib.RestfulResponse; import org.apache.isis.viewer.restfulobjects.rendering.IResourceContext; -import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException; -import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.MemberType; import lombok.RequiredArgsConstructor; import lombok.val; @@ -55,11 +51,11 @@ public class ObjectAdapterAccessHelper { public OneToOneAssociation getPropertyThatIsVisibleForIntent( final String propertyId, final AccessIntent intent) { - val propertyInteractor = objectInteractor.getPropertyInteractor(); + val propertyInteractor = objectInteractor.getPropertyInteractor(propertyId, where, intent); - val check = propertyInteractor.getPropertyThatIsVisibleForIntent(propertyId, where, intent); + val check = propertyInteractor.getPropertyThatIsVisibleForIntent(); check.right() - .ifPresent(failure->handleFailure(failure, propertyId, MemberType.PROPERTY)); + .ifPresent(failure->InteractionFailureHandler.onFailure(failure, propertyId)); return check.leftIfAny(); } @@ -67,11 +63,11 @@ public class ObjectAdapterAccessHelper { public OneToManyAssociation getCollectionThatIsVisibleForIntent( final String collectionId, final AccessIntent intent) { - val propertyInteractor = objectInteractor.getCollectionInteractor(); + val collectionInteractor = objectInteractor.getCollectionInteractor(collectionId, where, intent); - val check = propertyInteractor.getPropertyThatIsVisibleForIntent(collectionId, where, intent); + val check = collectionInteractor.getCollectionThatIsVisibleForIntent(); check.right() - .ifPresent(failure->handleFailure(failure, collectionId, MemberType.COLLECTION)); + .ifPresent(failure->InteractionFailureHandler.onFailure(failure, collectionId)); return check.leftIfAny(); } @@ -79,28 +75,14 @@ public class ObjectAdapterAccessHelper { public ObjectAction getObjectActionThatIsVisibleForIntent( final String actionId, final AccessIntent intent) { - val actionInteractor = objectInteractor.getActionInteractor(); + val actionInteractor = objectInteractor.getActionInteractor(actionId, where, intent); - val check = actionInteractor.getActionThatIsVisibleForIntent(actionId, where, intent); + val check = actionInteractor.getActionThatIsVisibleForIntent(); check.right() - .ifPresent(failure->handleFailure(failure, actionId, MemberType.ACTION)); + .ifPresent(failure->InteractionFailureHandler.onFailure(failure, actionId)); return check.leftIfAny(); } - private void handleFailure(final InteractionResponse failure, String memberId, MemberType memberType) { - switch(failure.getVeto()) { - case NOT_FOUND: - case HIDDEN: - throw RestfulObjectsApplicationException - .createWithMessage(RestfulResponse.HttpStatusCode.NOT_FOUND, - failure.getFailureMessage()); - case UNAUTHORIZED: - case FORBIDDEN: - throw RestfulObjectsApplicationException - .createWithMessage(RestfulResponse.HttpStatusCode.FORBIDDEN, - failure.getFailureMessage()); - } - } }