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 06331112f4b279d3feec618798f5170893127273
Author: danhaywood <[email protected]>
AuthorDate: Wed Jan 31 14:27:51 2024 +0000

    CAUSEWAY-3676: adds ability to lookup arbitrary domain objects from 
top-level query
---
 .../core/config/CausewayConfiguration.java         |  14 ++
 .../viewer/graphql/model/domain/GqlvAction.java    |   5 +-
 ...tegTest.change_department_name_visibility._.gql |   7 +
 ...change_department_name_visibility.approved.json |   9 +
 ...Test.java => DepartmentMutating_IntegTest.java} |  34 +---
 ...tegTest.change_department_name_visibility._.gql |  10 --
 ...change_department_name_visibility.approved.json |   0
 .../DeptHeadMutating_IntegTest.java                |  20 ---
 viewers/graphql/test/src/test/resources/schema.gql | 195 ++++++++++++++++-----
 .../integration/GraphQlSourceForCauseway.java      |  62 ++++---
 .../graphql/viewer/toplevel/GqlvTopLevelQuery.java |  43 ++++-
 11 files changed, 264 insertions(+), 135 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 6613c49d1b..507f3a7229 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
@@ -2392,6 +2392,20 @@ public class CausewayConfiguration {
                 private String fieldName = "_gqlv_meta";
             }
 
+            private final Lookup lookup = new Lookup();
+            @Data
+            public static class Lookup {
+                /**
+                 * Lookup field prefix
+                 */
+                private String fieldNamePrefix = "_gqlv_lookup__";
+                /**
+                 * Lookup field suffix
+                 */
+                private String fieldNameSuffix = "";
+                private String argument = "object";
+            }
+
             private final Mutation mutation = new Mutation();
             @Data
             public static class Mutation {
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAction.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAction.java
index 814f19a173..328f5eb32d 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAction.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAction.java
@@ -179,7 +179,7 @@ public class GqlvAction
     }
 
 
