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/05/27 08:32:46 UTC

[isis] branch master updated: ISIS-2340: simplify and fix parented collections (Vaadin)

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 de85e7d  ISIS-2340: simplify and fix parented collections (Vaadin)
de85e7d is described below

commit de85e7d63a38c90a4651736ddb4cf28d9f445ecf
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed May 27 10:32:32 2020 +0200

    ISIS-2340: simplify and fix parented collections (Vaadin)
---
 .../interactions/managed/ManagedCollection.java    | 36 ++++++++-
 .../vaadin/ui/components/collection/TableView.java | 21 ++---
 .../ui/components/object/ObjectFormView.java       | 26 +------
 .../common/model/binding/UiComponentFactory.java   |  5 +-
 .../ContentNegotiationServiceOrgApacheIsisV1.java  | 91 +++++++++-------------
 5 files changed, 80 insertions(+), 99 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedCollection.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedCollection.java
index 51f2305..ef0f7f7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedCollection.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedCollection.java
@@ -19,8 +19,12 @@
 package org.apache.isis.core.metamodel.interactions.managed;
 
 import java.util.Optional;
+import java.util.stream.Stream;
 
+import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
+import org.apache.isis.core.metamodel.facets.collections.CollectionFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 
 import lombok.Getter;
@@ -66,12 +70,36 @@ public final class ManagedCollection extends ManagedMember {
     public MemberType getMemberType() {
         return MemberType.COLLECTION;
     }
+    
+    public ObjectSpecification getElementSpecification() {
+        return getCollection().getSpecification();
+    }
 
     public ManagedObject getCollectionValue() {
-        val collection = getCollection();
-        
-        return Optional.ofNullable(collection.get(getOwner()))
-        .orElse(ManagedObject.of(collection.getSpecification(), null));
+        return Optional.ofNullable(getCollection().get(getOwner(), InteractionInitiatedBy.USER))
+                .orElse(ManagedObject.empty(getElementSpecification()));
+    }
+
+    // -- INTERACTION
+    
+    /**
+     * If visibility is vetoed, returns an empty Stream.
+     * @param interactionInitiatedBy 
+     * @return Stream of this collection's element values as to be used by the UI for representation
+     */
+    public Stream<ManagedObject> streamElements(InteractionInitiatedBy interactionInitiatedBy) {
+        val valueAdapter = getCollection().get(getOwner(), interactionInitiatedBy);
+        return CollectionFacet.streamAdapters(valueAdapter);
+    }
+
+    /**
+     * If visibility is vetoed, returns an empty Stream.
+     * @return Stream of this collection's element values as to be used by the UI for representation
+     */
+    public Stream<ManagedObject> streamElements() {
+        return streamElements(InteractionInitiatedBy.USER);
     }
 
+    
+
 }
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/collection/TableView.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/collection/TableView.java
index e824a79..a801d48 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/collection/TableView.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/collection/TableView.java
@@ -77,21 +77,12 @@ public class TableView extends VerticalLayout {
      */
     public static Component fromManagedCollection(ManagedCollection managedCollection) {
         
-        val assocObject = managedCollection.getOwner();
-        val assocObjectSpecification = assocObject.getSpecification();
-        val collectionFacet = assocObjectSpecification.getFacet(CollectionFacet.class);
-
-        val pojo = assocObject.getPojo();
-        if (pojo instanceof Collection) {
-            val objects = collectionFacet.stream(assocObject)
-                    .collect(Collectors.toList());
-            
-            return inferElementSpecification(objects)
-            .map(elementSpec->new TableView(elementSpec, objects))
-            .orElseGet(TableView::empty);
-        }
-        
-        return empty();
+        val elementSpec = managedCollection.getElementSpecification(); 
+        val elements = managedCollection.streamElements()
+                .collect(Collectors.toList());
+        return elements.isEmpty()
+                ? empty()
+                : new TableView(elementSpec, elements);
     }
     
     
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 37e2957..e5c4322 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
@@ -213,7 +213,7 @@ public class ObjectFormView extends VerticalLayout {
                 .ifPresent(managedCollection -> {
                     container.add(new H3(managedCollection.getName()));
                     
-                    val uiCollection = createCollectionComponent(managedCollection);
+                    val uiCollection = TableView.fromManagedCollection(managedCollection);
                     container.add(uiCollection);
                 });
                 
@@ -255,30 +255,6 @@ public class ObjectFormView extends VerticalLayout {
 
     }
 
-    // -- HELPER
-
-    private Component createCollectionComponent(
-            final ManagedCollection managedCollection) {
-
-        val labelLiteral = "Collection: " + managedCollection.getName();
-        val pojo = managedCollection.getCollectionValue().getPojo();
-        if (pojo instanceof Collection) {
-            return TableView.fromManagedCollection(managedCollection);
-        }
-
-        if (pojo == null) {
-            val textField = new TextField();
-            textField.setLabel(labelLiteral);
-
-            textField.setValue(NULL_LITERAL);
-            return textField;
-        }
-
-        val textField = new TextField();
-        textField.setLabel(labelLiteral);
-        textField.setValue("Unknown collection type: " + pojo.getClass());
-        return textField;
-    }
 
 
 }
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 6510071..52cb9ce 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
@@ -25,6 +25,7 @@ import javax.annotation.Nullable;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.core.commons.handler.ChainOfResponsibility;
 import org.apache.isis.core.commons.internal.exceptions._Exceptions;
+import org.apache.isis.core.commons.internal.functions._Predicates;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.interactions.managed.InteractionVeto;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedMember;
@@ -114,7 +115,9 @@ public interface UiComponentFactory<T> {
             val managedProperty = (ManagedProperty)getObjectFeature();
             //TODO do a type check before the cast, so we can throw a more detailed exception
             // that is, given type must be assignable from the actual pojo type 
-            return Optional.ofNullable(managedProperty.getPropertyValue(where).getPojo())
+            return Optional.ofNullable(managedProperty.getPropertyValue(where))
+                    .filter(_Predicates.not(ManagedObject::isNullOrUnspecifiedOrEmpty))
+                    .map(ManagedObject::getPojo)
                     .map(type::cast);
         }
 
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV1.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV1.java
index f18ae75..9f199f9 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV1.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV1.java
@@ -31,17 +31,14 @@ import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
-import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.client.SuppressionType;
 import org.apache.isis.core.metamodel.consent.Consent;
-import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.facets.collections.CollectionFacet;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedCollection;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedProperty;
 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.OneToManyAssociation;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
@@ -159,7 +156,7 @@ public class ContentNegotiationServiceOrgApacheIsisV1 extends ContentNegotiation
     @Override
     public Response.ResponseBuilder buildResponse(
             final IResourceContext resourceContext,
-            final ManagedCollection objectAndCollection) {
+            final ManagedCollection managedCollection) {
 
         if(!canAccept(resourceContext)) {
             return null;
@@ -169,10 +166,7 @@ public class ContentNegotiationServiceOrgApacheIsisV1 extends ContentNegotiation
 
         final JsonRepresentation rootRepresentation = JsonRepresentation.newArray();
 
-        ManagedObject objectAdapter = objectAndCollection.getOwner();
-        OneToManyAssociation collection = objectAndCollection.getMember();
-
-        appendCollectionTo(resourceContext, objectAdapter, collection, rootRepresentation, suppression);
+        appendCollectionTo(resourceContext, managedCollection, rootRepresentation, suppression);
 
         final JsonRepresentation $$roRepresentation;
         if(!suppressRO) {
@@ -188,7 +182,7 @@ public class ContentNegotiationServiceOrgApacheIsisV1 extends ContentNegotiation
 
         final Response.ResponseBuilder responseBuilder =
                 restfulObjectsV1_0.buildResponseTo(
-                        resourceContext, objectAndCollection, $$roRepresentation, rootRepresentation);
+                        resourceContext, managedCollection, $$roRepresentation, rootRepresentation);
 
         responseBuilder.type(CONTENT_TYPE_OAI_V1_OBJECT_COLLECTION);
 
@@ -225,7 +219,7 @@ public class ContentNegotiationServiceOrgApacheIsisV1 extends ContentNegotiation
         final EnumSet<SuppressionType> suppression = suppress(resourceContext);
         final boolean suppressRO = suppression.contains(SuppressionType.RO);
 
-        JsonRepresentation rootRepresentation = null;
+        final JsonRepresentation rootRepresentation;
         final JsonRepresentation $$roRepresentation;
         if(!suppressRO) {
             $$roRepresentation = JsonRepresentation.newMap();
@@ -252,13 +246,10 @@ public class ContentNegotiationServiceOrgApacheIsisV1 extends ContentNegotiation
         case LIST:
 
             rootRepresentation = JsonRepresentation.newArray();
-
-            //final CollectionFacet collectionFacet = returnType.getFacet(CollectionFacet.class);
-
-            final Stream<ManagedObject> collectionAdapters = 
-                    CollectionFacet.streamAdapters(returnedAdapter);
-
-            appendStreamTo(resourceContext, collectionAdapters, rootRepresentation, suppression);
+            
+            CollectionFacet.streamAdapters(returnedAdapter)
+            .forEach(element->
+                appendElementTo(resourceContext, element, rootRepresentation, suppression));
 
             // $$ro representation will be an object in the list with a single property named "$$ro"
             if(!suppressRO) {
@@ -274,6 +265,8 @@ public class ContentNegotiationServiceOrgApacheIsisV1 extends ContentNegotiation
 
             // not supported
             return null;
+        default:
+            rootRepresentation = null; // unexpected code reach
         }
 
         final Response.ResponseBuilder responseBuilder =
@@ -310,28 +303,31 @@ public class ContentNegotiationServiceOrgApacheIsisV1 extends ContentNegotiation
 
     private void appendObjectTo(
             final IResourceContext resourceContext,
-            final ManagedObject objectAdapter,
+            final ManagedObject owner,
             final JsonRepresentation rootRepresentation,
             final EnumSet<SuppressionType> suppression) {
 
-        appendPropertiesTo(resourceContext, objectAdapter, rootRepresentation, suppression);
-
-        final Where where = resourceContext.getWhere();
-        final Stream<OneToManyAssociation> collections = objectAdapter.getSpecification()
-                .streamCollections(Contributed.INCLUDED);
-
-        collections.forEach(collection->{
-            final JsonRepresentation collectionRepresentation = JsonRepresentation.newArray();
+        appendPropertiesTo(resourceContext, owner, rootRepresentation, suppression);
 
+        val where = resourceContext.getWhere();
+        
+        owner.getSpecification()
+        .streamCollections(Contributed.INCLUDED)
+        .forEach(collection->{
+            
+            val collectionRepresentation = JsonRepresentation.newArray();
             rootRepresentation.mapPut(collection.getId(), collectionRepresentation);
 
-            final InteractionInitiatedBy interactionInitiatedBy = determineInteractionInitiatedByFrom(resourceContext);
-            final Consent visibility = collection.isVisible(objectAdapter, interactionInitiatedBy, where);
-            if (!visibility.isAllowed()) {
+            val interactionInitiatedBy = resourceContext.getInteractionInitiatedBy();
+            val visibilityConsent = collection.isVisible(owner, interactionInitiatedBy, where);
+            if (!visibilityConsent.isAllowed()) {
                 return;
             }
 
-            appendCollectionTo(resourceContext, objectAdapter, collection, collectionRepresentation, suppression);
+            val managedCollection = ManagedCollection.of(owner, collection);
+            
+
+            appendCollectionTo(resourceContext, managedCollection, collectionRepresentation, suppression);
         });
 
     }
@@ -342,8 +338,8 @@ public class ContentNegotiationServiceOrgApacheIsisV1 extends ContentNegotiation
             final JsonRepresentation rootRepresentation,
             final EnumSet<SuppressionType> suppression) {
         
-        final InteractionInitiatedBy interactionInitiatedBy = determineInteractionInitiatedByFrom(resourceContext);
-        final Where where = resourceContext.getWhere();
+        val interactionInitiatedBy = resourceContext.getInteractionInitiatedBy();
+        val where = resourceContext.getWhere();
         final Stream<OneToOneAssociation> properties = objectAdapter.getSpecification()
                 .streamProperties(Contributed.INCLUDED);
 
@@ -394,38 +390,25 @@ public class ContentNegotiationServiceOrgApacheIsisV1 extends ContentNegotiation
 
     private void appendCollectionTo(
             final IResourceContext resourceContext,
-            final ManagedObject objectAdapter,
-            final OneToManyAssociation collection,
+            final ManagedCollection managedCollection,
             final JsonRepresentation representation, 
             final EnumSet<SuppressionType> suppression) {
 
-        val interactionInitiatedBy = determineInteractionInitiatedByFrom(resourceContext);
-        val valueAdapter = collection.get(objectAdapter, interactionInitiatedBy);
-        if (valueAdapter == null) {
-            return;
-        }
-
-        final Stream<ManagedObject> adapters = CollectionFacet.streamAdapters(valueAdapter);
-        appendStreamTo(resourceContext, adapters, representation, suppression);
+        managedCollection.streamElements(resourceContext.getInteractionInitiatedBy())
+        .forEach(element->
+            appendElementTo(resourceContext, element, representation, suppression));
     }
 
-    private void appendStreamTo(
+    private void appendElementTo(
             final IResourceContext resourceContext,
-            final Stream<ManagedObject> adapters,
+            final ManagedObject elementAdapter,
             final JsonRepresentation collectionRepresentation, 
             final EnumSet<SuppressionType> suppression) {
 
-        adapters.forEach(elementAdapter->{
-            JsonRepresentation elementRepresentation = JsonRepresentation.newMap();
-            appendPropertiesTo(resourceContext, elementAdapter, elementRepresentation, suppression);
-
-            collectionRepresentation.arrayAdd(elementRepresentation);
-        });
+        val elementRepresentation = JsonRepresentation.newMap();
+        appendPropertiesTo(resourceContext, elementAdapter, elementRepresentation, suppression);
+        collectionRepresentation.arrayAdd(elementRepresentation);
     }
 
-    private static InteractionInitiatedBy determineInteractionInitiatedByFrom(
-            final IResourceContext resourceContext) {
-        return resourceContext.getInteractionInitiatedBy();
-    }
 
 }