⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileuploadmanagerthread.java

📁 [linux.rar] - 嵌入式linux开发教程
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
package wjhk.jupload2.upload;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JProgressBar;
import javax.swing.Timer;

import wjhk.jupload2.exception.JUploadException;
import wjhk.jupload2.filedata.FileData;
import wjhk.jupload2.gui.JUploadPanel;
import wjhk.jupload2.gui.filepanel.FilePanel;
import wjhk.jupload2.gui.filepanel.SizeRenderer;
import wjhk.jupload2.policies.UploadPolicy;

/**
 * This class is responsible for managing the upload. At the end of the upload,
 * the {@link JUploadPanel#updateButtonState()} is called, to refresh the button
 * state. Its job is to: <DIR> <LI>Prepare upload for the file (calls to
 * {@link FileData#beforeUpload()} for each file in the file list. <LI>Create
 * the thread to send a packet of files. <LI>Prepare the packets, that will be
 * red by the upload thread. <LI>Manage the end of upload: trigger the call to
 * {@link JUploadPanel#updateButtonState()} and the call to
 * {@link UploadPolicy#afterUpload(Exception, String)}. <LI>Manage the 'stop'
 * button reaction. </DIR> This class is created by {@link JUploadPanel}, when
 * the user clicks on the upload button.
 * 
 * @author etienne_sf
 */
public class FileUploadManagerThread extends Thread implements ActionListener {

    // /////////////////////////////////////////////////////////////////////////////////////////
    // //////////////////// Possible Status for file upload
    // /////////////////////////////////////////////////////////////////////////////////////////

    /** Indicates that nothings has begun */
    public static final int UPLOAD_STATUS_NOT_STARTED = 1;

    /**
     * We're sending data to the server, for the file identified by
     * numOfFileInCurrentRequest.
     */
    public static final int UPLOAD_STATUS_UPLOADING = 2;

    /**
     * All data for the file identified by numOfFileInCurrentRequest has been
     * sent. But the server response has not been received.
     */
    public static final int UPLOAD_STATUS_UPLOADED_WAITING_FOR_RESPONSE = 3;

    /**
     * The upload for the file identified by numOfFileInCurrentRequest is
     * finished
     */
    public static final int UPLOAD_STATUS_UPLOADED = 4;

    // /////////////////////////////////////////////////////////////////////////////////////////
    // //////////////////// Possible Status for file upload
    // /////////////////////////////////////////////////////////////////////////////////////////

    /**
     * Contains the date/time (as a long) of the start of the current upload.
     * This allows to sum the time of the actual upload, and ignore the time the
     * applet is waiting for the server's response. Once the request is
     * finished, and the applet waits for the server's response, the duration of
     * the sending to the server is added to currentRequestStartTime, and
     * currentRequestStartTime is reseted to 0. It's then ready for the next
     * upload request.
     */
    private long currentRequestStartTime = 0;

    /** The current file list. */
    private FilePanel filePanel = null;

    /**
     * The upload thread, that will wait for the next file packet to be ready,
     * then send it.
     */
    private FileUploadThread fileUploadThread = null;

    /**
     * Contains the system time of the start of the global upload. This is used
     * to calculate the ETA, and display it to the user, on the status bar.
     */
    private long globalStartTime = 0;

    /** @see UploadPolicy#getMaxChunkSize() */
    long maxChunkSize = -1;

    /** Contains the sum of the files, ready for upload, and not uploaded yet */
    private long nbBytesReadyForUpload = 0;

    /**
     * Number of files that has been read by the {@link FileUploadThread}
     * thread. These files have been read by the {@link #getNextPacket()}
     * method.
     */
    private int nbFilesBeingUploaded = 0;

    /** @see UploadPolicy#getNbFilesPerRequest() */
    int nbFilesPerRequest = -1;

    /**
     * Number of files that are prepared for upload. A file is prepared for
     * upload, if the {@link FileData#beforeUpload()} has been called.
     */
    private int nbPreparedFiles = 0;