-    static Optional<Object> asPojo(
+    public static Optional<Object> asPojo(
             final ObjectSpecification elementType,
             final Object argumentValueObj,
             final BookmarkService bookmarkService) {
@@ -190,8 +190,7 @@ public class GqlvAction
         return bookmarkIfAny
                 .map(bookmarkService::lookup)
                 .filter(Optional::isPresent)
-                .map(Optional::get)
-;
+                .map(Optional::get);
     }
 
     public void addGqlArguments(
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DepartmentMutating_IntegTest.change_department_name_visibility._.gql
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DepartmentMutating_IntegTest.change_department_name_visibility._.gql
new file mode 100644
index 0000000000..41a7cf7c38
--- /dev/null
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DepartmentMutating_IntegTest.change_department_name_visibility._.gql
@@ -0,0 +1,7 @@
+{
+  _gqlv_lookup__university_dept_Department(object: {id: "$departmentId"}) {
+    changeName {
+      hidden
+    }
+  }
+}
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DepartmentMutating_IntegTest.change_department_name_visibility.approved.json
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DepartmentMutating_IntegTest.change_department_name_visibility.approved.json
new file mode 100644
index 0000000000..cb35165718
--- /dev/null
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DepartmentMutating_IntegTest.change_department_name_visibility.approved.json
@@ -0,0 +1,9 @@
+{
+  "data" : {
+    "_gqlv_lookup__university_dept_Department" : {
+      "changeName" : {
+        "hidden" : false
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DepartmentMutating_IntegTest.java
similarity index 72%
copy from 
viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.java
copy to 
viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DepartmentMutating_IntegTest.java
index e01706df71..e634270b27 100644
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.java
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DepartmentMutating_IntegTest.java
@@ -53,39 +53,7 @@ import lombok.val;
 @Order(110)
 @ActiveProfiles("test")
 @DirtiesContext
-public class DeptHeadMutating_IntegTest extends Abstract_IntegTest {
-
-    @Test
-    @UseReporter(DiffReporter.class)
-    void create_department() throws Exception {
-
-        // when lookup 'Prof. Dicky Horwich' and change it to 'Prof. Richard 
Horwich'
-        String response = submit();
-
-        // then payload
-        Approvals.verify(response, jsonOptions());
-
-    }
-
-    @Test
-    @UseReporter(DiffReporter.class)
-    void change_department_name() throws Exception {
-
-        final Bookmark bookmark =
-                transactionService.callTransactional(
-                        Propagation.REQUIRED,
-                        () -> {
-                            Department department = 
departmentRepository.findByName("Classics");
-                            Optional<Bookmark> bookmark1 = 
bookmarkService.bookmarkFor(department);
-                            return bookmark1.orElseThrow();
-                        }
-                ).valueAsNonNullElseFail();
-
-        val response = submit(_Maps.unmodifiable("$departmentId", 
bookmark.getIdentifier()));
-
-        // then payload
-        Approvals.verify(response, jsonOptions());
-    }
+public class DepartmentMutating_IntegTest extends Abstract_IntegTest {
 
     @Test
     @UseReporter(DiffReporter.class)
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.change_department_name_visibility._.gql
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.change_department_name_visibility._.gql
deleted file mode 100644
index 7c654d1143..0000000000
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.change_department_name_visibility._.gql
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  university_dept_Department__changeName(
-      _gqlv_target: {id : "$departmentId"},
-      newName: "Classics and Ancient History"
-  ) {
-    name {
-      get
-    }
-  }
-}
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.change_department_name_visibility.approved.json
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.change_department_name_visibility.approved.json
deleted file mode 100644
index e69de29bb2..0000000000
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.java
index e01706df71..d1f196a984 100644
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.java
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.java
@@ -87,24 +87,4 @@ public class DeptHeadMutating_IntegTest extends 
Abstract_IntegTest {
         Approvals.verify(response, jsonOptions());
     }
 
-    @Test
-    @UseReporter(DiffReporter.class)
-    void change_department_name_visibility() throws Exception {
-
-        final Bookmark bookmark =
-                transactionService.callTransactional(
-                        Propagation.REQUIRED,
-                        () -> {
-                            Department department = 
departmentRepository.findByName("Classics");
-                            Optional<Bookmark> bookmark1 = 
bookmarkService.bookmarkFor(department);
-                            return bookmark1.orElseThrow();
-                        }
-                ).valueAsNonNullElseFail();
-
-        val response = submit(_Maps.unmodifiable("$departmentId", 
bookmark.getIdentifier()));
-
-        // then payload
-        Approvals.verify(response, jsonOptions());
-    }
-
 }
diff --git a/viewers/graphql/test/src/test/resources/schema.gql 
b/viewers/graphql/test/src/test/resources/schema.gql
index 49ec448298..44ed0fc099 100644
--- a/viewers/graphql/test/src/test/resources/schema.gql
+++ b/viewers/graphql/test/src/test/resources/schema.gql
@@ -22,51 +22,44 @@ directive @specifiedBy(
     url: String!
   ) on SCALAR
 
-type Mutation {
-  causeway_applib_PropertyNode__mixedIn(_gqlv_target: 
causeway_applib_PropertyNode__gqlv_input, mixedIn: Boolean!): 
causeway_applib_PropertyNode
-  causeway_applib_node_ActionNode__mixedIn(_gqlv_target: 
causeway_applib_node_ActionNode__gqlv_input, mixedIn: Boolean!): 
causeway_applib_node_ActionNode
-  causeway_applib_node_CollectionNode__mixedIn(_gqlv_target: 
causeway_applib_node_CollectionNode__gqlv_input, mixedIn: Boolean!): 
causeway_applib_node_CollectionNode
-  causeway_applib_node_FacetNode__shadowed(_gqlv_target: 
causeway_applib_node_FacetNode__gqlv_input, shadowed: Boolean!): 
causeway_applib_node_FacetNode
-  causeway_conf_ConfigurationProperty__key(_gqlv_target: 
causeway_conf_ConfigurationProperty__gqlv_input, key: String!): 
causeway_conf_ConfigurationProperty
-  causeway_conf_ConfigurationProperty__value(_gqlv_target: 
causeway_conf_ConfigurationProperty__gqlv_input, value: String!): 
causeway_conf_ConfigurationProperty
-  causeway_schema_metamodel_v2_DomainClassDto__actions(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, actions: String!): 
causeway_schema_metamodel_v2_DomainClassDto
-  causeway_schema_metamodel_v2_DomainClassDto__annotations(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, annotations: String!): 
causeway_schema_metamodel_v2_DomainClassDto
-  causeway_schema_metamodel_v2_DomainClassDto__collections(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, collections: String!): 
causeway_schema_metamodel_v2_DomainClassDto
-  causeway_schema_metamodel_v2_DomainClassDto__facets(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, facets: String!): 
causeway_schema_metamodel_v2_DomainClassDto
-  causeway_schema_metamodel_v2_DomainClassDto__id(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, id: String!): 
causeway_schema_metamodel_v2_DomainClassDto
-  causeway_schema_metamodel_v2_DomainClassDto__majorVersion(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, majorVersion: String): 
causeway_schema_metamodel_v2_DomainClassDto
-  causeway_schema_metamodel_v2_DomainClassDto__minorVersion(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, minorVersion: String): 
causeway_schema_metamodel_v2_DomainClassDto
-  causeway_schema_metamodel_v2_DomainClassDto__properties(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, properties: String!): 
causeway_schema_metamodel_v2_DomainClassDto
-  causeway_schema_metamodel_v2_DomainClassDto__service(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, service: Boolean!): 
causeway_schema_metamodel_v2_DomainClassDto
-  
causeway_testing_fixtures_FixtureResult__fixtureScriptClassName(_gqlv_target: 
causeway_testing_fixtures_FixtureResult__gqlv_input, fixtureScriptClassName: 
String): causeway_testing_fixtures_FixtureResult
-  causeway_testing_fixtures_FixtureResult__key(_gqlv_target: 
causeway_testing_fixtures_FixtureResult__gqlv_input, key: String!): 
causeway_testing_fixtures_FixtureResult
-  causeway_testing_fixtures_FixtureResult__object(_gqlv_target: 
causeway_testing_fixtures_FixtureResult__gqlv_input, object: String!): 
causeway_testing_fixtures_FixtureResult
-  
org_apache_causeway_core_metamodel_inspect_model_MemberNode__mixedIn(_gqlv_target:
 org_apache_causeway_core_metamodel_inspect_model_MemberNode__gqlv_input, 
mixedIn: Boolean!): org_apache_causeway_core_metamodel_inspect_model_MemberNode
-  
org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript__friendlyName(_gqlv_target:
 
org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript__gqlv_input,
 friendlyName: String!): 
org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript
-  university_admin_AdminMenu__actionWithDisabledParam(firstParam: String!, 
secondParam: String!, thirdParameter: String!): String
-  university_admin_AdminMenu__actionWithHiddenParam(firstParam: String!, 
secondParam: String!): String
-  university_admin_AdminMenu__adminAction: String
-  university_admin_AdminMenu__otherAdminAction: String
-  university_dept_Department__addStaffMember(_gqlv_target: 
university_dept_Department__gqlv_input, staffMember: 
university_dept_StaffMember__gqlv_input!): university_dept_Department
-  university_dept_Department__addStaffMembers(_gqlv_target: 
university_dept_Department__gqlv_input, staffMembers: 
[university_dept_StaffMember__gqlv_input]): university_dept_Department
-  university_dept_Department__changeDeptHead(_gqlv_target: 
university_dept_Department__gqlv_input, newDeptHead: 
university_dept_DeptHead__gqlv_input!): university_dept_Department
-  university_dept_Department__changeName(_gqlv_target: 
university_dept_Department__gqlv_input, newName: String!): 
university_dept_Department
-  university_dept_Department__deptHead(_gqlv_target: 
university_dept_Department__gqlv_input, deptHead: 
university_dept_DeptHead__gqlv_input): university_dept_Department
-  university_dept_Department__name(_gqlv_target: 
university_dept_Department__gqlv_input, name: String!): 
university_dept_Department
-  university_dept_Department__removeStaffMember(_gqlv_target: 
university_dept_Department__gqlv_input, staffMember: 
university_dept_StaffMember__gqlv_input!): university_dept_Department
-  university_dept_Departments__createDepartment(deptHead: 
university_dept_DeptHead__gqlv_input, name: String!): university_dept_Department
-  university_dept_DeptHead__changeDepartment(_gqlv_target: 
university_dept_DeptHead__gqlv_input, department: 
university_dept_Department__gqlv_input!): university_dept_DeptHead
-  university_dept_DeptHead__changeName(_gqlv_target: 
university_dept_DeptHead__gqlv_input, newName: String!): 
university_dept_DeptHead
-  university_dept_DeptHead__department(_gqlv_target: 
university_dept_DeptHead__gqlv_input, department: 
university_dept_Department__gqlv_input): university_dept_DeptHead
-  university_dept_DeptHead__name(_gqlv_target: 
university_dept_DeptHead__gqlv_input, name: String): university_dept_DeptHead
-  university_dept_StaffMember__department(_gqlv_target: 
university_dept_StaffMember__gqlv_input, department: 
university_dept_Department__gqlv_input): university_dept_StaffMember
-  university_dept_StaffMember__grade(_gqlv_target: 
university_dept_StaffMember__gqlv_input, grade: String!): 
university_dept_StaffMember
-  university_dept_StaffMember__name(_gqlv_target: 
university_dept_StaffMember__gqlv_input, name: String!): 
university_dept_StaffMember
-  university_dept_StaffMember__photo(_gqlv_target: 
university_dept_StaffMember__gqlv_input, photo: String): 
university_dept_StaffMember
-  university_dept_Staff__createStaffMember(department: 
university_dept_Department__gqlv_input!, name: String!): 
university_dept_StaffMember
-}
-
 type Query {
+  _gqlv_lookup__causeway_applib_DomainObjectList(object: 
causeway_applib_DomainObjectList__gqlv_input): causeway_applib_DomainObjectList
+  _gqlv_lookup__causeway_applib_FacetGroupNode(object: 
causeway_applib_FacetGroupNode__gqlv_input): causeway_applib_FacetGroupNode
+  _gqlv_lookup__causeway_applib_ParameterNode(object: 
causeway_applib_ParameterNode__gqlv_input): causeway_applib_ParameterNode
+  _gqlv_lookup__causeway_applib_PropertyNode(object: 
causeway_applib_PropertyNode__gqlv_input): causeway_applib_PropertyNode
+  _gqlv_lookup__causeway_applib_RoleMemento(object: 
causeway_applib_RoleMemento__gqlv_input): causeway_applib_RoleMemento
+  _gqlv_lookup__causeway_applib_TypeNode(object: 
causeway_applib_TypeNode__gqlv_input): causeway_applib_TypeNode
+  _gqlv_lookup__causeway_applib_UserMemento(object: 
causeway_applib_UserMemento__gqlv_input): causeway_applib_UserMemento
+  _gqlv_lookup__causeway_applib_node_ActionNode(object: 
causeway_applib_node_ActionNode__gqlv_input): causeway_applib_node_ActionNode
+  _gqlv_lookup__causeway_applib_node_CollectionNode(object: 
causeway_applib_node_CollectionNode__gqlv_input): 
causeway_applib_node_CollectionNode
+  _gqlv_lookup__causeway_applib_node_FacetAttrNode(object: 
causeway_applib_node_FacetAttrNode__gqlv_input): 
causeway_applib_node_FacetAttrNode
+  _gqlv_lookup__causeway_applib_node_FacetNode(object: 
causeway_applib_node_FacetNode__gqlv_input): causeway_applib_node_FacetNode
+  _gqlv_lookup__causeway_conf_ConfigurationProperty(object: 
causeway_conf_ConfigurationProperty__gqlv_input): 
causeway_conf_ConfigurationProperty
+  _gqlv_lookup__causeway_conf_ConfigurationViewmodel(object: 
causeway_conf_ConfigurationViewmodel__gqlv_input): 
causeway_conf_ConfigurationViewmodel
+  _gqlv_lookup__causeway_feat_ApplicationFeatureViewModel(object: 
causeway_feat_ApplicationFeatureViewModel__gqlv_input): 
causeway_feat_ApplicationFeatureViewModel
+  _gqlv_lookup__causeway_feat_ApplicationNamespace(object: 
causeway_feat_ApplicationNamespace__gqlv_input): 
causeway_feat_ApplicationNamespace
+  _gqlv_lookup__causeway_feat_ApplicationType(object: 
causeway_feat_ApplicationType__gqlv_input): causeway_feat_ApplicationType
+  _gqlv_lookup__causeway_feat_ApplicationTypeAction(object: 
causeway_feat_ApplicationTypeAction__gqlv_input): 
causeway_feat_ApplicationTypeAction
+  _gqlv_lookup__causeway_feat_ApplicationTypeCollection(object: 
causeway_feat_ApplicationTypeCollection__gqlv_input): 
causeway_feat_ApplicationTypeCollection
+  _gqlv_lookup__causeway_feat_ApplicationTypeMember(object: 
causeway_feat_ApplicationTypeMember__gqlv_input): 
causeway_feat_ApplicationTypeMember
+  _gqlv_lookup__causeway_feat_ApplicationTypeProperty(object: 
causeway_feat_ApplicationTypeProperty__gqlv_input): 
causeway_feat_ApplicationTypeProperty
+  _gqlv_lookup__causeway_schema_metamodel_v2_DomainClassDto(object: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input): 
causeway_schema_metamodel_v2_DomainClassDto
+  _gqlv_lookup__causeway_security_LoginRedirect(object: 
causeway_security_LoginRedirect__gqlv_input): causeway_security_LoginRedirect
+  _gqlv_lookup__causeway_testing_fixtures_FixtureResult(object: 
causeway_testing_fixtures_FixtureResult__gqlv_input): 
causeway_testing_fixtures_FixtureResult
+  _gqlv_lookup__java_lang_Runnable(object: java_lang_Runnable__gqlv_input): 
java_lang_Runnable
+  _gqlv_lookup__java_util_Map(object: java_util_Map__gqlv_input): java_util_Map
+  _gqlv_lookup__java_util_SortedMap(object: java_util_SortedMap__gqlv_input): 
java_util_SortedMap
+  _gqlv_lookup__java_util_concurrent_Callable(object: 
java_util_concurrent_Callable__gqlv_input): java_util_concurrent_Callable
+  _gqlv_lookup__java_util_function_BiFunction(object: 
java_util_function_BiFunction__gqlv_input): java_util_function_BiFunction
+  _gqlv_lookup__java_util_function_Consumer(object: 
java_util_function_Consumer__gqlv_input): java_util_function_Consumer
+  _gqlv_lookup__java_util_function_Function(object: 
java_util_function_Function__gqlv_input): java_util_function_Function
+  _gqlv_lookup__java_util_stream_Stream(object: 
java_util_stream_Stream__gqlv_input): java_util_stream_Stream
+  
_gqlv_lookup__org_apache_causeway_core_metamodel_inspect_model_MMNode(object: 
org_apache_causeway_core_metamodel_inspect_model_MMNode__gqlv_input): 
org_apache_causeway_core_metamodel_inspect_model_MMNode
+  
_gqlv_lookup__org_apache_causeway_core_metamodel_inspect_model_MemberNode(object:
 org_apache_causeway_core_metamodel_inspect_model_MemberNode__gqlv_input): 
org_apache_causeway_core_metamodel_inspect_model_MemberNode
+  
_gqlv_lookup__org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript(object:
 
org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript__gqlv_input):
 org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript
+  _gqlv_lookup__university_dept_Department(object: 
university_dept_Department__gqlv_input): university_dept_Department
+  _gqlv_lookup__university_dept_DeptHead(object: 
university_dept_DeptHead__gqlv_input): university_dept_DeptHead
+  _gqlv_lookup__university_dept_StaffMember(object: 
university_dept_StaffMember__gqlv_input): university_dept_StaffMember
   causeway_applib_UserMenu: causeway_applib_UserMenu
   causeway_conf_ConfigurationMenu: causeway_conf_ConfigurationMenu
   causeway_security_LogoutMenu: causeway_security_LogoutMenu
@@ -91,6 +84,7 @@ type 
causeway_applib_DomainObjectList__actionArguments__gqlv_property {
   disabled: String
   get: String
   hidden: Boolean
+  set(actionArguments: String): causeway_applib_DomainObjectList
   validate(actionArguments: String): String
 }
 
@@ -98,6 +92,7 @@ type 
causeway_applib_DomainObjectList__actionId__gqlv_property {
   disabled: String
   get: String
   hidden: Boolean
+  set(actionId: String): causeway_applib_DomainObjectList
   validate(actionId: String): String
 }
 
@@ -105,6 +100,7 @@ type 
causeway_applib_DomainObjectList__actionOwningFqcn__gqlv_property {
   disabled: String
   get: String
   hidden: Boolean
+  set(actionOwningFqcn: String): causeway_applib_DomainObjectList
   validate(actionOwningFqcn: String): String
 }
 
@@ -112,6 +108,7 @@ type 
causeway_applib_DomainObjectList__elementTypeFqcn__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(elementTypeFqcn: String!): causeway_applib_DomainObjectList
   validate(elementTypeFqcn: String): String
 }
 
@@ -129,6 +126,7 @@ type causeway_applib_DomainObjectList__title__gqlv_property 
{
   disabled: String
   get: String!
   hidden: Boolean
+  set(title: String!): causeway_applib_DomainObjectList
   validate(title: String): String
 }
 
@@ -148,6 +146,7 @@ type causeway_applib_FacetGroupNode__facets__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(facets: String!): causeway_applib_FacetGroupNode
   validate(facets: String): String
 }
 
@@ -159,6 +158,7 @@ type causeway_applib_FacetGroupNode__gqlv_meta {
 type causeway_applib_FacetGroupNode__parentNode__gqlv_property {
   disabled: String
   hidden: Boolean
+  set(parentNode: 
org_apache_causeway_core_metamodel_inspect_model_MMNode__gqlv_input!): 
causeway_applib_FacetGroupNode
   validate(parentNode: 
org_apache_causeway_core_metamodel_inspect_model_MMNode__gqlv_input): String
 }
 
@@ -183,6 +183,7 @@ type 
causeway_applib_ParameterNode__parameter__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(parameter: String!): causeway_applib_ParameterNode
   validate(parameter: String): String
 }
 
@@ -190,6 +191,7 @@ type 
causeway_applib_ParameterNode__parentNode__gqlv_property {
   disabled: String
   get: causeway_applib_node_ActionNode!
   hidden: Boolean
+  set(parentNode: causeway_applib_node_ActionNode__gqlv_input!): 
causeway_applib_ParameterNode
   validate(parentNode: causeway_applib_node_ActionNode__gqlv_input): String
 }
 
@@ -215,6 +217,7 @@ type causeway_applib_PropertyNode__mixedIn__gqlv_property {
   disabled: String
   get: Boolean!
   hidden: Boolean
+  set(mixedIn: Boolean!): causeway_applib_PropertyNode
   validate(mixedIn: Boolean): String
 }
 
@@ -222,6 +225,7 @@ type 
causeway_applib_PropertyNode__parentNode__gqlv_property {
   disabled: String
   get: causeway_applib_TypeNode!
   hidden: Boolean
+  set(parentNode: causeway_applib_TypeNode__gqlv_input!): 
causeway_applib_PropertyNode
   validate(parentNode: causeway_applib_TypeNode__gqlv_input): String
 }
 
@@ -229,6 +233,7 @@ type causeway_applib_PropertyNode__property__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(property: String!): causeway_applib_PropertyNode
   validate(property: String): String
 }
 
@@ -242,6 +247,7 @@ type 
causeway_applib_RoleMemento__description__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(description: String!): causeway_applib_RoleMemento
   validate(description: String): String
 }
 
@@ -254,6 +260,7 @@ type causeway_applib_RoleMemento__name__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(name: String!): causeway_applib_RoleMemento
   validate(name: String): String
 }
 
@@ -273,6 +280,7 @@ type 
causeway_applib_TypeNode__domainClassDto__gqlv_property {
   disabled: String
   get: causeway_schema_metamodel_v2_DomainClassDto!
   hidden: Boolean
+  set(domainClassDto: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input!): 
causeway_applib_TypeNode
   validate(domainClassDto: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input): String
 }
 
@@ -284,6 +292,7 @@ type causeway_applib_TypeNode__gqlv_meta {
 type causeway_applib_TypeNode__parentNode__gqlv_property {
   disabled: String
   hidden: Boolean
+  set(parentNode: 
org_apache_causeway_core_metamodel_inspect_model_MMNode__gqlv_input!): 
causeway_applib_TypeNode
   validate(parentNode: 
org_apache_causeway_core_metamodel_inspect_model_MMNode__gqlv_input): String
 }
 
@@ -306,6 +315,7 @@ type 
causeway_applib_UserMemento__authenticationCode__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(authenticationCode: String!): causeway_applib_UserMemento
   validate(authenticationCode: String): String
 }
 
@@ -314,6 +324,7 @@ type 
causeway_applib_UserMemento__authenticationSource__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(authenticationSource: String!): causeway_applib_UserMemento
   validate(authenticationSource: String): String
 }
 
@@ -321,6 +332,7 @@ type causeway_applib_UserMemento__avatarUrl__gqlv_property {
   disabled: String
   get: String
   hidden: Boolean
+  set(avatarUrl: String): causeway_applib_UserMemento
   validate(avatarUrl: String): String
 }
 
@@ -333,6 +345,7 @@ type 
causeway_applib_UserMemento__impersonating__gqlv_property {
   disabled: String
   get: Boolean!
   hidden: Boolean
+  set(impersonating: Boolean!): causeway_applib_UserMemento
   validate(impersonating: Boolean): String
 }
 
@@ -340,6 +353,7 @@ type 
causeway_applib_UserMemento__languageLocale__gqlv_property {
   disabled: String
   get: String
   hidden: Boolean
+  set(languageLocale: String): causeway_applib_UserMemento
   validate(languageLocale: String): String
 }
 
@@ -347,6 +361,7 @@ type 
causeway_applib_UserMemento__multiTenancyToken__gqlv_property {
   disabled: String
   get: String
   hidden: Boolean
+  set(multiTenancyToken: String): causeway_applib_UserMemento
   validate(multiTenancyToken: String): String
 }
 
@@ -354,6 +369,7 @@ type causeway_applib_UserMemento__name__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(name: String!): causeway_applib_UserMemento
   validate(name: String): String
 }
 
