source: 3thparty/jupload/src/main/java/wjhk/jupload2/upload/helper/ProgressBarManager.java @ 3951

Revision 3951, 18.0 KB checked in by alexandrecorreia, 13 years ago (diff)

Ticket #1709 - Adicao de codigo fonte java do componente jupload

Line 
1//
2// $Id$
3//
4// jupload - A file upload applet.
5//
6// Copyright 2010 The JUpload Team
7//
8// Created: 10 févr. 2010
9// Creator: etienne_sf
10// Last modified: $Date$
11//
12// This program is free software; you can redistribute it and/or modify
13// it under the terms of the GNU General Public License as published by
14// the Free Software Foundation; either version 2 of the License, or
15// (at your option) any later version.
16//
17// This program is distributed in the hope that it will be useful,
18// but WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20// GNU General Public License for more details.
21//
22// You should have received a copy of the GNU General Public License
23// along with this program; if not, write to the Free Software
24// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26package wjhk.jupload2.upload.helper;
27
28import java.awt.event.ActionEvent;
29import java.awt.event.ActionListener;
30
31import javax.swing.JProgressBar;
32import javax.swing.Timer;
33
34import wjhk.jupload2.exception.JUploadException;
35import wjhk.jupload2.gui.JUploadPanel;
36import wjhk.jupload2.gui.filepanel.SizeRenderer;
37import wjhk.jupload2.policies.UploadPolicy;
38import wjhk.jupload2.upload.FilePreparationThread;
39import wjhk.jupload2.upload.FileUploadManagerThread;
40import wjhk.jupload2.upload.UploadFileData;
41import wjhk.jupload2.upload.UploadFilePacket;
42
43/**
44 * @author etienne_sf
45 */
46public class ProgressBarManager implements ActionListener {
47        /**
48         * The delay between to updates of the progress bar, in ms.
49         */
50        public final static int DELAY_FOR_UPDATE_OF_PROGRESS_BAR = 100;
51
52        /**
53         * Contains the date/time (as a long) of the start of the current upload.
54         * This allows to sum the time of the actual upload, and ignore the time the
55         * applet is waiting for the server's response. Once the request is
56         * finished, and the applet waits for the server's response, the duration of
57         * the sending to the server is added to currentRequestStartTime, and
58         * currentRequestStartTime is reseted to 0. It's then ready for the next
59         * upload request.
60         */
61        long currentRequestStartTime = 0;
62
63        /**
64         * The file that is currently being uploaded. Allow to refresh the progress
65         * bar, with up to date information, based on a timer event.
66         */
67        UploadFileData currentUploadFileData = null;
68
69        /**
70         * The files which is currently being sent to the server.
71         */
72        UploadFilePacket currentUploadFilePacket = null;
73
74        /**
75         * The file preparatoin thread prepares each file for upload, and manage
76         * possible errors that can occurs at preparation time.
77         */
78        FilePreparationThread filePreparationThread = null;
79
80        /**
81         * Contains the system time of the start of the global upload. This is used
82         * to calculate the ETA, and display it to the user, on the status bar.
83         */
84        long globalStartTime = 0;
85
86        /**
87         * Indicated the number of bytes that have currently been sent for the
88         * current file. This allows the management of the progress bar.
89         */
90        long nbBytesUploadedForCurrentFile = 0;
91
92        /**
93         * Number of files that have already been sent. The control on the upload
94         * success may be done or not. It's used to properly display the progress
95         * bar.
96         */
97        int nbSentFiles = 0;
98
99        /** Current number of bytes that have been uploaded. */
100        long nbUploadedBytes = 0;
101
102        /**
103         * The {@link JUploadPanel} progress bar, to follow the file preparation
104         * progress.
105         */
106        JProgressBar preparationProgressBar = null;
107
108        /**
109         * The timer which schedules the update for the progress and status bar.
110         */
111        Timer timer;
112
113        /**
114         * Contains the sum of the upload duration for all requests, in
115         * milliseconds. For instance, if sending in 10 chunks one big file, the
116         * uploadDuration contains the sum of the sending of these 10 request to the
117         * server. This allows to calculate the true upload speed, and ignore the
118         * time we'll wait for the server's response.
119         */
120        long totalUploadDuration = 0;
121
122        /** The current upload policy */
123        UploadPolicy uploadPolicy;
124
125        /**
126         * The {@link JUploadPanel} progress bar, to follow the upload of the
127         * prepared files to the server.
128         */
129        JProgressBar uploadProgressBar = null;
130
131        /**
132         * Indicates what is the current file being uploaded, and its upload status.
133         */
134        int uploadStatus = FileUploadManagerThread.UPLOAD_STATUS_NOT_STARTED;
135
136        /**
137         * @param uploadPolicy
138         * @param filePreparationThread
139         */
140        public ProgressBarManager(UploadPolicy uploadPolicy,
141                        FilePreparationThread filePreparationThread) {
142                this.uploadPolicy = uploadPolicy;
143                this.filePreparationThread = filePreparationThread;
144                // our timer is a daemon.
145                this.timer = new Timer(DELAY_FOR_UPDATE_OF_PROGRESS_BAR, this);
146
147                JUploadPanel uploadPanel = uploadPolicy.getContext().getUploadPanel();
148
149                this.uploadProgressBar = uploadPanel.getUploadProgressBar();
150                this.preparationProgressBar = uploadPanel.getPreparationProgressBar();
151
152                updateUploadProgressBarText();
153        }
154
155        /**
156         * The only event managed here is the timer event. We update the progress
157         * and status bar.
158         *
159         * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
160         */
161        public void actionPerformed(ActionEvent arg0) {
162                updateUploadProgressBarValue();
163                updateUploadStatusBar();
164
165        }
166
167        /**
168         * Called when a new file is uploaded. This method update the bars
169         * accordingly to this new status, by calling the
170         * updateUploadProgressBarText() method.
171         *
172         * @param uploadFilePacket
173         * @param uploadFileData
174         * @throws JUploadException
175         * @see wjhk.jupload2.upload.FileUploadManagerThread#anotherFileHasBeenSent(wjhk.jupload2.upload.UploadFilePacket,
176         *      wjhk.jupload2.upload.UploadFileData)
177         */
178        public synchronized void anotherFileHasBeenSent(
179                        UploadFilePacket uploadFilePacket, UploadFileData uploadFileData)
180                        throws JUploadException {
181                if (uploadFilePacket != this.currentUploadFilePacket) {
182                        throw new java.lang.AssertionError("Wrong file packet in "
183                                        + this.getClass().getName() + ".anotherFileHasBeenSent()");
184                }
185                if (uploadFileData != this.currentUploadFileData) {
186                        throw new java.lang.AssertionError("Wrong file packet in "
187                                        + this.getClass().getName() + ".anotherFileHasBeenSent()");
188                }
189                this.nbSentFiles += 1;
190                this.nbBytesUploadedForCurrentFile = 0;
191                this.uploadPolicy
192                                .displayDebug(
193                                                this.getClass().getName()
194                                                                + ".anotherFileHasBeenSent(): before call to newlyUploadedFileData.getUploadLength()",
195                                                100);
196
197                // We are finished with this one. Let's display it.
198                this.uploadStatus = FileUploadManagerThread.UPLOAD_STATUS_UPLOADED;
199                updateUploadProgressBarText();
200        }
201
202        /**
203         * Clean all bar content.
204         */
205        public void clearBarContent() {
206                // Let's stop the update process.
207                this.timer.stop();
208
209                this.preparationProgressBar.setValue(0);
210                this.preparationProgressBar.setString("");
211                this.uploadProgressBar.setValue(0);
212                this.uploadProgressBar.setString("");
213
214        }
215
216        /**
217         * @return the globalStartTime
218         */
219        public long getGlobalStartTime() {
220                return this.globalStartTime;
221        }
222
223        /**
224         * @return the nbUploadedBytes
225         */
226        public long getNbUploadedBytes() {
227                return this.nbUploadedBytes;
228        }
229
230        /**
231         * @return the uploadDuration
232         */
233        public long getUploadDuration() {
234            long currentRequestDuration = 0;
235            if (this.currentRequestStartTime!=0) {
236                //A request is running on
237                currentRequestDuration=System.currentTimeMillis()-this.currentRequestStartTime;
238            }
239
240                return this.totalUploadDuration + currentRequestDuration;
241        }
242
243        /**
244         * Initialize the maximum value for the two progress bar: 100*the number of
245         * files to upload.
246         *
247         * @throws JUploadException
248         * @see #updateUploadProgressBar(UploadFilePacket, UploadFileData)
249         */
250        private void initProgressBar() throws JUploadException {
251                // To follow the state of file preparation
252                this.preparationProgressBar.setMaximum(100 * this.filePreparationThread
253                                .getNbFilesToSent());
254                this.preparationProgressBar.setString("");
255
256                // To follow the state of the actual upload
257                this.uploadProgressBar.setMaximum(100 * this.uploadPolicy.getContext()
258                                .getUploadPanel().getFilePanel().getFilesLength());
259                this.uploadProgressBar.setString("");
260        }
261
262        /**
263         * The progressBar is updated each 50ms and each 10% of the target file.
264         *
265         * @param nbBytes
266         * @param uploadFileData
267         * @throws JUploadException
268         * @see wjhk.jupload2.upload.FileUploadManagerThread#nbBytesUploaded(long,
269         *      UploadFileData)
270         */
271        public synchronized void nbBytesUploaded(long nbBytes,
272                        UploadFileData uploadFileData) throws JUploadException {
273                this.nbUploadedBytes += nbBytes;
274                this.nbBytesUploadedForCurrentFile += nbBytes;
275        }
276
277        /**
278         * Set an error text, that will be displayed on the progress bar
279         *
280         * @param errorTexte
281         */
282        public void setErrorMessage(String errorTexte) {
283                this.preparationProgressBar.setString(errorTexte);
284        }
285
286        /**
287         * @param uploadFilePacket
288         * @param uploadFileData
289         * @param uploadStatus
290         * @throws JUploadException
291         */
292        public synchronized void setUploadStatus(UploadFilePacket uploadFilePacket,
293                        UploadFileData uploadFileData, int uploadStatus)
294                        throws JUploadException {
295                // Let's store the file we're working on.
296                this.currentUploadFileData = uploadFileData;
297                this.currentUploadFilePacket = uploadFilePacket;
298
299                switch (uploadStatus) {
300                case FileUploadManagerThread.UPLOAD_STATUS_CHUNK_UPLOADED_WAITING_FOR_RESPONSE:
301                case FileUploadManagerThread.UPLOAD_STATUS_FILE_UPLOADED_WAITING_FOR_RESPONSE:
302                        // We're waiting for the server: let's add it to the sending
303                        // duration.
304                        this.totalUploadDuration += System.currentTimeMillis()
305                                        - this.currentRequestStartTime;
306                        this.currentRequestStartTime = 0;
307                        break;
308                case FileUploadManagerThread.UPLOAD_STATUS_UPLOADING:
309                    //We mark the start of the request, if it was not already done.
310                        if (this.currentRequestStartTime == 0) {
311                                this.currentRequestStartTime = System.currentTimeMillis();
312                        }
313                        break;
314                case FileUploadManagerThread.UPLOAD_STATUS_UPLOADED:
315                        // Indicated that the current request is finished. Nothing to do
316                        break;
317                default:
318                        this.uploadPolicy.displayWarn("Unknown value for uploadStatus: "
319                                        + uploadStatus);
320                }
321                this.uploadStatus = uploadStatus;
322
323                this.updateUploadProgressBarText();
324        }
325
326        /**
327         * Update the progress bar, based on the following data: <DIR> <LI>
328         * nbSentFiles: number of files that have already been updated. <LI>
329         * nbBytesUploadedForCurrentFile: allows calculation of the upload progress
330         * for the current file, based on it total upload length. </DIR> <BR>
331         * Note 1: The progress bar update is ignored, if last update was less than
332         * 100ms before.<BR>
333         * Note 2: This method calls the
334         * {@link #updateUploadProgressBarValue(UploadFileData)} method, to also
335         * update its value.
336         *
337         * @throws JUploadException
338         */
339        private void updateUploadProgressBarText() {
340                /*
341                 * final String msgInfoUploaded = this.uploadPolicy
342                 * .getLocalizedString("infoUploaded"); final String msgInfoUploading =
343                 * this.uploadPolicy .getLocalizedString("infoUploading"); final String
344                 * msgNbUploadedFiles = this.uploadPolicy
345                 * .getLocalizedString("nbUploadedFiles");
346                 */
347                updateUploadProgressBarValue();
348
349                String msg = null;
350                switch (this.uploadStatus) {
351                case FileUploadManagerThread.UPLOAD_STATUS_NOT_STARTED:
352                        msg = "";
353                        break;
354                case FileUploadManagerThread.UPLOAD_STATUS_UPLOADING:
355                case FileUploadManagerThread.UPLOAD_STATUS_CHUNK_UPLOADED_WAITING_FOR_RESPONSE:
356                        // Uploading files %1$s
357                        msg = this.uploadPolicy.getLocalizedString("infoUploading",
358                                        (this.nbSentFiles + 1));
359                        break;
360                case FileUploadManagerThread.UPLOAD_STATUS_FILE_UPLOADED_WAITING_FOR_RESPONSE:
361                        // %1$s file(s) uploaded. Waiting for server response ...
362
363                        // nbSentFiles it number of files whose data is already sent to
364                        // the server. This include the currentUploadFileData (which
365                        // should be the last file in the packet)
366                        int firstFileInPacket = this.currentUploadFileData
367                                        .getNumOfFileInCurrentUpload();
368                        int currentFile = this.nbSentFiles;
369
370                        if (this.currentUploadFilePacket.size() == 1) {
371                                msg = currentFile + "/"
372                                                + this.filePreparationThread.getNbFilesToSent();
373                        } else {
374                                msg = firstFileInPacket + "-" + currentFile + "/"
375                                                + this.filePreparationThread.getNbFilesToSent();
376                        }
377                        msg = this.uploadPolicy.getLocalizedString("infoUploaded", msg);
378
379                        break;
380                case FileUploadManagerThread.UPLOAD_STATUS_UPLOADED:
381                        // %1$d file(s) uploaded
382                        msg = this.uploadPolicy.getLocalizedString("nbUploadedFiles",
383                                        (this.nbSentFiles));
384                        break;
385                default:
386                        // Hum, that's strange !
387                        this.uploadPolicy
388                                        .displayWarn("Unknown upload status in FileUploadManagerThreadImpl.updateProgressBar(): "
389                                                        + this.uploadStatus);
390                }
391
392                // Let's show the modifications to the user
393                this.uploadProgressBar.setString(msg);
394                // To be sure that the new text is displayed, we force instantaneous
395                // refresh. This won't slow down the upload, as it's done in separate
396                // thread.
397                this.uploadProgressBar.repaint(0);
398        }
399
400        /**
401         * Update the progress bar value, that is: the percent of upload of the
402         * current file. This is based on nbBytesUploadedForCurrentFile and the
403         * total upload length of the current file.<BR>
404         * Note: The progress bar update is ignored, if last update was less than
405         * 100ms before.
406         *
407         * @throws JUploadException
408         */
409        private void updateUploadProgressBarValue() {
410                /*
411                 * final String msgInfoUploaded = this.uploadPolicy
412                 * .getLocalizedString("infoUploaded"); final String msgInfoUploading =
413                 * this.uploadPolicy .getLocalizedString("infoUploading"); final String
414                 * msgNbUploadedFiles = this.uploadPolicy
415                 * .getLocalizedString("nbUploadedFiles");
416                 */
417                int percent = 0;
418
419                // First, we update the bar itself.
420                if (this.nbBytesUploadedForCurrentFile == 0
421                                || this.nbSentFiles == this.filePreparationThread
422                                                .getNbFilesToSent()) {
423                        percent = 0;
424                } else if (this.currentUploadFileData == null) {
425                        percent = 0;
426                } else {
427                        if (this.currentUploadFileData.isPreparedForUpload()) {
428                                percent = (int) (this.nbBytesUploadedForCurrentFile * 100 / this.currentUploadFileData
429                                                .getUploadLength());
430                        } else {
431                                // Hum, hum. The file is not prepared for upload yet. So we
432                                // actually didn't send any thing for it.
433                                percent = 0;
434                        }
435                        // Usually, a percentage if advancement for one file is no more than
436                        // 100. Let's check that.
437                        if (percent > 100) {
438                                this.uploadPolicy
439                                                .displayWarn("percent is more than 100 ("
440                                                                + percent
441                                                                + ") in FileUploadManagerThreadImpl.update.UploadProgressBar");
442                                percent = 100;
443                        }
444                }
445
446                this.uploadProgressBar.setValue(100 * this.nbSentFiles + percent);
447        }
448
449        /**
450         * Displays the current upload speed on the status bar.
451         */
452        private void updateUploadStatusBar() {
453                // We'll update the status bar, only if it exists and if the upload
454                // actually started.
455                if (null != this.uploadPolicy.getContext().getUploadPanel()
456                                .getStatusLabel()
457                                && this.nbUploadedBytes > 0) {
458                        double percent;
459                        // uploadCPS: contains the upload speed.
460                        double uploadSpeed;
461                        // globalCPS: contains the average speed, including the time the
462                        // applet is waiting for the server response.
463                        double globalCPS;
464                        long remaining;
465                        String eta;
466
467                        try {
468                                percent = 100.0 * this.nbUploadedBytes
469                                                / this.filePreparationThread.getTotalFileBytesToSend();
470
471                        } catch (ArithmeticException e1) {
472                                percent = 100;
473                        }
474
475                        // Calculation of the 'pure' upload speed.
476                        uploadSpeed = ((double) this.nbUploadedBytes)
477                                        / ((double) getUploadDuration() / 1000);
478                        if (uploadSpeed == Double.POSITIVE_INFINITY) {
479                                this.uploadPolicy.displayDebug(
480                                                "uploadSpeed is Infinity, for nbUploadedBytes="
481                                                                + nbUploadedBytes
482                                                                + " and actualUploadDuration(ms)="
483                                                                + getUploadDuration(), 80);
484                        }
485
486                        // Calculation of the 'global' upload speed.
487                        try {
488                                globalCPS = ((double) this.nbUploadedBytes)
489                                                / (System.currentTimeMillis() - this.globalStartTime)
490                                                * 1000;
491                        } catch (ArithmeticException e1) {
492                                globalCPS = this.nbUploadedBytes;
493                        }
494
495                        // Calculation of the ETA. It's based on the global upload speed.
496                        try {
497                                remaining = (long) ((this.filePreparationThread
498                                                .getTotalFileBytesToSend() - this.nbUploadedBytes) / globalCPS);
499                                if (remaining > 3600) {
500                                        eta = this.uploadPolicy.getLocalizedString("timefmt_hms",
501                                                        Long.valueOf(remaining / 3600), Long
502                                                                        .valueOf((remaining / 60) % 60), Long
503                                                                        .valueOf(remaining % 60));
504                                } else if (remaining > 60) {
505                                        eta = this.uploadPolicy.getLocalizedString("timefmt_ms",
506                                                        Long.valueOf(remaining / 60), Long
507                                                                        .valueOf(remaining % 60));
508                                } else
509                                        eta = this.uploadPolicy.getLocalizedString("timefmt_s",
510                                                        Long.valueOf(remaining));
511                        } catch (ArithmeticException e1) {
512                                eta = this.uploadPolicy.getLocalizedString("timefmt_unknown");
513                        }
514                        String status = this.uploadPolicy.getLocalizedString("status_msg",
515                                        Integer.valueOf((int) percent), SizeRenderer
516                                                        .formatFileUploadSpeed(uploadSpeed,
517                                                                        this.uploadPolicy), eta);
518                        this.uploadPolicy.getContext().getUploadPanel().getStatusLabel()
519                                        .setText(status);
520                        // this.uploadPanel.getStatusLabel().repaint();
521                        this.uploadPolicy.getContext().showStatus(status);
522                        // this.uploadPolicy.displayDebug("[updateUploadStatusBar] " +
523                        // status, 101);
524                }
525        }
526
527        /**
528         * This just stops the timer. A 'last' update is done.
529         */
530        public void uploadIsFinished() {
531                // Let's stop the update process.
532                this.timer.stop();
533
534                updateUploadProgressBarText();
535                updateUploadStatusBar();
536        }
537
538        /**
539         * @throws JUploadException
540         */
541        public void uploadIsStarted() throws JUploadException {
542                // Ok, the upload just starts. We keep the date, to later calculate the
543                // ETA.
544                this.globalStartTime = System.currentTimeMillis();
545                initProgressBar();
546
547                // Let's start the update process.
548                this.timer.start();
549        }
550
551}
Note: See TracBrowser for help on using the repository browser.