Ranides Atterwim пре 1 година
родитељ
комит
09f5301b8e

+ 51 - 0
assira.commons/src/main/java/net/ranides/assira/collection/maps/TypeMap.java

@@ -0,0 +1,51 @@
+package net.ranides.assira.collection.maps;
+
+import net.ranides.assira.collection.CollectionUtils;
+import net.ranides.assira.collection.query.CQuery;
+import net.ranides.assira.reflection.IClass;
+import net.ranides.assira.reflection.IClasses;
+import net.ranides.assira.reflection.IHints;
+import net.ranides.assira.reflection.impl.FElements;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+public class TypeMap<V> {
+
+    private final MultiMap<IClass<?>, V> content = new OpenMultiMap<>();
+
+    public V match(IClass<?> type) {
+        if(content.containsKey(type)) {
+            Collection<V> found = content.getAll(type);
+            if(found.size() > 1) {
+                throw new NoSuchElementException("There is ambiguous match for type: " + type);
+            }
+            return CollectionUtils.first(found).get();
+        }
+        throw new NoSuchElementException("There is no match for type: " + type);
+    }
+
+    public Collection<V> matchAll(IClass<?> type) {
+        return content.getAll(type);
+    }
+
+    public boolean matches(IClass<?>  key) {
+        return content.containsKey(key);
+    }
+
+    public void add(IClass<?> type, V value) {
+        content.put(type, value);
+        type.parents().forEach(a -> content.put(a, value));
+        type.interfaces().forEach(a -> content.put(a, value));
+    }
+
+    public void addAll(Map<? extends IClass<?>, ? extends V> values) {
+        values.forEach((t,v)-> add(t, v));
+    }
+
+    public IClasses types() {
+        return FElements.newClasses(IHints.none(), CQuery.from(content.uniqueKeySet()));
+    }
+
+}

+ 25 - 35
assira.commons/src/main/java/net/ranides/assira/system/impl/HostSimpleContext.java

@@ -1,54 +1,45 @@
 package net.ranides.assira.system.impl;
 
-import net.ranides.assira.collection.CollectionUtils;
-import net.ranides.assira.collection.maps.MultiMap;
-import net.ranides.assira.collection.maps.OpenMultiMap;
+import net.ranides.assira.collection.maps.OpenMap;
+import net.ranides.assira.collection.maps.TypeMap;
 import net.ranides.assira.reflection.IClass;
 import net.ranides.assira.system.HostContext;
+import net.ranides.assira.trace.LoggerUtils;
+import org.slf4j.Logger;
 
-import java.util.Collection;
+import java.util.Map;
 import java.util.NoSuchElementException;
 
 public class HostSimpleContext implements HostContext {
 
-    private final MultiMap<IClass<?>, IClass<?>> type2prototype = new OpenMultiMap<>();
+    private static final Logger LOGGER = LoggerUtils.getLogger();
 
-    private final MultiMap<String, IClass<?>> name2prototype = new OpenMultiMap<>();
+    private final TypeMap<IClass<?>> type2prototype = new TypeMap<>();
 
-    private final MultiMap<IClass<?>, Object> type2instance = new OpenMultiMap<>();
+    private final Map<String, IClass<?>> name2prototype = new OpenMap<>();
 
-    private final MultiMap<String, Object> name2instance = new OpenMultiMap<>();
+    private final TypeMap<Object> type2instance = new TypeMap<>();
+
+    private final Map<String, Object> name2instance = new OpenMap<>();
 
     @Override
     public Object getBean(String name) {
         if(name2instance.containsKey(name)) {
-            Collection<Object> found = name2instance.getAll(name);
-            if(found.size() == 1) {
-                return CollectionUtils.first(found).get();
-            }
+            return name2instance.get(name);
         }
         if(name2prototype.containsKey(name)) {
-            Collection<IClass<?>> found = name2prototype.getAll(name);
-            if(found.size() == 1) {
-                return CollectionUtils.first(found).get().construct();
-            }
+            return name2prototype.get(name).construct();
         }
         throw new NoSuchElementException("No bean with name: " + name);
     }
 
     @Override
     public <T> T getBean(IClass<T> type) {
-        if(type2instance.containsKey(type)) {
-            Collection<Object> found = type2instance.getAll(type);
-            if(found.size() == 1) {
-                return type.cast(CollectionUtils.first(found).get());
-            }
+        if(type2instance.matches(type)) {
+            return type.cast(type2instance.match(type));
         }
-        if(type2prototype.containsKey(type)) {
-            Collection<IClass<?>> found = type2prototype.getAll(type);
-            if(found.size() == 1) {
-                return type.cast(CollectionUtils.first(found).get().construct());
-            }
+        if(type2prototype.matches(type)) {
+            return type.cast(type2prototype.match(type).construct());
         }
         throw new NoSuchElementException("No bean with type: " + type);
     }
@@ -65,22 +56,21 @@ public class HostSimpleContext implements HostContext {
 
     @Override
     public void registerPrototype(String name, IClass<?> type) {
-        type2prototype.put(type, type);
-        type.parents().forEach(a -> type2prototype.put(a, type));
-        type.interfaces().forEach(a -> type2prototype.put(a, type));
+        type2prototype.add(type, type);
         if(name != null) {
-            name2prototype.put(name, type);
+            if(name2prototype.put(name, type) != null) {
+                LOGGER.warn("Bean conflict for name: " + name);
+            }
         }
     }
 
     @Override
     public void registerSingleton(String name, Object instance) {
-        IClass<Object> type = IClass.typefor(instance);
-        type2instance.put(type, instance);
-        type.parents().forEach(a -> type2instance.put(a, instance));
-        type.interfaces().forEach(a -> type2instance.put(a, instance));
+        type2instance.add(IClass.typefor(instance), instance);
         if(name != null) {
-            name2instance.put(name, instance);
+            if(name2instance.put(name, instance) != null) {
+                LOGGER.warn("Bean conflict for name: " + name);
+            }
         }
     }
 }

+ 3 - 3
assira.commons/src/test/java/net/ranides/assira/system/impl/HostSimpleContextTest.java

@@ -54,9 +54,9 @@ public class HostSimpleContextTest {
         assertNotNull(ctx.getBean("font"));
         assertNotNull(ctx.getBean("event"));
 
-        assertThrows(NoSuchElementException.class, () -> {
-            ctx.getBean("list");
-        });
+//        assertThrows(NoSuchElementException.class, () -> {
+//            ctx.getBean("list");
+//        });
         assertThrows(NoSuchElementException.class, () -> {
             ctx.getBean("invalid");
         });