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 1281d96aaaa56d07c319b6cbd83ebea4b1541e12
Author: danhaywood <[email protected]>
AuthorDate: Sun Feb 11 16:05:27 2024 +0000

    CAUSEWAY-3676: further refactorings
---
 .../graphql/model/domain/GqlvDomainObject.java     | 59 ++++++++++++++--------
 .../integration/GraphQlSourceForCauseway.java      | 45 ++++-------------
 .../viewer/toplevel/GqlvTopLevelMutation.java      | 38 ++------------
 .../graphql/viewer/toplevel/GqlvTopLevelQuery.java | 57 +++++++++------------
 4 files changed, 77 insertions(+), 122 deletions(-)

diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvDomainObject.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvDomainObject.java
index 997f780cd8..7595c0fefb 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvDomainObject.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvDomainObject.java
@@ -23,6 +23,7 @@ import java.util.SortedMap;
 import java.util.TreeMap;
 
 import graphql.Scalars;
+import graphql.schema.DataFetcher;
 import graphql.schema.FieldCoordinates;
 import graphql.schema.GraphQLArgument;
 import graphql.schema.GraphQLFieldDefinition;
@@ -44,19 +45,22 @@ import 
org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.registry.GraphQLTypeRegistry;
 
-import static 
org.apache.causeway.core.config.CausewayConfiguration.Viewer.Graphql.ApiVariant.QUERY_WITH_MUTATIONS_NON_SPEC_COMPLIANT;
-
 import lombok.Getter;
 import lombok.val;
 
 /**
  * Exposes a domain object (view model or entity) via the GQL viewer.
  */
