This is an automated email from the ASF dual-hosted git repository.

jdoornenbal pushed a commit to branch ISIS-2947
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/ISIS-2947 by this push:
     new 48f38e5e0c adds data fetcher for mutator (action) on domain object; 
w.i.p.
48f38e5e0c is described below

commit 48f38e5e0c88b7eaee7c71341859e7a4185bf1ae
Author: Johan Doornenbal <[email protected]>
AuthorDate: Fri May 20 15:43:16 2022 +0200

    adds data fetcher for mutator (action) on domain object; w.i.p.
---
 .../graphql/viewer/source/ObjectTypeFactory.java   | 212 +++++++++++++--------
 .../EndToEnd_IntegTest.changeName.approved.gql     |  15 +-
 .../EndToEnd_IntegTest.changeName.submit.gql       |   6 +-
 .../graphql/viewer/source/EndToEnd_IntegTest.java  |   7 +-
 4 files changed, 151 insertions(+), 89 deletions(-)

diff --git 
a/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/ObjectTypeFactory.java
 
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/ObjectTypeFactory.java
index d5ca5fb8e6..5a3270e9b5 100644
--- 
a/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/ObjectTypeFactory.java
+++ 
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/ObjectTypeFactory.java
@@ -18,13 +18,16 @@
  */
 package org.apache.isis.viewer.graphql.viewer.source;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 
 import javax.inject.Inject;
 
+import org.apache.isis.commons.collections.Can;
+import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
+import 
org.apache.isis.core.metamodel.interactions.managed.ActionInteractionHead;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
 import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.services.bookmark.Bookmark;
