mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2025-09-11 03:09:46 +02:00
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@8335 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
c46b6f2d08
commit
51272c823d
13 changed files with 3598 additions and 0 deletions
|
@ -0,0 +1,219 @@
|
|||
/**
|
||||
* $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.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* An incoming file transfer is created when the
|
||||
* {@link FileTransferManager#createIncomingFileTransfer(FileTransferRequest)}
|
||||
* method is invoked. It is a file being sent to the local user from another
|
||||
* user on the jabber network. There are two stages of the file transfer to be
|
||||
* concerned with and they can be handled in different ways depending upon the
|
||||
* method that is invoked on this class.
|
||||
* <p/>
|
||||
* The first way that a file is recieved is by calling the
|
||||
* {@link #recieveFile()} method. This method, negotiates the appropriate stream
|
||||
* method and then returns the <b><i>InputStream</b></i> to read the file
|
||||
* data from.
|
||||
* <p/>
|
||||
* The second way that a file can be recieved through this class is by invoking
|
||||
* the {@link #recieveFile(File)} method. This method returns immediatly and
|
||||
* takes as its parameter a file on the local file system where the file
|
||||
* recieved from the transfer will be put.
|
||||
*
|
||||
* @author Alexander Wenckus
|
||||
*/
|
||||
public class IncomingFileTransfer extends FileTransfer {
|
||||
|
||||
private FileTransferRequest recieveRequest;
|
||||
|
||||
private InputStream inputStream;
|
||||
|
||||
protected IncomingFileTransfer(FileTransferRequest request,
|
||||
FileTransferNegotiator transferNegotiator) {
|
||||
super(request.getRequestor(), request.getStreamID(), transferNegotiator);
|
||||
this.recieveRequest = request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Negotiates the stream method to transfer the file over and then returns
|
||||
* the negotiated stream.
|
||||
*
|
||||
* @return The negotiated InputStream from which to read the data.
|
||||
* @throws XMPPException If there is an error in the negotiation process an exception
|
||||
* is thrown.
|
||||
*/
|
||||
public InputStream recieveFile() throws XMPPException {
|
||||
if (inputStream != null) {
|
||||
throw new IllegalStateException("Transfer already negotiated!");
|
||||
}
|
||||
|
||||
try {
|
||||
inputStream = negotiateStream();
|
||||
}
|
||||
catch (XMPPException e) {
|
||||
setException(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method negotitates the stream and then transfer's the file over the
|
||||
* negotiated stream. The transfered file will be saved at the provided
|
||||
* location.
|
||||
* <p/>
|
||||
* This method will return immedialtly, file transfer progress can be
|
||||
* monitored through several methods:
|
||||
* <p/>
|
||||
* <UL>
|
||||
* <LI>{@link FileTransfer#getStatus()}
|
||||
* <LI>{@link FileTransfer#getProgress()}
|
||||
* <LI>{@link FileTransfer#isDone()}
|
||||
* </UL>
|
||||
*
|
||||
* @param file The location to save the file.
|
||||
* @throws XMPPException when the file transfer fails
|
||||
* @throws IllegalArgumentException This exception is thrown when the the provided file is
|
||||
* either null, or cannot be written to.
|
||||
*/
|
||||
public void recieveFile(final File file) throws XMPPException {
|
||||
if (file != null) {
|
||||
if (!file.exists()) {
|
||||
try {
|
||||
file.createNewFile();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new XMPPException(
|
||||
"Could not create file to write too", e);
|
||||
}
|
||||
}
|
||||
if (!file.canWrite()) {
|
||||
throw new IllegalArgumentException("Cannot write to provided file");
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("File cannot be null");
|
||||
}
|
||||
|
||||
Thread transferThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
inputStream = negotiateStream();
|
||||
}
|
||||
catch (XMPPException e) {
|
||||
handleXMPPException(e);
|
||||
return;
|
||||
}
|
||||
|
||||
OutputStream outputStream = null;
|
||||
try {
|
||||
outputStream = new FileOutputStream(file);
|
||||
setStatus(Status.in_progress);
|
||||
writeToStream(inputStream, outputStream);
|
||||
}
|
||||
catch (XMPPException e) {
|
||||
setStatus(Status.error);
|
||||
setError(Error.stream);
|
||||
setException(e);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
setStatus(Status.error);
|
||||
setError(Error.bad_file);
|
||||
setException(e);
|
||||
}
|
||||
|
||||
if (getStatus().equals(Status.in_progress)) {
|
||||
setStatus(Status.complete);
|
||||
}
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
}
|
||||
catch (Throwable io) {
|
||||
/* Ignore */
|
||||
}
|
||||
}
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
}
|
||||
catch (Throwable io) {
|
||||
/* Ignore */
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "File Transfer " + streamID);
|
||||
transferThread.start();
|
||||
}
|
||||
|
||||
private void handleXMPPException(XMPPException e) {
|
||||
setStatus(FileTransfer.Status.error);
|
||||
setException(e);
|
||||
}
|
||||
|
||||
private InputStream negotiateStream() throws XMPPException {
|
||||
setStatus(Status.negotiating_transfer);
|
||||
final StreamNegotiator streamNegotiator = negotiator
|
||||
.selectStreamNegotiator(recieveRequest);
|
||||
setStatus(Status.negotiating_stream);
|
||||
FutureTask<InputStream> streamNegotiatorTask = new FutureTask<InputStream>(
|
||||
new Callable<InputStream>() {
|
||||
|
||||
public InputStream call() throws Exception {
|
||||
System.out.println(new java.util.Date().toString() + ": IncomingFileTransfer>negotiateStream:186");
|
||||
return streamNegotiator
|
||||
.createIncomingStream(recieveRequest.getStreamInitiation());
|
||||
}
|
||||
});
|
||||
streamNegotiatorTask.run();
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
System.out.println(new java.util.Date().toString() + ": IncomingFileTransfer>negotiateStream:194");
|
||||
inputStream = streamNegotiatorTask.get(15, TimeUnit.SECONDS);
|
||||
System.out.println(new java.util.Date().toString() + ": IncomingFileTransfer>negotiateStream:196");
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
// throw new XMPPException("Interruption while executing", e);
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
System.out.println(new java.util.Date().toString() + ": IncomingFileTransfer>negotiateStream:202 Error in execution");
|
||||
// throw new XMPPException("Error in execution", e);
|
||||
}
|
||||
catch (TimeoutException e) {
|
||||
// throw new XMPPException("Request timed out", e);
|
||||
}
|
||||
finally {
|
||||
streamNegotiatorTask.cancel(true);
|
||||
}
|
||||
setStatus(Status.negotiated);
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
setStatus(Status.cancelled);
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue