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 adf6bd1889dc9dd884063bf0de1d05f64e02a013 Author: danhaywood <[email protected]> AuthorDate: Thu Feb 22 11:07:36 2024 +0000 CAUSEWAY-3676: wip - still factoring out simple vs rich schema --- .../graphql/model/domain/GqlvScenarioStep.java | 4 +- .../model/domain/common/SchemaStrategy.java | 38 +++++++++++-- .../domain/common/query/GqlvDomainService.java | 3 +- .../query/GqlvTopLevelQueryAbstractSchema.java | 8 ++- .../model/domain/common/query/GvqlActionUtils.java | 5 +- .../model/domain/rich/SchemaStrategyRich.java | 7 --- .../model/domain/simple/SchemaStrategySimple.java | 7 --- .../query/GqlvTopLevelQuerySimpleSchema.java | 37 ------------- viewers/graphql/test/src/test/resources/schema.gql | 63 ++++++++++++++++++++++ 9 files changed, 105 insertions(+), 67 deletions(-) diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvScenarioStep.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvScenarioStep.java index d340edc751..22ebf3f7fe 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvScenarioStep.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvScenarioStep.java @@ -37,7 +37,7 @@ public class GqlvScenarioStep case VIEW_MODEL: // @DomainObject(nature=VIEW_MODEL) case ENTITY: // @DomainObject(nature=ENTITY) - domainObjects.add(addChildFieldFor(GqlvTopLevelQuerySimpleSchema.of(schemaStrategy, objectSpec, context))); + domainObjects.add(addChildFieldFor(schemaStrategy.domainObjectFor(objectSpec, context))); break; } @@ -46,7 +46,7 @@ public class GqlvScenarioStep context.objectSpecifications().forEach(objectSpec -> { if (Objects.requireNonNull(objectSpec.getBeanSort()) == BeanSort.MANAGED_BEAN_CONTRIBUTING) { // @DomainService context.serviceRegistry.lookupBeanById(objectSpec.getLogicalTypeName()) - .ifPresent(servicePojo -> domainServices.add(addChildFieldFor(GqlvTopLevelQuerySimpleSchema.of(schemaStrategy, objectSpec, servicePojo, context)))); + .ifPresent(servicePojo -> domainServices.add(addChildFieldFor(schemaStrategy.domainServiceFor(objectSpec, servicePojo, context)))); } }); diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/SchemaStrategy.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/SchemaStrategy.java index 9eb1673ce1..64d0a0d4bd 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/SchemaStrategy.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/SchemaStrategy.java @@ -1,5 +1,7 @@ package org.apache.causeway.viewer.graphql.model.domain.common; +import lombok.val; + import java.util.Map; import org.apache.causeway.core.config.CausewayConfiguration; @@ -16,6 +18,8 @@ import org.apache.causeway.viewer.graphql.model.domain.common.query.GqlvMemberHo import org.apache.causeway.viewer.graphql.model.domain.rich.SchemaStrategyRich; import org.apache.causeway.viewer.graphql.model.domain.simple.SchemaStrategySimple; +import static org.apache.causeway.viewer.graphql.model.domain.common.query.GqlvTopLevelQueryAbstractSchema.superclassesOf; + public interface SchemaStrategy { SchemaStrategy RICH = new SchemaStrategyRich(); @@ -23,15 +27,27 @@ public interface SchemaStrategy { SchemaType getSchemaType(); + default GqlvDomainObject domainObjectFor( + final ObjectSpecification objectSpecification, + final Context context) { + + mapSuperclassesIfNecessary(this, objectSpecification, context); + return this.domainObjectBySpec(context).computeIfAbsent(objectSpecification, spec -> new GqlvDomainObject(this, spec, context)); + } + + default GqlvDomainService domainServiceFor( + final ObjectSpecification objectSpecification, + final Object servicePojo, + final Context context) { + return this.domainServiceBySpec(context).computeIfAbsent(objectSpecification, spec -> new GqlvDomainService(this, spec, servicePojo, context)); + } + Map<ObjectSpecification, GqlvDomainObject> domainObjectBySpec(Context context); Map<ObjectSpecification, GqlvDomainService> domainServiceBySpec(Context context); + String topLevelFieldNameFrom(CausewayConfiguration.Viewer.Graphql graphqlConfiguration); - GqlvAbstractCustom newGqlvDomainObject( - final ObjectSpecification objectSpecification, - final Context context - ); GqlvAbstractCustom newGqlvProperty( final GqlvMemberHolder holder, final OneToOneAssociation otoa, @@ -51,4 +67,18 @@ public interface SchemaStrategy { GqlvAbstractCustom newGqlvMeta( final GqlvDomainObject gqlvDomainObject, final Context context); + + private static void mapSuperclassesIfNecessary( + final SchemaStrategy schemaStrategy, + final ObjectSpecification objectSpecification, + final Context context) { + // no need to map if the target subclass has already been built + if(schemaStrategy.domainObjectBySpec(context).containsKey(objectSpecification)) { + return; + } + val superclasses = superclassesOf(objectSpecification); + superclasses.forEach(objectSpec -> schemaStrategy.domainObjectBySpec(context).computeIfAbsent(objectSpec, spec -> new GqlvDomainObject(schemaStrategy, spec, context))); + } + + } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/GqlvDomainService.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/GqlvDomainService.java index c91751ced9..347af2d9c8 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/GqlvDomainService.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/GqlvDomainService.java @@ -31,7 +31,6 @@ import org.apache.causeway.viewer.graphql.model.domain.GqlvAbstractCustom; import org.apache.causeway.viewer.graphql.model.domain.SchemaType; import org.apache.causeway.viewer.graphql.model.domain.TypeNames; import org.apache.causeway.viewer.graphql.model.domain.common.SchemaStrategy; -import org.apache.causeway.viewer.graphql.model.domain.simple.query.GqlvAction; import lombok.Getter; import lombok.val; @@ -88,7 +87,7 @@ public class GqlvDomainService .filter(objectAction -> objectAction.getSemantics().isSafeInNature() || apiVariant != CausewayConfiguration.Viewer.Graphql.ApiVariant.QUERY_ONLY // the other variants have an entry for all actions. ) - .forEach(act -> actions.add(addChildFieldFor(new GqlvAction(this, act, context)))); + .forEach(act -> actions.add(addChildFieldFor(schemaStrategy.newGqlvAction(this, act, context)))); } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/GqlvTopLevelQueryAbstractSchema.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/GqlvTopLevelQueryAbstractSchema.java index 683920affc..12536788f4 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/GqlvTopLevelQueryAbstractSchema.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/GqlvTopLevelQueryAbstractSchema.java @@ -5,14 +5,12 @@ import java.util.List; import graphql.schema.DataFetchingEnvironment; -import org.apache.causeway.core.config.CausewayConfiguration; 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.GqlvAbstract; import org.apache.causeway.viewer.graphql.model.domain.GqlvAbstractCustom; import org.apache.causeway.viewer.graphql.model.domain.Parent; import org.apache.causeway.viewer.graphql.model.domain.common.SchemaStrategy; -import org.apache.causeway.viewer.graphql.model.domain.simple.query.GqlvTopLevelQuerySimpleSchema; import lombok.Getter; import lombok.val; @@ -40,7 +38,7 @@ public abstract class GqlvTopLevelQueryAbstractSchema case VIEW_MODEL: // @DomainObject(nature=VIEW_MODEL) case ENTITY: // @DomainObject(nature=ENTITY) - domainObjects.add(addChildFieldFor(schemaStrategy.newGqlvDomainObject(objectSpec, context))); + domainObjects.add(addChildFieldFor(schemaStrategy.domainObjectFor(objectSpec, context))); break; } @@ -53,14 +51,14 @@ public abstract class GqlvTopLevelQueryAbstractSchema context.serviceRegistry.lookupBeanById(objectSpec.getLogicalTypeName()) .ifPresent(servicePojo -> domainServices.add( - addChildFieldFor(GqlvTopLevelQuerySimpleSchema.of(schemaStrategy, objectSpec, servicePojo, context)))); + addChildFieldFor(schemaStrategy.domainServiceFor(objectSpec, servicePojo, context)))); break; } }); } - protected static List<ObjectSpecification> superclassesOf(final ObjectSpecification objectSpecification) { + public static List<ObjectSpecification> superclassesOf(final ObjectSpecification objectSpecification) { val superclasses = new ArrayList<ObjectSpecification>(); ObjectSpecification superclass = objectSpecification.superclass(); while (superclass != null && superclass.getCorrespondingClass() != Object.class) { diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/GvqlActionUtils.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/GvqlActionUtils.java index 3f1f5f4ffa..fd53eecbfb 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/GvqlActionUtils.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/GvqlActionUtils.java @@ -1,7 +1,5 @@ package org.apache.causeway.viewer.graphql.model.domain.common.query; -import lombok.val; - import java.util.List; import java.util.Map; import java.util.Optional; @@ -16,9 +14,10 @@ import org.apache.causeway.core.metamodel.spec.feature.ObjectActionParameter; import org.apache.causeway.viewer.graphql.model.context.Context; import org.apache.causeway.viewer.graphql.model.domain.Environment; import org.apache.causeway.viewer.graphql.model.domain.common.SchemaStrategy; -import org.apache.causeway.viewer.graphql.model.domain.simple.query.GqlvMetaSaveAs; import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo; +import lombok.val; + public class GvqlActionUtils { public static Optional<Object> asPojo( diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/SchemaStrategyRich.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/SchemaStrategyRich.java index 7c53e0135c..653c482f57 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/SchemaStrategyRich.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/SchemaStrategyRich.java @@ -42,13 +42,6 @@ public class SchemaStrategyRich implements SchemaStrategy { return graphqlConfiguration.getTopLevelFieldNameForRich(); } - public GqlvAbstractCustom newGqlvDomainObject( - final ObjectSpecification objectSpecification, - final Context context - ) { - return new GqlvDomainObject(this, objectSpecification, context); - } - public GqlvAbstractCustom newGqlvProperty( final GqlvMemberHolder holder, final OneToOneAssociation otoa, diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/SchemaStrategySimple.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/SchemaStrategySimple.java index fe7b004182..b3ec1ef047 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/SchemaStrategySimple.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/SchemaStrategySimple.java @@ -42,13 +42,6 @@ public class SchemaStrategySimple implements SchemaStrategy { return graphqlConfiguration.getTopLevelFieldNameForSimple(); } - public GqlvAbstractCustom newGqlvDomainObject( - final ObjectSpecification objectSpecification, - final Context context - ) { - return new GqlvDomainObject(this, objectSpecification, context); - } - public GqlvAbstractCustom newGqlvProperty( final GqlvMemberHolder holder, final OneToOneAssociation otoa, diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/GqlvTopLevelQuerySimpleSchema.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/GqlvTopLevelQuerySimpleSchema.java index b1c2e486e6..e96fbf4a9a 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/GqlvTopLevelQuerySimpleSchema.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/GqlvTopLevelQuerySimpleSchema.java @@ -30,41 +30,4 @@ public class GqlvTopLevelQuerySimpleSchema .build()); } - public static GqlvDomainObject of( - final SchemaStrategy schemaStrategy, - final ObjectSpecification objectSpecification, - final Context context) { - - mapSuperclassesIfNecessary(schemaStrategy, objectSpecification, context); - return computeIfAbsentGqlvDomainObject(schemaStrategy, objectSpecification, context); - } - - private static void mapSuperclassesIfNecessary( - final SchemaStrategy schemaStrategy, - final ObjectSpecification objectSpecification, - final Context context) { - // no need to map if the target subclass has already been built - if(schemaStrategy.domainObjectBySpec(context).containsKey(objectSpecification)) { - return; - } - val superclasses = superclassesOf(objectSpecification); - superclasses.forEach(objectSpec -> computeIfAbsentGqlvDomainObject(schemaStrategy, objectSpec, context)); - } - - private static GqlvDomainObject computeIfAbsentGqlvDomainObject( - final SchemaStrategy schemaStrategy, - final ObjectSpecification objectSpec, - final Context context) { - return schemaStrategy.domainObjectBySpec(context).computeIfAbsent(objectSpec, spec -> new GqlvDomainObject(schemaStrategy, spec, context)); - } - - - public static GqlvDomainService of( - final SchemaStrategy schemaStrategy, - final ObjectSpecification objectSpecification, - final Object servicePojo, - final Context context) { - return schemaStrategy.domainServiceBySpec(context).computeIfAbsent(objectSpecification, spec -> new GqlvDomainService(schemaStrategy, spec, servicePojo, context)); - } - } diff --git a/viewers/graphql/test/src/test/resources/schema.gql b/viewers/graphql/test/src/test/resources/schema.gql index 8ddbaf62c8..d8742a001b 100644 --- a/viewers/graphql/test/src/test/resources/schema.gql +++ b/viewers/graphql/test/src/test/resources/schema.gql @@ -183,15 +183,53 @@ type Scenario { } type ScenarioStep { + causeway_applib_DomainObjectList(object: rich__causeway_applib_DomainObjectList__gqlv_input): rich__causeway_applib_DomainObjectList + causeway_applib_FacetGroupNode(object: rich__causeway_applib_FacetGroupNode__gqlv_input): rich__causeway_applib_FacetGroupNode + causeway_applib_ParameterNode(object: rich__causeway_applib_ParameterNode__gqlv_input): rich__causeway_applib_ParameterNode + causeway_applib_PropertyNode(object: rich__causeway_applib_PropertyNode__gqlv_input): rich__causeway_applib_PropertyNode + causeway_applib_RoleMemento(object: rich__causeway_applib_RoleMemento__gqlv_input): rich__causeway_applib_RoleMemento + causeway_applib_TypeNode(object: rich__causeway_applib_TypeNode__gqlv_input): rich__causeway_applib_TypeNode + causeway_applib_UserMemento(object: rich__causeway_applib_UserMemento__gqlv_input): rich__causeway_applib_UserMemento causeway_applib_UserMenu: rich__causeway_applib_UserMenu + causeway_applib_node_ActionNode(object: rich__causeway_applib_node_ActionNode__gqlv_input): rich__causeway_applib_node_ActionNode + causeway_applib_node_CollectionNode(object: rich__causeway_applib_node_CollectionNode__gqlv_input): rich__causeway_applib_node_CollectionNode + causeway_applib_node_FacetAttrNode(object: rich__causeway_applib_node_FacetAttrNode__gqlv_input): rich__causeway_applib_node_FacetAttrNode + causeway_applib_node_FacetNode(object: rich__causeway_applib_node_FacetNode__gqlv_input): rich__causeway_applib_node_FacetNode causeway_conf_ConfigurationMenu: rich__causeway_conf_ConfigurationMenu + causeway_conf_ConfigurationProperty(object: rich__causeway_conf_ConfigurationProperty__gqlv_input): rich__causeway_conf_ConfigurationProperty + causeway_conf_ConfigurationViewmodel(object: rich__causeway_conf_ConfigurationViewmodel__gqlv_input): rich__causeway_conf_ConfigurationViewmodel + causeway_feat_ApplicationFeatureViewModel(object: rich__causeway_feat_ApplicationFeatureViewModel__gqlv_input): rich__causeway_feat_ApplicationFeatureViewModel + causeway_feat_ApplicationNamespace(object: rich__causeway_feat_ApplicationNamespace__gqlv_input): rich__causeway_feat_ApplicationNamespace + causeway_feat_ApplicationType(object: rich__causeway_feat_ApplicationType__gqlv_input): rich__causeway_feat_ApplicationType + causeway_feat_ApplicationTypeAction(object: rich__causeway_feat_ApplicationTypeAction__gqlv_input): rich__causeway_feat_ApplicationTypeAction + causeway_feat_ApplicationTypeCollection(object: rich__causeway_feat_ApplicationTypeCollection__gqlv_input): rich__causeway_feat_ApplicationTypeCollection + causeway_feat_ApplicationTypeMember(object: rich__causeway_feat_ApplicationTypeMember__gqlv_input): rich__causeway_feat_ApplicationTypeMember + causeway_feat_ApplicationTypeProperty(object: rich__causeway_feat_ApplicationTypeProperty__gqlv_input): rich__causeway_feat_ApplicationTypeProperty + causeway_schema_metamodel_v2_DomainClassDto(object: rich__causeway_schema_metamodel_v2_DomainClassDto__gqlv_input): rich__causeway_schema_metamodel_v2_DomainClassDto + causeway_security_LoginRedirect(object: rich__causeway_security_LoginRedirect__gqlv_input): rich__causeway_security_LoginRedirect causeway_security_LogoutMenu: rich__causeway_security_LogoutMenu + causeway_testing_fixtures_FixtureResult(object: rich__causeway_testing_fixtures_FixtureResult__gqlv_input): rich__causeway_testing_fixtures_FixtureResult + java_lang_Runnable(object: rich__java_lang_Runnable__gqlv_input): rich__java_lang_Runnable + java_util_Map(object: rich__java_util_Map__gqlv_input): rich__java_util_Map + java_util_SortedMap(object: rich__java_util_SortedMap__gqlv_input): rich__java_util_SortedMap + java_util_concurrent_Callable(object: rich__java_util_concurrent_Callable__gqlv_input): rich__java_util_concurrent_Callable + java_util_function_BiFunction(object: rich__java_util_function_BiFunction__gqlv_input): rich__java_util_function_BiFunction + java_util_function_Consumer(object: rich__java_util_function_Consumer__gqlv_input): rich__java_util_function_Consumer + java_util_function_Function(object: rich__java_util_function_Function__gqlv_input): rich__java_util_function_Function + java_util_stream_Stream(object: rich__java_util_stream_Stream__gqlv_input): rich__java_util_stream_Stream + org_apache_causeway_core_metamodel_inspect_model_MMNode(object: rich__org_apache_causeway_core_metamodel_inspect_model_MMNode__gqlv_input): rich__org_apache_causeway_core_metamodel_inspect_model_MMNode + org_apache_causeway_core_metamodel_inspect_model_MemberNode(object: rich__org_apache_causeway_core_metamodel_inspect_model_MemberNode__gqlv_input): rich__org_apache_causeway_core_metamodel_inspect_model_MemberNode + org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript(object: rich__org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript__gqlv_input): rich__org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript university_admin_AdminMenu: rich__university_admin_AdminMenu university_calc_Calculator: rich__university_calc_Calculator + university_dept_Department(object: rich__university_dept_Department__gqlv_input): rich__university_dept_Department university_dept_Departments: rich__university_dept_Departments + university_dept_DeptHead(object: rich__university_dept_DeptHead__gqlv_input): rich__university_dept_DeptHead university_dept_DeptHeads: rich__university_dept_DeptHeads university_dept_People: rich__university_dept_People + university_dept_Person(object: rich__university_dept_Person__gqlv_input): rich__university_dept_Person university_dept_Staff: rich__university_dept_Staff + university_dept_StaffMember(object: rich__university_dept_StaffMember__gqlv_input): rich__university_dept_StaffMember } type SimpleAndRich { @@ -5471,6 +5509,22 @@ type simple__causeway_schema_metamodel_v2_DomainClassDto__service__gqlv_property validate(service: Boolean): String } +type simple__causeway_schema_metamodel_v2_FacetHolder { + "Object metadata" + _meta: simple__causeway_schema_metamodel_v2_FacetHolder__gqlv_meta +} + +type simple__causeway_schema_metamodel_v2_FacetHolder__gqlv_meta { + cssClass: String + grid: String + icon: String + id: String! + layout: String + logicalTypeName: String! + saveAs(ref: String): String + title: String! +} + type simple__causeway_security_LoginRedirect { "Object metadata" _meta: simple__causeway_security_LoginRedirect__gqlv_meta @@ -8464,6 +8518,15 @@ input simple__causeway_schema_metamodel_v2_DomainClassDto__gqlv_input { ref: String } +input simple__causeway_schema_metamodel_v2_FacetHolder__gqlv_input { + "Use either 'id' or 'ref'; looks up an entity from the persistent data store, or if a view model, then recreates using the id as a memento of the object's state" + id: ID + "If object identified by 'id', then optionally specifies concrete type. This is only required if the parameter type defines a super class" + logicalTypeName: String + "Use either 'ref' or 'id'; looks up an object previously saved to the execution context using 'saveAs(ref: ...)'" + ref: String +} + input simple__causeway_security_LoginRedirect__gqlv_input { "Use either 'id' or 'ref'; looks up an entity from the persistent data store, or if a view model, then recreates using the id as a memento of the object's state" id: ID
