]>
git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.util/src/org/argeo/util/register/StaticRegister.java
1 package org
.argeo
.util
.register
;
3 import java
.util
.HashSet
;
4 import java
.util
.IdentityHashMap
;
7 import java
.util
.concurrent
.CompletableFuture
;
8 import java
.util
.concurrent
.ExecutionException
;
9 import java
.util
.concurrent
.atomic
.AtomicBoolean
;
10 import java
.util
.function
.Predicate
;
12 /** A minimal component register. */
13 public class StaticRegister
implements ComponentRegister
{
14 private final static StaticRegister instance
= new StaticRegister();
16 public static ComponentRegister
getInstance() {
20 private final AtomicBoolean started
= new AtomicBoolean(false);
21 private final IdentityHashMap
<Object
, Component
<?
>> components
= new IdentityHashMap
<>();
24 public void accept(Component
<?
> component
) {
25 registerComponent(component
);
28 @SuppressWarnings({ "unchecked" })
30 public synchronized <T
> Component
<?
extends T
> find(Class
<T
> clss
, Predicate
<Map
<String
, Object
>> filter
) {
31 Set
<Component
<?
extends T
>> result
= new HashSet
<>();
32 instances
: for (Object instance
: components
.keySet()) {
33 if (!clss
.isAssignableFrom(instance
.getClass()))
35 Component
<?
extends T
> component
= (Component
<?
extends T
>) components
.get(instance
);
38 if (component
.isPublishedType(clss
))
39 result
.add(component
);
43 return result
.iterator().next();
47 synchronized void registerComponent(Component
<?
> component
) {
48 if (started
.get()) // TODO make it really dynamic
49 throw new IllegalStateException("Already activated");
50 if (components
.containsKey(component
.getInstance()))
51 throw new IllegalArgumentException("Already registered as component");
52 components
.put(component
.getInstance(), component
);
56 public synchronized Component
<?
> get(Object instance
) {
57 if (!components
.containsKey(instance
))
58 throw new IllegalArgumentException("Not registered as component");
59 return components
.get(instance
);
63 public synchronized void activate() {
65 throw new IllegalStateException("Already activated");
66 Set
<CompletableFuture
<?
>> constraints
= new HashSet
<>();
67 for (Component
<?
> component
: components
.values()) {
68 component
.startActivating();
69 constraints
.add(component
.getActivated());
74 CompletableFuture
.allOf(constraints
.toArray(new CompletableFuture
[0])).thenRun(() -> started
.set(true))
76 } catch (InterruptedException e
) {
77 throw new RuntimeException("Register activation has been interrupted", e
);
78 } catch (ExecutionException e
) {
79 if (RuntimeException
.class.isAssignableFrom(e
.getCause().getClass())) {
80 throw (RuntimeException
) e
.getCause();
82 throw new IllegalStateException("Cannot activate register", e
.getCause());
88 public synchronized void deactivate() {
90 throw new IllegalStateException("Not activated");
91 Set
<CompletableFuture
<?
>> constraints
= new HashSet
<>();
92 for (Component
<?
> component
: components
.values()) {
93 component
.startDeactivating();
94 constraints
.add(component
.getDeactivated());
99 CompletableFuture
.allOf(constraints
.toArray(new CompletableFuture
[0])).thenRun(() -> started
.set(false))
101 } catch (InterruptedException e
) {
102 throw new RuntimeException("Register deactivation has been interrupted", e
);
103 } catch (ExecutionException e
) {
104 if (RuntimeException
.class.isAssignableFrom(e
.getCause().getClass())) {
105 throw (RuntimeException
) e
.getCause();
107 throw new IllegalStateException("Cannot deactivate register", e
.getCause());
113 public synchronized boolean isActive() {
114 return started
.get();
118 public synchronized void clear() {