-public class GqlvDomainObject implements GqlvAction.Holder, 
GqlvProperty.Holder, GqlvCollection.Holder, GqlvMeta.Holder {
+public class GqlvDomainObject
+        implements GqlvAction.Holder, GqlvProperty.Holder, 
GqlvCollection.Holder, GqlvMeta.Holder {
 
+    private final Holder holder;
     @Getter private final ObjectSpecification objectSpecification;
     private final Context context;
 
+    @Getter
+    private final GraphQLFieldDefinition lookupField;
+
     private final GqlvMeta meta;
 
     private final GraphQLObjectType.Builder gqlObjectTypeBuilder;
@@ -70,10 +74,12 @@ public class GqlvDomainObject implements GqlvAction.Holder, 
GqlvProperty.Holder,
     @Getter private final GraphQLInputObjectType gqlInputObjectType;
 
     public GqlvDomainObject(
+            final GqlvDomainObject.Holder holder,
             final ObjectSpecification objectSpecification,
             final Context context,
             final ObjectManager objectManager,
             final GraphQLTypeRegistry graphQLTypeRegistry) {
+        this.holder = holder;
 
         this.objectSpecification = objectSpecification;
         this.context = context;
@@ -90,32 +96,35 @@ public class GqlvDomainObject implements GqlvAction.Holder, 
GqlvProperty.Holder,
                         .build());
         gqlInputObjectType = inputTypeBuilder.build();
 
+        this.lookupField = buildFieldDefinition(gqlInputObjectType);
+
         addMembers();
+
+        gqlObjectType = gqlObjectTypeBuilder.build();
+        graphQLTypeRegistry.addTypeIfNotAlreadyPresent(gqlObjectType);
+        meta.registerTypesInto(graphQLTypeRegistry);
+        graphQLTypeRegistry.addTypeIfNotAlreadyPresent(gqlInputObjectType);
+
     }
 
-    public GraphQLFieldDefinition getField() {
+    private GraphQLFieldDefinition buildFieldDefinition(GraphQLInputObjectType 
gqlInputObjectType) {
         val lookupConfig = 
this.context.causewayConfiguration.getViewer().getGraphql().getLookup();
-        ObjectSpecification objectSpec = getObjectSpecification();
+        val objectSpec = getObjectSpecification();
+        val fieldName = String.format("%s%s%s",
+                lookupConfig.getFieldNamePrefix(),          // eg 
"_gqlv_lookup__"
+                TypeNames.objectTypeNameFor(objectSpec),
+                lookupConfig.getFieldNameSuffix());
+
         return newFieldDefinition()
-                .name(String.format("%s%s%s",
-                        lookupConfig.getFieldNamePrefix(),          // eg 
"_gqlv_lookup__"
-                        TypeNames.objectTypeNameFor(objectSpec),
-                        lookupConfig.getFieldNameSuffix())          // eg ""
-                )
+                .name(fieldName)
                 .type(this.context.typeMapper.outputTypeFor(objectSpec))
                 .argument(GraphQLArgument.newArgument()
                         .name(lookupConfig.getArgument())   // eg "object"
-                        .type(getGqlInputObjectType())
+                        .type(gqlInputObjectType)
                         .build())
                 .build();
     }
 
-    public void addTypesInto(GraphQLTypeRegistry graphQLTypeRegistry) {
-        gqlObjectType = gqlObjectTypeBuilder.build();
-        graphQLTypeRegistry.addTypeIfNotAlreadyPresent(gqlObjectType);
-        meta.registerTypesInto(graphQLTypeRegistry);
-        graphQLTypeRegistry.addTypeIfNotAlreadyPresent(gqlInputObjectType);
-    }
 
 
     private void addMembers() {
@@ -156,6 +165,15 @@ public class GqlvDomainObject implements 
GqlvAction.Holder, GqlvProperty.Holder,
 
 
     public void addDataFetchers() {
+
+        this.context.codeRegistryBuilder.dataFetcher(
+                holder.coordinatesFor(getLookupField()),
+                (DataFetcher<Object>) environment -> {
+                    Object target = environment.getArgument("object");
+                    return GqlvAction.asPojo(getObjectSpecification(), target, 
this.context.bookmarkService)
+                            .orElse(null);
+                });
+
         meta.addDataFetchers();
         properties.forEach((id, property) -> property.addDataFetcher());
         collections.forEach((id, collection) -> collection.addDataFetcher());
@@ -165,10 +183,6 @@ public class GqlvDomainObject implements 
GqlvAction.Holder, GqlvProperty.Holder,
 
     @Override
     public FieldCoordinates coordinatesFor(final GraphQLFieldDefinition 
fieldDefinition) {
-        if (gqlObjectType == null) {
-            throw new IllegalStateException(String.format(
-                    "GraphQLObjectType has not yet been built for %s", 
objectSpecification.getLogicalTypeName()));
-        }
         return FieldCoordinates.coordinates(gqlObjectType, fieldDefinition);
     }
 
@@ -178,4 +192,7 @@ public class GqlvDomainObject implements GqlvAction.Holder, 
GqlvProperty.Holder,
         return objectSpecification.getLogicalTypeName();
     }
 
+    public interface Holder extends GqlvHolder {
+    }
+
 }
diff --git 
a/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/integration/GraphQlSourceForCauseway.java
 
b/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/integration/GraphQlSourceForCauseway.java
index 86a1b923e8..0c0c4c0420 100644
--- 
a/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/integration/GraphQlSourceForCauseway.java
+++ 
b/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/integration/GraphQlSourceForCauseway.java
@@ -19,12 +19,10 @@
 package org.apache.causeway.viewer.graphql.viewer.integration;
 
 import java.util.ArrayList;
-import java.util.LinkedHashMap;
 
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
-import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
 import org.apache.causeway.viewer.graphql.viewer.toplevel.GqlvTopLevelMutation;
 
 import org.springframework.graphql.execution.GraphQlSource;
@@ -105,49 +103,28 @@ public class GraphQlSourceForCauseway implements 
GraphQlSource {
         val codeRegistryBuilder = GraphQLCodeRegistry.newCodeRegistry();
         val context = new Context(codeRegistryBuilder, bookmarkService, 
specificationLoader, typeMapper, serviceRegistry, causewayConfiguration, 
causewaySystemEnvironment);
 
-        // domain objects
-        val domainObjects = new LinkedHashMap<ObjectSpecification, 
GqlvDomainObject>();
-        val domainObjectList = new ArrayList<GqlvDomainObject>();
-        context.objectSpecifications().forEach(objectSpec -> {
-            switch (objectSpec.getBeanSort()) {
-
-                case ABSTRACT:
-                case VIEW_MODEL: // @DomainObject(nature=VIEW_MODEL)
-                case ENTITY:     // @DomainObject(nature=ENTITY)
-
-                    val domainObject = new GqlvDomainObject(objectSpec, 
context, objectManager, graphQLTypeRegistry);
-                    domainObject.addTypesInto(graphQLTypeRegistry);
-                    domainObject.addDataFetchers();
-
-                    domainObjectList.add(domainObject);
-                    domainObjects.put(objectSpec, domainObject);
-
-                    break;
-            }
-        });
-
-        // top-level query type and (dependent on configuration) the top-level 
mutation type
-        val topLevelQuery = new GqlvTopLevelQuery(context, domainObjectList);
-
-
+        // top-level query and mutation type
+        val topLevelQuery = new GqlvTopLevelQuery(context, objectManager, 
graphQLTypeRegistry);
         val topLevelMutation =
                 causewayConfiguration.getViewer().getGraphql().getApiVariant() 
== CausewayConfiguration.Viewer.Graphql.ApiVariant.QUERY_AND_MUTATIONS ?
                         new GqlvTopLevelMutation(context)
                         : null;
 
+        // add the data fetchers
+        topLevelQuery.addDataFetchers();
+        if (topLevelMutation != null) {
+            topLevelMutation.addDataFetchers();
+        }
 
-        // finalize the fetcher/mutator code that's been registered
+        // finalize the fetcher/mutator code that's been added
         val codeRegistry = codeRegistryBuilder.build();
 
         // build the schema
-        val schemaBuilder = GraphQLSchema.newSchema()
+        return GraphQLSchema.newSchema()
                 .query(topLevelQuery.getObjectType())
                 .additionalTypes(graphQLTypeRegistry.getGraphQLTypes())
-                .codeRegistry(codeRegistry);
-        if (topLevelMutation != null) {
-            schemaBuilder.mutation(topLevelMutation.getGqlObjectType());
-        }
-        return schemaBuilder
+                .codeRegistry(codeRegistry)
+                .mutation(topLevelMutation != null ? 
topLevelMutation.getObjectType() : null)
                 .build();
     }
 
diff --git 
a/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/toplevel/GqlvTopLevelMutation.java
 
b/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/toplevel/GqlvTopLevelMutation.java
index 8b19244dc1..4bce77cc6c 100644
--- 
a/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/toplevel/GqlvTopLevelMutation.java
+++ 
b/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/toplevel/GqlvTopLevelMutation.java
@@ -1,7 +1,6 @@
 package org.apache.causeway.viewer.graphql.viewer.toplevel;
 
 import java.util.ArrayList;
-import java.util.Comparator;
 import java.util.List;
 
 import graphql.schema.FieldCoordinates;
@@ -10,8 +9,6 @@ import graphql.schema.GraphQLObjectType;
 
 import static graphql.schema.GraphQLObjectType.newObject;
 
-import org.apache.causeway.applib.id.HasLogicalType;
-import org.apache.causeway.commons.functional.Either;
 import 
org.apache.causeway.core.metamodel.facets.properties.update.modify.PropertySetterFacet;
 import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
 import org.apache.causeway.core.metamodel.spec.feature.MixedIn;
@@ -29,13 +26,10 @@ public class GqlvTopLevelMutation
 
     private final Context context;
 
-    @Getter final GraphQLObjectType.Builder gqlObjectTypeBuilder;
+    private final GraphQLObjectType.Builder gqlObjectTypeBuilder;
 
-
-    /**
-     * Built using {@link #buildMutationType()}
-     */
-    private GraphQLObjectType gqlObjectType;
+    @Getter
+    private final GraphQLObjectType objectType;
 
     private final List<GqlvMutationForAction> actions = new ArrayList<>();
     private final List<GqlvMutationForProperty> properties = new ArrayList<>();
@@ -57,29 +51,7 @@ public class GqlvTopLevelMutation
 
         });
 