    /**
     * Number of files that have already been sent. The control on the upload
     * success may be done or not. It's used to properly display the progress
     * bar.
     */
    private int nbSentFiles = 0;

    /**
     * Number of files that have been successfully uploaded. already been sent.
     * The control on the upload success may be done or not. It's used to
     * properly display the progress bar.
     */
    private int nbSuccessfullyUploadedFiles = 0;

    /**
     * Indicated the number of bytes that have currently been sent for the
     * current file. This allows the management of the progress bar.
     */
    private long nbBytesUploadedForCurrentFile = 0;

    /**
     * Sum of the length for all prepared files. This allow the calculation of
     * the estimatedTotalLength.
     * 
     * @see #anotherFileHasBeenSent(FileData)
     */
    private long nbTotalNumberOfPreparedBytes = 0;

    /**
     * During the upload, when uploading several files in one packet, this
     * attribute indicates which file is currently being uploaded.
     */
    private int numOfFileInCurrentRequest = 0;

    /**
     * Indicates what is the current file being uploaded, and its upload status.
     */
    private int uploadStatus = UPLOAD_STATUS_NOT_STARTED;

    /**
     * Contains the next packet to upload.
     * 
     * @see #getNextPacket()
     */
    private UploadFileData[] nextPacket = null;

    /**
     * The {@link JUploadPanel} progress bar, to follow the file preparation
     * progress.
     */
    private JProgressBar preparationProgressBar = null;

    /**
     * The {@link JUploadPanel} progress bar, to follow the upload of the
     * prepared files to the server.
     */
    private JProgressBar uploadProgressBar = null;

    /**
     * Indicates whether the upload is finished or not. Passed to true as soon
     * as one of these conditions becomes true: <DIR> <LI>All files are uploaded
     * (in the {@link #currentRequestIsFinished(UploadFileData[])} method) <LI>
     * An exception occurs (in the {@link #setUploadException(JUploadException)}
     * method) <LI>The user stops the upload (in the {@link #stopUpload()}
     * method) </DIR>
     */
    private boolean uploadFinished = false;

    /**
     * Contains the time of the actual start of upload. Doesn't take into
     * account the time for preparing files.
     */
    private long uploadStartTime = 0;

    /**
     * If set to 'true', the thread will stop the current upload. This attribute
     * is not private as the {@link UploadFileData} class us it.
     * 
     * @see UploadFileData#uploadFile(java.io.OutputStream, long)
     */
    private boolean stop = false;

    /** Thread Exception, if any occurred during upload. */
    private JUploadException uploadException = null;

    /**
     * Contains the sum of the upload duration for all requests. For instance,
     * if sending in 10 chunks one big file, the uploadDuration contains the sum
     * of the sending of these 10 request to the server. This allows to
     * calculate the true upload speed, and ignore the time we'll wait for the
     * server's response.
     */
    private long uploadDuration = 0;

    /** Current number of bytes that have been uploaded. */
    private long nbUploadedBytes = 0;

    /** A shortcut to the upload panel */
    private JUploadPanel uploadPanel = null;

    /** The current upload policy. */
    private UploadPolicy uploadPolicy = null;

    /** The list of files to upload */
    private UploadFileData[] uploadFileDataArray = null;

    // ////////////////////////////////////////////////////////////////////////////
    // To follow the upload speed.
    // ////////////////////////////////////////////////////////////////////////////

    /**
     * Used to update the status bar (upload speed, ETA...): 300ms make it
     * accurate, and avoid an always changing value.
     */
    private Timer timerStatusBar = new Timer(1000, this);

    /**
     * Used to update the progress: 50ms is nice, as it is fast enough, and
     * doesn't make CPU rise to 100%.
     */
    private Timer timerProgressBar = new Timer(50, this);

