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 d5ea89dada2fb574b78a5e27413aaea90ceb05f1
Author: danhaywood <[email protected]>
AuthorDate: Fri Jan 19 11:25:23 2024 +0000

    CAUSEWAY-3676: introduces GraphQLTypeRegistry
---
 .../integration/GraphQlSourceForCauseway.java      |  13 +-
 .../graphql/viewer/source/GraphQLTypeRegistry.java | 135 +++++++++++++++++++++
 .../graphql/viewer/source/ObjectTypeFactory.java   |  82 ++-----------
 3 files changed, 149 insertions(+), 81 deletions(-)

diff --git 
a/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/integration/GraphQlSourceForCauseway.java
 
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/integration/GraphQlSourceForCauseway.java
index 2e697b6a5b..536b72c2e2 100644
--- 
a/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/integration/GraphQlSourceForCauseway.java
+++ 
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/integration/GraphQlSourceForCauseway.java
@@ -33,8 +33,7 @@ import org.apache.causeway.applib.id.HasLogicalType;
 
 import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
 
-import 
org.apache.causeway.viewer.graphql.viewer.integration.AsyncExecutionStrategyResolvingWithinInteraction;
-
+import org.apache.causeway.viewer.graphql.viewer.source.GraphQLTypeRegistry;
 import org.apache.causeway.viewer.graphql.viewer.source.ObjectTypeFactory;
 import org.apache.causeway.viewer.graphql.viewer.source.QueryFieldFactory;
 