@@ -361,6 +377,7 @@ type 
causeway_applib_UserMemento__numberFormatLocale__gqlv_property {
   disabled: String
   get: String
   hidden: Boolean
+  set(numberFormatLocale: String): causeway_applib_UserMemento
   validate(numberFormatLocale: String): String
 }
 
@@ -368,6 +385,7 @@ type causeway_applib_UserMemento__realName__gqlv_property {
   disabled: String
   get: String
   hidden: Boolean
+  set(realName: String): causeway_applib_UserMemento
   validate(realName: String): String
 }
 
@@ -381,6 +399,7 @@ type 
causeway_applib_UserMemento__timeFormatLocale__gqlv_property {
   disabled: String
   get: String
   hidden: Boolean
+  set(timeFormatLocale: String): causeway_applib_UserMemento
   validate(timeFormatLocale: String): String
 }
 
@@ -407,6 +426,7 @@ type causeway_applib_node_ActionNode__action__gqlv_property 
{
   disabled: String
   get: String!
   hidden: Boolean
+  set(action: String!): causeway_applib_node_ActionNode
   validate(action: String): String
 }
 
@@ -424,6 +444,7 @@ type 
causeway_applib_node_ActionNode__mixedIn__gqlv_property {
   disabled: String
   get: Boolean!
   hidden: Boolean
+  set(mixedIn: Boolean!): causeway_applib_node_ActionNode
   validate(mixedIn: Boolean): String
 }
 
