From 9abef500b691b806ec83b36b081db3889adced8d Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Fri, 28 Jul 2023 07:23:00 +0200 Subject: [PATCH] [New] Mapped components by name and store types by class as a MapOfLists Now one can really have multiple components with the same API registered under different names --- .../agent/impl/ComponentContainerImpl.java | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/agent/src/main/java/li/strolch/agent/impl/ComponentContainerImpl.java b/agent/src/main/java/li/strolch/agent/impl/ComponentContainerImpl.java index e492b3028..476bc935a 100644 --- a/agent/src/main/java/li/strolch/agent/impl/ComponentContainerImpl.java +++ b/agent/src/main/java/li/strolch/agent/impl/ComponentContainerImpl.java @@ -29,6 +29,7 @@ import li.strolch.runtime.configuration.StrolchConfigurationException; import li.strolch.runtime.privilege.PrivilegeHandler; import li.strolch.runtime.privilege.PrivilegedRunnable; import li.strolch.runtime.privilege.PrivilegedRunnableWithResult; +import li.strolch.utils.collections.MapOfLists; import li.strolch.utils.dbc.DBC; import li.strolch.utils.helper.SystemHelper; import org.slf4j.Logger; @@ -51,7 +52,7 @@ public class ComponentContainerImpl implements ComponentContainer { private static final Logger logger = LoggerFactory.getLogger(ComponentContainerImpl.class); private final StrolchAgent agent; - private Map, StrolchComponent> componentsByType; + private MapOfLists, StrolchComponent> componentsByType; private Map componentsByName; private Map controllerMap; private ComponentDependencyAnalyzer dependencyAnalyzer; @@ -87,26 +88,33 @@ public class ComponentContainerImpl implements ComponentContainer { @Override public boolean hasComponent(Class clazz) { - return this.componentsByType != null && this.componentsByType.containsKey(clazz); + return this.componentsByType != null && this.componentsByType.containsList(clazz); } @Override @SuppressWarnings("unchecked") public T getComponent(Class clazz) throws IllegalArgumentException { - T component = (T) this.componentsByType.get(clazz); - if (component == null) { - String msg = "The component does not exist for class {0}"; + List components = this.componentsByType.getList(clazz); + if (components == null || components.isEmpty()) { + String msg = "No component exists for class {0}"; msg = MessageFormat.format(msg, clazz.getName()); throw new IllegalArgumentException(msg); } - return component; + if (components.size() > 1) { + String msg + = "Component clazz {0} is ambiguous as there are {1} components registered with this type! Get the component by name."; + msg = MessageFormat.format(msg, clazz.getName()); + throw new IllegalArgumentException(msg); + } + + return (T) components.get(0); } @Override public T getComponentByName(String name) throws IllegalArgumentException { @SuppressWarnings("unchecked") T component = (T) this.componentsByName.get(name); if (component == null) { - String msg = "The component {0} does not exist!"; + String msg = "The component with name {0} does not exist!"; msg = MessageFormat.format(msg, name); throw new IllegalArgumentException(msg); } @@ -187,7 +195,7 @@ public class ComponentContainerImpl implements ComponentContainer { return getPrivilegeHandler().runAsAgentWithResult(runnable); } - private StrolchComponent setupComponent(Map, StrolchComponent> componentMap, + private StrolchComponent setupComponent(MapOfLists, StrolchComponent> componentMap, Map controllerMap, ComponentConfiguration componentConfiguration) { String componentName = componentConfiguration.getName(); @@ -227,11 +235,7 @@ public class ComponentContainerImpl implements ComponentContainer { StrolchComponent strolchComponent = constructor.newInstance(this, componentName); strolchComponent.setup(componentConfiguration); - StrolchComponent existing = componentMap.put(apiClass, strolchComponent); - if (existing != null) - throw new IllegalStateException( - "Overwrote component " + existing.getName() + " with " + strolchComponent.getName() + - " as they share the same API Class!"); + componentMap.addElement(apiClass, strolchComponent); controllerMap.put(componentName, new ComponentController(strolchComponent)); return strolchComponent; @@ -268,7 +272,7 @@ public class ComponentContainerImpl implements ComponentContainer { System.getProperty("user.timezone"))); // set up the container itself - Map, StrolchComponent> componentMap = new HashMap<>(); + MapOfLists, StrolchComponent> componentMap = new MapOfLists<>(); Map componentsByName = new HashMap<>(); Map controllerMap = new HashMap<>(); Set componentNames = strolchConfiguration.getComponentNames();