@@ -68,6 +67,7 @@ public class GraphQlSourceForCauseway implements 
GraphQlSource {
     private final AsyncExecutionStrategyResolvingWithinInteraction 
executionStrategy;
     private final ObjectTypeFactory objectTypeFactory;
     private final QueryFieldFactory queryFieldFactory;
+    private final GraphQLTypeRegistry graphQLTypeRegistry;
 
     @PostConstruct
     public void init() {
@@ -96,12 +96,10 @@ public class GraphQlSourceForCauseway implements 
GraphQlSource {
         final GraphQLObjectType.Builder queryBuilder = 
newObject().name("Query");
         final GraphQLCodeRegistry.Builder codeRegistryBuilder = 
GraphQLCodeRegistry.newCodeRegistry();
 
-        Set<GraphQLType> graphQLObjectTypes = new HashSet<>();
-
         specificationLoader.snapshotSpecifications()
             .distinct((a, b) -> 
a.getLogicalTypeName().equals(b.getLogicalTypeName()))
             .sorted(Comparator.comparing(HasLogicalType::getLogicalTypeName))
-            .forEach(objectSpec -> handleObjectSpec(objectSpec, 
graphQLObjectTypes, queryBuilder, codeRegistryBuilder));
+            .forEach(objectSpec -> handleObjectSpec(objectSpec, queryBuilder, 
codeRegistryBuilder));
 
         val query_numServices = newFieldDefinition()
                 .name("numServices")
@@ -120,14 +118,13 @@ public class GraphQlSourceForCauseway implements 
GraphQlSource {
 
         return GraphQLSchema.newSchema()
                 .query(query)
-                .additionalTypes(graphQLObjectTypes)
+                .additionalTypes(graphQLTypeRegistry.getGraphQLObjectTypes())
                 .codeRegistry(codeRegistry)
                 .build();
     }
 
     private void handleObjectSpec(
             final ObjectSpecification objectSpec,
-            final Set<GraphQLType> graphQLObjectTypes,
             final GraphQLObjectType.Builder queryBuilder,
             final GraphQLCodeRegistry.Builder codeRegistryBuilder
     ) {
@@ -139,7 +136,7 @@ public class GraphQlSourceForCauseway implements 
GraphQlSource {
             case ENTITY:     // @DomainObject(nature=ENTITY)
 
                 // TODO: App interface should map to gql interfaces?
-                
objectTypeFactory.objectTypeFromObjectSpecification(objectSpec, 
graphQLObjectTypes, codeRegistryBuilder);
+                
objectTypeFactory.objectTypeFromObjectSpecification(objectSpec, 
codeRegistryBuilder);
 
                 break;
 
diff --git 
a/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GraphQLTypeRegistry.java
 
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GraphQLTypeRegistry.java
new file mode 100644
index 0000000000..a5fb72e23d
--- /dev/null
+++ 
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GraphQLTypeRegistry.java
@@ -0,0 +1,135 @@
+package org.apache.causeway.viewer.graphql.viewer.source;
+
+import graphql.schema.GraphQLInputObjectType;
+import graphql.schema.GraphQLNamedType;
+import graphql.schema.GraphQLObjectType;
+import graphql.schema.GraphQLType;
+
+import lombok.extern.log4j.Log4j2;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.springframework.stereotype.Component;
+
+@Component
+@Log4j2
+public class GraphQLTypeRegistry {
+
+
+    Set<GraphQLType> graphQLObjectTypes = new HashSet<>();
+
+    public Set<GraphQLType> getGraphQLObjectTypes() {
+        return Collections.unmodifiableSet(graphQLObjectTypes);
+    }
+
+
+    void addTypeIfNotAlreadyPresent(
+            final GraphQLType typeToAdd,
+            final String logicalTypeName) {
+
+        if (typeToAdd instanceof GraphQLObjectType) {
+            addTypeIfNotAlreadyPresent((GraphQLObjectType) typeToAdd, 
logicalTypeName);
+            return;
+        }
+
+        if (typeToAdd instanceof GraphQLInputObjectType) {
+            addTypeIfNotAlreadyPresent((GraphQLInputObjectType) typeToAdd, 
logicalTypeName);
+            return;
+        }
+
+        // TODO: none of these types yet handled
+        // GraphQLTypeReference
+        // GraphQLScalarType
+        // GraphQLCompositeType
+        // GraphQLUnionType
+        // GraphQLEnumType
+        // GraphQLInterfaceType
+        // GraphQLList
+        // GraphQLNonNull
+        log.warn("GraphQLType {} not yet implemented", 
typeToAdd.getClass().getName());
+    }
+
+    void addTypeIfNotAlreadyPresent(
+            final GraphQLInputObjectType typeToAdd,
+            final String logicalTypeName) {
+        if (isPresent(typeToAdd, GraphQLInputObjectType.class)){
+            // For now we just log and skip
+            log.info("GraphQLInputObjectType for {} already present", 
logicalTypeName);
+            return;
+        }
+        graphQLObjectTypes.add(typeToAdd);
+    }
+
+    void addTypeIfNotAlreadyPresent(
+            final GraphQLObjectType typeToAdd,
+            final String logicalTypeName){
+
+        if (isPresent(typeToAdd, GraphQLObjectType.class)){
+            // For now we just log and skip
+            log.info("GraphQLObjectType for {} already present", 
logicalTypeName);
+            return;
+        }
+        graphQLObjectTypes.add(typeToAdd);
+    }
+
+
+    public void addTypeIfNotAlreadyPresent(final GraphQLType typeToAdd) {
+
+        if (typeToAdd instanceof GraphQLObjectType) {
+            addTypeIfNotAlreadyPresent((GraphQLObjectType) typeToAdd);
+            return;
+        }
+
+        if (typeToAdd instanceof GraphQLInputObjectType) {
+            addTypeIfNotAlreadyPresent((GraphQLInputObjectType) typeToAdd);
+            return;
+        }
+
+        // TODO: none of these types yet handled
+        // GraphQLTypeReference
+        // GraphQLScalarType
+        // GraphQLCompositeType
+        // GraphQLUnionType
+        // GraphQLEnumType
+        // GraphQLInterfaceType
+        // GraphQLList
+        // GraphQLNonNull
+        log.warn("GraphQLType {} not yet implemented", 
typeToAdd.getClass().getName());
+    }
+
+    void addTypeIfNotAlreadyPresent(final GraphQLObjectType typeToAdd){
+        if (isPresent(typeToAdd, GraphQLObjectType.class)){
+            // For now we just log and skip
+            log.info("GraphQLObjectType for {} already present", 
typeToAdd.getName());
+            return;
+        }
+        add(typeToAdd);
+    }
+
+
+    void addTypeIfNotAlreadyPresent(final GraphQLInputObjectType typeToAdd) {
+        if (isPresent(typeToAdd, GraphQLInputObjectType.class)){
+            // For now we just log and skip
+            log.info("GraphQLInputObjectType for {} already present", 
typeToAdd.getName());
+            return;
+        }
+        add(typeToAdd);
+    }
+
+    private boolean isPresent(
+            final GraphQLNamedType typeToAdd,
+            final Class<? extends GraphQLNamedType> cls) {
+        return  graphQLObjectTypes.stream()
+                .filter(o -> o.getClass().isAssignableFrom(cls))
+                .map(cls::cast)
+                .anyMatch(ot -> ot.getName().equals(typeToAdd.getName()));
+    }
+
+
+    private void add(GraphQLType typeToAdd) {
+        graphQLObjectTypes.add(typeToAdd);
+    }
+
+}
diff --git 
a/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/ObjectTypeFactory.java
 
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/ObjectTypeFactory.java
index 4490daf6c9..0810a15e90 100644
--- 
a/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/ObjectTypeFactory.java
+++ 
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/ObjectTypeFactory.java
@@ -54,7 +54,6 @@ import graphql.schema.GraphQLFieldDefinition;
 import graphql.schema.GraphQLInputObjectField;
 import graphql.schema.GraphQLInputObjectType;
 import graphql.schema.GraphQLInputType;
-import graphql.schema.GraphQLNamedType;
 import graphql.schema.GraphQLObjectType;
 import graphql.schema.GraphQLOutputType;
 import graphql.schema.GraphQLType;
@@ -63,7 +62,6 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.RequiredArgsConstructor;
 import lombok.experimental.UtilityClass;
-import lombok.extern.java.Log;
 import lombok.extern.log4j.Log4j2;
 import lombok.val;
 
@@ -73,10 +71,11 @@ import lombok.val;
 public class ObjectTypeFactory {
 
     final static String GQL_INPUTTYPE_PREFIX = "_gql_input__";
-    final static String GQL_MUTATTIONS_FIELDNAME = "_gql_mutations";
+    final static String GQL_MUTATIONS_FIELDNAME = "_gql_mutations";
     private final BookmarkService bookmarkService;
     private final SpecificationLoader specificationLoader;
     private final ObjectManager objectManager;
+    private final GraphQLTypeRegistry graphQLTypeRegistry;
 
     static String mutatorsTypeName(final String logicalTypeNameSanitized){
         return logicalTypeNameSanitized + "__DomainObject_mutators";
@@ -106,7 +105,6 @@ public class ObjectTypeFactory {
 
     public void objectTypeFromObjectSpecification(
             final ObjectSpecification objectSpec,
-            final Set<GraphQLType> graphQLObjectTypes,
             final GraphQLCodeRegistry.Builder codeRegistryBuilder) {
 
         val gqlvObjectSpec = new GqlvObjectSpec(objectSpec);
@@ -117,7 +115,7 @@ public class ObjectTypeFactory {
 
         GraphQLObjectType metaType = gqlvObjectSpec.getMetaType();
 
-        addTypeIfNotAlreadyPresent(graphQLObjectTypes, metaType, 
logicalTypeNameSanitized);
+        graphQLTypeRegistry.addTypeIfNotAlreadyPresent(metaType, 
logicalTypeNameSanitized);
 
         // add meta field
         val _gql_meta_Field = 
newFieldDefinition().name("_gql_meta").type(metaType).build();
@@ -133,7 +131,7 @@ public class ObjectTypeFactory {
                 .build());
         GraphQLInputType inputType = inputTypeBuilder.build();
 
-        addTypeIfNotAlreadyPresent(graphQLObjectTypes, inputType, 
inputTypeName);
+        graphQLTypeRegistry.addTypeIfNotAlreadyPresent(inputType, 
inputTypeName);
 
         // add fields
         gqlvObjectSpec.addFields();
@@ -143,11 +141,11 @@ public class ObjectTypeFactory {
 
         // add actions
         MutatorsDataForEntity mutatorsDataForEntity =
-                addActions(gqlvObjectSpec.getLogicalTypeNameSanitized(), 
objectSpec, gqlvObjectSpec.getObjectTypeBuilder(), graphQLObjectTypes);
+                addActions(gqlvObjectSpec.getLogicalTypeNameSanitized(), 
objectSpec, gqlvObjectSpec.getObjectTypeBuilder());
 
         // build and register object type
         GraphQLObjectType graphQLObjectType = 
gqlvObjectSpec.getObjectTypeBuilder().build();
-        addTypeIfNotAlreadyPresent(graphQLObjectTypes, graphQLObjectType, 
gqlvObjectSpec.getLogicalTypeNameSanitized());
+        graphQLTypeRegistry.addTypeIfNotAlreadyPresent(graphQLObjectType, 
gqlvObjectSpec.getLogicalTypeNameSanitized());
 
         // create and register data fetchers
         createAndRegisterDataFetchersForMetaData(
@@ -168,67 +166,6 @@ public class ObjectTypeFactory {
 
     }
 
-    void addTypeIfNotAlreadyPresent(
-            final Set<GraphQLType> graphQLObjectTypes,
-            final GraphQLType typeToAdd,
-            final String logicalTypeName) {
-
-        if (typeToAdd instanceof GraphQLObjectType) {
-            addTypeIfNotAlreadyPresent(graphQLObjectTypes, (GraphQLObjectType) 
typeToAdd, logicalTypeName);
-            return;
-        }
-
-        if (typeToAdd instanceof GraphQLInputObjectType) {
-            addTypeIfNotAlreadyPresent(graphQLObjectTypes, 
(GraphQLInputObjectType) typeToAdd, logicalTypeName);
-            return;
-        }
-
-        // TODO: none of these types yet handled
-        // GraphQLTypeReference
-        // GraphQLScalarType
-        // GraphQLCompositeType
-        // GraphQLUnionType
-        // GraphQLEnumType
-        // GraphQLInterfaceType
-        // GraphQLList
-        // GraphQLNonNull
-        log.warn("GraphQLType {} not yet implemented", 
typeToAdd.getClass().getName());
-    }
-
-    private static void addTypeIfNotAlreadyPresent(
-            final Set<GraphQLType> graphQLObjectTypes,
-            final GraphQLInputObjectType typeToAdd,
-            final String logicalTypeName) {
-        if (isPresent(graphQLObjectTypes, typeToAdd, 
GraphQLInputObjectType.class)){
-            // For now we just log and skip
-            log.info("GraphQLInputObjectType for {} already present", 
logicalTypeName);
-            return;
-        }
-        graphQLObjectTypes.add(typeToAdd);
-    }
-
-    void addTypeIfNotAlreadyPresent(
-            final Set<GraphQLType> graphQLObjectTypes,
-            final GraphQLObjectType typeToAdd,
-            final String logicalTypeName){
-
-        if (isPresent(graphQLObjectTypes, typeToAdd, GraphQLObjectType.class)){
-            // For now we just log and skip
-            log.info("GraphQLObjectType for {} already present", 
logicalTypeName);
-            return;
-        }
-        graphQLObjectTypes.add(typeToAdd);
-    }
-
-    private static boolean isPresent(
-            final Set<GraphQLType> graphQLObjectTypes,
-            final GraphQLNamedType typeToAdd,
-            final Class<? extends GraphQLNamedType> cls) {
-        return graphQLObjectTypes.stream()
-                .filter(o -> o.getClass().isAssignableFrom(cls))
-                .map(cls::cast)
-                .anyMatch(ot -> ot.getName().equals(typeToAdd.getName()));
-    }
 
     void createAndRegisterDataFetchersForField(
             final ObjectSpecification objectSpecification,
@@ -256,8 +193,7 @@ public class ObjectTypeFactory {
     MutatorsDataForEntity addActions(
             final String logicalTypeNameSanitized,
             final ObjectSpecification objectSpecification,
-            final GraphQLObjectType.Builder objectTypeBuilder,
-            final Set<GraphQLType> graphQLObjectTypes) {
+            final GraphQLObjectType.Builder objectTypeBuilder) {
 
         MutatorManager result = mutatorManager(logicalTypeNameSanitized);
 
@@ -268,9 +204,9 @@ public class ObjectTypeFactory {
 
         if (!result.mutatorsTypeFields.isEmpty()){
             GraphQLObjectType mutatorsType = 
result.mutatorsTypeBuilder.build();
-            addTypeIfNotAlreadyPresent(graphQLObjectTypes, mutatorsType, 
result.mutatorsTypeName);
+            graphQLTypeRegistry.addTypeIfNotAlreadyPresent(mutatorsType, 
result.mutatorsTypeName);
             GraphQLFieldDefinition gql_mutations = newFieldDefinition()
-                    .name(GQL_MUTATTIONS_FIELDNAME)
+                    .name(GQL_MUTATIONS_FIELDNAME)
                     .type(mutatorsType)
                     .build();
             objectTypeBuilder.field(gql_mutations);

Reply via email to