@@ -431,6 +452,7 @@ type 
causeway_applib_node_ActionNode__parentNode__gqlv_property {
   disabled: String
   get: causeway_applib_TypeNode!
   hidden: Boolean
+  set(parentNode: causeway_applib_TypeNode__gqlv_input!): 
causeway_applib_node_ActionNode
   validate(parentNode: causeway_applib_TypeNode__gqlv_input): String
 }
 
@@ -451,6 +473,7 @@ type 
causeway_applib_node_CollectionNode__collection__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(collection: String!): causeway_applib_node_CollectionNode
   validate(collection: String): String
 }
 
@@ -463,6 +486,7 @@ type 
causeway_applib_node_CollectionNode__mixedIn__gqlv_property {
   disabled: String
   get: Boolean!
   hidden: Boolean
+  set(mixedIn: Boolean!): causeway_applib_node_CollectionNode
   validate(mixedIn: Boolean): String
 }
 
@@ -470,6 +494,7 @@ type 
causeway_applib_node_CollectionNode__parentNode__gqlv_property {
   disabled: String
   get: causeway_applib_TypeNode!
   hidden: Boolean
+  set(parentNode: causeway_applib_TypeNode__gqlv_input!): 
causeway_applib_node_CollectionNode
   validate(parentNode: causeway_applib_TypeNode__gqlv_input): String
 }
 
@@ -489,6 +514,7 @@ type 
causeway_applib_node_FacetAttrNode__facetAttr__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(facetAttr: String!): causeway_applib_node_FacetAttrNode
   validate(facetAttr: String): String
 }
 
@@ -501,6 +527,7 @@ type 
causeway_applib_node_FacetAttrNode__parentNode__gqlv_property {
   disabled: String
   get: causeway_applib_node_FacetNode!
   hidden: Boolean
+  set(parentNode: causeway_applib_node_FacetNode__gqlv_input!): 
causeway_applib_node_FacetAttrNode
   validate(parentNode: causeway_applib_node_FacetNode__gqlv_input): String
 }
 
