Project

General

Profile

Download (8.63 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
public class ProgressMonitorClientManager {
34
    private static final Logger logger = Logger.getLogger(ProgressMonitorClientManager.class);
35

    
36
    /**
37
     * Polls the progress monitor service for the progress status of a monitor
38
     * corresponding to the given uuid.
39
     *
40
     * @param label for the operation
41
     * @param uuid of the remoting monitor already started on the server
42
     * @param pollInterval in milliseconds
43
     * @param cancelable flag which determines whether the operation can be cancelled
44
     * @param postOp callback for running post operation logic
45
     * @param feedbackGenerator feedback generator corresponding to the
46
     *        'wait on feedback' request made on the remoting monitor
47
     * @param monitor to be updated
48
     * @return a final progress monitor after the operation is completed
49
     * @throws InterruptedException
50
     */
51
    public IRemotingProgressMonitor pollMonitor(final String label,
52
            final UUID uuid,
53
            final int pollInterval,
54
            final IPostMoniteredOperationEnabled postOp,
55
            IFeedbackGenerator feedbackGenerator,
56
            SubMonitor monitor) throws InterruptedException {
57
        return pollMonitor(label, uuid, pollInterval, postOp, Arrays.asList(feedbackGenerator), monitor);
58
    }
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

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

    
102
            // if the total work is still not been set then we assume that the
103
            // operation has zero work units
104
            if(remotingMonitor.getTotalWork() == 0 && remotingMonitor.isDone()) {
105
                return remotingMonitor;
106
            }else if (remotingMonitor.getTotalWork() == 0 ){
107
                Object result = remotingMonitor.getResult();
108
                InterruptedException exception = new InterruptedException("Monitor has zero work units");
109
                if (result instanceof UpdateResult){
110
                    ((UpdateResult)result).addException(exception);
111
                }else if (result == null){
112
                    result = new UpdateResult();
113
                }
114
            }
115

    
116
            // start the client monitor
117
            logger.info("Work to be done: " + remotingMonitor.getTotalWork());
118
            int editorTotalWorkDone = 0;
119
            int serverTotalWorkDone = 0;
120
            // loop until the operation is done
121
            int feedbackCount = 0;
122
            int failCount = 10;
123
            while(!(remotingMonitor.isCanceled() || remotingMonitor.isFailed() || remotingMonitor.isDone())) {
124
                // wait for pollInterval, then
125
                // .... retrieve remoting monitor, then
126
                //      .... set client monitor info
127

    
128
                IRemotingProgressMonitor previousRemotingMonitor = remotingMonitor;
129
                Thread.sleep(pollInterval);
130
                try{
131
                    remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
132
                }catch(RemoteAccessException e){
133
                    failCount--;
134
                    if (failCount > 0){
135
                        remotingMonitor = previousRemotingMonitor;
136
                        continue;
137
                    }else{
138
                        throw e;
139
                    }
140
                }
141

    
142
                // check if remoting monitor is waiting for feedback
143
                if(remotingMonitor.getIsWaitingForFeedback()) {
144
                    if(feedbackGenerators != null) {
145
                        // if we have run out of feedback generators while
146
                        // the remoting monitor is waiting on feedback
147
                        // then throw exception
148
                        if(feedbackCount + 1 > feedbackGenerators.size()) {
149
                            IllegalStateException exception = new IllegalStateException("Remoting monitor waiting on feedback that does not exist");
150
                            Object result = remotingMonitor.getResult();
151
                            if (result instanceof UpdateResult){
152
                                ((UpdateResult)result).addException(exception);
153
                            }
154
                            return remotingMonitor;
155
                        }
156
                        feedbackGenerators.get(feedbackCount).setFeedbackForMonitor(uuid);
157
                        feedbackCount++;
158
                    }
159
                }
160

    
161
                serverTotalWorkDone = (int) remotingMonitor.getWorkDone();
162
                logger.info("Work done from start: " + serverTotalWorkDone);
163

    
164
                if (serverTotalWorkDone > editorTotalWorkDone){
165
                    int worked = serverTotalWorkDone - editorTotalWorkDone;
166
                    if(worked > 0) {
167
                        logger.info("Work done since last check: " + worked);
168
                        monitor.worked(worked);
169
                    }
170
                }
171

    
172
                // set dialog text
173
                String subTaskName = remotingMonitor.getSubTask();
174
                String percentage = "0";
175
                if (remotingMonitor.getTotalWork() != 0){
176
                    percentage = new DecimalFormat("#.##").format(remotingMonitor.getPercentage());
177
                }
178
                subTaskName = subTaskName + " (" + percentage +"% done)";
179
                //Note: do not update taskname as it resets percentage in status line
180
                monitor.subTask(subTaskName );
181

    
182
                editorTotalWorkDone = serverTotalWorkDone;
183
            }
184
            if(remotingMonitor.getResult() instanceof Exception) {
185
                UpdateResult result = new UpdateResult();
186
                result.addException((Exception) remotingMonitor.getResult());
187
            }
188
            return remotingMonitor;
189
        } finally {
190
            if(postOp != null && remotingMonitor != null && remotingMonitor.isDone()) {
191
                postOp.postOperation(remotingMonitor);
192
            }
193
        }
194
    }
195
}
(3-3/5)