-        buildMutationType();
-
-        addDataFetchers();
-    }
-
-
-
-    public GraphQLObjectType buildMutationType() {
-        if (gqlObjectType != null) {
-            throw new IllegalStateException("Mutation type has already been 
built");
-        }
-        return gqlObjectType = gqlObjectTypeBuilder.build();
-    }
-
-    /**
-     *
-     * @see #buildMutationType()
-     */
-    public GraphQLObjectType getGqlObjectType() {
-        if (gqlObjectType == null) {
-            throw new IllegalStateException("Mutation type has not yet been 
built");
-        }
-        return gqlObjectType;
+        objectType = gqlObjectTypeBuilder.build();
     }
 
 
@@ -99,7 +71,7 @@ public class GqlvTopLevelMutation
 
     @Override
     public FieldCoordinates coordinatesFor(GraphQLFieldDefinition 
fieldDefinition) {
-        return FieldCoordinates.coordinates(gqlObjectType, fieldDefinition);
+        return FieldCoordinates.coordinates(objectType, fieldDefinition);
     }
 
     public void addDataFetchers() {
diff --git 
a/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/toplevel/GqlvTopLevelQuery.java
 
b/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/toplevel/GqlvTopLevelQuery.java
index f8dd4cbd35..53f87e4887 100644
--- 
a/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/toplevel/GqlvTopLevelQuery.java
+++ 
b/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/toplevel/GqlvTopLevelQuery.java
@@ -3,52 +3,50 @@ package org.apache.causeway.viewer.graphql.viewer.toplevel;
 import java.util.ArrayList;
 import java.util.List;
 
-import graphql.schema.DataFetcher;
 import graphql.schema.FieldCoordinates;
-import graphql.schema.GraphQLArgument;
 import graphql.schema.GraphQLFieldDefinition;
 import graphql.schema.GraphQLObjectType;
 
-import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition;
 import static graphql.schema.GraphQLObjectType.newObject;
 
+import org.apache.causeway.core.metamodel.objectmanager.ObjectManager;
 import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
 import org.apache.causeway.viewer.graphql.model.context.Context;
-import org.apache.causeway.viewer.graphql.model.domain.GqlvAction;
 import org.apache.causeway.viewer.graphql.model.domain.GqlvDomainObject;
 import org.apache.causeway.viewer.graphql.model.domain.GqlvDomainService;
-import org.apache.causeway.viewer.graphql.model.domain.TypeNames;
+import org.apache.causeway.viewer.graphql.model.registry.GraphQLTypeRegistry;
 
 import lombok.Getter;
 import lombok.val;
 
-public class GqlvTopLevelQuery implements GqlvDomainService.Holder {
+public class GqlvTopLevelQuery implements GqlvDomainService.Holder, 
GqlvDomainObject.Holder {
+
+    private static final String OBJECT_TYPE_NAME = "Query";
 
     final GraphQLObjectType.Builder objectTypeBuilder;
+    @Getter private final GraphQLObjectType objectType;
 
     private final List<GqlvDomainService> domainServices = new ArrayList<>();
+    private final List<GqlvDomainObject> domainObjects = new ArrayList<>();
     private final Context context;
-    private final List<GqlvDomainObject> domainObjects;
-
-
-    @Getter private final GraphQLObjectType objectType;
-
 
     public GqlvTopLevelQuery(
             final Context context,
-            final List<GqlvDomainObject> domainObjects) {
+            final ObjectManager objectManager,
+            final GraphQLTypeRegistry graphQLTypeRegistry) {
+
         this.context = context;
-        this.domainObjects = domainObjects;
-        this.objectTypeBuilder = newObject().name("Query");
+        this.objectTypeBuilder = newObject().name(OBJECT_TYPE_NAME);
 
-        // add services to top-level query
         context.objectSpecifications().forEach(objectSpec -> {
             switch (objectSpec.getBeanSort()) {
-                case MANAGED_BEAN_CONTRIBUTING: // @DomainService
-                    
context.serviceRegistry.lookupBeanById(objectSpec.getLogicalTypeName())
-                            .ifPresent(servicePojo -> {
-                                addDomainService(objectSpec, servicePojo, 
context);
-                            });
+
+                case ABSTRACT:
+                case VIEW_MODEL: // @DomainObject(nature=VIEW_MODEL)
+                case ENTITY:     // @DomainObject(nature=ENTITY)
+
+                    domainObjects.add(new GqlvDomainObject(this, objectSpec, 
context, objectManager, graphQLTypeRegistry));
+
                     break;
             }
         });
@@ -59,7 +57,7 @@ public class GqlvTopLevelQuery implements 
GqlvDomainService.Holder {
                 case MANAGED_BEAN_CONTRIBUTING: // @DomainService
                     
context.serviceRegistry.lookupBeanById(objectSpec.getLogicalTypeName())
                             .ifPresent(servicePojo -> {
-                                addDataFetchers();
+                                addDomainService(objectSpec, servicePojo, 
context);
                             });
                     break;
             }
@@ -67,10 +65,9 @@ public class GqlvTopLevelQuery implements 
GqlvDomainService.Holder {
 
         // add lookup to top-level query
         for (GqlvDomainObject domainObject : this.domainObjects) {
-            addField(domainObject.getField());
+            addField(domainObject.getLookupField());
         }
 
-
         objectType = objectTypeBuilder.build();
     }
 
@@ -82,7 +79,7 @@ public class GqlvTopLevelQuery implements 
GqlvDomainService.Holder {
 
     @Override
     public FieldCoordinates coordinatesFor(GraphQLFieldDefinition 
fieldDefinition) {
-        return FieldCoordinates.coordinates("Query", 
fieldDefinition.getName());
+        return FieldCoordinates.coordinates(OBJECT_TYPE_NAME, 
fieldDefinition.getName());
     }
 
     @Override
@@ -99,16 +96,8 @@ public class GqlvTopLevelQuery implements 
GqlvDomainService.Holder {
             }
         });
 
-        domainObjects.forEach(domainObject -> {
-            ObjectSpecification objectSpec = 
domainObject.getObjectSpecification();
-            this.context.codeRegistryBuilder.dataFetcher(
-                    coordinatesFor(domainObject.getField()),
-                    (DataFetcher<Object>) environment -> {
-                        Object target = environment.getArgument("object");
-                        return GqlvAction.asPojo(objectSpec, target, 
this.context.bookmarkService)
-                                .orElse(null);
-                    });
-        });
+
+        domainObjects.forEach(GqlvDomainObject::addDataFetchers);
 
     }
 

Reply via email to