2006-02-03 19:44:22 +01:00
|
|
|
/**
|
2006-02-03 20:13:23 +01:00
|
|
|
* $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.
|
2006-02-03 19:44:22 +01:00
|
|
|
*/
|
|
|
|
package org.jivesoftware.smackx.filetransfer;
|
|
|
|
|
|
|
|
import org.jivesoftware.smack.PacketListener;
|
2010-02-09 12:55:56 +01:00
|
|
|
import org.jivesoftware.smack.Connection;
|
2006-02-03 19:44:22 +01:00
|
|
|
import org.jivesoftware.smack.filter.AndFilter;
|
|
|
|
import org.jivesoftware.smack.filter.IQTypeFilter;
|
|
|
|
import org.jivesoftware.smack.filter.PacketTypeFilter;
|
|
|
|
import org.jivesoftware.smack.packet.IQ;
|
|
|
|
import org.jivesoftware.smack.packet.Packet;
|
|
|
|
import org.jivesoftware.smack.packet.XMPPError;
|
|
|
|
import org.jivesoftware.smackx.packet.StreamInitiation;
|
|
|
|
|
2008-06-19 20:06:32 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
|
2006-02-03 19:44:22 +01:00
|
|
|
/**
|
|
|
|
* The file transfer manager class handles the sending and recieving of files.
|
|
|
|
* To send a file invoke the {@link #createOutgoingFileTransfer(String)} method.
|
|
|
|
* <p>
|
|
|
|
* And to recieve a file add a file transfer listener to the manager. The
|
|
|
|
* listener will notify you when there is a new file transfer request. To create
|
|
|
|
* the {@link IncomingFileTransfer} object accept the transfer, or, if the
|
|
|
|
* transfer is not desirable reject it.
|
|
|
|
*
|
|
|
|
* @author Alexander Wenckus
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public class FileTransferManager {
|
|
|
|
|
|
|
|
private final FileTransferNegotiator fileTransferNegotiator;
|
|
|
|
|
2009-06-04 13:58:25 +02:00
|
|
|
private List<FileTransferListener> listeners;
|
2006-02-03 19:44:22 +01:00
|
|
|
|
2010-02-09 12:55:56 +01:00
|
|
|
private Connection connection;
|
2006-02-03 19:44:22 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a file transfer manager to initiate and receive file transfers.
|
|
|
|
*
|
|
|
|
* @param connection
|
2010-02-09 12:55:56 +01:00
|
|
|
* The Connection that the file transfers will use.
|
2006-02-03 19:44:22 +01:00
|
|
|
*/
|
2010-02-09 12:55:56 +01:00
|
|
|
public FileTransferManager(Connection connection) {
|
2006-02-03 19:44:22 +01:00
|
|
|
this.connection = connection;
|
|
|
|
this.fileTransferNegotiator = FileTransferNegotiator
|
|
|
|
.getInstanceFor(connection);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a file transfer listener to listen to incoming file transfer
|
|
|
|
* requests.
|
|
|
|
*
|
|
|
|
* @param li
|
|
|
|
* The listener
|
|
|
|
* @see #removeFileTransferListener(FileTransferListener)
|
|
|
|
* @see FileTransferListener
|
|
|
|
*/
|
|
|
|
public void addFileTransferListener(final FileTransferListener li) {
|
|
|
|
if (listeners == null) {
|
|
|
|
initListeners();
|
|
|
|
}
|
|
|
|
synchronized (this.listeners) {
|
|
|
|
listeners.add(li);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void initListeners() {
|
2009-06-04 13:58:25 +02:00
|
|
|
listeners = new ArrayList<FileTransferListener>();
|
2006-02-03 19:44:22 +01:00
|
|
|
|
|
|
|
connection.addPacketListener(new PacketListener() {
|
|
|
|
public void processPacket(Packet packet) {
|
|
|
|
fireNewRequest((StreamInitiation) packet);
|
|
|
|
}
|
|
|
|
}, new AndFilter(new PacketTypeFilter(StreamInitiation.class),
|
|
|
|
new IQTypeFilter(IQ.Type.SET)));
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void fireNewRequest(StreamInitiation initiation) {
|
|
|
|
FileTransferListener[] listeners = null;
|
|
|
|
synchronized (this.listeners) {
|
|
|
|
listeners = new FileTransferListener[this.listeners.size()];
|
|
|
|
this.listeners.toArray(listeners);
|
|
|
|
}
|
|
|
|
FileTransferRequest request = new FileTransferRequest(this, initiation);
|
|
|
|
for (int i = 0; i < listeners.length; i++) {
|
|
|
|
listeners[i].fileTransferRequest(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes a file transfer listener.
|
|
|
|
*
|
|
|
|
* @param li
|
|
|
|
* The file transfer listener to be removed
|
|
|
|
* @see FileTransferListener
|
|
|
|
*/
|
|
|
|
public void removeFileTransferListener(final FileTransferListener li) {
|
|
|
|
if (listeners == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
synchronized (this.listeners) {
|
|
|
|
listeners.remove(li);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an OutgoingFileTransfer to send a file to another user.
|
|
|
|
*
|
|
|
|
* @param userID
|
|
|
|
* The fully qualified jabber ID with resource of the user to
|
|
|
|
* send the file to.
|
|
|
|
* @return The send file object on which the negotiated transfer can be run.
|
|
|
|
*/
|
|
|
|
public OutgoingFileTransfer createOutgoingFileTransfer(String userID) {
|
2008-06-19 20:06:32 +02:00
|
|
|
// Why is this only accepting fully qualified JID?
|
|
|
|
// if (userID == null || StringUtils.parseName(userID).length() <= 0
|
|
|
|
// || StringUtils.parseServer(userID).length() <= 0
|
|
|
|
// || StringUtils.parseResource(userID).length() <= 0) {
|
|
|
|
// throw new IllegalArgumentException(
|
|
|
|
// "The provided user id was not fully qualified");
|
|
|
|
// }
|
2006-02-03 19:44:22 +01:00
|
|
|
|
|
|
|
return new OutgoingFileTransfer(connection.getUser(), userID,
|
|
|
|
fileTransferNegotiator.getNextStreamID(),
|
|
|
|
fileTransferNegotiator);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* When the file transfer request is acceptable, this method should be
|
|
|
|
* invoked. It will create an IncomingFileTransfer which allows the
|
|
|
|
* transmission of the file to procede.
|
|
|
|
*
|
|
|
|
* @param request
|
|
|
|
* The remote request that is being accepted.
|
|
|
|
* @return The IncomingFileTransfer which manages the download of the file
|
|
|
|
* from the transfer initiator.
|
|
|
|
*/
|
|
|
|
protected IncomingFileTransfer createIncomingFileTransfer(
|
|
|
|
FileTransferRequest request) {
|
|
|
|
if (request == null) {
|
|
|
|
throw new NullPointerException("RecieveRequest cannot be null");
|
|
|
|
}
|
|
|
|
|
|
|
|
IncomingFileTransfer transfer = new IncomingFileTransfer(request,
|
|
|
|
fileTransferNegotiator);
|
|
|
|
transfer.setFileInfo(request.getFileName(), request.getFileSize());
|
|
|
|
|
|
|
|
return transfer;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void rejectIncomingFileTransfer(FileTransferRequest request) {
|
|
|
|
StreamInitiation initiation = request.getStreamInitiation();
|
|
|
|
|
|
|
|
IQ rejection = FileTransferNegotiator.createIQ(
|
|
|
|
initiation.getPacketID(), initiation.getFrom(), initiation
|
|
|
|
.getTo(), IQ.Type.ERROR);
|
2006-07-19 21:24:00 +02:00
|
|
|
rejection.setError(new XMPPError(XMPPError.Condition.forbidden));
|
2006-02-03 19:44:22 +01:00
|
|
|
connection.sendPacket(rejection);
|
|
|
|
}
|
|
|
|
}
|