@@ -521,6 +548,7 @@ type causeway_applib_node_FacetNode__facet__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(facet: String!): causeway_applib_node_FacetNode
   validate(facet: String): String
 }
 
@@ -532,6 +560,7 @@ type causeway_applib_node_FacetNode__gqlv_meta {
 type causeway_applib_node_FacetNode__parentNode__gqlv_property {
   disabled: String
   hidden: Boolean
+  set(parentNode: 
org_apache_causeway_core_metamodel_inspect_model_MMNode__gqlv_input!): 
causeway_applib_node_FacetNode
   validate(parentNode: 
org_apache_causeway_core_metamodel_inspect_model_MMNode__gqlv_input): String
 }
 
@@ -539,6 +568,7 @@ type 
causeway_applib_node_FacetNode__shadowed__gqlv_property {
   disabled: String
   get: Boolean!
   hidden: Boolean
+  set(shadowed: Boolean!): causeway_applib_node_FacetNode
   validate(shadowed: Boolean): String
 }
 
@@ -568,6 +598,7 @@ type 
causeway_conf_ConfigurationProperty__key__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(key: String!): causeway_conf_ConfigurationProperty
   validate(key: String): String
 }
 
@@ -575,6 +606,7 @@ type 
causeway_conf_ConfigurationProperty__value__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(value: String!): causeway_conf_ConfigurationProperty
   validate(value: String): String
 }
 
@@ -625,6 +657,7 @@ type 
causeway_feat_ApplicationFeatureViewModel__memberName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(memberName: String!): causeway_feat_ApplicationFeatureViewModel
   validate(memberName: String): String
 }
 
@@ -632,12 +665,14 @@ type 
causeway_feat_ApplicationFeatureViewModel__namespaceName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(namespaceName: String!): causeway_feat_ApplicationFeatureViewModel
   validate(namespaceName: String): String
 }
 
 type causeway_feat_ApplicationFeatureViewModel__parent__gqlv_property {
   disabled: String
   hidden: Boolean
+  set(parent: causeway_feat_ApplicationFeatureViewModel__gqlv_input!): 
causeway_feat_ApplicationFeatureViewModel
   validate(parent: causeway_feat_ApplicationFeatureViewModel__gqlv_input): 
String
 }
 
@@ -645,6 +680,7 @@ type 
causeway_feat_ApplicationFeatureViewModel__typeSimpleName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(typeSimpleName: String!): causeway_feat_ApplicationFeatureViewModel
   validate(typeSimpleName: String): String
 }
 
@@ -671,6 +707,7 @@ type 
causeway_feat_ApplicationNamespace__memberName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(memberName: String!): causeway_feat_ApplicationNamespace
   validate(memberName: String): String
 }
 
@@ -678,12 +715,14 @@ type 
causeway_feat_ApplicationNamespace__namespaceName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(namespaceName: String!): causeway_feat_ApplicationNamespace
   validate(namespaceName: String): String
 }
 
 type causeway_feat_ApplicationNamespace__parent__gqlv_property {
   disabled: String
   hidden: Boolean
+  set(parent: causeway_feat_ApplicationFeatureViewModel__gqlv_input!): 
causeway_feat_ApplicationNamespace
   validate(parent: causeway_feat_ApplicationFeatureViewModel__gqlv_input): 
String
 }
 
@@ -691,6 +730,7 @@ type 
causeway_feat_ApplicationNamespace__typeSimpleName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(typeSimpleName: String!): causeway_feat_ApplicationNamespace
   validate(typeSimpleName: String): String
 }
 
@@ -720,6 +760,7 @@ type 
causeway_feat_ApplicationTypeAction__actionSemantics__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(actionSemantics: String!): causeway_feat_ApplicationTypeAction
   validate(actionSemantics: String): String
 }
 
@@ -732,6 +773,7 @@ type 
causeway_feat_ApplicationTypeAction__memberName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(memberName: String!): causeway_feat_ApplicationTypeAction
   validate(memberName: String): String
 }
 
@@ -739,12 +781,14 @@ type 
causeway_feat_ApplicationTypeAction__namespaceName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(namespaceName: String!): causeway_feat_ApplicationTypeAction
   validate(namespaceName: String): String
 }
 
 type causeway_feat_ApplicationTypeAction__parent__gqlv_property {
   disabled: String
   hidden: Boolean
+  set(parent: causeway_feat_ApplicationFeatureViewModel__gqlv_input!): 
causeway_feat_ApplicationTypeAction
   validate(parent: causeway_feat_ApplicationFeatureViewModel__gqlv_input): 
String
 }
 
@@ -752,6 +796,7 @@ type 
causeway_feat_ApplicationTypeAction__returnType__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(returnType: String!): causeway_feat_ApplicationTypeAction
   validate(returnType: String): String
 }
 
@@ -759,6 +804,7 @@ type 
causeway_feat_ApplicationTypeAction__typeSimpleName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(typeSimpleName: String!): causeway_feat_ApplicationTypeAction
   validate(typeSimpleName: String): String
 }
 
@@ -776,6 +822,7 @@ type 
causeway_feat_ApplicationTypeCollection__derived__gqlv_property {
   disabled: String
   get: Boolean!
   hidden: Boolean
+  set(derived: Boolean!): causeway_feat_ApplicationTypeCollection
   validate(derived: Boolean): String
 }
 
@@ -783,6 +830,7 @@ type 
causeway_feat_ApplicationTypeCollection__elementType__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(elementType: String!): causeway_feat_ApplicationTypeCollection
   validate(elementType: String): String
 }
 
@@ -795,6 +843,7 @@ type 
causeway_feat_ApplicationTypeCollection__memberName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(memberName: String!): causeway_feat_ApplicationTypeCollection
   validate(memberName: String): String
 }
 
@@ -802,12 +851,14 @@ type 
causeway_feat_ApplicationTypeCollection__namespaceName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(namespaceName: String!): causeway_feat_ApplicationTypeCollection
   validate(namespaceName: String): String
 }
 
 type causeway_feat_ApplicationTypeCollection__parent__gqlv_property {
   disabled: String
   hidden: Boolean
+  set(parent: causeway_feat_ApplicationFeatureViewModel__gqlv_input!): 
causeway_feat_ApplicationTypeCollection
   validate(parent: causeway_feat_ApplicationFeatureViewModel__gqlv_input): 
String
 }
 
@@ -815,6 +866,7 @@ type 
causeway_feat_ApplicationTypeCollection__typeSimpleName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(typeSimpleName: String!): causeway_feat_ApplicationTypeCollection
   validate(typeSimpleName: String): String
 }
 
@@ -835,6 +887,7 @@ type 
causeway_feat_ApplicationTypeMember__memberName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(memberName: String!): causeway_feat_ApplicationTypeMember
   validate(memberName: String): String
 }
 
@@ -842,12 +895,14 @@ type 
causeway_feat_ApplicationTypeMember__namespaceName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(namespaceName: String!): causeway_feat_ApplicationTypeMember
   validate(namespaceName: String): String
 }
 
 type causeway_feat_ApplicationTypeMember__parent__gqlv_property {
   disabled: String
   hidden: Boolean
+  set(parent: causeway_feat_ApplicationFeatureViewModel__gqlv_input!): 
causeway_feat_ApplicationTypeMember
   validate(parent: causeway_feat_ApplicationFeatureViewModel__gqlv_input): 
String
 }
 
