1 package de.fhdw.wtf.common.task;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Iterator;
6 import java.util.concurrent.Callable;
7
8 import de.fhdw.wtf.common.exception.walker.CyclicDependencyException;
9 import de.fhdw.wtf.common.exception.walker.DependencyException;
10 import de.fhdw.wtf.common.task.result.ExceptionalTaskResult;
11 import de.fhdw.wtf.common.task.result.OKTaskResult;
12 import de.fhdw.wtf.common.task.result.TaskResult;
13 import de.fhdw.wtf.common.task.result.visitor.TaskResultVisitor;
14
15
16
17
18
19
20
21
22 public abstract class DependencyTask implements Task, Callable<TaskResult> {
23
24
25
26
27 private final DependencyList dependencies;
28
29
30
31
32 private final Collection<DependencyTask> observers;
33
34
35
36
37 private final TaskExecutor taskmanager;
38
39
40
41
42
43
44
45
46
47 public DependencyTask(final TaskExecutor taskmanager) {
48 this.dependencies = DependencyList.create(this);
49 this.observers = new ArrayList<>();
50 this.taskmanager = taskmanager;
51 taskmanager.introduce(this);
52 }
53
54 @Override
55 public String toString() {
56 return this.getClass().getSimpleName();
57 }
58
59 @Override
60 public final void start() {
61 System.out.println("[submitted] " + this);
62 this.taskmanager.submit(this);
63 }
64
65
66
67
68
69
70
71
72
73 public void addDependency(final DependencyTask a) throws CyclicDependencyException {
74
75 if (this.contains(a)) {
76 throw CyclicDependencyException.create(a.toString());
77 } else {
78 this.getDependencies().addDependency(a);
79 a.register(this);
80 }
81
82 }
83
84
85
86
87
88
89
90 private void register(final DependencyTask a) {
91 this.observers.add(a);
92 }
93
94
95
96
97 synchronized void notifyObservers() {
98 final Iterator<DependencyTask> i = this.observers.iterator();
99 while (i.hasNext()) {
100 final DependencyTask current = i.next();
101 current.updateFinished(this);
102 }
103 }
104
105
106
107
108
109
110
111
112 private synchronized void updateFinished(final DependencyTask task) {
113 final boolean removed = this.getDependencies().remove(task);
114 if (!removed) {
115 throw new DependencyException(this.toString() + ": Task <" + task.toString()
116 + "> is not registered as dependency or already removed!!");
117 }
118 if (this.getDependencies().isEmpty()) {
119 this.start();
120 }
121 }
122
123
124
125
126
127
128
129
130 public boolean contains(final DependencyTask a) {
131 return this.equals(a) || this.containsTransitive(a);
132 }
133
134
135
136
137
138
139
140
141 public abstract boolean containsTransitive(DependencyTask a);
142
143 @Override
144 public final TaskResult call() {
145 System.out.println("[started] " + this);
146 final TaskResult result = this.doWork();
147 System.out.println("[ended] " + this);
148 result.accept(new TaskResultVisitor() {
149 @Override
150 public void handleOkTaskResult(final OKTaskResult okTaskResult) {
151 DependencyTask.this.notifyObservers();
152 }
153
154 @Override
155 public void handleExceptionalTaskResult(final ExceptionalTaskResult exceptionalTaskResult) {
156
157 }
158 });
159
160 return result;
161 }
162
163
164
165
166
167
168 public abstract TaskResult doWork();
169
170
171
172
173
174
175 protected DependencyList getDependencies() {
176 return this.dependencies;
177 }
178 }