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

danhaywood pushed a commit to branch CAUSEWAY-3676
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit 151645243976418b675d4f75832217145b2d7cbe
Author: danhaywood <[email protected]>
AuthorDate: Fri Jan 26 10:31:16 2024 +0000

    CAUSEWAY-3676: wip, adding support for collection params
---
 .../viewer/graphql/model/domain/GqlvAction.java    | 24 +++++++++++++++----
 .../graphql/model/domain/GqlvDomainObject.java     |  2 +-
 .../viewer/graphql/model/types/TypeMapper.java     | 27 +++++++++++++++++++++-
 .../src/test/resources/application-test.properties |  2 +-
 .../graphql/test/src/test/resources/schema.gql     | 20 ++++++++++++++++
 5 files changed, 68 insertions(+), 7 deletions(-)

diff --git 
a/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAction.java
 
b/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAction.java
index fa95ef680a..e99ac54172 100644
--- 
a/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAction.java
+++ 
b/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAction.java
@@ -25,6 +25,7 @@ import 
org.apache.causeway.core.metamodel.object.ManagedObject;
 import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
 import org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
 import org.apache.causeway.core.metamodel.spec.feature.ObjectActionParameter;
+import 
org.apache.causeway.core.metamodel.spec.feature.OneToManyActionParameter;
 import org.apache.causeway.core.metamodel.spec.feature.OneToOneActionParameter;
 import org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojoFetcher;
@@ -141,8 +142,7 @@ public class GqlvAction
         val parameters = objectAction.getParameters();
         val arguments = parameters.stream()
                 .limit(upTo)
-                .map(OneToOneActionParameter.class::cast)   // TODO: remove - 
we previously filter to ignore any actions that have collection parameters
-                .map(oneToOneActionParameter -> 
gqlArgumentFor(oneToOneActionParameter, inputContext))
+                .map(objectActionParameter -> 
gqlArgumentFor(objectActionParameter, inputContext))
                 .collect(Collectors.toList());
         if (!arguments.isEmpty()) {
             builder.arguments(arguments);
@@ -157,14 +157,21 @@ public class GqlvAction
 
         val parameters = objectAction.getParameters();
         val arguments = parameters.get(paramNum).stream()
-                .map(OneToOneActionParameter.class::cast)   // TODO: remove - 
we previously filter to ignore any actions that have collection parameters
-                .map(oneToOneActionParameter -> 
gqlArgumentFor(oneToOneActionParameter, inputContext))
+                .map(objectActionParameter -> 
gqlArgumentFor(objectActionParameter, inputContext))
                 .collect(Collectors.toList());
         if (!arguments.isEmpty()) {
             builder.arguments(arguments);
         }
     }
 
+    static GraphQLArgument gqlArgumentFor(
+            final ObjectActionParameter objectActionParameter,
+            final TypeMapper.InputContext inputContext) {
+        return objectActionParameter.isPlural()
+                ? gqlArgumentFor((OneToManyActionParameter) 
objectActionParameter, inputContext)
+                : gqlArgumentFor((OneToOneActionParameter) 
objectActionParameter, inputContext);
+    }
+
     static GraphQLArgument gqlArgumentFor(
             final OneToOneActionParameter oneToOneActionParameter,
             final TypeMapper.InputContext inputContext) {
@@ -174,6 +181,15 @@ public class GqlvAction
                 .build();
     }
 
+    static GraphQLArgument gqlArgumentFor(
+            final OneToManyActionParameter oneToManyActionParameter,
+            final TypeMapper.InputContext inputContext) {
+        return GraphQLArgument.newArgument()
+                .name(oneToManyActionParameter.getId())
+                .type(TypeMapper.inputTypeFor(oneToManyActionParameter, 
inputContext))
+                .build();
+    }
+
     @Override
     public ObjectSpecification getObjectSpecification() {
         return holder.getObjectSpecification();
diff --git 
a/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvDomainObject.java
 
b/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvDomainObject.java
index 49f0abae38..720430e08a 100644
--- 
a/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvDomainObject.java
+++ 
b/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvDomainObject.java
@@ -103,7 +103,7 @@ public class GqlvDomainObject implements GqlvAction.Holder, 
GqlvProperty.Holder,
         objectSpecification.streamActions(ActionScope.PRODUCTION, 
MixedIn.INCLUDED)
                 // TODO: for now, we ignore any actions that have any 
collection parameters
                 //  however, this is supportable in GraphQL, 
https://chat.openai.com/c/7ca721d5-865a-4765-9f90-5c28046516cd
-                .filter(objectAction -> 
objectAction.getParameters().stream().noneMatch(ObjectActionParameter::isPlural))
+                // .filter(objectAction -> 
objectAction.getParameters().stream().noneMatch(ObjectActionParameter::isPlural))
                 .forEach(objectAction -> {
                     actions.put(objectAction.getId(), new GqlvAction(this, 
objectAction, context));
                 });
