diff --git a/source/org/jivesoftware/smackx/filetransfer/FileTransfer.java b/source/org/jivesoftware/smackx/filetransfer/FileTransfer.java index ac5eaebbb..a287d0ddc 100644 --- a/source/org/jivesoftware/smackx/filetransfer/FileTransfer.java +++ b/source/org/jivesoftware/smackx/filetransfer/FileTransfer.java @@ -28,9 +28,9 @@ import org.jivesoftware.smack.XMPPException; /** * Contains the generic file information and progress related to a particular * file transfer. - * + * * @author Alexander Wenckus - * + * */ public abstract class FileTransfer { @@ -44,6 +44,8 @@ public abstract class FileTransfer { private org.jivesoftware.smackx.filetransfer.FileTransfer.Status status; + private final Object statusMonitor = new Object(); + protected FileTransferNegotiator negotiator; protected String streamID; @@ -74,7 +76,7 @@ public abstract class FileTransfer { /** * Returns the size of the file being transfered. - * + * * @return Returns the size of the file being transfered. */ public long getFileSize() { @@ -83,7 +85,7 @@ public abstract class FileTransfer { /** * Returns the name of the file being transfered. - * + * * @return Returns the name of the file being transfered. */ public String getFileName() { @@ -92,7 +94,7 @@ public abstract class FileTransfer { /** * Returns the local path of the file. - * + * * @return Returns the local path of the file. */ public String getFilePath() { @@ -101,7 +103,7 @@ public abstract class FileTransfer { /** * Returns the JID of the peer for this file transfer. - * + * * @return Returns the JID of the peer for this file transfer. */ public String getPeer() { @@ -110,21 +112,21 @@ public abstract class FileTransfer { /** * Returns the progress of the file transfer as a number between 0 and 1. - * + * * @return Returns the progress of the file transfer as a number between 0 * and 1. */ public double getProgress() { - if(amountWritten == 0) { + if (amountWritten <= 0 || fileSize <= 0) { return 0; } - return amountWritten / fileSize; + return (double) amountWritten / (double) fileSize; } /** * Returns true if the transfer has been cancled, if it has stopped because * of a an error, or the transfer completed succesfully. - * + * * @return Returns true if the transfer has been cancled, if it has stopped * because of a an error, or the transfer completed succesfully. */ @@ -135,7 +137,7 @@ public abstract class FileTransfer { /** * Retuns the current status of the file transfer. - * + * * @return Retuns the current status of the file transfer. */ public Status getStatus() { @@ -150,7 +152,7 @@ public abstract class FileTransfer { * When {@link #getStatus()} returns that there was an {@link Status#ERROR} * during the transfer, the type of error can be retrieved through this * method. - * + * * @return Returns the type of error that occured if one has occured. */ public Error getError() { @@ -160,7 +162,7 @@ public abstract class FileTransfer { /** * If an exception occurs asynchronously it will be stored for later * retrival. If there is an error there maybe an exception set. - * + * * @return The exception that occured or null if there was no exception. * @see #getError() */ @@ -178,13 +180,25 @@ public abstract class FileTransfer { } protected final void setStatus(Status status) { - this.status = status; - } + synchronized (statusMonitor) { + this.status = status; + } + } + + protected final boolean updateStatus(Status oldStatus, Status newStatus) { + synchronized (statusMonitor) { + if (oldStatus != status) { + return false; + } + status = newStatus; + return true; + } + } protected void writeToStream(final InputStream in, final OutputStream out) throws XMPPException { final byte[] b = new byte[1000]; - int count = 0; + int count; amountWritten = 0; try { count = in.read(b); @@ -217,30 +231,37 @@ public abstract class FileTransfer { // equal if (!getStatus().equals(Status.CANCLED) && getError() == Error.NONE && amountWritten != fileSize) { + setStatus(Status.ERROR); this.error = Error.CONNECTION; } } /** * A class to represent the current status of the file transfer. - * + * * @author Alexander Wenckus - * + * */ public static class Status { + /** * An error occured during the transfer. - * + * * @see FileTransfer#getError() */ public static final Status ERROR = new Status(); /** + * The initial status of the file transfer. + */ + public static final Status INITIAL = new Status(); + + /** * The file transfer is being negotiated with the peer. The party * recieving the file has the option to accept or refuse a file transfer * request. If they accept, then the process of stream negotiation will * begin. If they refuse the file will not be transfered. - * + * * @see #NEGOTIATING_STREAM */ public static final Status NEGOTIATING_TRANSFER = new Status(); @@ -255,7 +276,7 @@ public abstract class FileTransfer { * The stream to transfer the file is being negotiated over the chosen * stream type. After the stream negotiating process is complete the * status becomes negotiated. - * + * * @see #NEGOTIATED */ public static final Status NEGOTIATING_STREAM = new Status(); @@ -269,7 +290,7 @@ public abstract class FileTransfer { /** * The transfer is in progress. - * + * * @see FileTransfer#getProgress() */ public static final Status IN_PROGRESS = new Status(); @@ -338,7 +359,7 @@ public abstract class FileTransfer { /** * Returns a String representation of this error. - * + * * @return Returns a String representation of this error. */ public String getMessage() { diff --git a/source/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java b/source/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java index 0774904a3..cc378edba 100644 --- a/source/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java +++ b/source/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java @@ -149,7 +149,7 @@ public class FileTransferNegotiator { * @param type The iq type of the packet. * @return The created IQ packet. */ - protected static IQ createIQ(final String ID, final String to, + public static IQ createIQ(final String ID, final String to, final String from, final IQ.Type type) { IQ iqPacket = new IQ() { public String getChildElementXML() { diff --git a/source/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java b/source/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java index d38e77e64..0897d5e83 100644 --- a/source/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java +++ b/source/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java @@ -19,23 +19,18 @@ */ package org.jivesoftware.smackx.filetransfer; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.XMPPError; +import java.io.*; + /** * Handles the sending of a file to another user. File transfer's in jabber have * several steps and there are several methods in this class that handle these * steps differently. - * + * * @author Alexander Wenckus - * + * */ public class OutgoingFileTransfer extends FileTransfer { @@ -44,7 +39,7 @@ public class OutgoingFileTransfer extends FileTransfer { /** * Returns the time in milliseconds after which the file transfer * negotiation process will timeout if the other user has not responded. - * + * * @return Returns the time in milliseconds after which the file transfer * negotiation process will timeout if the remote user has not * responded. @@ -56,7 +51,7 @@ public class OutgoingFileTransfer extends FileTransfer { /** * Sets the time in milliseconds after which the file transfer negotiation * process will timeout if the other user has not responded. - * + * * @param responseTimeout * The timeout time in milliseconds. */ @@ -86,7 +81,7 @@ public class OutgoingFileTransfer extends FileTransfer { * Returns the output stream connected to the peer to transfer the file. It * is only available after it has been succesfully negotiated by the * {@link StreamNegotiator}. - * + * * @return Returns the output stream connected to the peer to transfer the * file. */ @@ -101,7 +96,7 @@ public class OutgoingFileTransfer extends FileTransfer { /** * This method handles the negotiation of the file transfer and the stream, * it only returns the created stream after the negotiation has been completed. - * + * * @param fileName * The name of the file that will be transmitted. It is * preferable for this name to have an extension as it will be @@ -138,7 +133,7 @@ public class OutgoingFileTransfer extends FileTransfer { * {@link NegotiationProgress} callback. When the negotiation process is * complete the OutputStream can be retrieved from the callback via the * {@link NegotiationProgress#getOutputStream()} method. - * + * * @param fileName * The name of the file that will be transmitted. It is * preferable for this name to have an extension as it will be @@ -186,13 +181,13 @@ public class OutgoingFileTransfer extends FileTransfer { * This method handles the stream negotiation process and transmits the file * to the remote user. It returns immediatly and the progress of the file * transfer can be monitored through several methods: - * + * *