From 8207e8f4aa9461c8b508a36b9418b6239a348189 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Tue, 4 Jan 2022 07:42:06 +0100 Subject: [PATCH] Start making the component system more dynamic --- .../org/argeo/util/register/Component.java | 38 ++++++++++++------- .../argeo/util/register/StaticRegister.java | 32 ++++++++++++++++ 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/org.argeo.enterprise/src/org/argeo/util/register/Component.java b/org.argeo.enterprise/src/org/argeo/util/register/Component.java index dccb77d38..4a812f83b 100644 --- a/org.argeo.enterprise/src/org/argeo/util/register/Component.java +++ b/org.argeo.enterprise/src/org/argeo/util/register/Component.java @@ -29,8 +29,8 @@ public class Component { private Set> dependants = new HashSet<>(); - Component(I instance, Runnable init, Runnable close, Set> dependencies, - Set> classes) { + Component(Consumer> register, I instance, Runnable init, Runnable close, + Set> dependencies, Set> classes) { assert instance != null; assert init != null; assert close != null; @@ -44,9 +44,9 @@ public class Component { // types Map, PublishedType> types = new HashMap<>(classes.size()); for (Class clss : classes) { - if (!clss.isAssignableFrom(instance.getClass())) - throw new IllegalArgumentException( - "Type " + clss.getName() + " is not compatible with " + instance.getClass().getName()); +// if (!clss.isAssignableFrom(instance.getClass())) +// throw new IllegalArgumentException( +// "Type " + clss.getName() + " is not compatible with " + instance.getClass().getName()); types.put(clss, new PublishedType<>(this, clss)); } this.types = Collections.unmodifiableMap(types); @@ -64,7 +64,7 @@ public class Component { // TODO check whether context is active, so that we start right away prepareNextActivation(); - StaticRegister.registerComponent(this); + register.accept(this); } private void prepareNextActivation() { @@ -106,7 +106,7 @@ public class Component { CompletableFuture dependenciesActivated(Void v) { Set> constraints = new HashSet<>(this.dependencies.size()); for (Dependency dependency : this.dependencies) { - CompletableFuture dependencyActivated = dependency.getPublisher().activated // + CompletableFuture dependencyActivated = dependency.publisherActivated() // .thenCompose(dependency::set); constraints.add(dependencyActivated); } @@ -116,7 +116,7 @@ public class Component { CompletableFuture dependantsDeactivated(Void v) { Set> constraints = new HashSet<>(this.dependants.size()); for (Dependency dependant : this.dependants) { - CompletableFuture dependantDeactivated = dependant.getDependantComponent().deactivated // + CompletableFuture dependantDeactivated = dependant.dependantDeactivated() // .thenCompose(dependant::unset); constraints.add(dependantDeactivated); } @@ -141,22 +141,32 @@ public class Component { return (PublishedType) types.get(clss); } + boolean isPublishedType(Class clss) { + return types.containsKey(clss); + } + public static class PublishedType { private Component component; private Class clss; +// private CompletableFuture> publisherAvailable; private CompletableFuture value; public PublishedType(Component component, Class clss) { this.clss = clss; this.component = component; value = CompletableFuture.completedFuture((T) component.instance); +// value = publisherAvailable.thenApply((c) -> c.getInstance()); } Component getPublisher() { return component; } +// CompletableFuture> publisherAvailable() { +// return publisherAvailable; +// } + Class getType() { return clss; } @@ -175,7 +185,7 @@ public class Component { this.instance = instance; } - public Component build() { + public Component build(Consumer> register) { // default values if (types.isEmpty()) { types.add(getInstanceClass()); @@ -189,7 +199,7 @@ public class Component { }; // instantiation - Component component = new Component(instance, init, close, dependencies, types); + Component component = new Component(register, instance, init, close, dependencies, types); for (Dependency dependency : dependencies) { dependency.type.getPublisher().addDependant(dependency); } @@ -253,12 +263,12 @@ public class Component { this.dependantComponent = component; } - Component getPublisher() { - return type.getPublisher(); + CompletableFuture publisherActivated() { + return type.getPublisher().activated.copy(); } - Component getDependantComponent() { - return dependantComponent; + CompletableFuture dependantDeactivated() { + return dependantComponent.deactivated.copy(); } CompletableFuture set(Void v) { diff --git a/org.argeo.enterprise/src/org/argeo/util/register/StaticRegister.java b/org.argeo.enterprise/src/org/argeo/util/register/StaticRegister.java index 0c55bddb2..c186aff08 100644 --- a/org.argeo.enterprise/src/org/argeo/util/register/StaticRegister.java +++ b/org.argeo.enterprise/src/org/argeo/util/register/StaticRegister.java @@ -2,16 +2,44 @@ package org.argeo.util.register; import java.util.HashSet; import java.util.IdentityHashMap; +import java.util.Map; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import java.util.function.Predicate; /** A minimal component register. */ public class StaticRegister { private final static AtomicBoolean started = new AtomicBoolean(false); private final static IdentityHashMap> components = new IdentityHashMap<>(); + public static Consumer> asConsumer() { + return (c) -> registerComponent(c); + } + +// public static BiFunction, Predicate>, Component> asProvider() { +// +// } + + static synchronized Component find(Class clss, Predicate> filter) { + Set> result = new HashSet<>(); + instances: for (Object instance : components.keySet()) { + if (!clss.isAssignableFrom(instance.getClass())) + continue instances; + Component component = (Component) components.get(instance); + + // TODO filter + if (component.isPublishedType(clss)) + result.add(component); + } + if (result.isEmpty()) + return null; + return result.iterator().next(); + + } + static synchronized void registerComponent(Component component) { if (started.get()) // TODO make it really dynamic throw new IllegalStateException("Already activated"); @@ -62,4 +90,8 @@ public class StaticRegister { } } + synchronized static void clear() { + components.clear(); + } + } -- 2.30.2