OSDN Git Service

進捗報告実装
[coroid/inqubus.git] / frontend / src / yukihane / inqubus / manager / TaskManage.java
1 package yukihane.inqubus.manager;
2
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.concurrent.ExecutorService;
6 import java.util.concurrent.Executors;
7 import java.util.concurrent.Future;
8 import java.util.logging.Level;
9 import java.util.logging.Logger;
10 import saccubus.worker.WorkerListener;
11 import saccubus.worker.impl.MessageReportable;
12 import saccubus.worker.impl.PercentageReportable;
13 import saccubus.worker.impl.convert.Convert;
14 import saccubus.worker.impl.convert.ConvertProgress;
15 import saccubus.worker.impl.convert.ConvertResult;
16 import saccubus.worker.impl.download.Download;
17 import saccubus.worker.impl.download.DownloadProgress;
18 import saccubus.worker.impl.download.DownloadResult;
19 import saccubus.worker.profile.ConvertProfile;
20 import saccubus.worker.profile.DownloadProfile;
21
22 /**
23  *
24  * @author yuki
25  */
26 public class TaskManage {
27
28     private static final Logger logger = Logger.getLogger(TaskManage.class.getName());
29     private final ExecutorService downloadExecutorService;
30     private final ExecutorService convertExecutorService;
31     private final Map<Integer, ManageTarget<DownloadResult>> downloadTargets = new HashMap<>();
32     private final Map<Integer, ManageTarget<ConvertResult>> convertTargets = new HashMap<>();
33     private final TaskManageListener clientListener;
34
35     public TaskManage() {
36         this(1, 1, null);
37     }
38
39     public TaskManage(int maxDownload, int maxConvert) {
40         this(maxDownload, maxConvert, null);
41     }
42
43     public TaskManage(int maxDownload, int maxConvert, TaskManageListener listener) {
44         downloadExecutorService = Executors.newFixedThreadPool(maxDownload);
45         convertExecutorService = Executors.newFixedThreadPool(maxConvert);
46         this.clientListener = listener;
47     }
48
49     public synchronized boolean add(RequestProcess request) {
50         final DownloadProfile dp = request.getDownloadProfile();
51         final ConvertProfile cp = request.getConvertProfile();
52         if (dp != null && (dp.getVideoProfile().isDownload() || dp.getCommentProfile().isDownload())) {
53             // ダウンロードするものがあればまずダウンロード処理
54             final Download task = new Download(dp, request.getVideoId(),
55                     new DownloadListener(request.getRowId()));
56             final Future<DownloadResult> future = downloadExecutorService.submit(task);
57             downloadTargets.put(request.getRowId(), new ManageTarget<>(request, future));
58             return true;
59
60         } else if (cp != null && cp.isConvert()) {
61             final Convert task = new Convert(cp, dp.getVideoProfile().getLocalFile(), dp.getCommentProfile().
62                     getLocalFile(), new ConvertListener(request.getRowId()));
63             final Future<ConvertResult> future = convertExecutorService.submit(task);
64             convertTargets.put(request.getRowId(), new ManageTarget<>(request, future));
65             return true;
66         }
67         return false;
68     }
69
70     private class DownloadListener extends TaskManageInnerListener<DownloadResult, DownloadProgress> {
71
72         private DownloadListener(int rowId) {
73             super(rowId);
74         }
75
76         @Override
77         public void done(DownloadResult result) {
78             super.done(result);
79             // TODO 変換が必要なら変換キューに入れる
80         }
81
82         @Override
83         protected TaskKind getKind() {
84             return TaskKind.DOWNLOAD;
85         }
86     }
87
88     private class ConvertListener extends TaskManageInnerListener<ConvertResult, ConvertProgress> {
89
90         private ConvertListener(int rowId) {
91             super(rowId);
92         }
93
94         @Override
95         protected TaskKind getKind() {
96             return TaskKind.CONVERT;
97         }
98     }
99
100     abstract class TaskManageInnerListener<T, V extends PercentageReportable & MessageReportable> implements WorkerListener<T, V> {
101
102         private final int rowId;
103
104         protected TaskManageInnerListener(int rowId) {
105             this.rowId = rowId;
106         }
107
108         private void notify(TaskStatus status) {
109             notify(status, 0.0, "");
110         }
111
112         private void notify(TaskStatus status, double percentage, String message) {
113             if (getListener() == null) {
114                 return;
115             }
116             getListener().process(rowId, getKind(), status, percentage, message);
117         }
118
119         private TaskManageListener getListener() {
120             return clientListener;
121         }
122
123         protected abstract TaskKind getKind();
124
125         @Override
126         public void process(V progress) {
127             logger.log(Level.FINEST, "process: {0}", progress);
128             notify(TaskStatus.DOING, progress.getPercentage(), progress.getMessage());
129         }
130
131         @Override
132         public void cancelled() {
133             logger.log(Level.FINE, "cancelled: {0}", toString());
134             notify(TaskStatus.CANCELLED);
135         }
136
137         @Override
138         public void done(T result) {
139             logger.log(Level.FINE, "done: {0}", result);
140             notify(TaskStatus.DONE);
141         }
142
143         @Override
144         public void error(Throwable th) {
145             logger.log(Level.SEVERE, "error", th);
146             notify(TaskStatus.ERROR, 0.0, th.getMessage());
147         }
148     }
149
150     class ManageTarget<T> {
151
152         private final RequestProcess request;
153         private final Future<T> future;
154
155         ManageTarget(RequestProcess request, Future<T> future) {
156             this.request = request;
157             this.future = future;
158         }
159
160         Future<T> getFuture() {
161             return future;
162         }
163
164         RequestProcess getRequest() {
165             return request;
166         }
167     }
168 }