]>
git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.api.register/src/org/argeo/api/register/SimpleRegister.java
1 package org
.argeo
.api
.register
;
3 import java
.util
.HashSet
;
4 import java
.util
.IdentityHashMap
;
7 import java
.util
.SortedSet
;
8 import java
.util
.TreeSet
;
9 import java
.util
.concurrent
.CompletableFuture
;
10 import java
.util
.concurrent
.ExecutionException
;
11 import java
.util
.concurrent
.atomic
.AtomicBoolean
;
12 import java
.util
.concurrent
.atomic
.AtomicLong
;
13 import java
.util
.function
.Predicate
;
15 /** A minimal component register. */
16 public class SimpleRegister
implements ComponentRegister
{
17 private final AtomicBoolean started
= new AtomicBoolean(false);
18 private final IdentityHashMap
<Object
, Component
<?
>> components
= new IdentityHashMap
<>();
19 private final AtomicLong nextServiceId
= new AtomicLong(0l);
22 public long register(Component
<?
> component
) {
23 return registerComponent(component
);
26 @SuppressWarnings({ "unchecked" })
28 public synchronized <T
> SortedSet
<Component
<?
extends T
>> find(Class
<T
> clss
,
29 Predicate
<Map
<String
, Object
>> filter
) {
30 SortedSet
<Component
<?
extends T
>> result
= new TreeSet
<>();
31 instances
: for (Object instance
: components
.keySet()) {
32 if (!clss
.isAssignableFrom(instance
.getClass()))
34 Component
<?
extends T
> component
= (Component
<?
extends T
>) components
.get(instance
);
36 if (component
.isPublishedType(clss
)) {
38 filter
.test(component
.getProperties());
40 result
.add(component
);
49 synchronized long registerComponent(Component
<?
> component
) {
50 if (started
.get()) // TODO make it really dynamic
51 throw new IllegalStateException("Already activated");
52 if (components
.containsKey(component
.get()))
53 throw new IllegalArgumentException("Already registered as component");
54 components
.put(component
.get(), component
);
55 return nextServiceId
.incrementAndGet();
59 public synchronized Component
<?
> get(Object instance
) {
60 if (!components
.containsKey(instance
))
61 throw new IllegalArgumentException("Not registered as component");
62 return components
.get(instance
);
66 public synchronized void activate() {
68 throw new IllegalStateException("Already activated");
69 Set
<CompletableFuture
<?
>> constraints
= new HashSet
<>();
70 for (Component
<?
> component
: components
.values()) {
71 component
.startActivating();
72 constraints
.add(component
.getActivated());
77 CompletableFuture
.allOf(constraints
.toArray(new CompletableFuture
[0])).thenRun(() -> started
.set(true))
79 } catch (InterruptedException e
) {
80 throw new RuntimeException("Register activation has been interrupted", e
);
81 } catch (ExecutionException e
) {
82 if (RuntimeException
.class.isAssignableFrom(e
.getCause().getClass())) {
83 throw (RuntimeException
) e
.getCause();
85 throw new IllegalStateException("Cannot activate register", e
.getCause());
91 public synchronized void deactivate() {
93 throw new IllegalStateException("Not activated");
94 Set
<CompletableFuture
<?
>> constraints
= new HashSet
<>();
95 for (Component
<?
> component
: components
.values()) {
96 component
.startDeactivating();
97 constraints
.add(component
.getDeactivated());
102 CompletableFuture
.allOf(constraints
.toArray(new CompletableFuture
[0])).thenRun(() -> started
.set(false))
104 } catch (InterruptedException e
) {
105 throw new RuntimeException("Register deactivation has been interrupted", e
);
106 } catch (ExecutionException e
) {
107 if (RuntimeException
.class.isAssignableFrom(e
.getCause().getClass())) {
108 throw (RuntimeException
) e
.getCause();
110 throw new IllegalStateException("Cannot deactivate register", e
.getCause());
116 public synchronized boolean isActive() {
117 return started
.get();
121 public synchronized void clear() {