Project

General

Profile

Download (8.75 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

    
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

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

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

    
190

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

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