private Set<Dependency<?>> dependants = new HashSet<>();
- Component(I instance, Runnable init, Runnable close, Set<Dependency<?>> dependencies,
- Set<Class<? super I>> classes) {
+ Component(Consumer<Component<?>> register, I instance, Runnable init, Runnable close,
+ Set<Dependency<?>> dependencies, Set<Class<? super I>> classes) {
assert instance != null;
assert init != null;
assert close != null;
// types
Map<Class<? super I>, PublishedType<? super I>> types = new HashMap<>(classes.size());
for (Class<? super I> 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);
// TODO check whether context is active, so that we start right away
prepareNextActivation();
- StaticRegister.registerComponent(this);
+ register.accept(this);
}
private void prepareNextActivation() {
CompletableFuture<Void> dependenciesActivated(Void v) {
Set<CompletableFuture<?>> constraints = new HashSet<>(this.dependencies.size());
for (Dependency<?> dependency : this.dependencies) {
- CompletableFuture<Void> dependencyActivated = dependency.getPublisher().activated //
+ CompletableFuture<Void> dependencyActivated = dependency.publisherActivated() //
.thenCompose(dependency::set);
constraints.add(dependencyActivated);
}
CompletableFuture<Void> dependantsDeactivated(Void v) {
Set<CompletableFuture<?>> constraints = new HashSet<>(this.dependants.size());
for (Dependency<?> dependant : this.dependants) {
- CompletableFuture<Void> dependantDeactivated = dependant.getDependantComponent().deactivated //
+ CompletableFuture<Void> dependantDeactivated = dependant.dependantDeactivated() //
.thenCompose(dependant::unset);
constraints.add(dependantDeactivated);
}
return (PublishedType<T>) types.get(clss);
}
+ <T> boolean isPublishedType(Class<T> clss) {
+ return types.containsKey(clss);
+ }
+
public static class PublishedType<T> {
private Component<? extends T> component;
private Class<T> clss;
+// private CompletableFuture<Component<? extends T>> publisherAvailable;
private CompletableFuture<T> value;
public PublishedType(Component<? extends T> component, Class<T> clss) {
this.clss = clss;
this.component = component;
value = CompletableFuture.completedFuture((T) component.instance);
+// value = publisherAvailable.thenApply((c) -> c.getInstance());
}
Component<?> getPublisher() {
return component;
}
+// CompletableFuture<Component<? extends T>> publisherAvailable() {
+// return publisherAvailable;
+// }
+
Class<T> getType() {
return clss;
}
this.instance = instance;
}
- public Component<I> build() {
+ public Component<I> build(Consumer<Component<?>> register) {
// default values
if (types.isEmpty()) {
types.add(getInstanceClass());
};
// instantiation
- Component<I> component = new Component<I>(instance, init, close, dependencies, types);
+ Component<I> component = new Component<I>(register, instance, init, close, dependencies, types);
for (Dependency<?> dependency : dependencies) {
dependency.type.getPublisher().addDependant(dependency);
}
this.dependantComponent = component;
}
- Component<?> getPublisher() {
- return type.getPublisher();
+ CompletableFuture<Void> publisherActivated() {
+ return type.getPublisher().activated.copy();
}
- Component<?> getDependantComponent() {
- return dependantComponent;
+ CompletableFuture<Void> dependantDeactivated() {
+ return dependantComponent.deactivated.copy();
}
CompletableFuture<Void> set(Void v) {
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<Object, Component<?>> components = new IdentityHashMap<>();
+ public static Consumer<Component<?>> asConsumer() {
+ return (c) -> registerComponent(c);
+ }
+
+// public static BiFunction<Class<?>, Predicate<Map<String, Object>>, Component<?>> asProvider() {
+//
+// }
+
+ static synchronized <T> Component<? extends T> find(Class<T> clss, Predicate<Map<String, Object>> filter) {
+ Set<Component<? extends T>> result = new HashSet<>();
+ instances: for (Object instance : components.keySet()) {
+ if (!clss.isAssignableFrom(instance.getClass()))
+ continue instances;
+ Component<? extends T> component = (Component<? extends T>) 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");
}
}
+ synchronized static void clear() {
+ components.clear();
+ }
+
}