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:
parent
ef74695a1b
commit
8b54f34153
74 changed files with 11866 additions and 1902 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue