This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch v4
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit e97bc3a61e587ebcd6d81dd0d212c07faf251c92
Author: Andi Huber <[email protected]>
AuthorDate: Mon Oct 6 17:17:37 2025 +0200

    CAUSEWAY-2297: refactors ComponentFactoryRegistry into a record
---
 .../ui/app/registry/ComponentFactoryList.java      | 29 ++++++++++---
 .../ui/app/registry/ComponentFactoryRegistry.java  | 49 ++++++++--------------
 2 files changed, 41 insertions(+), 37 deletions(-)

diff --git 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/app/registry/ComponentFactoryList.java
 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/app/registry/ComponentFactoryList.java
index 5fbef603afd..53449bdb722 100644
--- 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/app/registry/ComponentFactoryList.java
+++ 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/app/registry/ComponentFactoryList.java
@@ -18,23 +18,27 @@
  */
 package org.apache.causeway.viewer.wicket.ui.app.registry;
 
-import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
-import java.util.List;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
 import java.util.stream.Stream;
 
+import org.apache.causeway.commons.internal.collections._Multimaps;
+import 
org.apache.causeway.commons.internal.collections._Multimaps.ListMultimap;
+import org.apache.causeway.viewer.commons.model.components.UiComponentType;
 import org.apache.causeway.viewer.wicket.ui.ComponentFactory;
 
 public record ComponentFactoryList(
-        List<ComponentFactory> componentFactories) implements 
Iterable<ComponentFactory> {
+        Set<ComponentFactory> componentFactories) implements 
Iterable<ComponentFactory> {
 
     public ComponentFactoryList() {
-        this(new ArrayList<>());
+        this(new LinkedHashSet<>());
     }
 
     public void add(final ComponentFactory componentFactory) {
-        if(componentFactories.contains(componentFactory)) return;
-
         componentFactories.add(componentFactory);
     }
 
@@ -52,4 +56,17 @@ public <T extends ComponentFactory> Stream<T> stream(final 
Class<T> requiredClas
                 .filter(requiredClass::isInstance)
                 .map(requiredClass::cast);
     }
+
+    public ListMultimap<UiComponentType, ComponentFactory> 
asFactoriesByComponentType() {
+        var map = _Multimaps.<UiComponentType, 
ComponentFactory>newListMultimap();
+        stream().forEach(cf->map.putElement(cf.getComponentType(), cf));
+        return map.asUnmodifiable();
+    }
+
+    public Map<Class<? extends ComponentFactory>, ComponentFactory> 
asFactoriesByType() {
+        var map = new HashMap<Class<? extends ComponentFactory>, 
ComponentFactory>();
+        stream().forEach(cf->map.put(cf.getClass(), cf));
+        return Collections.unmodifiableMap(map);
+    }
+
 }
\ No newline at end of file
diff --git 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/app/registry/ComponentFactoryRegistry.java
 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/app/registry/ComponentFactoryRegistry.java
index 9f08850be4d..ab0f44a910e 100644
--- 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/app/registry/ComponentFactoryRegistry.java
+++ 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/app/registry/ComponentFactoryRegistry.java
@@ -18,7 +18,6 @@
  */
 package org.apache.causeway.viewer.wicket.ui.app.registry;
 
-import java.util.HashMap;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Optional;
@@ -28,13 +27,11 @@
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.model.IModel;
-
 import org.jspecify.annotations.Nullable;
 
 import org.apache.causeway.commons.collections.ImmutableEnumSet;
 import org.apache.causeway.commons.internal.base._Refs;
 import org.apache.causeway.commons.internal.base._Text;
-import org.apache.causeway.commons.internal.collections._Multimaps;
 import 
org.apache.causeway.commons.internal.collections._Multimaps.ListMultimap;
 import org.apache.causeway.core.metamodel.context.MetaModelContext;
 import org.apache.causeway.viewer.commons.model.components.UiComponentType;
