📄 fileuploadmanagerthread.java
字号:
// We'll add the files, up to :
// 1) The number of new files prepared and not uploaded (or being
// uploaded by another upload thread),
// 2) The number of files per request is no more than the
// nbFilesPerRequest applet parameter.
// 3) The total length of files in the packet may be more than the
// maxChunkSize applet parameter.
while (!isPacketFinished && nbFilesInPacket < maxPacketSize
&& packetLength < this.maxChunkSize) {
// We're working on this file:
currentFileData = this.uploadFileDataArray[this.nbSentFiles
+ this.nbFilesBeingUploaded + nbFilesInPacket];
if (nbFilesInPacket > 0
&& packetLength + currentFileData.getUploadLength() > this.maxChunkSize) {
// We can't add this file: the file size would be bigger
// than maxChunkSize. So this packet is ready.
isPacketFinished = true;
} else {
// Let's add this file.
tempFileData[nbFilesInPacket] = currentFileData;
packetLength += currentFileData.getUploadLength();
nbFilesInPacket += 1;
}
}
// We've extracted some files into the tempFileData array. The
// question is: is this packet full ?
if (!isPacketFinished) {
if (packetLength > this.maxChunkSize) {
// The packet can't contain more bytes!
if (nbFilesInPacket > 1) {
throw new JUploadException(
"totalContentLength >= chunkSize: this.filesToUpload.length should not be more than 1 (checkIfNextPacketIsReady)");
}
isPacketFinished = true;
} else if (nbFilesInPacket == this.nbFilesPerRequest) {
// The packet can't contain more files!
isPacketFinished = true;
} else if (this.nbSentFiles + this.nbFilesBeingUploaded
+ nbFilesInPacket == this.uploadFileDataArray.length) {
// We're up to the last file.
isPacketFinished = true;
}
}
if (isPacketFinished) {
// The packet is full. Let's copy the temp data to the next
// packet data.
this.nextPacket = new UploadFileData[nbFilesInPacket];
System.arraycopy(tempFileData, 0, this.nextPacket, 0,
nbFilesInPacket);
}
}
return this.nextPacket != null;
}
/**
* This method is called each time a new file is ready to upload. It
* calculates if a new packet of files is ready to upload. It is private, as
* it may be called only from this class.
*
* @throws JUploadException
*/
private synchronized void anotherFileIsReady(FileData newlyPreparedFileData)
throws JUploadException {
this.nbPreparedFiles += 1;
this.nbBytesReadyForUpload += newlyPreparedFileData.getUploadLength();
this.nbTotalNumberOfPreparedBytes += newlyPreparedFileData
.getUploadLength();
}
/**
* This method is called each time a new file is sent to the server. It's
* main aim is to allow a proper display of the progress bar. It is public,
* as upload is done in another thread, whose class maybe in another
* package.
*
* @param newlyUploadedFileData
* @throws JUploadException
*/
public synchronized void anotherFileHasBeenSent(
FileData newlyUploadedFileData) throws JUploadException {
this.nbSentFiles += 1;
this.nbFilesBeingUploaded -= 1;
this.nbBytesUploadedForCurrentFile = 0;
this.nbBytesReadyForUpload -= newlyUploadedFileData.getUploadLength();
// We are finished with this one. Let's display it.
this.uploadStatus = UPLOAD_STATUS_UPLOADED;
updateUploadProgressBar();
}
/**
* This method is called when the server response for the upload indicates a
* success. It is public, as upload is done in another thread, whose class
* maybe in another package.
*
* @param currentPacket The packet of files that was successfully uploaded.
* @throws JUploadException
*/
public synchronized void currentRequestIsFinished(
UploadFileData[] currentPacket) throws JUploadException {
// If no error occurs, we're happy ! (that's a useful comment...)
if (this.getUploadException() == null) {
// We should now remove this file from the list of files to upload,
// to show the user that there is less and less work to do.
for (int i = 0; i < currentPacket.length; i += 1) {
this.filePanel.remove(currentPacket[i]);
this.nbSuccessfullyUploadedFiles += 1;
}
// If all files have been sent, the upload is finished.
if (!this.uploadFinished) {
this.uploadFinished = (this.nbSuccessfullyUploadedFiles == this.uploadFileDataArray.length);
}
} else {
// Hum, we're not happy! We stop here.
this.uploadFinished = true;
// Nothing else to do: the error is already displayed to the user.
}
}
/**
* Returns the next packet of files, for upload, according to the current
* upload policy.
*
* @return The array of files to upload.
* @throws JUploadException
*/
public synchronized UploadFileData[] getNextPacket()
throws JUploadException {
// If the upload is finished, we stop here.
if (isUploadFinished()) {
return null;
}
// If no packet was ready before, perhaps one is ready now ?
if (this.nextPacket == null) {
checkIfNextPacketIsReady();
}
// If the next packet is ready, let's manage it.
if (this.nextPacket == null || isUploadFinished()) {
return null;
} else {
// If it's the first packet, we noted the current time as the upload
// start time.
if (this.nbSentFiles == 0 && this.uploadStartTime == 0) {
this.uploadStartTime = System.currentTimeMillis();
}
UploadFileData[] fileDataTmp = this.nextPacket;
this.nextPacket = null;
this.nbFilesBeingUploaded += fileDataTmp.length;
return fileDataTmp;
}
}
/**
* Update the progress bar, based on the following data: <DIR> <LI>
* nbSentFiles: number of files that have already been updated. <LI>
* nbBytesUploadedForCurrentFile: allows calculation of the upload progress
* for the current file, based on it total upload length. </DIR> <BR>
* Note: The progress bar update is ignored, if last update was less than
* 100ms before.
*
* @throws JUploadException
*/
private synchronized void updateUploadProgressBar() {
final String msgInfoUploaded = this.uploadPolicy
.getString("infoUploaded");
final String msgInfoUploading = this.uploadPolicy
.getString("infoUploading");
final String msgNbUploadedFiles = this.uploadPolicy
.getString("nbUploadedFiles");
int percent = 0;
// First, we update the bar itself.
if (this.nbBytesUploadedForCurrentFile == 0
|| this.nbSentFiles == this.uploadFileDataArray.length) {
percent = 0;
} else {
try {
percent = (int) (this.nbBytesUploadedForCurrentFile * 100 / this.uploadFileDataArray[this.nbSentFiles]
.getUploadLength());
} catch (JUploadException e) {
this.uploadPolicy.displayWarn(e.getClass().getName()
+ " in updateUploadProgressBar (" + e.getMessage()
+ "). percent forced to 0.");
percent = 0;
}
// Usually, a percentage if advancement for one file is no more than
// 100. Let's check that.
if (percent > 100) {
this.uploadPolicy
.displayWarn("percent is more than 100 ("
+ percent
+ ") in FileUploadManagerThread.update.UploadProgressBar");
percent = 100;
}
}
this.uploadProgressBar.setValue(100 * this.nbSentFiles + percent);
String msg = null;
switch (this.uploadStatus) {
case UPLOAD_STATUS_NOT_STARTED:
msg = "";
break;
case UPLOAD_STATUS_UPLOADING:
// Uploading files %1$s
msg = String.format(msgInfoUploading, (this.nbSentFiles + 1));
break;
case UPLOAD_STATUS_UPLOADED_WAITING_FOR_RESPONSE:
// %1$s file(s) uploaded. Waiting for server response ...
if (this.numOfFileInCurrentRequest == 1) {
msg = (this.nbSentFiles) + "/"
+ (this.uploadFileDataArray.length);
} else {
msg = (this.nbSentFiles - this.numOfFileInCurrentRequest + 1)
+ "-"
+ (this.nbSentFiles)
+ "/"
+ (this.uploadFileDataArray.length);
}
msg = String.format(msgInfoUploaded, msg);
break;
case UPLOAD_STATUS_UPLOADED:
// %1$d file(s) uploaded
msg = String.format(msgNbUploadedFiles, (this.nbSentFiles));
break;
default:
// Hum, that's strange !
this.uploadPolicy
.displayWarn("Unknown upload status in FileUploadManagerThread.updateProgressBar(): "
+ this.uploadStatus);
}
// Let's show the modifications to the user
this.uploadProgressBar.setString(msg);
this.uploadProgressBar.repaint(0);
}
// //////////////////////////////////////////////////////////////////////////////////////////////
// /////////////////// PRIVATE METHODS
// //////////////////////////////////////////////////////////////////////////////////////////////
/**
* This method is called by the {@link #run()} method, to prepare all files.
* It's executed in the current thread, while upload is executed in the
* another thread, by {@link FileUploadThread}.
*/
private void prepareFiles() {
this.preparationProgressBar
.setMaximum(100 * this.uploadFileDataArray.length);
try {
// We loop through all files, and check before each if we should
// stop (for instance if an error occurs)
for (int i = 0; i < this.uploadFileDataArray.length
&& !isUploadFinished(); i += 1) {
this.uploadPolicy.displayDebug(
"============== Start of file preparation ("
+ this.uploadFileDataArray[i].getFileName()
+ ")", 30);
// Let's indicate to the user what's running on.
this.preparationProgressBar.setString(String.format(
this.uploadPolicy.getString("preparingFile"),
new Integer(i + 1), new Integer(
this.uploadFileDataArray.length)));
this.preparationProgressBar.repaint(100);
// Then, we work
this.uploadFileDataArray[i].beforeUpload();
this.uploadPolicy.displayDebug(
"============== End of file preparation ("
+ this.uploadFileDataArray[i].getFileName()
+ ")", 30);
anotherFileIsReady(this.uploadFileDataArray[i]);
// The file preparation is finished. Let's update the progress
// bar.
this.preparationProgressBar
.setValue(this.nbPreparedFiles * 100);
this.preparationProgressBar.repaint();
}
} catch (JUploadException e) {
setUploadException(e);
stopUpload();
}
}
/**
* Creates and starts the upload thread. It will wait until the first packet
* is ready.
*/
private void createUploadThread() {
try {
if (this.uploadPolicy.getPostURL().substring(0, 4).equals("ftp:")) {
this.fileUploadThread = new FileUploadThreadFTP(
this.uploadPolicy, this);
} else {
this.fileUploadThread = new FileUploadThreadHTTP(
this.uploadPolicy, this);
}
} catch (JUploadException e1) {
// Too bad !
this.uploadPolicy.displayErr(e1);
}
this.fileUploadThread.start();
}
/**
* Initialize the maximum value for the two progress bar: 100*the number of
* files to upload.
*
* @throws JUploadException
*
* @see #updateUploadProgressBar()
*/
private synchronized void initProgressBar() throws JUploadException {
// To follow the state of file preparation
this.preparationProgressBar
.setMaximum(100 * this.uploadFileDataArray.length);
this.preparationProgressBar.setString("");
// To follow the state of the actual upload
this.uploadProgressBar
.setMaximum(100 * this.uploadFileDataArray.length);
this.uploadProgressBar.setString("");
this.updateUploadProgressBar();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -