Project

General

Profile

Download (8.55 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
        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.isDone()){
91
                return remotingMonitor;
92
            }
93
            for(int i=0;i<START_DELAY;i++) {
94
                Thread.sleep(10);
95
                logger.info("Waiting for monitered work to start ..");
96
                remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
97
                if (remotingMonitor != null){
98
                    if(remotingMonitor.getTotalWork() > 0) {
99
                        break;
100
                    }
101
                    break;
102
                }
103
            }
104

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

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

    
114
            }else if (remotingMonitor.getTotalWork() == 0 ){
115
                Object result = remotingMonitor.getResult();
116
                InterruptedException exception = new InterruptedException("Monitor has zero work units");
117
                if (result instanceof UpdateResult){
118
                    ((UpdateResult)result).addException(exception);
119
                }else if (result == null){
120
                    result = new UpdateResult();
121
                }
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
                Thread.sleep(pollInterval);
137
                try{
138
                    remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
139
                }catch(RemoteAccessException e){
140
                    failCount--;
141
                    if (failCount > 0){
142
                        continue;
143
                    }
144

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

    
171

    
172
                // set dialog text
173
                monitor.setTaskName(remotingMonitor.getTaskName());
174
                monitor.subTask(" " + percentage + "% done ");
175

    
176
                int worked = 0;
177
                if (serverTotalWorkDone > editorTotalWorkDone){
178
                    worked = serverTotalWorkDone - editorTotalWorkDone;
179
                }
180
                if(worked > 0) {
181
                    logger.info("Work done since last check: " + worked);
182
                    monitor.worked(worked);
183
                }
184

    
185

    
186
                editorTotalWorkDone = serverTotalWorkDone;
187
            }
188
            if(remotingMonitor.getResult() instanceof Exception) {
189
                UpdateResult result = new UpdateResult();
190
                result.addException((Exception) remotingMonitor.getResult());
191

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