Merge branch 'release/5.1.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / util / ProgressMonitorClientManager.java
1 /**
2 * Copyright (C) 2015 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.taxeditor.util;
10
11 import java.text.DecimalFormat;
12 import java.util.Arrays;
13 import java.util.List;
14 import java.util.UUID;
15
16 import org.apache.log4j.Logger;
17 import org.eclipse.core.runtime.SubMonitor;
18
19 import eu.etaxonomy.cdm.api.application.CdmApplicationState;
20 import eu.etaxonomy.cdm.api.service.IProgressMonitorService;
21 import eu.etaxonomy.cdm.api.service.UpdateResult;
22 import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
23 import eu.etaxonomy.taxeditor.operation.IFeedbackGenerator;
24 import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
25
26 /**
27 * Manages client side progress monitors
28 *
29 * @author cmathew
30 * @date 23 Oct 2015
31 *
32 */
33
34 public class ProgressMonitorClientManager {
35 private static final Logger logger = Logger.getLogger(ProgressMonitorClientManager.class);
36
37 /**
38 * Polls the progress monitor service for the progress status of a monitor
39 * corresponding to the given uuid.
40 *
41 * @param label for the operation
42 * @param uuid of the remoting monitor already started on the server
43 * @param pollInterval in milliseconds
44 * @param cancelable flag which determines whether the operation can be cancelled
45 * @param postOp callback for running post operation logic
46 * @param feedbackGenerator feedback generator corresponding to the
47 * 'wait on feedback' request made on the remoting monitor
48 * @param monitor to be updated
49 * @return a final progress monitor after the operation is completed
50 * @throws InterruptedException
51 */
52 public IRemotingProgressMonitor pollMonitor(final String label,
53 final UUID uuid,
54 final int pollInterval,
55 final IPostMoniteredOperationEnabled postOp,
56 IFeedbackGenerator feedbackGenerator,
57 SubMonitor monitor) throws InterruptedException {
58 return pollMonitor(label, uuid, pollInterval, postOp, Arrays.asList(feedbackGenerator), monitor);
59 }
60 /**
61 * Polls the progress monitor service for the progress status of a monitor
62 * corresponding to the given uuid.
63 *
64 *
65 * @param label for the operation
66 * @param uuid of the remoting monitor already started on the server
67 * @param pollInterval in milliseconds
68 * @param cancelable flag which determines whether the operation can be cancelled
69 * @param postOp callback for running post operation logic
70 * @param feedbackGenerators list of feedback generators corresponding to the
71 * size and exact order of the 'wait on feedback' requests made on the
72 * remoting monitor
73 * @param monitor to be updated
74 * @return a final progress monitor after the operation is completed
75 * @throws InterruptedException
76 */
77 public IRemotingProgressMonitor pollMonitor(final String label,
78 final UUID uuid,
79 final int pollInterval,
80 final IPostMoniteredOperationEnabled postOp,
81 List<IFeedbackGenerator> feedbackGenerators,
82 SubMonitor monitor) throws InterruptedException {
83 IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
84 IRemotingProgressMonitor remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
85 try {
86 final int START_DELAY=10;
87 // wait about 10 seconds for the remoting monitor to be initialised
88 // (i.e. for the begin task method to be called ON THE REMOTING MONITOR)
89 if ( remotingMonitor.isDone()){
90 return remotingMonitor;
91 }
92 for(int i=0;i<START_DELAY;i++) {
93 Thread.sleep(10);
94 logger.info("Waiting for monitered work to start ..");
95 remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
96 if (remotingMonitor != null){
97 if(remotingMonitor.getTotalWork() > 0) {
98 break;
99 }
100 break;
101 }
102 }
103
104 if (remotingMonitor == null){
105 return null;
106 }
107 // if the total work is still not been set then we assume that the
108 // operation has zero work units
109
110 if(remotingMonitor.getTotalWork() == 0 && remotingMonitor.isDone()) {
111 return remotingMonitor;
112
113 }else if (remotingMonitor.getTotalWork() == 0 ){
114 Object result = remotingMonitor.getResult();
115 InterruptedException exception = new InterruptedException("Monitor has zero work units");
116 if (result instanceof UpdateResult){
117 ((UpdateResult)result).addException(exception);
118 }else if (result == null){
119 result = new UpdateResult();
120 }
121
122 }
123 // start the client monitor
124 // monitor.subTask(remotingMonitor.getTaskName());
125 monitor.beginTask(remotingMonitor.getTaskName(), remotingMonitor.getTotalWork());
126 logger.info("Work to be done: " + remotingMonitor.getTotalWork());
127 int editorTotalWorkDone = 0;
128 int serverTotalWorkDone = 0;
129 // loop until the operation is done
130 int feedbackCount = 0;
131 while(!(remotingMonitor.isCanceled() || remotingMonitor.isFailed() || remotingMonitor.isDone())) {
132 // wait for pollInterval, then
133 // .... retrieve remoting monitor, then
134 // .... set client monitor info
135 Thread.sleep(pollInterval);
136 remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
137 // check if remoting monitor is waiting for feedback
138 if(remotingMonitor.getIsWaitingForFeedback()) {
139 if(feedbackGenerators != null) {
140 // if we have run out of feedback generators while
141 // the remoting monitor is waiting on feedback
142 // then throw exception
143 if(feedbackCount + 1 > feedbackGenerators.size()) {
144 IllegalStateException exception = new IllegalStateException("Remoting monitor waiting on feedback that does not exist");
145 Object result = remotingMonitor.getResult();
146 if (result instanceof UpdateResult){
147 ((UpdateResult)result).addException(exception);
148 }
149 return remotingMonitor;
150 }
151 feedbackGenerators.get(feedbackCount).setFeedbackForMonitor(uuid);
152 feedbackCount++;
153 }
154 }
155 serverTotalWorkDone = (int) remotingMonitor.getWorkDone();
156 logger.info("Work done from start: " + serverTotalWorkDone);
157 String percentage = "100";
158 if (remotingMonitor.getTotalWork() != 0){
159 percentage = new DecimalFormat("#.##").format(remotingMonitor.getPercentage());
160 }
161
162
163 // set dialog text
164 monitor.setTaskName(label + " " + percentage + "% done ");
165 monitor.subTask(remotingMonitor.getSubTask());
166 // monitor.setWorkRemaining((int) (remotingMonitor.getTotalWork()-remotingMonitor.getWorkDone()));
167 // monitor.subTask(remotingMonitor.getSubTask(), remotingMonitor.getWorkDone());
168 int worked = 0;
169 if (serverTotalWorkDone > editorTotalWorkDone){
170 worked = serverTotalWorkDone - editorTotalWorkDone;
171 }
172 if(worked > 0) {
173 logger.info("Work done since last check: " + worked);
174 monitor.worked(worked);
175 }
176
177
178 editorTotalWorkDone = serverTotalWorkDone;
179 }
180 if(remotingMonitor.getResult() instanceof Exception) {
181 UpdateResult result = new UpdateResult();
182 result.addException((Exception) remotingMonitor.getResult());
183 // throw new IllegalStateException((Exception)remotingMonitor.getResult());
184 }
185 return remotingMonitor;
186 } finally {
187 if(postOp != null && remotingMonitor != null && remotingMonitor.isDone()) {
188 postOp.postOperation(remotingMonitor);
189 }
190 }
191 }
192 }