diff --git 
a/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapper.java
 
b/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapper.java
index f445f93776..f1697f4f5a 100644
--- 
a/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapper.java
+++ 
b/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapper.java
@@ -31,6 +31,7 @@ import javax.ws.rs.NotSupportedException;
 
 import org.apache.causeway.commons.internal.collections._Maps;
 import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
+import 
org.apache.causeway.core.metamodel.spec.feature.OneToManyActionParameter;
 import org.apache.causeway.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.causeway.core.metamodel.spec.feature.OneToOneFeature;
 import org.apache.causeway.viewer.graphql.model.domain.TypeNames;
@@ -149,7 +150,31 @@ public class TypeMapper {
                 return scalarTypeFor(elementType.getCorrespondingClass());
 
             case COLLECTION:
-                // TODO ...
+                throw new 
IllegalArgumentException(String.format("OneToOneFeature '%s' is not expected to 
have a beanSort of COLLECTION", 
oneToOneFeature.getFeatureIdentifier().toString()));
+            default:
+                // for now
+                return Scalars.GraphQLString;
+        }
+    }
+
+    public static GraphQLList inputTypeFor(final OneToManyActionParameter 
oneToManyActionParameter, final InputContext inputContextUnused){
+        ObjectSpecification elementType = 
oneToManyActionParameter.getElementType();
+        return GraphQLList.list(TypeMapper.inputTypeFor_(elementType));
+    }
+
+    private static GraphQLInputType inputTypeFor_(final ObjectSpecification 
elementType){
+        switch (elementType.getBeanSort()) {
+            case ABSTRACT:
+            case ENTITY:
+            case VIEW_MODEL:
+                return typeRef(TypeNames.inputTypeNameFor(elementType));
+
+            case VALUE:
+                return scalarTypeFor(elementType.getCorrespondingClass());
+
+            case COLLECTION:
+                throw new IllegalArgumentException(String.format("ObjectSpec 
'%s' is not expected to have a beanSort of COLLECTION", 
elementType.getFullIdentifier()));
+
             default:
                 // for now
                 return Scalars.GraphQLString;
diff --git 
a/incubator/viewers/graphql/test/src/test/resources/application-test.properties 
b/incubator/viewers/graphql/test/src/test/resources/application-test.properties
index 74f02709ab..1ed5bab4ab 100644
--- 
a/incubator/viewers/graphql/test/src/test/resources/application-test.properties
+++ 
b/incubator/viewers/graphql/test/src/test/resources/application-test.properties
@@ -1,3 +1,3 @@
-#logging.level.org.springframework=DEBUG
+logging.level.org.springframework=DEBUG
 logging.level.graphql=DEBUG
 
diff --git a/incubator/viewers/graphql/test/src/test/resources/schema.gql 
b/incubator/viewers/graphql/test/src/test/resources/schema.gql
index 9e0b06b033..2b7fa5581b 100644
--- a/incubator/viewers/graphql/test/src/test/resources/schema.gql
+++ b/incubator/viewers/graphql/test/src/test/resources/schema.gql
@@ -2228,6 +2228,7 @@ type 
university_admin_AdminMenu__otherAdminAction__gqlv_action {
 type university_dept_Department {
   _gql_meta: university_dept_Department__gqlv_meta
   addStaffMember: university_dept_Department__addStaffMember__gqlv_action
+  addStaffMembers: university_dept_Department__addStaffMembers__gqlv_action
   changeDeptHead: university_dept_Department__changeDeptHead__gqlv_action
   changeName: university_dept_Department__changeName__gqlv_action
   deptHead: university_dept_Department__deptHead__gqlv_property
@@ -2255,6 +2256,25 @@ type 
university_dept_Department__addStaffMember__staffMember__gqlv_action_parame
   validity(staffMember: university_dept_StaffMember__gqlv_input): String
 }
 
+type university_dept_Department__addStaffMembers__gqlv_action {
+  disabled: String
+  hidden: Boolean
+  invokeIdempotent(staffMembers: [university_dept_StaffMember__gqlv_input]): 
university_dept_Department
+  params: university_dept_Department__addStaffMembers__gqlv_action_params
+  validate(staffMembers: [university_dept_StaffMember__gqlv_input]): String
+}
+
+type university_dept_Department__addStaffMembers__gqlv_action_params {
+  staffMembers: 
university_dept_Department__addStaffMembers__staffMembers__gqlv_action_parameter
+}
+
+type 
university_dept_Department__addStaffMembers__staffMembers__gqlv_action_parameter
 {
+  choices: [university_dept_StaffMember]
+  disabled(staffMembers: [university_dept_StaffMember__gqlv_input]): String
+  hidden: Boolean
+  validity(staffMembers: [university_dept_StaffMember__gqlv_input]): String
+}
+
 type university_dept_Department__changeDeptHead__gqlv_action {
   disabled: String
   hidden: Boolean

Reply via email to