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
The following commit(s) were added to refs/heads/CAUSEWAY-3676 by this push:
new d87e120a50 CAUSEWAY-3676: introduces GqlvObjectBehaviour
d87e120a50 is described below
commit d87e120a5072fe18d4256455d10db94b62b3bc39
Author: danhaywood <[email protected]>
AuthorDate: Fri Jan 19 13:37:48 2024 +0000
CAUSEWAY-3676: introduces GqlvObjectBehaviour
---
.../graphql/viewer/source/GqlvObjectBehaviour.java | 167 ++++++++++++++++++++
...qlvObjectSpec.java => GqlvObjectStructure.java} | 38 +----
.../graphql/viewer/source/ObjectTypeFactory.java | 168 +++------------------
3 files changed, 191 insertions(+), 182 deletions(-)
diff --git
a/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GqlvObjectBehaviour.java
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GqlvObjectBehaviour.java
new file mode 100644
index 0000000000..c5117c9e62
--- /dev/null
+++
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GqlvObjectBehaviour.java
@@ -0,0 +1,167 @@
+package org.apache.causeway.viewer.graphql.viewer.source;
+
+
+import graphql.schema.DataFetcher;
+import graphql.schema.FieldCoordinates;
+import graphql.schema.GraphQLCodeRegistry;
+
+import graphql.schema.GraphQLFieldDefinition;
+import graphql.schema.GraphQLObjectType;
+import graphql.schema.GraphQLType;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.RequiredArgsConstructor;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.causeway.applib.services.bookmark.BookmarkService;
+import org.apache.causeway.applib.services.metamodel.BeanSort;
+import org.apache.causeway.core.metamodel.object.ManagedObject;
+import org.apache.causeway.core.metamodel.objectmanager.ObjectManager;
+import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
+import org.apache.causeway.core.metamodel.spec.feature.MixedIn;
+import org.apache.causeway.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.causeway.core.metamodel.specloader.SpecificationLoader;
+
+import static graphql.schema.GraphQLObjectType.newObject;
+
+@RequiredArgsConstructor
+public class GqlvObjectBehaviour {
+
+ private final GqlvObjectStructure gqlvObjectStructure;
+ private final GraphQLCodeRegistry.Builder codeRegistryBuilder;
+ private final BookmarkService bookmarkService;
+ private final ObjectManager objectManager;
+ private final SpecificationLoader specificationLoader;
+
+
+
+ public void createAndRegisterDataFetchersForMetaData() {
+
+ codeRegistryBuilder.dataFetcher(
+
FieldCoordinates.coordinates(gqlvObjectStructure.getGqlObjectType(),
gqlvObjectStructure.getMetaField()),
+ (DataFetcher<Object>) environment -> {
+ return bookmarkService.bookmarkFor(environment.getSource())
+ .map(bookmark -> new GqlvMeta(bookmark,
bookmarkService, objectManager))
+ .orElse(null); //TODO: is this correct ?
+ });
+
+ GraphQLObjectType metaType = gqlvObjectStructure.getMetaType();
+ gqlvObjectStructure.getMetaField().getType();
+ codeRegistryBuilder.dataFetcher(
+ FieldCoordinates.coordinates(metaType,
ObjectTypeFactory.Fields.id),
+ (DataFetcher<Object>) environment -> {
+ GqlvMeta gqlvMeta = environment.getSource();
+ return gqlvMeta.id();
+ });
+
+ codeRegistryBuilder.dataFetcher(
+
FieldCoordinates.coordinates(gqlvObjectStructure.getMetaType(),
ObjectTypeFactory.Fields.logicalTypeName),
+ (DataFetcher<Object>) environment -> {
+ GqlvMeta gqlvMeta = environment.getSource();
+ return gqlvMeta.logicalTypeName();
+ });
+
+ if (gqlvObjectStructure.getBeanSort() == BeanSort.ENTITY) {
+ codeRegistryBuilder.dataFetcher(
+
FieldCoordinates.coordinates(gqlvObjectStructure.getMetaType(),
ObjectTypeFactory.Fields.version),
+ (DataFetcher<Object>) environment -> {
+ GqlvMeta gqlvMeta = environment.getSource();
+ return gqlvMeta.version();
+ });
+ }
+ }
+
+
+ public void createAndRegisterDataFetchersForField() {
+ gqlvObjectStructure.getObjectSpec().streamProperties(MixedIn.INCLUDED)
+
.forEach(this::createAndRegisterDataFetcherForObjectAssociation);
+ }
+
+ void createAndRegisterDataFetchersForCollection() {
+ gqlvObjectStructure.getObjectSpec().streamCollections(MixedIn.INCLUDED)
+
.forEach(this::createAndRegisterDataFetcherForObjectAssociation);
+ }
+
+
+ private void createAndRegisterDataFetcherForObjectAssociation(final
ObjectAssociation otom) {
+
+ final GraphQLObjectType graphQLObjectType =
gqlvObjectStructure.getGqlObjectType();
+
+ ObjectSpecification fieldObjectSpecification = otom.getElementType();
+ BeanSort beanSort = fieldObjectSpecification.getBeanSort();
+ switch (beanSort) {
+
+ case VALUE: //TODO: does this work for values as well?
+
+ case VIEW_MODEL:
+
+ case ENTITY:
+
+ codeRegistryBuilder
+ .dataFetcher(
+
FieldCoordinates.coordinates(graphQLObjectType, otom.getId()),
+ (DataFetcher<Object>) environment -> {
+
+ Object domainObjectInstance =
environment.getSource();
+
+ Class<?> domainObjectInstanceClass =
domainObjectInstance.getClass();
+ ObjectSpecification specification =
specificationLoader.loadSpecification(domainObjectInstanceClass);
+
+ ManagedObject owner =
ManagedObject.adaptSingular(specification, domainObjectInstance);
+
+ ManagedObject managedObject =
otom.get(owner);
+
+ return managedObject!=null ?
managedObject.getPojo() : null;
+
+ });
+
+
+ break;
+
+ }
+ }
+
+ public void createAndRegisterDataFetchersForMutators() {
+
+ // something like:
+
+//
codeRegistryBuilder.dataFetcher(FieldCoordinates.coordinates(graphQLTypeReference,
gql_mutations), new DataFetcher<Object>() {
+// @Override
+// public Object get(DataFetchingEnvironment environment)
throws Exception {
+//
+// Bookmark bookmark =
bookmarkService.bookmarkFor(environment.getSource()).orElse(null);
+// if (bookmark == null) return null; //TODO: is this
correct ?
+// return new GqlvMutations(bookmark, bookmarkService,
mutatorsTypeFields);
+// }
+// });
+//
+// // for each field something like
+//
codeRegistryBuilder.dataFetcher(FieldCoordinates.coordinates(mutatorsType,
idField), new DataFetcher<Object>() {
+// @Override
+// public Object get(DataFetchingEnvironment environment)
throws Exception {
+//
+// GqlvMeta gqlMeta = environment.getSource();
+//
+// return gqlMeta.id();
+// }
+// });
+
+
+ }
+
+
+ GraphQLObjectType createAndRegisterMutatorsType(
+ final Set<GraphQLType> graphQLObjectTypes) {
+
+ //TODO: this is not going to work, because we need to dynamically add
fields
+ String mutatorsTypeName =
gqlvObjectStructure.getLogicalTypeNameSanitized() + "__DomainObject_mutators";
+ GraphQLObjectType.Builder mutatorsTypeBuilder =
newObject().name(mutatorsTypeName);
+ GraphQLObjectType mutatorsType = mutatorsTypeBuilder.build();
+ graphQLObjectTypes.add(mutatorsType);
+ return mutatorsType;
+ }
+
+}
diff --git
a/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GqlvObjectSpec.java
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GqlvObjectStructure.java
similarity index 86%
rename from
incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GqlvObjectSpec.java
rename to
incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GqlvObjectStructure.java
index e9e433e7e2..e6d6d00fed 100644
---
a/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GqlvObjectSpec.java
+++
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GqlvObjectStructure.java
@@ -39,7 +39,7 @@ import static
org.apache.causeway.viewer.graphql.viewer.source.ObjectTypeFactory
/**
* A wrapper around {@link ObjectSpecification}
*/
-public class GqlvObjectSpec {
+public class GqlvObjectStructure {
@Getter private final ObjectSpecification objectSpec;
@Getter private final GraphQLFieldDefinition metaField;
@@ -80,7 +80,7 @@ public class GqlvObjectSpec {
*/
private Optional<GraphQLObjectType> mutatorsTypeIfAny;
- public GqlvObjectSpec(final ObjectSpecification objectSpec) {
+ public GqlvObjectStructure(final ObjectSpecification objectSpec) {
this.objectSpec = objectSpec;
this.gqlObjectTypeBuilder =
newObject().name(getLogicalTypeNameSanitized());
@@ -208,7 +208,7 @@ public class GqlvObjectSpec {
if (parameters.isNotEmpty()) {
builder.arguments(parameters.stream()
- .map(GqlvObjectSpec::gqlArgumentFor)
+ .map(GqlvObjectStructure::gqlArgumentFor)
.collect(Collectors.toList()));
}
}
@@ -285,15 +285,13 @@ public class GqlvObjectSpec {
: Optional.empty();
}
- ObjectTypeFactory.MutatorsDataForEntity addActions(GraphQLTypeRegistry
graphQLTypeRegistry) {
+ void addActions() {
getObjectSpec().streamActions(ActionScope.PRODUCTION, MixedIn.INCLUDED)
.forEach(this::addAction);
Optional<GraphQLObjectType> mutatorsTypeIfAny =
buildMutatorsTypeIfAny();
- return mutatorsTypeIfAny.map(mutatorsType -> {
-
- //graphQLTypeRegistry.addTypeIfNotAlreadyPresent(mutatorsType,
getMutatorsTypeName());
+ mutatorsTypeIfAny.ifPresent(mutatorsType -> {
GraphQLFieldDefinition gql_mutations = newFieldDefinition()
.name(ObjectTypeFactory.GQL_MUTATIONS_FIELDNAME)
@@ -301,31 +299,7 @@ public class GqlvObjectSpec {
.build();
getGqlObjectTypeBuilder().field(gql_mutations);
- return new ObjectTypeFactory.MutatorsDataForEntity(mutatorsType,
mutatorsTypeFields);
-
-// // I think we have to create and register data fetcher for
mutations here, but we can't since we have no objectTypeYet
-//
codeRegistryBuilder.dataFetcher(FieldCoordinates.coordinates(graphQLTypeReference,
gql_mutations), new DataFetcher<Object>() {
-// @Override
-// public Object get(DataFetchingEnvironment environment)
throws Exception {
-//
-// Bookmark bookmark =
bookmarkService.bookmarkFor(environment.getSource()).orElse(null);
-// if (bookmark == null) return null; //TODO: is this
correct ?
-// return new GqlvMutations(bookmark, bookmarkService,
mutatorsTypeFields);
-// }
-// });
-//
-// // for each field something like
-//
codeRegistryBuilder.dataFetcher(FieldCoordinates.coordinates(mutatorsType,
idField), new DataFetcher<Object>() {
-// @Override
-// public Object get(DataFetchingEnvironment environment)
throws Exception {
-//
-// GqlvMeta gqlMeta = environment.getSource();
-//
-// return gqlMeta.id();
-// }
-// });
- })
- .orElse(null);
+ });
}
}
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 36da141964..d9930f1bcb 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
@@ -64,10 +64,10 @@ public class ObjectTypeFactory {
final static String GQL_INPUTTYPE_PREFIX = "_gql_input__";
final static String GQL_MUTATIONS_FIELDNAME = "_gql_mutations";
+ private final GraphQLTypeRegistry graphQLTypeRegistry;
private final BookmarkService bookmarkService;
- private final SpecificationLoader specificationLoader;
private final ObjectManager objectManager;
- private final GraphQLTypeRegistry graphQLTypeRegistry;
+ private final SpecificationLoader specificationLoader;
@UtilityClass
static class Fields {
@@ -91,171 +91,39 @@ public class ObjectTypeFactory {
final ObjectSpecification objectSpec,
final GraphQLCodeRegistry.Builder codeRegistryBuilder) {
- val gqlvObjectSpec = new GqlvObjectSpec(objectSpec);
+ val gqlvObjectStructure = new GqlvObjectStructure(objectSpec);
-
graphQLTypeRegistry.addTypeIfNotAlreadyPresent(gqlvObjectSpec.getMetaField().getType());
+
graphQLTypeRegistry.addTypeIfNotAlreadyPresent(gqlvObjectStructure.getMetaField().getType());
// create input type
- GraphQLInputType inputType = gqlvObjectSpec.getGqlInputObjectType();
+ GraphQLInputType inputType =
gqlvObjectStructure.getGqlInputObjectType();
graphQLTypeRegistry.addTypeIfNotAlreadyPresent(inputType);
- gqlvObjectSpec.addPropertiesAsFields();
+ gqlvObjectStructure.addPropertiesAsFields();
- gqlvObjectSpec.addCollectionsAsLists();
+ gqlvObjectStructure.addCollectionsAsLists();
// add actions
- MutatorsDataForEntity mutatorsDataForEntity =
gqlvObjectSpec.addActions(graphQLTypeRegistry);
- if(gqlvObjectSpec.hasMutators()) {
-
gqlvObjectSpec.getMutatorsTypeIfAny().ifPresent(graphQLTypeRegistry::addTypeIfNotAlreadyPresent);
+ gqlvObjectStructure.addActions();
+ if(gqlvObjectStructure.hasMutators()) {
+
gqlvObjectStructure.getMutatorsTypeIfAny().ifPresent(graphQLTypeRegistry::addTypeIfNotAlreadyPresent);
}
// build and register object type
- GraphQLObjectType graphQLObjectType =
gqlvObjectSpec.buildGqlObjectType();
+ GraphQLObjectType graphQLObjectType =
gqlvObjectStructure.buildGqlObjectType();
graphQLTypeRegistry.addTypeIfNotAlreadyPresent(graphQLObjectType);
- // create and register data fetchers
- createAndRegisterDataFetchersForMetaData(codeRegistryBuilder,
gqlvObjectSpec);
- if (mutatorsDataForEntity!=null) {
- createAndRegisterDataFetchersForMutators(
- codeRegistryBuilder, gqlvObjectSpec.getBeanSort(),
mutatorsDataForEntity, gqlvObjectSpec.getGqlObjectType());
- }
- createAndRegisterDataFetchersForField(objectSpec, codeRegistryBuilder,
graphQLObjectType);
- createAndRegisterDataFetchersForCollection(objectSpec,
codeRegistryBuilder, graphQLObjectType);
- }
-
- private void createAndRegisterDataFetchersForMutators(
- final GraphQLCodeRegistry.Builder codeRegistryBuilder,
- final BeanSort objectSpecificationBeanSort,
- final MutatorsDataForEntity mutatorsDataForEntity,
- final GraphQLObjectType graphQLObjectType) {
-
- }
-
- void createAndRegisterDataFetchersForField(
- final ObjectSpecification objectSpecification,
- final GraphQLCodeRegistry.Builder codeRegistryBuilder,
- final GraphQLObjectType graphQLObjectType) {
- objectSpecification.streamProperties(MixedIn.INCLUDED)
- .forEach(otoa -> {
-
-
createAndRegisterDataFetcherForObjectAssociation(codeRegistryBuilder,
graphQLObjectType, otoa);
-
- });
- }
-
- void createAndRegisterDataFetchersForCollection(
- final ObjectSpecification objectSpecification,
- final GraphQLCodeRegistry.Builder codeRegistryBuilder,
- final GraphQLObjectType graphQLObjectType) {
-
- objectSpecification.streamCollections(MixedIn.INCLUDED)
- .forEach(otom -> {
-
createAndRegisterDataFetcherForObjectAssociation(codeRegistryBuilder,
graphQLObjectType, otom);
- });
- }
-
-
- @Data
- @AllArgsConstructor
- static class MutatorsDataForEntity {
-
- private GraphQLObjectType mutatorsType;
-
- private List<GraphQLFieldDefinition> mutatorsTypeFields;
-
- }
-
- private void createAndRegisterDataFetcherForObjectAssociation(
- final GraphQLCodeRegistry.Builder codeRegistryBuilder,
- final GraphQLObjectType graphQLObjectType,
- final ObjectAssociation otom) {
-
- ObjectSpecification fieldObjectSpecification = otom.getElementType();
- BeanSort beanSort = fieldObjectSpecification.getBeanSort();
- switch (beanSort) {
+ GqlvObjectBehaviour gqlvObjectBehaviour =
+ new GqlvObjectBehaviour(gqlvObjectStructure,
codeRegistryBuilder, bookmarkService, objectManager, specificationLoader);
- case VALUE: //TODO: does this work for values as well?
-
- case VIEW_MODEL:
-
- case ENTITY:
-
- codeRegistryBuilder
- .dataFetcher(
- FieldCoordinates.coordinates(graphQLObjectType,
otom.getId()),
- (DataFetcher<Object>) environment -> {
-
- Object domainObjectInstance = environment.getSource();
-
- Class<?> domainObjectInstanceClass =
domainObjectInstance.getClass();
- ObjectSpecification specification =
specificationLoader.loadSpecification(domainObjectInstanceClass);
-
- ManagedObject owner =
ManagedObject.adaptSingular(specification, domainObjectInstance);
-
- ManagedObject managedObject = otom.get(owner);
-
- return managedObject!=null ? managedObject.getPojo() :
null;
-
- });
-
-
- break;
-
- }
- }
-
-
- GraphQLObjectType createAndRegisterMutatorsType(
- final String logicalTypeNameSanitized,
- final BeanSort objectSpecificationBeanSort,
- final Set<GraphQLType> graphQLObjectTypes) {
-
- //TODO: this is not going to work, because we need to dynamically add
fields
- String mutatorsTypeName = logicalTypeNameSanitized +
"__DomainObject_mutators";
- GraphQLObjectType.Builder mutatorsTypeBuilder =
newObject().name(mutatorsTypeName);
- GraphQLObjectType mutatorsType = mutatorsTypeBuilder.build();
- graphQLObjectTypes.add(mutatorsType);
- return mutatorsType;
- }
-
- void createAndRegisterDataFetchersForMetaData(
- final GraphQLCodeRegistry.Builder codeRegistryBuilder,
- final GqlvObjectSpec gqlvObjectSpec) {
-
- codeRegistryBuilder.dataFetcher(
-
FieldCoordinates.coordinates(gqlvObjectSpec.getGqlObjectType(),
gqlvObjectSpec.getMetaField()),
- (DataFetcher<Object>) environment -> {
- return bookmarkService.bookmarkFor(environment.getSource())
- .map(bookmark -> new GqlvMeta(bookmark,
bookmarkService, objectManager))
- .orElse(null); //TODO: is this correct ?
- });
-
- GraphQLObjectType metaType = gqlvObjectSpec.getMetaType();
- gqlvObjectSpec.getMetaField().getType();
- codeRegistryBuilder.dataFetcher(
- FieldCoordinates.coordinates(metaType, Fields.id),
- (DataFetcher<Object>) environment -> {
- GqlvMeta gqlvMeta = environment.getSource();
- return gqlvMeta.id();
- });
-
- codeRegistryBuilder.dataFetcher(
- FieldCoordinates.coordinates(gqlvObjectSpec.getMetaType(),
Fields.logicalTypeName),
- (DataFetcher<Object>) environment -> {
- GqlvMeta gqlvMeta = environment.getSource();
- return gqlvMeta.logicalTypeName();
- });
+ // create and register data fetchers
+ gqlvObjectBehaviour.createAndRegisterDataFetchersForMetaData();
+ gqlvObjectBehaviour.createAndRegisterDataFetchersForMutators();
- if (gqlvObjectSpec.getBeanSort() == BeanSort.ENTITY) {
- codeRegistryBuilder.dataFetcher(
- FieldCoordinates.coordinates(gqlvObjectSpec.getMetaType(),
Fields.version),
- (DataFetcher<Object>) environment -> {
- GqlvMeta gqlvMeta = environment.getSource();
- return gqlvMeta.version();
- });
- }
+ gqlvObjectBehaviour.createAndRegisterDataFetchersForField();
+ gqlvObjectBehaviour.createAndRegisterDataFetchersForCollection();
}
}