Project

General

Profile

Download (8.22 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.IProgressMonitor;
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
            IProgressMonitor 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
            IProgressMonitor 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.beginTask(label, remotingMonitor.getTotalWork());
125
            logger.info("Work to be done: " + remotingMonitor.getTotalWork());
126
            int editorTotalWorkDone = 0;
127
            int serverTotalWorkDone = 0;
128
            // loop until the operation is done
129
            int feedbackCount = 0;
130
            while(!(remotingMonitor.isCanceled() || remotingMonitor.isFailed() || remotingMonitor.isDone())) {
131
                // wait for pollInterval, then
132
                // .... retrieve remoting monitor, then
133
                //      .... set client monitor info
134
                Thread.sleep(pollInterval);
135
                remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
136
                // check if remoting monitor is waiting for feedback
137
                if(remotingMonitor.getIsWaitingForFeedback()) {
138
                    if(feedbackGenerators != null) {
139
                        // if we have run out of feedback generators while
140
                        // the remoting monitor is waiting on feedback
141
                        // then throw exception
142
                        if(feedbackCount + 1 > feedbackGenerators.size()) {
143
                            IllegalStateException exception = new IllegalStateException("Remoting monitor waiting on feedback that does not exist");
144
                            Object result = remotingMonitor.getResult();
145
                            if (result instanceof UpdateResult){
146
                                ((UpdateResult)result).addException(exception);
147
                            }
148
                            return remotingMonitor;
149
                        }
150
                        feedbackGenerators.get(feedbackCount).setFeedbackForMonitor(uuid);
151
                        feedbackCount++;
152
                    }
153
                }
154
                serverTotalWorkDone = (int) remotingMonitor.getWorkDone();
155
                logger.info("Work done from start: " + serverTotalWorkDone);
156
                String percentage = "100";
157
                if (remotingMonitor.getTotalWork() != 0){
158
                    percentage = new DecimalFormat("#.##").format(remotingMonitor.getPercentage());
159
                }
160

    
161

    
162
                // set dialog text
163
                monitor.setTaskName(label + " " + percentage + "% done ");
164
                monitor.subTask(remotingMonitor.getSubTask());
165
                int worked = serverTotalWorkDone - editorTotalWorkDone;
166
                if(worked > 0) {
167
                    logger.info("Work done since last check: " + worked);
168
                    monitor.worked(worked);
169
                }
170
                editorTotalWorkDone = serverTotalWorkDone;
171
            }
172
            if(remotingMonitor.getResult() instanceof Exception) {
173
                UpdateResult result = new UpdateResult();
174
                result.addException((Exception) remotingMonitor.getResult());
175
//                throw new IllegalStateException((Exception)remotingMonitor.getResult());
176
            }
177
            return remotingMonitor;
178
        } finally {
179
            if(postOp != null && remotingMonitor != null &&  remotingMonitor.isDone()) {
180
                postOp.postOperation(remotingMonitor);
181
            }
182
        }
183
    }
184
}
(3-3/5)