1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2025-09-10 09:39:39 +02:00

merged branch improve_bytestreams in trunk

git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@11821 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
Henning Staib 2010-08-15 11:57:11 +00:00 committed by henning
parent ef74695a1b
commit 8b54f34153
74 changed files with 11866 additions and 1902 deletions

View file

@ -19,9 +19,20 @@
*/
package org.jivesoftware.smackx.filetransfer;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketIDFilter;
import org.jivesoftware.smack.packet.IQ;
@ -30,40 +41,26 @@ import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.FormField;
import org.jivesoftware.smackx.ServiceDiscoveryManager;
import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager;
import org.jivesoftware.smackx.packet.DataForm;
import org.jivesoftware.smackx.packet.StreamInitiation;
import java.net.URLConnection;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* Manages the negotiation of file transfers according to JEP-0096. If a file is
* being sent the remote user chooses the type of stream under which the file
* will be sent.
*
* @author Alexander Wenckus
* @see <a href=http://www.jabber.org/jeps/jep-0096.html>JEP-0096: File Transfer</a>
* @see <a href="http://www.jabber.org/jeps/jep-0096.html">JEP-0096: File Transfer</a>
*/
public class FileTransferNegotiator {
// Static
/**
* The XMPP namespace of the SOCKS5 bytestream
*/
public static final String BYTE_STREAM = "http://jabber.org/protocol/bytestreams";
/**
* The XMPP namespace of the In-Band bytestream
*/
public static final String INBAND_BYTE_STREAM = "http://jabber.org/protocol/ibb";
private static final String[] NAMESPACE = {
"http://jabber.org/protocol/si/profile/file-transfer",
"http://jabber.org/protocol/si", BYTE_STREAM, INBAND_BYTE_STREAM};
private static final String[] PROTOCOLS = {BYTE_STREAM, INBAND_BYTE_STREAM};
"http://jabber.org/protocol/si"};
private static final Map<Connection, FileTransferNegotiator> transferObject =
new ConcurrentHashMap<Connection, FileTransferNegotiator>();
@ -121,14 +118,24 @@ public class FileTransferNegotiator {
final boolean isEnabled) {
ServiceDiscoveryManager manager = ServiceDiscoveryManager
.getInstanceFor(connection);
for (String ns : NAMESPACE) {
List<String> namespaces = new ArrayList<String>();
namespaces.addAll(Arrays.asList(NAMESPACE));
namespaces.add(InBandBytestreamManager.NAMESPACE);
if (!IBB_ONLY) {
namespaces.add(Socks5BytestreamManager.NAMESPACE);
}
for (String namespace : namespaces) {
if (isEnabled) {
manager.addFeature(ns);
}
else {
manager.removeFeature(ns);
if (!manager.includesFeature(namespace)) {
manager.addFeature(namespace);
}
} else {
manager.removeFeature(namespace);
}
}
}
/**
@ -139,20 +146,31 @@ public class FileTransferNegotiator {
* @return True if all related services are enabled, false if they are not.
*/
public static boolean isServiceEnabled(final Connection connection) {
for (String ns : NAMESPACE) {
if (!ServiceDiscoveryManager.getInstanceFor(connection).includesFeature(ns))
ServiceDiscoveryManager manager = ServiceDiscoveryManager
.getInstanceFor(connection);
List<String> namespaces = new ArrayList<String>();
namespaces.addAll(Arrays.asList(NAMESPACE));
namespaces.add(InBandBytestreamManager.NAMESPACE);
if (!IBB_ONLY) {
namespaces.add(Socks5BytestreamManager.NAMESPACE);
}
for (String namespace : namespaces) {
if (!manager.includesFeature(namespace)) {
return false;
}
}
return true;
}
/**
* A convience method to create an IQ packet.
* A convenience method to create an IQ packet.
*
* @param ID The packet ID of the
* @param to To whom the packet is addressed.
* @param from From whom the packet is sent.
* @param type The iq type of the packet.
* @param type The IQ type of the packet.
* @return The created IQ packet.
*/
public static IQ createIQ(final String ID, final String to,
@ -176,14 +194,19 @@ public class FileTransferNegotiator {
* @return Returns a collection of the supported transfer protocols.
*/
public static Collection<String> getSupportedProtocols() {
return Collections.unmodifiableList(Arrays.asList(PROTOCOLS));
List<String> protocols = new ArrayList<String>();
protocols.add(InBandBytestreamManager.NAMESPACE);
if (!IBB_ONLY) {
protocols.add(Socks5BytestreamManager.NAMESPACE);
}
return Collections.unmodifiableList(protocols);
}
// non-static
private final Connection connection;
private final Socks5TransferNegotiatorManager byteStreamTransferManager;
private final StreamNegotiator byteStreamTransferManager;
private final StreamNegotiator inbandTransferManager;
@ -191,7 +214,7 @@ public class FileTransferNegotiator {
configureConnection(connection);
this.connection = connection;
byteStreamTransferManager = new Socks5TransferNegotiatorManager(connection);
byteStreamTransferManager = new Socks5TransferNegotiator(connection);
inbandTransferManager = new IBBTransferNegotiator(connection);
}
@ -221,7 +244,6 @@ public class FileTransferNegotiator {
private void cleanup(final Connection connection) {
if (transferObject.remove(connection) != null) {
byteStreamTransferManager.cleanup();
inbandTransferManager.cleanup();
}
}
@ -288,10 +310,10 @@ public class FileTransferNegotiator {
boolean isIBB = false;
for (Iterator<FormField.Option> it = field.getOptions(); it.hasNext();) {
variable = it.next().getValue();
if (variable.equals(BYTE_STREAM) && !IBB_ONLY) {
if (variable.equals(Socks5BytestreamManager.NAMESPACE) && !IBB_ONLY) {
isByteStream = true;
}
else if (variable.equals(INBAND_BYTE_STREAM)) {
else if (variable.equals(InBandBytestreamManager.NAMESPACE)) {
isIBB = true;
}
}
@ -304,11 +326,11 @@ public class FileTransferNegotiator {
if (isByteStream && isIBB && field.getType().equals(FormField.TYPE_LIST_MULTI)) {
return new FaultTolerantNegotiator(connection,
byteStreamTransferManager.createNegotiator(),
byteStreamTransferManager,
inbandTransferManager);
}
else if (isByteStream) {
return byteStreamTransferManager.createNegotiator();
return byteStreamTransferManager;
}
else {
return inbandTransferManager;
@ -346,11 +368,11 @@ public class FileTransferNegotiator {
* the option of, accepting, rejecting, or not responding to a received file
* transfer request.
* <p/>
* If they accept, the packet will contain the other user's choosen stream
* If they accept, the packet will contain the other user's chosen stream
* type to send the file across. The two choices this implementation
* provides to the other user for file transfer are <a
* href="http://www.jabber.org/jeps/jep-0065.html">SOCKS5 Bytestreams</a>,
* which is the prefered method of transfer, and <a
* which is the preferred method of transfer, and <a
* href="http://www.jabber.org/jeps/jep-0047.html">In-Band Bytestreams</a>,
* which is the fallback mechanism.
* <p/>
@ -422,10 +444,10 @@ public class FileTransferNegotiator {
boolean isIBB = false;
for (Iterator<String> it = field.getValues(); it.hasNext();) {
variable = it.next();
if (variable.equals(BYTE_STREAM) && !IBB_ONLY) {
if (variable.equals(Socks5BytestreamManager.NAMESPACE) && !IBB_ONLY) {
isByteStream = true;
}
else if (variable.equals(INBAND_BYTE_STREAM)) {
else if (variable.equals(InBandBytestreamManager.NAMESPACE)) {
isIBB = true;
}
}
@ -438,10 +460,10 @@ public class FileTransferNegotiator {
if (isByteStream && isIBB) {
return new FaultTolerantNegotiator(connection,
byteStreamTransferManager.createNegotiator(), inbandTransferManager);
byteStreamTransferManager, inbandTransferManager);
}
else if (isByteStream) {
return byteStreamTransferManager.createNegotiator();
return byteStreamTransferManager;
}
else {
return inbandTransferManager;
@ -453,9 +475,9 @@ public class FileTransferNegotiator {
FormField field = new FormField(STREAM_DATA_FIELD_NAME);
field.setType(FormField.TYPE_LIST_MULTI);
if (!IBB_ONLY) {
field.addOption(new FormField.Option(BYTE_STREAM));
field.addOption(new FormField.Option(Socks5BytestreamManager.NAMESPACE));
}
field.addOption(new FormField.Option(INBAND_BYTE_STREAM));
field.addOption(new FormField.Option(InBandBytestreamManager.NAMESPACE));
form.addField(field);
return form;
}