Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java')
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java353
1 files changed, 353 insertions, 0 deletions
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java
new file mode 100644
index 000000000..c58d44736
--- /dev/null
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java
@@ -0,0 +1,353 @@
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2006 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.filetransfer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+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 {
+
+ private String fileName;
+
+ private String filePath;
+
+ private long fileSize;
+
+ private String peer;
+
+ private org.jivesoftware.smackx.filetransfer.FileTransfer.Status status;
+
+ protected FileTransferNegotiator negotiator;
+
+ protected String streamID;
+
+ protected long amountWritten = -1;
+
+ private Error error;
+
+ private Exception exception;
+
+ protected FileTransfer(String peer, String streamID,
+ FileTransferNegotiator negotiator) {
+ this.peer = peer;
+ this.streamID = streamID;
+ this.negotiator = negotiator;
+ }
+
+ protected void setFileInfo(String fileName, long fileSize) {
+ this.fileName = fileName;
+ this.fileSize = fileSize;
+ }
+
+ protected void setFileInfo(String path, String fileName, long fileSize) {
+ this.filePath = path;
+ this.fileName = fileName;
+ this.fileSize = fileSize;
+ }
+
+ /**
+ * Returns the size of the file being transfered.
+ *
+ * @return Returns the size of the file being transfered.
+ */
+ public long getFileSize() {
+ return fileSize;
+ }
+
+ /**
+ * Returns the name of the file being transfered.
+ *
+ * @return Returns the name of the file being transfered.
+ */
+ public String getFileName() {
+ return fileName;
+ }
+
+ /**
+ * Returns the local path of the file.
+ *
+ * @return Returns the local path of the file.
+ */
+ public String getFilePath() {
+ return filePath;
+ }
+
+ /**
+ * Returns the JID of the peer for this file transfer.
+ *
+ * @return Returns the JID of the peer for this file transfer.
+ */
+ public String getPeer() {
+ return peer;
+ }
+
+ /**
+ * 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) {
+ return 0;
+ }
+ return amountWritten / 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.
+ */
+ public boolean isDone() {
+ return status == Status.CANCLED || status == Status.ERROR
+ || status == Status.COMPLETE;
+ }
+
+ /**
+ * Retuns the current status of the file transfer.
+ *
+ * @return Retuns the current status of the file transfer.
+ */
+ public Status getStatus() {
+ return status;
+ }
+
+ protected void setError(Error type) {
+ this.error = type;
+ }
+
+ /**
+ * 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() {
+ return error;
+ }
+
+ /**
+ * 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()
+ */
+ public Exception getException() {
+ return exception;
+ }
+
+ /**
+ * Cancels the file transfer.
+ */
+ public abstract void cancel();
+
+ protected void setException(Exception exception) {
+ this.exception = exception;
+ }
+
+ protected final void setStatus(Status status) {
+ this.status = status;
+ }
+
+ protected void writeToStream(final InputStream in, final OutputStream out)
+ throws XMPPException {
+ final byte[] b = new byte[1000];
+ int count = 0;
+ amountWritten = 0;
+ try {
+ count = in.read(b);
+ } catch (IOException e) {
+ throw new XMPPException("error reading from input stream", e);
+ }
+ while (count != -1 && !getStatus().equals(Status.CANCLED)) {
+ if (getStatus().equals(Status.CANCLED)) {
+ return;
+ }
+
+ // write to the output stream
+ try {
+ out.write(b, 0, count);
+ } catch (IOException e) {
+ throw new XMPPException("error writing to output stream", e);
+ }
+
+ amountWritten += count;
+
+ // read more bytes from the input stream
+ try {
+ count = in.read(b);
+ } catch (IOException e) {
+ throw new XMPPException("error reading from input stream", e);
+ }
+ }
+
+ // the connection was likely terminated abrubtly if these are not
+ // equal
+ if (!getStatus().equals(Status.CANCLED) && getError() == Error.NONE
+ && amountWritten != fileSize) {
+ 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 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();
+
+ /**
+ * The peer has refused the file transfer request halting the file
+ * transfer negotiation process.
+ */
+ public static final Status REFUSED = new Status();
+
+ /**
+ * 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();
+
+ /**
+ * After the stream negotitation has completed the intermediate state
+ * between the time when the negotiation is finished and the actual
+ * transfer begins.
+ */
+ public static final Status NEGOTIATED = new Status();
+
+ /**
+ * The transfer is in progress.
+ *
+ * @see FileTransfer#getProgress()
+ */
+ public static final Status IN_PROGRESS = new Status();
+
+ /**
+ * The transfer has completed successfully.
+ */
+ public static final Status COMPLETE = new Status();
+
+ /**
+ * The file transfer was canceled
+ */
+ public static final Status CANCLED = new Status();
+ }
+
+ /**
+ * Return the length of bytes written out to the stream.
+ * @return the amount in bytes written out.
+ */
+ public long getAmountWritten(){
+ return amountWritten;
+ }
+
+ public static class Error {
+ /**
+ * No error
+ */
+ public static final Error NONE = new Error("No error");
+
+ /**
+ * The peer did not find any of the provided stream mechanisms
+ * acceptable.
+ */
+ public static final Error NOT_ACCEPTABLE = new Error(
+ "The peer did not find any of the provided stream mechanisms acceptable.");
+
+ /**
+ * The provided file to transfer does not exist or could not be read.
+ */
+ public static final Error BAD_FILE = new Error(
+ "The provided file to transfer does not exist or could not be read.");
+
+ /**
+ * The remote user did not respond or the connection timed out.
+ */
+ public static final Error NO_RESPONSE = new Error(
+ "The remote user did not respond or the connection timed out.");
+
+ /**
+ * An error occured over the socket connected to send the file.
+ */
+ public static final Error CONNECTION = new Error(
+ "An error occured over the socket connected to send the file.");
+
+ /**
+ * An error occured while sending or recieving the file
+ */
+ protected static final Error STREAM = new Error(
+ "An error occured while sending or recieving the file");
+
+ private final String msg;
+
+ private Error(String msg) {
+ this.msg = msg;
+ }
+
+ /**
+ * Returns a String representation of this error.
+ *
+ * @return Returns a String representation of this error.
+ */
+ public String getMessage() {
+ return msg;
+ }
+
+ public String toString() {
+ return msg;
+ }
+ }
+
+}

Back to the top