@@ -855,6 +910,7 @@ type 
causeway_feat_ApplicationTypeMember__typeSimpleName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(typeSimpleName: String!): causeway_feat_ApplicationTypeMember
   validate(typeSimpleName: String): String
 }
 
@@ -874,6 +930,7 @@ type 
causeway_feat_ApplicationTypeProperty__derived__gqlv_property {
   disabled: String
   get: Boolean!
   hidden: Boolean
+  set(derived: Boolean!): causeway_feat_ApplicationTypeProperty
   validate(derived: Boolean): String
 }
 
@@ -886,6 +943,7 @@ type 
causeway_feat_ApplicationTypeProperty__maxLength__gqlv_property {
   disabled: String
   get: Int
   hidden: Boolean
+  set(maxLength: Int): causeway_feat_ApplicationTypeProperty
   validate(maxLength: Int): String
 }
 
@@ -893,6 +951,7 @@ type 
causeway_feat_ApplicationTypeProperty__memberName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(memberName: String!): causeway_feat_ApplicationTypeProperty
   validate(memberName: String): String
 }
 
@@ -900,12 +959,14 @@ type 
causeway_feat_ApplicationTypeProperty__namespaceName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(namespaceName: String!): causeway_feat_ApplicationTypeProperty
   validate(namespaceName: String): String
 }
 
 type causeway_feat_ApplicationTypeProperty__parent__gqlv_property {
   disabled: String
   hidden: Boolean
+  set(parent: causeway_feat_ApplicationFeatureViewModel__gqlv_input!): 
causeway_feat_ApplicationTypeProperty
   validate(parent: causeway_feat_ApplicationFeatureViewModel__gqlv_input): 
String
 }
 
@@ -913,6 +974,7 @@ type 
causeway_feat_ApplicationTypeProperty__returnType__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(returnType: String!): causeway_feat_ApplicationTypeProperty
   validate(returnType: String): String
 }
 
@@ -920,6 +982,7 @@ type 
causeway_feat_ApplicationTypeProperty__typeSimpleName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(typeSimpleName: String!): causeway_feat_ApplicationTypeProperty
   validate(typeSimpleName: String): String
 }
 
@@ -927,6 +990,7 @@ type 
causeway_feat_ApplicationTypeProperty__typicalLength__gqlv_property {
   disabled: String
   get: Int
   hidden: Boolean
+  set(typicalLength: Int): causeway_feat_ApplicationTypeProperty
   validate(typicalLength: Int): String
 }
 
@@ -951,6 +1015,7 @@ type 
causeway_feat_ApplicationType__memberName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(memberName: String!): causeway_feat_ApplicationType
   validate(memberName: String): String
 }
 
@@ -958,12 +1023,14 @@ type 
causeway_feat_ApplicationType__namespaceName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(namespaceName: String!): causeway_feat_ApplicationType
   validate(namespaceName: String): String
 }
 
 type causeway_feat_ApplicationType__parent__gqlv_property {
   disabled: String
   hidden: Boolean
+  set(parent: causeway_feat_ApplicationFeatureViewModel__gqlv_input!): 
causeway_feat_ApplicationType
   validate(parent: causeway_feat_ApplicationFeatureViewModel__gqlv_input): 
String
 }
 
@@ -977,6 +1044,7 @@ type 
causeway_feat_ApplicationType__typeSimpleName__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(typeSimpleName: String!): causeway_feat_ApplicationType
   validate(typeSimpleName: String): String
 }
 
@@ -997,6 +1065,7 @@ type 
causeway_schema_metamodel_v2_DomainClassDto__actions__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(actions: String!): causeway_schema_metamodel_v2_DomainClassDto
   validate(actions: String): String
 }
 
@@ -1004,6 +1073,7 @@ type 
causeway_schema_metamodel_v2_DomainClassDto__annotations__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(annotations: String!): causeway_schema_metamodel_v2_DomainClassDto
   validate(annotations: String): String
 }
 
@@ -1011,6 +1081,7 @@ type 
causeway_schema_metamodel_v2_DomainClassDto__collections__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(collections: String!): causeway_schema_metamodel_v2_DomainClassDto
   validate(collections: String): String
 }
 
@@ -1018,6 +1089,7 @@ type 
causeway_schema_metamodel_v2_DomainClassDto__facets__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(facets: String!): causeway_schema_metamodel_v2_DomainClassDto
   validate(facets: String): String
 }
 
@@ -1030,6 +1102,7 @@ type 
causeway_schema_metamodel_v2_DomainClassDto__id__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(id: String!): causeway_schema_metamodel_v2_DomainClassDto
   validate(id: String): String
 }
 
@@ -1037,6 +1110,7 @@ type 
causeway_schema_metamodel_v2_DomainClassDto__majorVersion__gqlv_property {
   disabled: String
   get: String
   hidden: Boolean
+  set(majorVersion: String): causeway_schema_metamodel_v2_DomainClassDto
   validate(majorVersion: String): String
 }
 
@@ -1044,6 +1118,7 @@ type 
causeway_schema_metamodel_v2_DomainClassDto__minorVersion__gqlv_property {
   disabled: String
   get: String
   hidden: Boolean
+  set(minorVersion: String): causeway_schema_metamodel_v2_DomainClassDto
   validate(minorVersion: String): String
 }
 
@@ -1051,6 +1126,7 @@ type 
causeway_schema_metamodel_v2_DomainClassDto__properties__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(properties: String!): causeway_schema_metamodel_v2_DomainClassDto
   validate(properties: String): String
 }
 
@@ -1058,6 +1134,7 @@ type 
causeway_schema_metamodel_v2_DomainClassDto__service__gqlv_property {
   disabled: String
   get: Boolean!
   hidden: Boolean
+  set(service: Boolean!): causeway_schema_metamodel_v2_DomainClassDto
   validate(service: Boolean): String
 }
 
@@ -1093,6 +1170,7 @@ type 
causeway_testing_fixtures_FixtureResult__className__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(className: String!): causeway_testing_fixtures_FixtureResult
   validate(className: String): String
 }
 
@@ -1100,6 +1178,7 @@ type 
causeway_testing_fixtures_FixtureResult__fixtureScriptClassName__gqlv_prope
   disabled: String
   get: String
   hidden: Boolean
+  set(fixtureScriptClassName: String): causeway_testing_fixtures_FixtureResult
   validate(fixtureScriptClassName: String): String
 }
 
@@ -1112,12 +1191,14 @@ type 
causeway_testing_fixtures_FixtureResult__key__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(key: String!): causeway_testing_fixtures_FixtureResult
   validate(key: String): String
 }
 
 type causeway_testing_fixtures_FixtureResult__object__gqlv_property {
   disabled: String
   hidden: Boolean
+  set(object: String!): causeway_testing_fixtures_FixtureResult
   validate(object: String): String
 }
 
@@ -1212,6 +1293,7 @@ type 
org_apache_causeway_core_metamodel_inspect_model_MMNode__gqlv_meta {
 type 
org_apache_causeway_core_metamodel_inspect_model_MMNode__parentNode__gqlv_property
 {
   disabled: String
   hidden: Boolean
+  set(parentNode: 
org_apache_causeway_core_metamodel_inspect_model_MMNode__gqlv_input!): 
org_apache_causeway_core_metamodel_inspect_model_MMNode
   validate(parentNode: 
org_apache_causeway_core_metamodel_inspect_model_MMNode__gqlv_input): String
 }
 
@@ -1236,6 +1318,7 @@ type 
org_apache_causeway_core_metamodel_inspect_model_MemberNode__mixedIn__gqlv_
   disabled: String
   get: Boolean!
   hidden: Boolean
+  set(mixedIn: Boolean!): 
org_apache_causeway_core_metamodel_inspect_model_MemberNode
   validate(mixedIn: Boolean): String
 }
 
