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 c2a98c7b0f0bc7bf34a0436d8229c7a82d4c6df5 Author: danhaywood <[email protected]> AuthorDate: Tue Feb 20 23:32:36 2024 +0000 CAUSEWAY-3676: wip on introducing rich and simple schema styles --- .../core/config/CausewayConfiguration.java | 4 ++ .../graphql/model/src/main/java/module-info.java | 1 + .../graphql/model/domain/GqlvAbstractCustom.java | 5 ++- .../rich/GqlvTopLevelRich.java} | 23 +++++++---- .../GqlvTopLevelQueryForSimpleAndRich.java | 26 ++++++++++++ .../viewer/graphql/model/toplevel/RichSchema.java | 19 +++++++++ .../graphql/model/toplevel/SimpleSchema.java | 19 +++++++++ .../integration/GraphQlSourceForCauseway.java | 46 ++++++++++++++++++---- 8 files changed, 127 insertions(+), 16 deletions(-) diff --git a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java index aed45643f7..6084e42e23 100644 --- a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java +++ b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java @@ -2375,6 +2375,10 @@ public class CausewayConfiguration { */ SIMPLE_AND_RICH, ; + + public boolean isRich() { + return this == RICH_ONLY || this == SIMPLE_AND_RICH; + } } /** diff --git a/viewers/graphql/model/src/main/java/module-info.java b/viewers/graphql/model/src/main/java/module-info.java index 4da4776905..5ee6bb25a1 100644 --- a/viewers/graphql/model/src/main/java/module-info.java +++ b/viewers/graphql/model/src/main/java/module-info.java @@ -8,6 +8,7 @@ module org.apache.causeway.incubator.viewer.graphql.model { exports org.apache.causeway.viewer.graphql.model.context; exports org.apache.causeway.viewer.graphql.model.mmproviders; exports org.apache.causeway.viewer.graphql.model.fetcher; + exports org.apache.causeway.viewer.graphql.model.domain.rich; requires org.apache.causeway.core.config; requires org.apache.causeway.incubator.viewer.graphql.applib; diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAbstractCustom.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAbstractCustom.java index 714437947a..1d6cee0e5b 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAbstractCustom.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAbstractCustom.java @@ -39,7 +39,7 @@ public abstract class GqlvAbstractCustom extends GqlvAbstract implements Parent protected final GraphQLObjectType.Builder gqlObjectTypeBuilder; private final String typeName; - @Getter(AccessLevel.PROTECTED) + @Getter private GraphQLObjectType gqlObjectType; protected GqlvAbstractCustom( @@ -111,6 +111,9 @@ public abstract class GqlvAbstractCustom extends GqlvAbstract implements Parent return this.gqlObjectType; } + public void addDataFetchers() { + } + public final FieldCoordinates coordinatesFor(final GraphQLFieldDefinition field) { if (gqlObjectType == null) { throw new IllegalStateException( diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/toplevel/GqlvTopLevelQuery.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/GqlvTopLevelRich.java similarity index 79% rename from viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/toplevel/GqlvTopLevelQuery.java rename to viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/GqlvTopLevelRich.java index f2a325f6f0..639d3962d8 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/toplevel/GqlvTopLevelQuery.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/GqlvTopLevelRich.java @@ -1,4 +1,4 @@ -package org.apache.causeway.viewer.graphql.model.toplevel; +package org.apache.causeway.viewer.graphql.model.domain.rich; import java.util.ArrayList; import java.util.List; @@ -6,25 +6,28 @@ import java.util.List; import graphql.schema.DataFetchingEnvironment; import graphql.schema.GraphQLObjectType; +import org.apache.causeway.core.config.CausewayConfiguration; import org.apache.causeway.viewer.graphql.model.context.Context; import org.apache.causeway.viewer.graphql.model.domain.GqlvAbstractCustom; -import org.apache.causeway.viewer.graphql.model.domain.rich.GqlvDomainObject; -import org.apache.causeway.viewer.graphql.model.domain.rich.GqlvDomainService; import org.apache.causeway.viewer.graphql.model.domain.GqlvScenario; import org.apache.causeway.viewer.graphql.model.domain.Parent; -public class GqlvTopLevelQuery +public class GqlvTopLevelRich extends GqlvAbstractCustom implements Parent { + private final CausewayConfiguration.Viewer.Graphql graphqlConfiguration; + private final List<GqlvDomainService> domainServices = new ArrayList<>(); private final List<GqlvDomainObject> domainObjects = new ArrayList<>(); private final GqlvScenario scenario; - public GqlvTopLevelQuery(final Context context) { + public GqlvTopLevelRich(final Context context) { super("Query", context); + graphqlConfiguration = context.causewayConfiguration.getViewer().getGraphql(); + // add domain object lookup to top-level query context.objectSpecifications().forEach(objectSpec -> { switch (objectSpec.getBeanSort()) { @@ -51,7 +54,11 @@ public class GqlvTopLevelQuery } }); - addChildFieldFor(scenario = new GqlvScenario(context)); + if (graphqlConfiguration.isIncludeTestingFieldInRich()) { + addChildFieldFor(scenario = new GqlvScenario(context)); + } else { + scenario = null; + } buildObjectType(); } @@ -84,6 +91,8 @@ public class GqlvTopLevelQuery domainObjects.forEach(domainObject -> domainObject.addDataFetcher(this)); - scenario.addDataFetcher(this); + if (scenario != null) { + scenario.addDataFetcher(this); + } } } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/toplevel/GqlvTopLevelQueryForSimpleAndRich.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/toplevel/GqlvTopLevelQueryForSimpleAndRich.java new file mode 100644 index 0000000000..af2f6c1e8c --- /dev/null +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/toplevel/GqlvTopLevelQueryForSimpleAndRich.java @@ -0,0 +1,26 @@ +package org.apache.causeway.viewer.graphql.model.toplevel; + +import graphql.schema.DataFetchingEnvironment; + +import org.apache.causeway.viewer.graphql.model.context.Context; +import org.apache.causeway.viewer.graphql.model.domain.GqlvAbstractCustom; + +public class GqlvTopLevelQueryForSimpleAndRich extends GqlvAbstractCustom { + + private final RichSchema richSchema; + private final SimpleSchema simpleSchema; + + public GqlvTopLevelQueryForSimpleAndRich(final Context context) { + super("SimpleAndRich", context); + + addChildFieldFor(richSchema = new RichSchema(context)); + addChildFieldFor(simpleSchema = new SimpleSchema(context)); + + buildObjectType(); + } + + @Override + protected Object fetchData(DataFetchingEnvironment environment) { + return environment; + } +} diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/toplevel/RichSchema.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/toplevel/RichSchema.java new file mode 100644 index 0000000000..39b6fd0a91 --- /dev/null +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/toplevel/RichSchema.java @@ -0,0 +1,19 @@ +package org.apache.causeway.viewer.graphql.model.toplevel; + +import graphql.schema.DataFetchingEnvironment; + +import org.apache.causeway.viewer.graphql.model.context.Context; +import org.apache.causeway.viewer.graphql.model.domain.GqlvAbstractCustom; + +public class RichSchema extends GqlvAbstractCustom { + + protected RichSchema(final Context context) { + super("rich", context); + + } + + @Override + protected Object fetchData(DataFetchingEnvironment environment) { + return environment; + } +} diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/toplevel/SimpleSchema.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/toplevel/SimpleSchema.java new file mode 100644 index 0000000000..9557001d5a --- /dev/null +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/toplevel/SimpleSchema.java @@ -0,0 +1,19 @@ +package org.apache.causeway.viewer.graphql.model.toplevel; + +import graphql.schema.DataFetchingEnvironment; + +import org.apache.causeway.viewer.graphql.model.context.Context; +import org.apache.causeway.viewer.graphql.model.domain.GqlvAbstractCustom; + +public class SimpleSchema extends GqlvAbstractCustom { + + protected SimpleSchema(final Context context) { + super("simple", context); + + } + + @Override + protected Object fetchData(DataFetchingEnvironment environment) { + return environment; + } +} 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 2404d5f950..bb314e0351 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,15 @@ package org.apache.causeway.viewer.graphql.viewer.integration; import javax.annotation.PostConstruct; -import javax.inject.Inject; import graphql.GraphQL; import graphql.execution.SimpleDataFetcherExceptionHandler; import graphql.schema.GraphQLSchema; +import org.apache.causeway.viewer.graphql.model.domain.GqlvAbstractCustom; + +import org.apache.causeway.viewer.graphql.model.toplevel.GqlvTopLevelQueryForSimpleAndRich; + import org.springframework.graphql.execution.GraphQlSource; import org.springframework.stereotype.Service; @@ -35,13 +38,12 @@ import org.apache.causeway.core.metamodel.specloader.SpecificationLoader; import org.apache.causeway.viewer.graphql.model.context.Context; import org.apache.causeway.viewer.graphql.model.registry.GraphQLTypeRegistry; import org.apache.causeway.viewer.graphql.model.toplevel.GqlvTopLevelMutation; -import org.apache.causeway.viewer.graphql.model.toplevel.GqlvTopLevelQuery; +import org.apache.causeway.viewer.graphql.model.domain.rich.GqlvTopLevelRich; -import lombok.RequiredArgsConstructor; import lombok.val; @Service() -@RequiredArgsConstructor(onConstructor_ = {@Inject}) +//@RequiredArgsConstructor(onConstructor_ = {@Inject}) public class GraphQlSourceForCauseway implements GraphQlSource { private final CausewayConfiguration causewayConfiguration; @@ -49,9 +51,27 @@ public class GraphQlSourceForCauseway implements GraphQlSource { private final SpecificationLoader specificationLoader; private final GraphQLTypeRegistry graphQLTypeRegistry; private final Context context; - private final AsyncExecutionStrategyResolvingWithinInteraction executionStrategy; + private CausewayConfiguration.Viewer.Graphql graphqlConfiguration; + + public GraphQlSourceForCauseway( + final CausewayConfiguration causewayConfiguration, + final CausewaySystemEnvironment causewaySystemEnvironment, + final SpecificationLoader specificationLoader, + final GraphQLTypeRegistry graphQLTypeRegistry, + final Context context, + final AsyncExecutionStrategyResolvingWithinInteraction executionStrategy) { + this.causewayConfiguration = causewayConfiguration; + this.causewaySystemEnvironment = causewaySystemEnvironment; + this.specificationLoader = specificationLoader; + this.graphQLTypeRegistry = graphQLTypeRegistry; + this.context = context; + this.executionStrategy = executionStrategy; + + this.graphqlConfiguration = causewayConfiguration.getViewer().getGraphql(); + } + @PostConstruct public void init() { boolean fullyIntrospect = IntrospectionMode.isFullIntrospect(causewayConfiguration, causewaySystemEnvironment); @@ -82,11 +102,21 @@ public class GraphQlSourceForCauseway implements GraphQlSource { throw new IllegalStateException("Metamodel is not fully introspected"); } - // top-level query and mutation type - val topLevelQuery = new GqlvTopLevelQuery(context); + GqlvAbstractCustom topLevelQuery; + switch (graphqlConfiguration.getSchemaStyle()) { + case SIMPLE_ONLY: + throw new IllegalStateException("SIMPLE_ONLY not yet supported"); + case RICH_ONLY: + topLevelQuery = new GqlvTopLevelRich(context); + break; + case SIMPLE_AND_RICH: + default: + topLevelQuery = new GqlvTopLevelQueryForSimpleAndRich(context); + break; + } + val topLevelMutation = new GqlvTopLevelMutation(context); - // add the data fetchers topLevelQuery.addDataFetchers(); topLevelMutation.addDataFetchers();