    /**
     * Standard constructor of the class.
     * 
     * @param uploadPolicy
     */
    public FileUploadManagerThread(UploadPolicy uploadPolicy) {
        super("FileUploadManagerThread thread");

        // General shortcuts on the current applet.
        this.uploadPolicy = uploadPolicy;
        this.uploadPanel = uploadPolicy.getApplet().getUploadPanel();
        this.filePanel = this.uploadPanel.getFilePanel();
        this.uploadProgressBar = this.uploadPanel.getUploadProgressBar();
        this.preparationProgressBar = this.uploadPanel
                .getPreparationProgressBar();

        // Let's start the upload thread. It will wait until the first
        // packet is ready.
        createUploadThread();

        // Let's store some upload parameters, to avoid querying all the time.
        this.nbFilesPerRequest = this.uploadPolicy.getNbFilesPerRequest();
        this.maxChunkSize = this.uploadPolicy.getMaxChunkSize();

        // Prepare the list of files to upload. We do this here, to minimize the
        // risk of concurrency, if the user drops or pastes files on the applet
        // while uploading.
        FileData[] fileDataArray = this.uploadPanel.getFilePanel().getFiles();
        this.uploadFileDataArray = new UploadFileData[fileDataArray.length];
        for (int i = 0; i < this.uploadFileDataArray.length; i += 1) {
            this.uploadFileDataArray[i] = new UploadFileData(fileDataArray[i],
                    this, this.uploadPolicy);
        }
    }

    /**
     * The heart of the program. This method prepare the upload, then calls
     * doUpload for each HTTP request.
     * 
     * @see java.lang.Thread#run()
     */
    @Override
    final public void run() {
        try {
            this.uploadPolicy.displayDebug(
                    "Start of the FileUploadManagerThread", 5);

            // Let's let the current upload policy have any preparation work
            this.uploadPolicy.beforeUpload();

            // The upload is started. Let's change the button state.
            this.uploadPanel.updateButtonState();

            // Let's prepare the progress bar, to display the current upload
            // stage.
            initProgressBar();

            // Create a timer, to update the status bar.
            this.timerProgressBar.start();
            this.timerStatusBar.start();
            this.uploadPolicy.displayDebug("Timer started", 50);

            // We have to prepare the files, then to create the upload thread
            // for
            // each file packet.
            prepareFiles();

            // The thread upload may need some information about the current
            // one, like ... knowing that upload is actually finished (no more
            // file to send).
            while (this.fileUploadThread != null
                    && this.fileUploadThread.isAlive()
                    && this.nbSuccessfullyUploadedFiles < this.uploadFileDataArray.length
                    && this.getUploadException() == null && !this.stop) {
                try {
                    this.uploadPolicy.displayDebug(
                            "Waiting for fileUploadThread to die", 10);
                    this.fileUploadThread.join();
                } catch (InterruptedException e) {
                    // This should not occur, and should not be a problem. Let's
                    // trace a warning info.
                    this.uploadPolicy
                            .displayWarn("An InterruptedException occured in FileUploadManagerThread.run()");
                }
            }

            // Let's restore the button state.
            this.uploadPanel.updateButtonState();
            this.uploadPolicy.getApplet().getAppletContext().showStatus("");
            this.uploadPolicy.getApplet().getUploadPanel().getStatusLabel()
                    .setText("");

            // If no error occurs, we tell to the upload policy that a
            // successful
            // upload has been done.

            if (getUploadException() == null) {
                this.uploadPolicy
                        .displayInfo("Upload finished normally. "
                                + this.uploadFileDataArray.length
                                + " file(s) uploaded in "
                                + (int) ((System.currentTimeMillis() - this.globalStartTime) / 1000)
                                + " seconds. Average upload speed: "
                                + (int) (this.nbUploadedBytes / this.uploadDuration)
                                + " (kbytes/s)");

                try {
                    this.uploadPolicy.afterUpload(this.getUploadException(),
                            this.fileUploadThread.getResponseMsg());
                } catch (JUploadException e1) {
                    this.uploadPolicy.displayErr(
                            "error in uploadPolicy.afterUpload (JUploadPanel)",
                            e1);
                }
            } else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -