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