@@ -45,23 +42,27 @@
 
 /**
  * API for finding registered {@link ComponentFactory}s.
- * <p>
- * Ultimately all requests to locate {@link ComponentFactory}s are routed
- * through to an object implementing this interface.
+ *
+ * <p>Ultimately all requests to locate {@link ComponentFactory}s are routed
+ * through this registry.
  */
 @Slf4j
-public final class ComponentFactoryRegistry {
-
-    private final ListMultimap<UiComponentType, ComponentFactory> 
componentFactoriesByComponentType =
-            _Multimaps.newListMultimap();
-    private final Map<Class<? extends ComponentFactory>, ComponentFactory> 
componentFactoriesByType =
-            new HashMap<>();
+public record ComponentFactoryRegistry(
+    ListMultimap<UiComponentType, ComponentFactory> factoriesByComponentType,
+    Map<Class<? extends ComponentFactory>, ComponentFactory> factoriesByType
+    ) {
 
     public ComponentFactoryRegistry(
             final ComponentFactoryList factoryList,
             final MetaModelContext mmc) {
-        super();
-        factoryList.forEach(compFactory->this.registerComponentFactory(mmc, 
compFactory));
+        this(factoryList.asFactoriesByComponentType(), 
factoryList.asFactoriesByType());
+        factoryList.forEach(compFactory->{
+            // handle dependency injection for factories
+            mmc.getServiceInjector().injectServicesInto(compFactory);
+            if(compFactory instanceof ComponentFactoryAbstract) {
+                
((ComponentFactoryAbstract)compFactory).setMetaModelContext(mmc);
+            }
+        });
         ensureAllComponentTypesRegistered();
     }
 
@@ -147,7 +148,7 @@ public Stream<ComponentFactory> streamComponentFactories(
 
         var exclusiveIfAny = _Refs.<ComponentFactory>objectRef(null);
 
-        var allThatApply = 
componentFactoriesByComponentType.streamElements(uiComponentType)
+        var allThatApply = 
factoriesByComponentType.streamElements(uiComponentType)
                 .filter(componentFactory->{
                     var advice = componentFactory.appliesTo(uiComponentType, 
model);
                     if(advice.appliesExclusively()) {
@@ -175,7 +176,7 @@ public Stream<ComponentFactory> streamComponentFactories(
 
     @SuppressWarnings("unchecked")
     public <T extends ComponentFactory> Optional<T> lookupFactory(final 
Class<T> factoryClass) {
-        return 
Optional.ofNullable((T)componentFactoriesByType.get(factoryClass));
+        return Optional.ofNullable((T)factoriesByType.get(factoryClass));
     }
 
     public <T extends ComponentFactory> T lookupFactoryElseFail(final Class<T> 
factoryClass) {
@@ -186,20 +187,6 @@ public <T extends ComponentFactory> T 
lookupFactoryElseFail(final Class<T> facto
 
     // -- HELPER
 
-    private void registerComponentFactory(
-            final MetaModelContext commonContext,
-            final ComponentFactory componentFactory) {
-        componentFactoriesByType.put(componentFactory.getClass(), 
componentFactory);
-
-        // handle dependency injection for factories
-        
commonContext.getServiceInjector().injectServicesInto(componentFactory);
-        if(componentFactory instanceof ComponentFactoryAbstract) {
-            
((ComponentFactoryAbstract)componentFactory).setMetaModelContext(commonContext);
-        }
-
-        
componentFactoriesByComponentType.putElement(componentFactory.getComponentType(),
 componentFactory);
-    }
-
     private void ensureAllComponentTypesRegistered() {
         for (var componentType : UiComponentType.values()) {
 
@@ -207,7 +194,7 @@ private void ensureAllComponentTypesRegistered() {
                 continue;
             }
 
-            if 
(componentFactoriesByComponentType.getOrElseEmpty(componentType).isEmpty()) {
+            if 
(factoriesByComponentType.getOrElseEmpty(componentType).isEmpty()) {
                 throw new IllegalStateException("No component factories 
registered for " + componentType);
             }
         }

Reply via email to