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 752cdc6744 CAUSEWAY-3676: behaviour iterates by map
752cdc6744 is described below
commit 752cdc67443986d953ed867c519aef3d0d4aa644
Author: danhaywood <[email protected]>
AuthorDate: Fri Jan 19 16:45:00 2024 +0000
CAUSEWAY-3676: behaviour iterates by map
---
incubator/viewers/graphql/viewer/pom.xml | 12 ++-
.../graphql/viewer/src/main/java/module-info.java | 1 +
.../graphql/viewer/source/GqlvObjectBehaviour.java | 22 +++--
.../graphql/viewer/source/GqlvObjectStructure.java | 27 +++++-
.../viewer/graphql/viewer/util/_BiMap.java | 48 +++++++++++
.../viewer/graphql/viewer/util/_BiMap_Test.java | 98 ++++++++++++++++++++++
6 files changed, 191 insertions(+), 17 deletions(-)
diff --git a/incubator/viewers/graphql/viewer/pom.xml
b/incubator/viewers/graphql/viewer/pom.xml
index 48e4150842..c63762fee6 100644
--- a/incubator/viewers/graphql/viewer/pom.xml
+++ b/incubator/viewers/graphql/viewer/pom.xml
@@ -67,8 +67,18 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <scope>test</scope>
+ </dependency>
- </dependencies>
+ </dependencies>
</project>
diff --git a/incubator/viewers/graphql/viewer/src/main/java/module-info.java
b/incubator/viewers/graphql/viewer/src/main/java/module-info.java
index a1bf0e3120..c6a090775f 100644
--- a/incubator/viewers/graphql/viewer/src/main/java/module-info.java
+++ b/incubator/viewers/graphql/viewer/src/main/java/module-info.java
@@ -2,6 +2,7 @@ module org.apache.causeway.incubator.viewer.graphql.viewer {
exports org.apache.causeway.viewer.graphql.viewer;
exports org.apache.causeway.viewer.graphql.viewer.source;
exports org.apache.causeway.viewer.graphql.viewer.integration;
+ exports org.apache.causeway.viewer.graphql.viewer.util;
requires com.fasterxml.jackson.core;
requires com.fasterxml.jackson.databind;
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
index fca594cad5..00c315dc64 100644
---
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
@@ -1,6 +1,7 @@
package org.apache.causeway.viewer.graphql.viewer.source;
+import java.util.Map;
import java.util.Set;
import org.apache.causeway.applib.services.bookmark.BookmarkService;
@@ -12,6 +13,8 @@ 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 graphql.schema.GraphQLFieldDefinition;
+
import lombok.RequiredArgsConstructor;
import graphql.schema.DataFetcher;
@@ -69,21 +72,19 @@ public class GqlvObjectBehaviour {
public void createAndRegisterDataFetchersForField() {
- structure.getObjectSpec().streamProperties(MixedIn.INCLUDED)
-
.forEach(this::createAndRegisterDataFetcherForObjectAssociation);
+
structure.getProperties().entrySet().forEach(this::createAndRegisterDataFetcherForAssociation);
}
void createAndRegisterDataFetchersForCollection() {
- structure.getObjectSpec().streamCollections(MixedIn.INCLUDED)
-
.forEach(this::createAndRegisterDataFetcherForObjectAssociation);
+
structure.getCollections().entrySet().forEach(this::createAndRegisterDataFetcherForAssociation);
}
-
- private void createAndRegisterDataFetcherForObjectAssociation(final
ObjectAssociation otom) {
+ private void createAndRegisterDataFetcherForAssociation(
+ final Map.Entry<? extends ObjectAssociation,
GraphQLFieldDefinition> propertyAndField) {
final GraphQLObjectType graphQLObjectType =
structure.getGqlObjectType();
- ObjectSpecification fieldObjectSpecification = otom.getElementType();
+ ObjectSpecification fieldObjectSpecification =
propertyAndField.getKey().getElementType();
BeanSort beanSort = fieldObjectSpecification.getBeanSort();
switch (beanSort) {
@@ -95,7 +96,7 @@ public class GqlvObjectBehaviour {
codeRegistryBuilder
.dataFetcher(
-
FieldCoordinates.coordinates(graphQLObjectType, otom.getId()),
+
FieldCoordinates.coordinates(graphQLObjectType,
propertyAndField.getKey().getId()),
(DataFetcher<Object>) environment -> {
Object domainObjectInstance =
environment.getSource();
@@ -104,14 +105,11 @@ public class GqlvObjectBehaviour {
ObjectSpecification specification =
specificationLoader.loadSpecification(domainObjectInstanceClass);
ManagedObject owner =
ManagedObject.adaptSingular(specification, domainObjectInstance);
-
- ManagedObject managedObject =
otom.get(owner);
+ ManagedObject managedObject =
propertyAndField.getKey().get(owner);
return managedObject!=null ?
managedObject.getPojo() : null;
-
});
-
break;
}
diff --git
a/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GqlvObjectStructure.java
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GqlvObjectStructure.java
index c40d9d3087..cb307d506e 100644
---
a/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GqlvObjectStructure.java
+++
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/source/GqlvObjectStructure.java
@@ -1,6 +1,7 @@
package org.apache.causeway.viewer.graphql.viewer.source;
import graphql.Scalars;
+import graphql.com.google.common.collect.BiMap;
import graphql.schema.GraphQLArgument;
import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.GraphQLInputObjectType;
@@ -12,6 +13,7 @@ import graphql.schema.GraphQLType;
import graphql.schema.GraphQLTypeReference;
import lombok.Getter;
+import lombok.Synchronized;
import lombok.experimental.UtilityClass;
import lombok.val;
@@ -31,6 +33,7 @@ import
org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
import org.apache.causeway.core.metamodel.spec.feature.ObjectActionParameter;
import org.apache.causeway.core.metamodel.spec.feature.OneToManyAssociation;
import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.causeway.viewer.graphql.viewer.util._BiMap;
import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition;
import static graphql.schema.GraphQLInputObjectField.newInputObjectField;
@@ -91,10 +94,26 @@ public class GqlvObjectStructure {
final GraphQLObjectType.Builder mutatorsTypeBuilder;
- private final Map<OneToOneAssociation, GraphQLFieldDefinition>
propertyToField = new LinkedHashMap<>();
- private final Map<OneToManyAssociation, GraphQLFieldDefinition>
collectionToField = new LinkedHashMap<>();
- private final Map<ObjectAction, GraphQLFieldDefinition> safeActionToField
= new LinkedHashMap<>();
- private final Map<ObjectAction, GraphQLFieldDefinition>
mutatorActionToField = new LinkedHashMap<>();
+ private final _BiMap<OneToOneAssociation, GraphQLFieldDefinition>
propertyToField = new _BiMap<>();
+ private final _BiMap<OneToManyAssociation, GraphQLFieldDefinition>
collectionToField = new _BiMap<>();
+ private final _BiMap<ObjectAction, GraphQLFieldDefinition>
safeActionToField = new _BiMap<>();
+ private final _BiMap<ObjectAction, GraphQLFieldDefinition>
mutatorActionToField = new _BiMap<>();
+
+ Map<OneToOneAssociation, GraphQLFieldDefinition> getProperties() {
+ return propertyToField.getForwardMapAsImmutable();
+ }
+
+ Map<OneToManyAssociation, GraphQLFieldDefinition> getCollections() {
+ return collectionToField.getForwardMapAsImmutable();
+ }
+
+ Map<ObjectAction, GraphQLFieldDefinition> getSafeActions() {
+ return safeActionToField.getForwardMapAsImmutable();
+ }
+
+ Map<ObjectAction, GraphQLFieldDefinition> getMutatorActions() {
+ return mutatorActionToField.getForwardMapAsImmutable();
+ }
/**
* Built using {@link #buildGqlObjectType()}
diff --git
a/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/util/_BiMap.java
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/util/_BiMap.java
new file mode 100644
index 0000000000..c3b7bba68c
--- /dev/null
+++
b/incubator/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/util/_BiMap.java
@@ -0,0 +1,48 @@
+package org.apache.causeway.viewer.graphql.viewer.util;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class _BiMap<K, V> {
+ private final Map<K, V> forwardMap = new LinkedHashMap<>();
+ private final Map<V, K> inverseMap = new LinkedHashMap<>();
+
+ public void put(K key, V value) {
+ forwardMap.put(key, value);
+ inverseMap.put(value, key);
+ }
+
+ public V get(K key) {
+ return forwardMap.get(key);
+ }
+
+ public _BiMap<V, K> inverse() {
+ _BiMap<V, K> inverseBiMap = new _BiMap<>();
+ inverseBiMap.forwardMap.putAll(inverseMap);
+ inverseBiMap.inverseMap.putAll(forwardMap);
+ return inverseBiMap;
+ }
+
+ public boolean isEmpty() {
+ return forwardMap.isEmpty();
+ }
+
+ public Set<Map.Entry<K, V>> entrySet() {
+ return forwardMap.entrySet();
+ }
+
+ public Set<K> keySet() {
+ return forwardMap.keySet();
+ }
+
+ public Collection<V> values() {
+ return forwardMap.values();
+ }
+
+ public Map<K, V> getForwardMapAsImmutable() {
+ return Collections.unmodifiableMap(forwardMap);
+ }
+}
\ No newline at end of file
diff --git
a/incubator/viewers/graphql/viewer/src/test/java/org/apache/causeway/viewer/graphql/viewer/util/_BiMap_Test.java
b/incubator/viewers/graphql/viewer/src/test/java/org/apache/causeway/viewer/graphql/viewer/util/_BiMap_Test.java
new file mode 100644
index 0000000000..71ba72b992
--- /dev/null
+++
b/incubator/viewers/graphql/viewer/src/test/java/org/apache/causeway/viewer/graphql/viewer/util/_BiMap_Test.java
@@ -0,0 +1,98 @@
+package org.apache.causeway.viewer.graphql.viewer.util;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.jupiter.api.Test;
+import static org.assertj.core.api.Assertions.*;
+
+public class _BiMap_Test {
+
+ @Test
+ public void testPutAndGet() {
+ _BiMap<String, Integer> biMap = new _BiMap<>();
+ biMap.put("one", 1);
+ biMap.put("two", 2);
+
+ assertThat(biMap.get("one")).isEqualTo(1);
+ assertThat(biMap.get("two")).isEqualTo(2);
+ assertThat(biMap.get("nonexistent")).isNull();
+ }
+
+ @Test
+ public void testInverse() {
+ _BiMap<String, Integer> biMap = new _BiMap<>();
+ biMap.put("one", 1);
+ biMap.put("two", 2);
+
+ _BiMap<Integer, String> inverseBiMap = biMap.inverse();
+
+ assertThat(inverseBiMap.get(1)).isEqualTo("one");
+ assertThat(inverseBiMap.get(2)).isEqualTo("two");
+ assertThat(inverseBiMap.get(3)).isNull();
+ }
+
+ @Test
+ public void testIsEmpty() {
+ _BiMap<String, Integer> biMap = new _BiMap<>();
+ assertThat(biMap.isEmpty()).isTrue();
+
+ biMap.put("one", 1);
+ assertThat(biMap.isEmpty()).isFalse();
+ }
+
+ @Test
+ public void testEntrySet() {
+ _BiMap<String, Integer> biMap = new _BiMap<>();
+ biMap.put("one", 1);
+ biMap.put("two", 2);
+
+ Set<Map.Entry<String, Integer>> entrySet = biMap.entrySet();
+
+ assertThat(entrySet).containsExactlyInAnyOrder(
+ Map.entry("one", 1),
+ Map.entry("two", 2)
+ );
+ }
+
+ @Test
+ public void testKeySet() {
+ _BiMap<String, Integer> biMap = new _BiMap<>();
+ biMap.put("one", 1);
+ biMap.put("two", 2);
+
+ Set<String> keySet = biMap.keySet();
+
+ assertThat(keySet).containsExactlyInAnyOrder("one", "two");
+ }
+
+ @Test
+ public void testValues() {
+ _BiMap<String, Integer> biMap = new _BiMap<>();
+ biMap.put("one", 1);
+ biMap.put("two", 2);
+
+ Collection<Integer> values = biMap.values();
+
+ assertThat(values).containsExactlyInAnyOrder(1, 2);
+ }
+
+ @Test
+ public void testGetForwardMapAsImmutable() {
+ _BiMap<String, Integer> biMap = new _BiMap<>();
+ biMap.put("one", 1);
+ biMap.put("two", 2);
+
+ Map<String, Integer> immutableForwardMap =
biMap.getForwardMapAsImmutable();
+
+ assertThat(immutableForwardMap).containsExactly(
+ Map.entry("one", 1),
+ Map.entry("two", 2)
+ );
+
+ // Ensure the immutable map cannot be modified
+ assertThatThrownBy(() -> immutableForwardMap.put("three", 3))
+ .isInstanceOf(UnsupportedOperationException.class);
+ }
+}