@@ -1243,6 +1326,7 @@ type 
org_apache_causeway_core_metamodel_inspect_model_MemberNode__parentNode__gq
   disabled: String
   get: causeway_applib_TypeNode!
   hidden: Boolean
+  set(parentNode: causeway_applib_TypeNode__gqlv_input!): 
org_apache_causeway_core_metamodel_inspect_model_MemberNode
   validate(parentNode: causeway_applib_TypeNode__gqlv_input): String
 }
 
@@ -1256,6 +1340,7 @@ type 
org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript__f
   disabled: String
   get: String!
   hidden: Boolean
+  set(friendlyName: String!): 
org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript
   validate(friendlyName: String): String
 }
 
@@ -1268,6 +1353,7 @@ type 
org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript__q
   disabled: String
   get: String!
   hidden: Boolean
+  set(qualifiedName: String!): 
org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript
   validate(qualifiedName: String): String
 }
 
@@ -1287,6 +1373,7 @@ type 
university_admin_AdminMenu__actionWithDisabledParam__firstParam__gqlv_actio
 type university_admin_AdminMenu__actionWithDisabledParam__gqlv_action {
   disabled: String
   hidden: Boolean
+  invokeNonIdempotent(firstParam: String!, secondParam: String!, 
thirdParameter: String!): String
   params: 
university_admin_AdminMenu__actionWithDisabledParam__gqlv_action_params
   validate(firstParam: String, secondParam: String, thirdParameter: String): 
String
 }
@@ -1318,6 +1405,7 @@ type 
university_admin_AdminMenu__actionWithHiddenParam__firstParam__gqlv_action_
 type university_admin_AdminMenu__actionWithHiddenParam__gqlv_action {
   disabled: String
   hidden: Boolean
+  invokeNonIdempotent(firstParam: String!, secondParam: String!): String
   params: university_admin_AdminMenu__actionWithHiddenParam__gqlv_action_params
   validate(firstParam: String, secondParam: String): String
 }
@@ -1336,12 +1424,14 @@ type 
university_admin_AdminMenu__actionWithHiddenParam__secondParam__gqlv_action
 type university_admin_AdminMenu__adminAction__gqlv_action {
   disabled: String
   hidden: Boolean
+  invokeNonIdempotent: String
   validate: String
 }
 
 type university_admin_AdminMenu__otherAdminAction__gqlv_action {
   disabled: String
   hidden: Boolean
+  invokeNonIdempotent: String
   validate: String
 }
 
@@ -1844,6 +1934,7 @@ type university_dept_Department {
 type university_dept_Department__addStaffMember__gqlv_action {
   disabled: String
   hidden: Boolean
+  invokeIdempotent(staffMember: university_dept_StaffMember__gqlv_input!): 
university_dept_Department
   params: university_dept_Department__addStaffMember__gqlv_action_params
   validate(staffMember: university_dept_StaffMember__gqlv_input): String
 }
@@ -1862,6 +1953,7 @@ type 
university_dept_Department__addStaffMember__staffMember__gqlv_action_parame
 type university_dept_Department__addStaffMembers__gqlv_action {
   disabled: String
   hidden: Boolean
+  invokeIdempotent(staffMembers: [university_dept_StaffMember__gqlv_input]): 
university_dept_Department
   params: university_dept_Department__addStaffMembers__gqlv_action_params
   validate(staffMembers: [university_dept_StaffMember__gqlv_input]): String
 }
@@ -1880,6 +1972,7 @@ type 
university_dept_Department__addStaffMembers__staffMembers__gqlv_action_para
 type university_dept_Department__changeDeptHead__gqlv_action {
   disabled: String
   hidden: Boolean
+  invokeIdempotent(newDeptHead: university_dept_DeptHead__gqlv_input!): 
university_dept_Department
   params: university_dept_Department__changeDeptHead__gqlv_action_params
   validate(newDeptHead: university_dept_DeptHead__gqlv_input): String
 }
@@ -1899,6 +1992,7 @@ type 
university_dept_Department__changeDeptHead__newDeptHead__gqlv_action_parame
 type university_dept_Department__changeName__gqlv_action {
   disabled: String
   hidden: Boolean
+  invokeIdempotent(newName: String!): university_dept_Department
   params: university_dept_Department__changeName__gqlv_action_params
   validate(newName: String): String
 }
@@ -1919,6 +2013,7 @@ type university_dept_Department__deptHead__gqlv_property {
   disabled: String
   get: university_dept_DeptHead
   hidden: Boolean
+  set(deptHead: university_dept_DeptHead__gqlv_input): 
university_dept_Department
   validate(deptHead: university_dept_DeptHead__gqlv_input): String
 }
 
@@ -1932,12 +2027,14 @@ type university_dept_Department__name__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(name: String!): university_dept_Department
   validate(name: String): String
 }
 
 type university_dept_Department__removeStaffMember__gqlv_action {
   disabled: String
   hidden: Boolean
+  invokeIdempotent(staffMember: university_dept_StaffMember__gqlv_input!): 
university_dept_Department
   params: university_dept_Department__removeStaffMember__gqlv_action_params
   validate(staffMember: university_dept_StaffMember__gqlv_input): String
 }
@@ -1975,6 +2072,7 @@ type 
university_dept_Departments__createDepartment__deptHead__gqlv_action_parame
 type university_dept_Departments__createDepartment__gqlv_action {
   disabled: String
   hidden: Boolean
+  invokeNonIdempotent(deptHead: university_dept_DeptHead__gqlv_input, name: 
String!): university_dept_Department
   params: university_dept_Departments__createDepartment__gqlv_action_params
   validate(deptHead: university_dept_DeptHead__gqlv_input, name: String): 
String
 }
@@ -2033,6 +2131,7 @@ type 
university_dept_DeptHead__changeDepartment__department__gqlv_action_paramet
 type university_dept_DeptHead__changeDepartment__gqlv_action {
   disabled: String
   hidden: Boolean
+  invokeIdempotent(department: university_dept_Department__gqlv_input!): 
university_dept_DeptHead
   params: university_dept_DeptHead__changeDepartment__gqlv_action_params
   validate(department: university_dept_Department__gqlv_input): String
 }
@@ -2044,6 +2143,7 @@ type 
university_dept_DeptHead__changeDepartment__gqlv_action_params {
 type university_dept_DeptHead__changeName__gqlv_action {
   disabled: String
   hidden: Boolean
+  invokeIdempotent(newName: String!): university_dept_DeptHead
   params: university_dept_DeptHead__changeName__gqlv_action_params
   validate(newName: String): String
 }
@@ -2064,6 +2164,7 @@ type university_dept_DeptHead__department__gqlv_property {
   disabled: String
   get: university_dept_Department
   hidden: Boolean
+  set(department: university_dept_Department__gqlv_input): 
university_dept_DeptHead
   validate(department: university_dept_Department__gqlv_input): String
 }
 
@@ -2077,6 +2178,7 @@ type university_dept_DeptHead__name__gqlv_property {
   disabled: String
   get: String
   hidden: Boolean
+  set(name: String): university_dept_DeptHead
   validate(name: String): String
 }
 
@@ -2129,6 +2231,7 @@ type 
university_dept_StaffMember__department__gqlv_property {
   disabled: String
   get: university_dept_Department
   hidden: Boolean
+  set(department: university_dept_Department__gqlv_input): 
university_dept_StaffMember
   validate(department: university_dept_Department__gqlv_input): String
 }
 
@@ -2143,6 +2246,7 @@ type university_dept_StaffMember__grade__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(grade: String!): university_dept_StaffMember
   validate(grade: String): String
 }
 
