Project

General

Profile

Download (8.78 KB) Statistics
| Branch: | Tag: | Revision:
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
import org.springframework.remoting.RemoteAccessException;
19

    
20
import eu.etaxonomy.cdm.api.application.CdmApplicationState;
21
import eu.etaxonomy.cdm.api.service.IProgressMonitorService;
22
import eu.etaxonomy.cdm.api.service.UpdateResult;
23
import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
24
import eu.etaxonomy.taxeditor.operation.IFeedbackGenerator;
25
import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
26

    
27
/**
28
 * Manages client side progress monitors
29
 *
30
 * @author cmathew
31
 * @date 23 Oct 2015
32
 *
33
 */
34

    
35
public class ProgressMonitorClientManager {
36
    private static final Logger logger = Logger.getLogger(ProgressMonitorClientManager.class);
37

    
38
    /**
39
     * Polls the progress monitor service for the progress status of a monitor
40
     * corresponding to the given uuid.
41
     *
42
     * @param label for the operation
43
     * @param uuid of the remoting monitor already started on the server
44
     * @param pollInterval in milliseconds
45
     * @param cancelable flag which determines whether the operation can be cancelled
46
     * @param postOp callback for running post operation logic
47
     * @param feedbackGenerator feedback generator corresponding to the
48
     *        'wait on feedback' request made on the remoting monitor
49
     * @param monitor to be updated
50
     * @return a final progress monitor after the operation is completed
51
     * @throws InterruptedException
52
     */
53
    public IRemotingProgressMonitor pollMonitor(final String label,
54
            final UUID uuid,
55
            final int pollInterval,
56
            final IPostMoniteredOperationEnabled postOp,
57
            IFeedbackGenerator feedbackGenerator,
58
            SubMonitor monitor) throws InterruptedException {
59
        return pollMonitor(label, uuid, pollInterval, postOp, Arrays.asList(feedbackGenerator), monitor);
60
    }
61
    /**
62
     * Polls the progress monitor service for the progress status of a monitor
63
     * corresponding to the given uuid.
64
     *
65
     *
66
     * @param label for the operation
67
     * @param uuid of the remoting monitor already started on the server
68
     * @param pollInterval in milliseconds
69
     * @param cancelable flag which determines whether the operation can be cancelled
70
     * @param postOp callback for running post operation logic
71
     * @param feedbackGenerators list of feedback generators corresponding to the
72
     *        size and exact order of the 'wait on feedback' requests made on the
73
     *        remoting monitor
74
     * @param monitor to be updated
75
     * @return a final progress monitor after the operation is completed
76
     * @throws InterruptedException
77
     */
78
    public IRemotingProgressMonitor pollMonitor(final String label,
79
            final UUID uuid,
80
            final int pollInterval,
81
            final IPostMoniteredOperationEnabled postOp,
82
            List<IFeedbackGenerator> feedbackGenerators,
83
            SubMonitor monitor) throws InterruptedException {
84

    
85
        IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
86
        IRemotingProgressMonitor remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
87
        try {
88
            final int START_DELAY=10;
89
            // wait about 10 seconds for the remoting monitor to be initialised
90
            // (i.e. for the begin task method to be called ON THE REMOTING MONITOR)
91
            if (remotingMonitor != null && remotingMonitor.isDone()){
92
                return remotingMonitor;
93
            }
94
            for(int i=0;i<START_DELAY;i++) {
95
                Thread.sleep(10);
96
                logger.info("Waiting for monitered work to start ..");
97
                remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
98
                if (remotingMonitor != null){
99
                    if(remotingMonitor.getTotalWork() > 0) {
100
                        break;
101
                    }
102
                    break;
103
                }
104
            }
105

    
106
            if (remotingMonitor == null){
107
                return null;
108
            }
109
            // if the total work is still not been set then we assume that the
110
            // operation has zero work units
111

    
112
            if(remotingMonitor.getTotalWork() == 0 && remotingMonitor.isDone()) {
113
                return remotingMonitor;
114

    
115
            }else if (remotingMonitor.getTotalWork() == 0 ){
116
                Object result = remotingMonitor.getResult();
117
                InterruptedException exception = new InterruptedException("Monitor has zero work units");
118
                if (result instanceof UpdateResult){
119
                    ((UpdateResult)result).addException(exception);
120
                }else if (result == null){
121
                    result = new UpdateResult();
122
                }
123
            }
124
            // start the client monitor
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
            int failCount = 10;
132
            while(!(remotingMonitor.isCanceled() || remotingMonitor.isFailed() || remotingMonitor.isDone())) {
133
                // wait for pollInterval, then
134
                // .... retrieve remoting monitor, then
135
                //      .... set client monitor info
136

    
137
                IRemotingProgressMonitor previousRemotingMonitor = remotingMonitor;
138
                Thread.sleep(pollInterval);
139
                try{
140
                    remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
141
                }catch(RemoteAccessException e){
142
                    failCount--;
143
                    if (failCount > 0){
144
                        remotingMonitor = previousRemotingMonitor;
145
                        continue;
146
                    }else{
147
                        throw e;
148
                    }
149

    
150
                }
151
                // check if remoting monitor is waiting for feedback
152
                if(remotingMonitor.getIsWaitingForFeedback()) {
153
                    if(feedbackGenerators != null) {
154
                        // if we have run out of feedback generators while
155
                        // the remoting monitor is waiting on feedback
156
                        // then throw exception
157
                        if(feedbackCount + 1 > feedbackGenerators.size()) {
158
                            IllegalStateException exception = new IllegalStateException("Remoting monitor waiting on feedback that does not exist");
159
                            Object result = remotingMonitor.getResult();
160
                            if (result instanceof UpdateResult){
161
                                ((UpdateResult)result).addException(exception);
162
                            }
163
                            return remotingMonitor;
164
                        }
165
                        feedbackGenerators.get(feedbackCount).setFeedbackForMonitor(uuid);
166
                        feedbackCount++;
167
                    }
168
                }
169
                serverTotalWorkDone = (int) remotingMonitor.getWorkDone();
170
                logger.info("Work done from start: " + serverTotalWorkDone);
171
                String percentage = "100";
172
                if (remotingMonitor.getTotalWork() != 0){
173
                    percentage = new DecimalFormat("#.##").format(remotingMonitor.getPercentage());
174
                }
175

    
176
                // set dialog text
177
                monitor.setTaskName(remotingMonitor.getTaskName());
178
                monitor.subTask(" " + percentage + "% done ");
179

    
180
                int worked = 0;
181
                if (serverTotalWorkDone > editorTotalWorkDone){
182
                    worked = serverTotalWorkDone - editorTotalWorkDone;
183
                }
184
                if(worked > 0) {
185
                    logger.info("Work done since last check: " + worked);
186
                    monitor.worked(worked);
187
                }
188

    
189
                editorTotalWorkDone = serverTotalWorkDone;
190
            }
191
            if(remotingMonitor.getResult() instanceof Exception) {
192
                UpdateResult result = new UpdateResult();
193
                result.addException((Exception) remotingMonitor.getResult());
194

    
195
            }
196
            return remotingMonitor;
197
        } finally {
198
            if(postOp != null && remotingMonitor != null && remotingMonitor.isDone()) {
199
                postOp.postOperation(remotingMonitor);
200
            }
201
        }
202
    }
203
}
(3-3/5)