X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.util%2Fsrc%2Forg%2Fargeo%2Futil%2Fregister%2FComponent.java;h=275811e9db66510cbb77cdf4be350ec33115d70c;hb=3c1cdc594d954520b14646102b366290bdad58c7;hp=66ac2ada9233b9d9b121eb24b6d29648ef3e4869;hpb=7974745f1de448353bf47012b5df36b451dce2fa;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.util/src/org/argeo/util/register/Component.java b/org.argeo.util/src/org/argeo/util/register/Component.java index 66ac2ada9..275811e9d 100644 --- a/org.argeo.util/src/org/argeo/util/register/Component.java +++ b/org.argeo.util/src/org/argeo/util/register/Component.java @@ -1,17 +1,21 @@ 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 { +public class Component implements Supplier, Comparable> { private final I instance; @@ -20,6 +24,7 @@ public class Component { private final Map, PublishedType> types; private final Set> dependencies; + private final Map properties; private CompletableFuture activationStarted = null; private CompletableFuture activated = null; @@ -27,10 +32,13 @@ public class Component { private CompletableFuture deactivationStarted = null; private CompletableFuture deactivated = null; + // internal private Set> dependants = new HashSet<>(); - Component(Consumer> register, I instance, Runnable init, Runnable close, - Set> dependencies, Set> classes) { + private RankingKey rankingKey; + + Component(ComponentRegister register, I instance, Runnable init, Runnable close, Set> dependencies, + Set> classes, Map properties) { assert instance != null; assert init != null; assert close != null; @@ -64,7 +72,11 @@ public class Component { // TODO check whether context is active, so that we start right away prepareNextActivation(); - register.accept(this); + long serviceId = register.register(this); + Map props = new HashMap<>(properties); + props.put(RankingKey.SERVICE_ID, serviceId); + this.properties = Collections.unmodifiableMap(props); + rankingKey = new RankingKey(properties); } private void prepareNextActivation() { @@ -130,7 +142,8 @@ public class Component { dependants.add(dependant); } - public I getInstance() { + @Override + public I get() { return instance; } @@ -145,6 +158,33 @@ public class Component { return types.containsKey(clss); } + public Map 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 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 { private Component component; @@ -165,10 +205,14 @@ public class Component { public Class getType() { return clss; } + + public CompletionStage getValue() { + return value.minimalCompletionStage(); + } } /** Builds a {@link Component}. */ - public static class Builder { + public static class Builder implements Supplier { private final I instance; private Runnable init; @@ -176,12 +220,13 @@ public class Component { private Set> dependencies = new HashSet<>(); private Set> types = new HashSet<>(); + private final Map properties = new HashMap<>(); public Builder(I instance) { this.instance = instance; } - public Component build(Consumer> register) { + public Component build(ComponentRegister register) { // default values if (types.isEmpty()) { types.add(getInstanceClass()); @@ -195,7 +240,7 @@ public class Component { }; // instantiation - Component component = new Component(register, instance, init, close, dependencies, types); + Component component = new Component(register, instance, init, close, dependencies, types, properties); for (Dependency dependency : dependencies) { dependency.type.getPublisher().addDependant(dependency); } @@ -226,6 +271,13 @@ public class Component { 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; }