1 package cz.cuni.amis.pogamut.base.utils.future;
2
3 import java.util.concurrent.CountDownLatch;
4 import java.util.concurrent.TimeUnit;
5
6 import cz.cuni.amis.pogamut.base.component.IComponent;
7 import cz.cuni.amis.pogamut.base.component.bus.IComponentBus;
8 import cz.cuni.amis.pogamut.base.component.bus.event.BusAwareCountDownLatch;
9 import cz.cuni.amis.pogamut.base.component.bus.exception.ComponentNotRunningException;
10 import cz.cuni.amis.utils.future.FutureWithListeners;
11
12
13
14
15
16
17
18
19
20
21 public class ComponentFuture<RESULT> extends FutureWithListeners<RESULT> {
22
23 private IComponent[] dependants;
24 private IComponentBus bus;
25
26
27
28
29
30
31
32 public ComponentFuture(IComponentBus bus, IComponent... dependants) {
33 this.bus = bus;
34 this.dependants = dependants;
35 }
36
37 @Override
38 protected CountDownLatch createLatch() {
39 if (bus != null && dependants != null && dependants.length > 0) {
40 return new BusAwareCountDownLatch(1, bus, dependants);
41 } else {
42 return new CountDownLatch(1);
43 }
44 }
45
46
47
48
49
50
51
52
53
54
55
56 @Override
57 public RESULT get() throws ComponentFutureException {
58 super.get();
59 synchronized(mutex) {
60 switch (getStatus()) {
61 case FUTURE_IS_READY: return super.get();
62 case CANCELED: throw new ComponentFutureException("The computation has been canceled.", this);
63 case COMPUTATION_EXCEPTION: throw new ComponentFutureException("Computation exception.", getException());
64 case FUTURE_IS_BEING_COMPUTED:
65 computationException(new ComponentNotRunningException("One of the component dealing with the future computation has stopped.", this));
66 throw new ComponentFutureException("One of the component has stopped, future can't be computer.", getException());
67 }
68 }
69 return null;
70 }
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 @Override
86 public RESULT get(long timeout, TimeUnit unit) throws ComponentFutureException {
87 super.get(timeout, unit);
88 synchronized(mutex) {
89 switch (getStatus()) {
90 case FUTURE_IS_READY: return super.get();
91 case CANCELED: throw new ComponentFutureException("The computation has been canceled.", this);
92 case COMPUTATION_EXCEPTION: throw new ComponentFutureException("Computation exception.", getException());
93 case FUTURE_IS_BEING_COMPUTED:
94 if (latch.getCount() == 0) {
95
96 computationException(new ComponentNotRunningException("One of the component dealing with the future computation has stopped.", this));
97 throw new ComponentFutureException("One of the component has stopped, future can't be computer.", getException());
98 }
99 }
100 }
101 return null;
102 }
103
104 }