@@ -105,10 +108,10 @@ public class ObjectTypeFactory {
         String inputTypeName = _Utils.GQL_INPUTTYPE_PREFIX + 
logicalTypeNameSanitized;
         GraphQLInputObjectType.Builder inputTypeBuilder = 
newInputObject().name(inputTypeName);
         inputTypeBuilder
-            .field(GraphQLInputObjectField.newInputObjectField()
-                .name("id")
-                .type(nonNull(Scalars.GraphQLID))
-                .build());
+                .field(GraphQLInputObjectField.newInputObjectField()
+                        .name("id")
+                        .type(nonNull(Scalars.GraphQLID))
+                        .build());
         GraphQLInputType inputType = inputTypeBuilder.build();
         addTypeIfNotAlreadyPresent(graphQLObjectTypes, inputType, 
inputTypeName);
 
@@ -129,7 +132,7 @@ public class ObjectTypeFactory {
         // create and register data fetchers
         createAndRegisterDataFetchersForMetaData(
                 codeRegistryBuilder, objectSpecificationBeanSort, metaType, 
gql_meta, graphQLObjectType);
-        if (mutatorsDataForEntity!=null) 
createAndRegisterDataFetchersForMutators(
+        if (mutatorsDataForEntity != null) 
createAndRegisterDataFetchersForMutators(
                 codeRegistryBuilder, objectSpecificationBeanSort, 
mutatorsDataForEntity, graphQLObjectType);
         createAndRegisterDataFetchersForField(objectSpecification, 
codeRegistryBuilder, graphQLObjectType);
         createAndRegisterDataFetchersForCollection(objectSpecification, 
codeRegistryBuilder, graphQLObjectType);
@@ -143,7 +146,75 @@ public class ObjectTypeFactory {
             final MutatorsDataForEntity mutatorsDataForEntity,
             final GraphQLObjectType graphQLObjectType) {
 
+        List<String> mutatorsTypeFields = 
mutatorsDataForEntity.getMutatorsTypeFields().stream().map(f -> 
f.getName()).collect(Collectors.toList());
 
+        
codeRegistryBuilder.dataFetcher(FieldCoordinates.coordinates(graphQLObjectType, 
_Utils.GQL_MUTATTIONS_FIELDNAME), new DataFetcher<Object>() {
+
+            @Override
+            public Object get(DataFetchingEnvironment environment) throws 
Exception {
+
+                Bookmark bookmark = 
bookmarkService.bookmarkFor(environment.getSource()).orElse(null);
+                if (bookmark == null) return null;
+                return new GQLMutations(bookmark, bookmarkService, 
mutatorsTypeFields);
+
+            }
+
+        });
+
+        GraphQLObjectType mutatorsType = 
mutatorsDataForEntity.getMutatorsType();
+        ObjectSpecification objectSpecification = 
mutatorsDataForEntity.getObjectSpecification();
+        mutatorsDataForEntity.getMutatorsTypeFields().forEach(
+                mf -> {
+                    Optional<ObjectAction> action = 
objectSpecification.getAction(mf.getName());
+                    if (action.isPresent()) {
+                        ObjectAction objectAction = action.get();
+                        codeRegistryBuilder
+                                .dataFetcher(
+                                        
FieldCoordinates.coordinates(mutatorsType, mf.getName()),
+                                        new DataFetcher<Object>() {
+
+                                            @Override
+                                            public Object get(final 
DataFetchingEnvironment dataFetchingEnvironment) throws Exception {
+
+                                                GQLMutations gqlMutations = 
dataFetchingEnvironment.getSource();
+
+                                                Optional<Object> 
optionalDomainObject = bookmarkService.lookup(gqlMutations.getBookmark());
+
+                                                if 
(!optionalDomainObject.isPresent()) return null;
+                                                Object domainObject = 
optionalDomainObject.get();
+
+                                                Class<?> 
domainObjectInstanceClass = domainObject.getClass();
+                                                ObjectSpecification 
specification = specificationLoader
+                                                        
.loadSpecification(domainObjectInstanceClass);
+
+                                                ManagedObject owner = 
ManagedObject.of(specification, domainObject);
+
+                                                ActionInteractionHead 
actionInteractionHead = objectAction.interactionHead(owner);
+
+                                                Map<String, Object> arguments 
= dataFetchingEnvironment.getArguments();
+                                                Can<ObjectActionParameter> 
parameters = objectAction.getParameters();
+                                                Can<ManagedObject> canOfParams 
= parameters.stream().map(oap -> {
+                                                    Object argumentValue = 
arguments.get(oap.getId());
+                                                    ObjectSpecification 
elementType = oap.getElementType();
+
+                                                    if (argumentValue == null)
+                                                        return 
ManagedObject.empty(elementType);
+                                                    return 
ManagedObject.of(elementType, argumentValue);
+
+
+                                                }).collect(Can.toCan());
+
+                                                ManagedObject managedObject = 
objectAction
+                                                        
.execute(actionInteractionHead, canOfParams, InteractionInitiatedBy.USER);
+
+                                                return managedObject.getPojo();
+                                            }
+
+                                        });
+
+                    }
+                }
+        );
 
 
     }
@@ -151,10 +222,10 @@ public class ObjectTypeFactory {
     void addTypeIfNotAlreadyPresent(
             final Set<GraphQLType> graphQLObjectTypes,
             final GraphQLType typeToAdd,
-            final String logicalTypeName){
+            final String logicalTypeName) {
 
         boolean present;
-        if (typeToAdd.getClass().isAssignableFrom(GraphQLObjectType.class)){
+        if (typeToAdd.getClass().isAssignableFrom(GraphQLObjectType.class)) {
             GraphQLObjectType typeToAdd1 = (GraphQLObjectType) typeToAdd;
             present = graphQLObjectTypes.stream()
                     .filter(o -> 
o.getClass().isAssignableFrom(GraphQLObjectType.class))
@@ -170,7 +241,7 @@ public class ObjectTypeFactory {
                     .filter(ot -> ot.getName().equals(typeToAdd1.getName()))
                     .findFirst().isPresent();
         }
-        if (present){
+        if (present) {
             // For now we just log and skip
             System.out.println("==== DOUBLE ====");
             System.out.println(logicalTypeName);
@@ -185,43 +256,43 @@ public class ObjectTypeFactory {
             final GraphQLObjectType.Builder objectTypeBuilder) {
 
         objectSpecification.streamProperties(MixedIn.INCLUDED)
-        .forEach(otoa -> {
+                .forEach(otoa -> {
 
-            ObjectSpecification fieldObjectSpecification = 
otoa.getElementType();
-            BeanSort beanSort = fieldObjectSpecification.getBeanSort();
-            switch (beanSort) {
+                    ObjectSpecification fieldObjectSpecification = 
otoa.getElementType();
+                    BeanSort beanSort = fieldObjectSpecification.getBeanSort();
+                    switch (beanSort) {
 
-                case VIEW_MODEL:
-                case ENTITY:
+                        case VIEW_MODEL:
+                        case ENTITY:
 
-                    String logicalTypeNameOfField = 
fieldObjectSpecification.getLogicalTypeName();
+                            String logicalTypeNameOfField = 
fieldObjectSpecification.getLogicalTypeName();
 
-                    GraphQLFieldDefinition.Builder fieldBuilder = 
newFieldDefinition()
-                        .name(otoa.getId())
-                        .type(otoa.isOptional()
-                                ? GraphQLTypeReference.typeRef(
-                                        
_Utils.logicalTypeNameSanitized(logicalTypeNameOfField))
-                                : nonNull(GraphQLTypeReference.typeRef(
-                                        
_Utils.logicalTypeNameSanitized(logicalTypeNameOfField))));
-                    objectTypeBuilder.field(fieldBuilder);
+                            GraphQLFieldDefinition.Builder fieldBuilder = 
newFieldDefinition()
+                                    .name(otoa.getId())
+                                    .type(otoa.isOptional()
+                                            ? GraphQLTypeReference.typeRef(
+                                            
_Utils.logicalTypeNameSanitized(logicalTypeNameOfField))
+                                            : 
nonNull(GraphQLTypeReference.typeRef(
+                                            
_Utils.logicalTypeNameSanitized(logicalTypeNameOfField))));
+                            objectTypeBuilder.field(fieldBuilder);
 
-                    break;
+                            break;
 
-                case VALUE:
+                        case VALUE:
 
-                    // todo: map ...
+                            // todo: map ...
 
-                    GraphQLFieldDefinition.Builder valueBuilder = 
newFieldDefinition()
-                        .name(otoa.getId())
-                        .type(otoa.isOptional()
-                                ? Scalars.GraphQLString
-                                : nonNull(Scalars.GraphQLString));
-                    objectTypeBuilder.field(valueBuilder);
+                            GraphQLFieldDefinition.Builder valueBuilder = 
newFieldDefinition()
+                                    .name(otoa.getId())
+                                    .type(otoa.isOptional()
+                                            ? Scalars.GraphQLString
+                                            : nonNull(Scalars.GraphQLString));
+                            objectTypeBuilder.field(valueBuilder);
 
-                    break;
+                            break;
 
-            }
-        });
+                    }
+                });
     }
 
     void createAndRegisterDataFetchersForField(
@@ -229,11 +300,11 @@ public class ObjectTypeFactory {
             final GraphQLCodeRegistry.Builder codeRegistryBuilder,
             final GraphQLObjectType graphQLObjectType) {
         objectSpecification.streamProperties(MixedIn.INCLUDED)
-        .forEach(otoa -> {
+                .forEach(otoa -> {
 
-            
createAndRegisterDataFetcherForObjectAssociation(codeRegistryBuilder, 
graphQLObjectType, otoa);
+                    
createAndRegisterDataFetcherForObjectAssociation(codeRegistryBuilder, 
graphQLObjectType, otoa);
 
-        });
+                });
     }
 
     void addCollections(
@@ -251,9 +322,9 @@ public class ObjectTypeFactory {
 
                     String logicalTypeNameOfField = 
elementType.getLogicalTypeName();
                     GraphQLFieldDefinition.Builder fieldBuilder = 
newFieldDefinition()
-                        .name(otom.getId())
-                        .type(GraphQLList.list(GraphQLTypeReference.typeRef(
-                                
_Utils.logicalTypeNameSanitized(logicalTypeNameOfField))));
+                            .name(otom.getId())
+                            
.type(GraphQLList.list(GraphQLTypeReference.typeRef(
+                                    
_Utils.logicalTypeNameSanitized(logicalTypeNameOfField))));
                     objectTypeBuilder.field(fieldBuilder);
 
                     break;
@@ -261,8 +332,8 @@ public class ObjectTypeFactory {
                 case VALUE:
 
                     GraphQLFieldDefinition.Builder valueBuilder = 
newFieldDefinition()
-                        .name(otom.getId())
-                        
.type(GraphQLList.list(TypeMapper.typeFor(elementType.getCorrespondingClass())));
+                            .name(otom.getId())
+                            
.type(GraphQLList.list(TypeMapper.typeFor(elementType.getCorrespondingClass())));
                     objectTypeBuilder.field(valueBuilder);
 
                     break;
@@ -341,7 +412,7 @@ public class ObjectTypeFactory {
 
                 });
 
-        if (!mutatorsTypeFields.isEmpty()){
+        if (!mutatorsTypeFields.isEmpty()) {
             GraphQLObjectType mutatorsType = mutatorsTypeBuilder.build();
             addTypeIfNotAlreadyPresent(graphQLObjectTypes, mutatorsType, 
mutatorsTypeName);
             GraphQLFieldDefinition gql_mutations = newFieldDefinition()
@@ -350,29 +421,8 @@ public class ObjectTypeFactory {
                     .build();
             objectTypeBuilder.field(gql_mutations);
 
-            return new MutatorsDataForEntity(mutatorsType, mutatorsTypeFields);
-
-//            // I think we have to create and register data fetcher for 
mutations here, but we can't since we have no objectTypeYet
-//            
codeRegistryBuilder.dataFetcher(FieldCoordinates.coordinates(graphQLTypeReference,
 gql_mutations), new DataFetcher<Object>() {
-//                @Override
-//                public Object get(DataFetchingEnvironment environment) 
throws Exception {
-//
-//                    Bookmark bookmark = 
bookmarkService.bookmarkFor(environment.getSource()).orElse(null);
-//                    if (bookmark == null) return null; //TODO: is this 
correct ?
-//                    return new GQLMutations(bookmark, bookmarkService, 
mutatorsTypeFields);
-//                }
-//            });
-//
-//            // for each field something like
-//            
codeRegistryBuilder.dataFetcher(FieldCoordinates.coordinates(mutatorsType, 
idField), new DataFetcher<Object>() {
-//                @Override
-//                public Object get(DataFetchingEnvironment environment) 
throws Exception {
-//
-//                    GQLMeta gqlMeta = environment.getSource();
-//
-//                    return gqlMeta.id();
-//                }
-//            });
+            return new MutatorsDataForEntity(objectSpecification, 
mutatorsType, mutatorsTypeFields);
+
         }
 
         return null;
@@ -383,6 +433,8 @@ public class ObjectTypeFactory {
     @AllArgsConstructor
     class MutatorsDataForEntity {
 
+        private ObjectSpecification objectSpecification;
+
         private GraphQLObjectType mutatorsType;
 
         private List<GraphQLFieldDefinition> mutatorsTypeFields;
@@ -405,22 +457,22 @@ public class ObjectTypeFactory {
             case ENTITY:
 
                 codeRegistryBuilder
-                .dataFetcher(
-                    FieldCoordinates.coordinates(graphQLObjectType, 
otom.getId()),
-                    (DataFetcher<Object>) environment -> {
+                        .dataFetcher(
+                                
FieldCoordinates.coordinates(graphQLObjectType, otom.getId()),
+                                (DataFetcher<Object>) environment -> {
 
-                        Object domainObjectInstance = environment.getSource();
+                                    Object domainObjectInstance = 
environment.getSource();
 
-                        Class<?> domainObjectInstanceClass = 
domainObjectInstance.getClass();
-                        ObjectSpecification specification = 
specificationLoader.loadSpecification(domainObjectInstanceClass);
+                                    Class<?> domainObjectInstanceClass = 
domainObjectInstance.getClass();
+                                    ObjectSpecification specification = 
specificationLoader.loadSpecification(domainObjectInstanceClass);
 
-                        ManagedObject owner = ManagedObject.of(specification, 
domainObjectInstance);
+                                    ManagedObject owner = 
ManagedObject.of(specification, domainObjectInstance);
 
-                        ManagedObject managedObject = otom.get(owner);
+                                    ManagedObject managedObject = 
otom.get(owner);
 
-                        return managedObject!=null ? managedObject.getPojo() : 
null;
+                                    return managedObject != null ? 
managedObject.getPojo() : null;
 
-                    });
+                                });
 
 
                 break;
diff --git 
a/incubator/viewers/graphql/viewer/src/test/java/org/apache/isis/viewer/graphql/viewer/source/EndToEnd_IntegTest.changeName.approved.gql
 
b/incubator/viewers/graphql/viewer/src/test/java/org/apache/isis/viewer/graphql/viewer/source/EndToEnd_IntegTest.changeName.approved.gql
index e57317ab99..7131e7be74 100644
--- 
a/incubator/viewers/graphql/viewer/src/test/java/org/apache/isis/viewer/graphql/viewer/source/EndToEnd_IntegTest.changeName.approved.gql
+++ 
b/incubator/viewers/graphql/viewer/src/test/java/org/apache/isis/viewer/graphql/viewer/source/EndToEnd_IntegTest.changeName.approved.gql
@@ -1 +1,14 @@
-{"data":{"gqltestdomain_GQLTestDomainMenu":{"findAllE2":[{"name":"foo","_gql_mutations":null}]}}}
\ No newline at end of file
+{
+  "data" : {
+    "gqltestdomain_GQLTestDomainMenu" : {
+      "findE2" : {
+        "name" : "foo",
+        "_gql_mutations" : {
+          "changeName" : {
+            "name" : "bar"
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git 
a/incubator/viewers/graphql/viewer/src/test/java/org/apache/isis/viewer/graphql/viewer/source/EndToEnd_IntegTest.changeName.submit.gql
 
b/incubator/viewers/graphql/viewer/src/test/java/org/apache/isis/viewer/graphql/viewer/source/EndToEnd_IntegTest.changeName.submit.gql
index e2b8760084..a408a6ef8c 100644
--- 
a/incubator/viewers/graphql/viewer/src/test/java/org/apache/isis/viewer/graphql/viewer/source/EndToEnd_IntegTest.changeName.submit.gql
+++ 
b/incubator/viewers/graphql/viewer/src/test/java/org/apache/isis/viewer/graphql/viewer/source/EndToEnd_IntegTest.changeName.submit.gql
@@ -1,12 +1,10 @@
 {
   gqltestdomain_GQLTestDomainMenu {
     findE2(name:"foo") {
-      name_gql_mutations {
+      name,
+      _gql_mutations {
         changeName(newName:"bar") {
           name
-          e1 {
-            name
-          }
         }
       }
     }
diff --git 
a/incubator/viewers/graphql/viewer/src/test/java/org/apache/isis/viewer/graphql/viewer/source/EndToEnd_IntegTest.java
 
b/incubator/viewers/graphql/viewer/src/test/java/org/apache/isis/viewer/graphql/viewer/source/EndToEnd_IntegTest.java
index 05e7b42496..f5463573ba 100644
--- 
a/incubator/viewers/graphql/viewer/src/test/java/org/apache/isis/viewer/graphql/viewer/source/EndToEnd_IntegTest.java
+++ 
b/incubator/viewers/graphql/viewer/src/test/java/org/apache/isis/viewer/graphql/viewer/source/EndToEnd_IntegTest.java
@@ -203,10 +203,9 @@ public class EndToEnd_IntegTest extends 
TestDomainModuleIntegTestAbstract {
 
         E2 e2Modified = e2List.get(0);
 
-        //TODO: implement ...
-//        assertEquals("bar", e2Modified.getName());
-//
-//        Approvals.verify(response, new Options());
+        assertEquals("bar", e2Modified.getName());
+
+        Approvals.verify(response, gqlOptions());
 
     }
 

Reply via email to