]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.util/src/org/argeo/util/register/StaticRegister.java
Use latest release of Argeo Maven parent
[lgpl/argeo-commons.git] / org.argeo.util / src / org / argeo / util / register / StaticRegister.java
1 package org.argeo.util.register;
2
3 import java.util.HashSet;
4 import java.util.IdentityHashMap;
5 import java.util.Map;
6 import java.util.Set;
7 import java.util.concurrent.CompletableFuture;
8 import java.util.concurrent.ExecutionException;
9 import java.util.concurrent.atomic.AtomicBoolean;
10 import java.util.function.Consumer;
11 import java.util.function.Predicate;
12
13 /** A minimal component register. */
14 public class StaticRegister {
15 private final static AtomicBoolean started = new AtomicBoolean(false);
16 private final static IdentityHashMap<Object, Component<?>> components = new IdentityHashMap<>();
17
18 public static Consumer<Component<?>> asConsumer() {
19 return (c) -> registerComponent(c);
20 }
21
22 // public static BiFunction<Class<?>, Predicate<Map<String, Object>>, Component<?>> asProvider() {
23 //
24 // }
25
26 static synchronized <T> Component<? extends T> find(Class<T> clss, Predicate<Map<String, Object>> filter) {
27 Set<Component<? extends T>> result = new HashSet<>();
28 instances: for (Object instance : components.keySet()) {
29 if (!clss.isAssignableFrom(instance.getClass()))
30 continue instances;
31 Component<? extends T> component = (Component<? extends T>) components.get(instance);
32
33 // TODO filter
34 if (component.isPublishedType(clss))
35 result.add(component);
36 }
37 if (result.isEmpty())
38 return null;
39 return result.iterator().next();
40
41 }
42
43 static synchronized void registerComponent(Component<?> component) {
44 if (started.get()) // TODO make it really dynamic
45 throw new IllegalStateException("Already activated");
46 if (components.containsKey(component.getInstance()))
47 throw new IllegalArgumentException("Already registered as component");
48 components.put(component.getInstance(), component);
49 }
50
51 static synchronized Component<?> get(Object instance) {
52 if (!components.containsKey(instance))
53 throw new IllegalArgumentException("Not registered as component");
54 return components.get(instance);
55 }
56
57 synchronized static void activate() {
58 if (started.get())
59 throw new IllegalStateException("Already activated");
60 Set<CompletableFuture<?>> constraints = new HashSet<>();
61 for (Component<?> component : components.values()) {
62 component.startActivating();
63 constraints.add(component.getActivated());
64 }
65
66 // wait
67 try {
68 CompletableFuture.allOf(constraints.toArray(new CompletableFuture[0])).thenRun(() -> started.set(true))
69 .get();
70 } catch (ExecutionException | InterruptedException e) {
71 throw new RuntimeException(e);
72 }
73 }
74
75 synchronized static void deactivate() {
76 if (!started.get())
77 throw new IllegalStateException("Not activated");
78 Set<CompletableFuture<?>> constraints = new HashSet<>();
79 for (Component<?> component : components.values()) {
80 component.startDeactivating();
81 constraints.add(component.getDeactivated());
82 }
83
84 // wait
85 try {
86 CompletableFuture.allOf(constraints.toArray(new CompletableFuture[0])).thenRun(() -> started.set(false))
87 .get();
88 } catch (ExecutionException | InterruptedException e) {
89 throw new RuntimeException(e);
90 }
91 }
92
93 synchronized static void clear() {
94 components.clear();
95 }
96
97 }