@@ -2150,6 +2254,7 @@ type university_dept_StaffMember__name__gqlv_property {
   disabled: String
   get: String!
   hidden: Boolean
+  set(name: String!): university_dept_StaffMember
   validate(name: String): String
 }
 
@@ -2157,6 +2262,7 @@ type university_dept_StaffMember__photo__gqlv_property {
   disabled: String
   get: String
   hidden: Boolean
+  set(photo: String): university_dept_StaffMember
   validate(photo: String): String
 }
 
@@ -2170,6 +2276,7 @@ type 
university_dept_Staff__createStaffMember__department__gqlv_action_parameter
 type university_dept_Staff__createStaffMember__gqlv_action {
   disabled: String
   hidden: Boolean
+  invokeNonIdempotent(department: university_dept_Department__gqlv_input!, 
name: String!): university_dept_StaffMember
   params: university_dept_Staff__createStaffMember__gqlv_action_params
   validate(department: university_dept_Department__gqlv_input, name: String): 
String
 }
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 493dd1defd..fe8b13bb7e 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 java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.Map;
 
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
 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;
 import org.apache.causeway.viewer.graphql.viewer.toplevel.GqlvTopLevelMutation;
 
@@ -107,14 +110,6 @@ public class GraphQlSourceForCauseway implements 
GraphQlSource {
         val codeRegistryBuilder = GraphQLCodeRegistry.newCodeRegistry();
         val context = new Context(codeRegistryBuilder, bookmarkService, 
specificationLoader, typeMapper, serviceRegistry, causewayConfiguration, 
causewaySystemEnvironment);
 
-        // add to the top-level query type and (dependent on configuration) 
the top-level mutation type also
-        val topLevelQuery = new GqlvTopLevelQuery();
-        val topLevelMutation =
-                causewayConfiguration.getViewer().getGraphql().getApiVariant() 
== CausewayConfiguration.Viewer.Graphql.ApiVariant.QUERY_AND_MUTATIONS ?
-                    new GqlvTopLevelMutation(context)
-                    : null;
-
-
         val objectSpecifications = specificationLoader.snapshotSpecifications()
                 .filter(x -> x.getCorrespondingClass().getPackage() != 
Either.class.getPackage())   // exclude the 
org.apache_causeway.commons.functional
                 .distinct((a, b) -> 
a.getLogicalTypeName().equals(b.getLogicalTypeName()))
@@ -122,7 +117,35 @@ public class GraphQlSourceForCauseway implements 
GraphQlSource {
                 
.sorted(Comparator.comparing(HasLogicalType::getLogicalTypeName))
                 .toList();
 
-        // add to top-level query
+        // top-level query type and (dependent on configuration) the top-level 
mutation type
+        val topLevelQuery = new GqlvTopLevelQuery(context);
+        val topLevelMutation =
+                causewayConfiguration.getViewer().getGraphql().getApiVariant() 
== CausewayConfiguration.Viewer.Graphql.ApiVariant.QUERY_AND_MUTATIONS ?
+                        new GqlvTopLevelMutation(context)
+                        : null;
+
+
+        // domain objects
+        val domainObjects = new LinkedHashMap<ObjectSpecification, 
GqlvDomainObject>();
+        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();
+
+                    domainObjects.put(objectSpec, domainObject);
+
+                    break;
+            }
+        });
+
+
+        // add services to top-level query
         objectSpecifications.forEach(objectSpec -> {
             switch (objectSpec.getBeanSort()) {
                 case MANAGED_BEAN_CONTRIBUTING: // @DomainService
@@ -134,6 +157,12 @@ public class GraphQlSourceForCauseway implements 
GraphQlSource {
                     break;
             }
         });
+
+        // add lookup to top-level query
+        domainObjects.forEach((objectSpec, domainObject) -> {
+            topLevelQuery.addLookupFor(objectSpec, domainObject);
+        });
+
         topLevelQuery.buildQueryType();
 
         // add top-level mutation (if application configuration requires it)
@@ -152,21 +181,6 @@ public class GraphQlSourceForCauseway implements 
GraphQlSource {
             topLevelMutation.addDataFetchers();
         }
 
-        // add remaining domain objects
-        objectSpecifications.forEach(objectSpec -> {
-            switch (objectSpec.getBeanSort()) {
-
-                case ABSTRACT:
-                case VIEW_MODEL: // @DomainObject(nature=VIEW_MODEL)
-                case ENTITY:     // @DomainObject(nature=ENTITY)
-
-                    val gqlvDomainObject = new GqlvDomainObject(objectSpec, 
context, objectManager, graphQLTypeRegistry);
-                    gqlvDomainObject.addTypesInto(graphQLTypeRegistry);
-                    gqlvDomainObject.addDataFetchers();
-
-                    break;
-            }
-        });
 
 
 
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 3ebf14055a..3404f8f05a 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,22 +3,32 @@ package org.apache.causeway.viewer.graphql.viewer.toplevel;
 import java.util.ArrayList;
 import java.util.List;
 
+import graphql.schema.DataFetcher;
+import graphql.schema.DataFetchingEnvironment;
 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.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 lombok.Getter;
+import lombok.val;
 
 public class GqlvTopLevelQuery implements GqlvDomainService.Holder {
+
     @Getter final GraphQLObjectType.Builder queryBuilder;
 
     private final List<GqlvDomainService> domainServices = new ArrayList<>();
+    private final Context context;
 
 
     /**
@@ -27,7 +37,8 @@ public class GqlvTopLevelQuery implements 
GqlvDomainService.Holder {
     private GraphQLObjectType queryType;
 
 
-    public GqlvTopLevelQuery() {
+    public GqlvTopLevelQuery(Context context) {
+        this.context = context;
         queryBuilder = newObject().name("Query");
     }
 
@@ -76,5 +87,35 @@ public class GqlvTopLevelQuery implements 
GqlvDomainService.Holder {
         });
     }
 
+    public void addLookupFor(
+            final ObjectSpecification objectSpec,
+            final GqlvDomainObject domainObject) {
+        val lookupConfig = 
context.causewayConfiguration.getViewer().getGraphql().getLookup();
+        val field = newFieldDefinition()
+                        .name(String.format("%s%s%s",
+                                lookupConfig.getFieldNamePrefix(),          // 
eg "_gqlv_lookup__"
+                                TypeNames.objectTypeNameFor(objectSpec),
+                                lookupConfig.getFieldNameSuffix())          // 
eg ""
+                        )
+                        .type(context.typeMapper.outputTypeFor(objectSpec))
+                        .argument(GraphQLArgument.newArgument()
+                                        .name(lookupConfig.getArgument())   // 
eg "object"
+                                        
.type(domainObject.getGqlInputObjectType())
+                                        .build())
+                        .build();
+        addField(field);
+
+        context.codeRegistryBuilder.dataFetcher(
+                coordinatesFor(field),
+                (DataFetcher<Object>) environment -> lookup(objectSpec, 
environment));
+
+    }
+
+    private Object lookup(ObjectSpecification objectSpec, 
DataFetchingEnvironment dataFetchingEnvironment) {
+        Object target = dataFetchingEnvironment.getArgument("object");
+        return GqlvAction.asPojo(objectSpec, target, context.bookmarkService)
+                .orElse(null);
+    }
+
 
 }

Reply via email to