aboutsummaryrefslogtreecommitdiff
path: root/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java
diff options
context:
space:
mode:
authorShuyi Chen <shuyichen@google.com>2013-05-22 14:51:55 -0700
committerShuyi Chen <shuyichen@google.com>2013-05-22 17:19:30 -0700
commitd7955ce24d294fb2014c59d11fca184471056f44 (patch)
treee260500b0b7639127038495d46a0ad6dcbb6d96c /src/org/jivesoftware/smackx/filetransfer/FileTransfer.java
parent8f4ce9ea0de51fee918bffe19c434612d6bbb2d7 (diff)
downloadsmack-5dc06320c2974c5e17d0770ccc54a1ccd13fc967.tar.gz
Add android smack source.HEADandroid-wear-5.0.0_r1android-sdk-4.4.2_r1.0.1android-sdk-4.4.2_r1android-l-preview_r2android-cts-5.1_r9android-cts-5.1_r8android-cts-5.1_r7android-cts-5.1_r6android-cts-5.1_r5android-cts-5.1_r4android-cts-5.1_r3android-cts-5.1_r28android-cts-5.1_r27android-cts-5.1_r26android-cts-5.1_r25android-cts-5.1_r24android-cts-5.1_r23android-cts-5.1_r22android-cts-5.1_r21android-cts-5.1_r20android-cts-5.1_r2android-cts-5.1_r19android-cts-5.1_r18android-cts-5.1_r17android-cts-5.1_r16android-cts-5.1_r15android-cts-5.1_r14android-cts-5.1_r13android-cts-5.1_r10android-cts-5.1_r1android-cts-5.0_r9android-cts-5.0_r8android-cts-5.0_r7android-cts-5.0_r6android-cts-5.0_r5android-cts-5.0_r4android-cts-5.0_r3android-cts-4.4_r4android-cts-4.4_r1android-5.1.1_r9android-5.1.1_r8android-5.1.1_r7android-5.1.1_r6android-5.1.1_r5android-5.1.1_r4android-5.1.1_r38android-5.1.1_r37android-5.1.1_r36android-5.1.1_r35android-5.1.1_r34android-5.1.1_r33android-5.1.1_r30android-5.1.1_r3android-5.1.1_r29android-5.1.1_r28android-5.1.1_r26android-5.1.1_r25android-5.1.1_r24android-5.1.1_r23android-5.1.1_r22android-5.1.1_r20android-5.1.1_r2android-5.1.1_r19android-5.1.1_r18android-5.1.1_r17android-5.1.1_r16android-5.1.1_r15android-5.1.1_r14android-5.1.1_r13android-5.1.1_r12android-5.1.1_r10android-5.1.1_r1android-5.1.0_r5android-5.1.0_r4android-5.1.0_r3android-5.1.0_r1android-5.0.2_r3android-5.0.2_r1android-5.0.1_r1android-5.0.0_r7android-5.0.0_r6android-5.0.0_r5.1android-5.0.0_r5android-5.0.0_r4android-5.0.0_r3android-5.0.0_r2android-5.0.0_r1android-4.4w_r1android-4.4_r1.2.0.1android-4.4_r1.2android-4.4_r1.1.0.1android-4.4_r1.1android-4.4_r1.0.1android-4.4_r1android-4.4_r0.9android-4.4_r0.8android-4.4_r0.7android-4.4.4_r2.0.1android-4.4.4_r2android-4.4.4_r1.0.1android-4.4.4_r1android-4.4.3_r1.1.0.1android-4.4.3_r1.1android-4.4.3_r1.0.1android-4.4.3_r1android-4.4.2_r2.0.1android-4.4.2_r2android-4.4.2_r1.0.1android-4.4.2_r1android-4.4.1_r1.0.1android-4.4.1_r1android-4.3_r3.1android-4.3_r3android-4.3_r2.3android-4.3_r2.2android-4.3_r2.1android-4.3_r2android-4.3_r1.1android-4.3_r1android-4.3_r0.9.1android-4.3_r0.9android-4.3.1_r1tools_r22.2mastermainlollipop-wear-releaselollipop-releaselollipop-mr1-wfc-releaselollipop-mr1-releaselollipop-mr1-fi-releaselollipop-mr1-devlollipop-mr1-cts-releaselollipop-devlollipop-cts-releasel-previewkitkat-wearkitkat-releasekitkat-mr2.2-releasekitkat-mr2.1-releasekitkat-mr2-releasekitkat-mr1.1-releasekitkat-mr1-releasekitkat-devkitkat-cts-releasekitkat-cts-devjb-mr2.0.0-releasejb-mr2.0-releasejb-mr2-releasejb-mr2-devidea133-weekly-releaseidea133
Change-Id: I49ce97136c17173c4ae3965c694af6e7bc49897d
Diffstat (limited to 'src/org/jivesoftware/smackx/filetransfer/FileTransfer.java')
-rw-r--r--src/org/jivesoftware/smackx/filetransfer/FileTransfer.java380
1 files changed, 380 insertions, 0 deletions
diff --git a/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java b/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java
new file mode 100644
index 0000000..b840fd5
--- /dev/null
+++ b/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java
@@ -0,0 +1,380 @@
+/**
+ * $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 org.jivesoftware.smack.XMPPException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * 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 Status status = Status.initial;
+
+ private final Object statusMonitor = new Object();
+
+ protected FileTransferNegotiator negotiator;
+
+ protected String streamID;
+
+ protected long amountWritten = -1;
+
+ private Error error;
+
+ private Exception exception;
+
+ /**
+ * Buffer size between input and output
+ */
+ private static final int BUFFER_SIZE = 8192;
+
+ 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 || fileSize <= 0) {
+ return 0;
+ }
+ return (double) amountWritten / (double) fileSize;
+ }
+
+ /**
+ * Returns true if the transfer has been cancelled, if it has stopped because
+ * of a an error, or the transfer completed successfully.
+ *
+ * @return Returns true if the transfer has been cancelled, if it has stopped
+ * because of a an error, or the transfer completed successfully.
+ */
+ public boolean isDone() {
+ return status == Status.cancelled || status == Status.error
+ || status == Status.complete || status == Status.refused;
+ }
+
+ /**
+ * Returns the current status of the file transfer.
+ *
+ * @return Returns 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 occurred if one has occurred.
+ */
+ public Error getError() {
+ return error;
+ }
+
+ /**
+ * If an exception occurs asynchronously it will be stored for later
+ * retrieval. If there is an error there maybe an exception set.
+ *
+ * @return The exception that occurred or null if there was no exception.
+ * @see #getError()
+ */
+ public Exception getException() {
+ return exception;
+ }
+
+ public String getStreamID() {
+ return streamID;
+ }
+
+ /**
+ * Cancels the file transfer.
+ */
+ public abstract void cancel();
+
+ protected void setException(Exception exception) {
+ this.exception = exception;
+ }
+
+ protected void setStatus(Status status) {
+ synchronized (statusMonitor) {
+ this.status = status;
+ }
+ }
+
+ protected 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[BUFFER_SIZE];
+ int count = 0;
+ amountWritten = 0;
+
+ do {
+ // 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);
+ }
+ } while (count != -1 && !getStatus().equals(Status.cancelled));
+
+ // the connection was likely terminated abrubtly if these are not equal
+ if (!getStatus().equals(Status.cancelled) && 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 enum Status {
+
+ /**
+ * An error occurred during the transfer.
+ *
+ * @see FileTransfer#getError()
+ */
+ error("Error"),
+
+ /**
+ * The initial status of the file transfer.
+ */
+ initial("Initial"),
+
+ /**
+ * The file transfer is being negotiated with the peer. The party
+ * Receiving 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
+ */
+ negotiating_transfer("Negotiating Transfer"),
+
+ /**
+ * The peer has refused the file transfer request halting the file
+ * transfer negotiation process.
+ */
+ refused("Refused"),
+
+ /**
+ * 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
+ */
+ negotiating_stream("Negotiating Stream"),
+
+ /**
+ * After the stream negotiation has completed the intermediate state
+ * between the time when the negotiation is finished and the actual
+ * transfer begins.
+ */
+ negotiated("Negotiated"),
+
+ /**
+ * The transfer is in progress.
+ *
+ * @see FileTransfer#getProgress()
+ */
+ in_progress("In Progress"),
+
+ /**
+ * The transfer has completed successfully.
+ */
+ complete("Complete"),
+
+ /**
+ * The file transfer was cancelled
+ */
+ cancelled("Cancelled");
+
+ private String status;
+
+ private Status(String status) {
+ this.status = status;
+ }
+
+ public String toString() {
+ return status;
+ }
+ }
+
+ /**
+ * Return the length of bytes written out to the stream.
+ * @return the amount in bytes written out.
+ */
+ public long getAmountWritten(){
+ return amountWritten;
+ }
+
+ public enum Error {
+ /**
+ * No error
+ */
+ none("No error"),
+
+ /**
+ * The peer did not find any of the provided stream mechanisms
+ * acceptable.
+ */
+ not_acceptable("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.
+ */
+ bad_file("The provided file to transfer does not exist or could not be read."),
+
+ /**
+ * The remote user did not respond or the connection timed out.
+ */
+ no_response("The remote user did not respond or the connection timed out."),
+
+ /**
+ * An error occurred over the socket connected to send the file.
+ */
+ connection("An error occured over the socket connected to send the file."),
+
+ /**
+ * An error occurred while sending or receiving the file
+ */
+ stream("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;
+ }
+ }
+
+}