Massive package refactoring
[lgpl/argeo-commons.git] / org.argeo.util / src / org / argeo / util / register / Component.java
diff --git a/org.argeo.util/src/org/argeo/util/register/Component.java b/org.argeo.util/src/org/argeo/util/register/Component.java
deleted file mode 100644 (file)
index 275811e..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-package org.argeo.util.register;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CompletionStage;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-/**
- * A wrapper for an object, whose dependencies and life cycle can be managed.
- */
-public class Component<I> implements Supplier<I>, Comparable<Component<?>> {
-
-       private final I instance;
-
-       private final Runnable init;
-       private final Runnable close;
-
-       private final Map<Class<? super I>, PublishedType<? super I>> types;
-       private final Set<Dependency<?>> dependencies;
-       private final Map<String, Object> properties;
-
-       private CompletableFuture<Void> activationStarted = null;
-       private CompletableFuture<Void> activated = null;
-
-       private CompletableFuture<Void> deactivationStarted = null;
-       private CompletableFuture<Void> deactivated = null;
-
-       // internal
-       private Set<Dependency<?>> dependants = new HashSet<>();
-
-       private RankingKey rankingKey;
-
-       Component(ComponentRegister register, I instance, Runnable init, Runnable close, Set<Dependency<?>> dependencies,
-                       Set<Class<? super I>> classes, Map<String, Object> properties) {
-               assert instance != null;
-               assert init != null;
-               assert close != null;
-               assert dependencies != null;
-               assert classes != null;
-
-               this.instance = instance;
-               this.init = init;
-               this.close = close;
-
-               // 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());
-                       types.put(clss, new PublishedType<>(this, clss));
-               }
-               this.types = Collections.unmodifiableMap(types);
-
-               // dependencies
-               this.dependencies = Collections.unmodifiableSet(new HashSet<>(dependencies));
-               for (Dependency<?> dependency : this.dependencies) {
-                       dependency.setDependantComponent(this);
-               }
-
-               // deactivated by default
-               deactivated = CompletableFuture.completedFuture(null);
-               deactivationStarted = CompletableFuture.completedFuture(null);
-
-               // TODO check whether context is active, so that we start right away
-               prepareNextActivation();
-
-               long serviceId = register.register(this);
-               Map<String, Object> props = new HashMap<>(properties);
-               props.put(RankingKey.SERVICE_ID, serviceId);
-               this.properties = Collections.unmodifiableMap(props);
-               rankingKey = new RankingKey(properties);
-       }
-
-       private void prepareNextActivation() {
-               activationStarted = new CompletableFuture<Void>();
-               activated = activationStarted //
-                               .thenComposeAsync(this::dependenciesActivated) //
-                               .thenRun(this.init) //
-                               .thenRun(() -> prepareNextDeactivation());
-       }
-
-       private void prepareNextDeactivation() {
-               deactivationStarted = new CompletableFuture<Void>();
-               deactivated = deactivationStarted //
-                               .thenComposeAsync(this::dependantsDeactivated) //
-                               .thenRun(this.close) //
-                               .thenRun(() -> prepareNextActivation());
-       }
-
-       CompletableFuture<Void> getActivated() {
-               return activated;
-       }
-
-       CompletableFuture<Void> getDeactivated() {
-               return deactivated;
-       }
-
-       void startActivating() {
-               if (activated.isDone() || activationStarted.isDone())
-                       return;
-               activationStarted.complete(null);
-       }
-
-       void startDeactivating() {
-               if (deactivated.isDone() || deactivationStarted.isDone())
-                       return;
-               deactivationStarted.complete(null);
-       }
-
-       CompletableFuture<Void> dependenciesActivated(Void v) {
-               Set<CompletableFuture<?>> constraints = new HashSet<>(this.dependencies.size());
-               for (Dependency<?> dependency : this.dependencies) {
-                       CompletableFuture<Void> dependencyActivated = dependency.publisherActivated() //
-                                       .thenCompose(dependency::set);
-                       constraints.add(dependencyActivated);
-               }
-               return CompletableFuture.allOf(constraints.toArray(new CompletableFuture[constraints.size()]));
-       }
-
-       CompletableFuture<Void> dependantsDeactivated(Void v) {
-               Set<CompletableFuture<?>> constraints = new HashSet<>(this.dependants.size());
-               for (Dependency<?> dependant : this.dependants) {
-                       CompletableFuture<Void> dependantDeactivated = dependant.dependantDeactivated() //
-                                       .thenCompose(dependant::unset);
-                       constraints.add(dependantDeactivated);
-               }
-               CompletableFuture<Void> dependantsDeactivated = CompletableFuture
-                               .allOf(constraints.toArray(new CompletableFuture[constraints.size()]));
-               return dependantsDeactivated;
-
-       }
-
-       void addDependant(Dependency<?> dependant) {
-               dependants.add(dependant);
-       }
-
-       @Override
-       public I get() {
-               return instance;
-       }
-
-       @SuppressWarnings("unchecked")
-       public <T> PublishedType<T> getType(Class<T> clss) {
-               if (!types.containsKey(clss))
-                       throw new IllegalArgumentException(clss.getName() + " is not a type published by this component");
-               return (PublishedType<T>) types.get(clss);
-       }
-
-       public <T> boolean isPublishedType(Class<T> clss) {
-               return types.containsKey(clss);
-       }
-
-       public Map<String, Object> getProperties() {
-               return properties;
-       }
-
-       @Override
-       public int compareTo(Component<?> o) {
-               return rankingKey.compareTo(rankingKey);
-       }
-
-       @Override
-       public int hashCode() {
-               Long serviceId = (Long) properties.get(RankingKey.SERVICE_ID);
-               if (serviceId != null)
-                       return serviceId.intValue();
-               else
-                       return super.hashCode();
-       }
-
-       @Override
-       public String toString() {
-               List<String> classes = new ArrayList<>();
-               for (Class<?> clss : types.keySet()) {
-                       classes.add(clss.getName());
-               }
-               return "Component " + classes + " " + properties + "";
-       }
-
-       /** A type which has been explicitly exposed by a component. */
-       public static class PublishedType<T> {
-               private Component<? extends T> component;
-               private Class<T> clss;
-
-               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);
-               }
-
-               public Component<?> getPublisher() {
-                       return component;
-               }
-
-               public Class<T> getType() {
-                       return clss;
-               }
-
-               public CompletionStage<T> getValue() {
-                       return value.minimalCompletionStage();
-               }
-       }
-
-       /** Builds a {@link Component}. */
-       public static class Builder<I> implements Supplier<I> {
-               private final I instance;
-
-               private Runnable init;
-               private Runnable close;
-
-               private Set<Dependency<?>> dependencies = new HashSet<>();
-               private Set<Class<? super I>> types = new HashSet<>();
-               private final Map<String, Object> properties = new HashMap<>();
-
-               public Builder(I instance) {
-                       this.instance = instance;
-               }
-
-               public Component<I> build(ComponentRegister register) {
-                       // default values
-                       if (types.isEmpty()) {
-                               types.add(getInstanceClass());
-                       }
-
-                       if (init == null)
-                               init = () -> {
-                               };
-                       if (close == null)
-                               close = () -> {
-                               };
-
-                       // instantiation
-                       Component<I> component = new Component<I>(register, instance, init, close, dependencies, types, properties);
-                       for (Dependency<?> dependency : dependencies) {
-                               dependency.type.getPublisher().addDependant(dependency);
-                       }
-                       return component;
-               }
-
-               public Builder<I> addType(Class<? super I> clss) {
-                       types.add(clss);
-                       return this;
-               }
-
-               public Builder<I> addActivation(Runnable init) {
-                       if (this.init != null)
-                               throw new IllegalArgumentException("init method is already set");
-                       this.init = init;
-                       return this;
-               }
-
-               public Builder<I> addDeactivation(Runnable close) {
-                       if (this.close != null)
-                               throw new IllegalArgumentException("close method is already set");
-                       this.close = close;
-                       return this;
-               }
-
-               public <D> Builder<I> addDependency(PublishedType<D> type, Consumer<D> set, Consumer<D> unset) {
-                       dependencies.add(new Dependency<D>(type, set, unset));
-                       return this;
-               }
-
-               public void addProperty(String key, Object value) {
-                       if (properties.containsKey(key))
-                               throw new IllegalStateException("Key " + key + " is already set.");
-                       properties.put(key, value);
-               }
-
-               @Override
-               public I get() {
-                       return instance;
-               }
-
-               @SuppressWarnings("unchecked")
-               private Class<I> getInstanceClass() {
-                       return (Class<I>) instance.getClass();
-               }
-
-       }
-
-       static class Dependency<D> {
-               private PublishedType<D> type;
-               private Consumer<D> set;
-               private Consumer<D> unset;
-
-               // live
-               Component<?> dependantComponent;
-               CompletableFuture<Void> setStage;
-               CompletableFuture<Void> unsetStage;
-
-               public Dependency(PublishedType<D> types, Consumer<D> set, Consumer<D> unset) {
-                       super();
-                       this.type = types;
-                       this.set = set != null ? set : t -> {
-                       };
-                       this.unset = unset != null ? unset : t -> {
-                       };
-               }
-
-               // live
-               void setDependantComponent(Component<?> component) {
-                       this.dependantComponent = component;
-               }
-
-               CompletableFuture<Void> publisherActivated() {
-                       return type.getPublisher().activated.copy();
-               }
-
-               CompletableFuture<Void> dependantDeactivated() {
-                       return dependantComponent.deactivated.copy();
-               }
-
-               CompletableFuture<Void> set(Void v) {
-                       return type.value.thenAccept(set);
-               }
-
-               CompletableFuture<Void> unset(Void v) {
-                       return type.value.thenAccept(unset);
-               }
-
-       }
-}