mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-27 14:32:06 +01:00
Improve JFT API
This commit is contained in:
parent
d7df408661
commit
e53165a96c
8 changed files with 112 additions and 40 deletions
|
@ -78,7 +78,11 @@ public final class JetManager extends Manager implements JingleDescriptionManage
|
|||
return manager;
|
||||
}
|
||||
|
||||
public OutgoingFileOfferController sendEncryptedFile(FullJid recipient, File file, JingleEncryptionMethod method) throws Exception {
|
||||
public OutgoingFileOfferController sendEncryptedFile(File file, FullJid recipient, JingleEncryptionMethod method) throws Exception {
|
||||
return sendEncryptedFile(file, null, recipient, method);
|
||||
}
|
||||
|
||||
public OutgoingFileOfferController sendEncryptedFile(File file, String filename, FullJid recipient, JingleEncryptionMethod method) throws Exception {
|
||||
if (file == null || !file.exists()) {
|
||||
throw new IllegalArgumentException("File MUST NOT be null and MUST exist.");
|
||||
}
|
||||
|
@ -94,6 +98,9 @@ public final class JetManager extends Manager implements JingleDescriptionManage
|
|||
session.addContent(content);
|
||||
|
||||
JingleOutgoingFileOffer offer = new JingleOutgoingFileOffer(file);
|
||||
if (filename != null) {
|
||||
offer.getFile().setName(filename);
|
||||
}
|
||||
content.setDescription(offer);
|
||||
|
||||
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(recipient);
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
package org.jivesoftware.smackx.jingle_filetransfer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -29,6 +31,7 @@ import org.jivesoftware.smack.Manager;
|
|||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
|
||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||
import org.jivesoftware.smackx.jingle.JingleDescriptionManager;
|
||||
import org.jivesoftware.smackx.jingle.JingleManager;
|
||||
|
@ -64,6 +67,7 @@ public final class JingleFileTransferManager extends Manager implements JingleDe
|
|||
|
||||
private final List<IncomingFileOfferListener> offerListeners =
|
||||
Collections.synchronizedList(new ArrayList<IncomingFileOfferListener>());
|
||||
|
||||
private final List<IncomingFileRequestListener> requestListeners =
|
||||
Collections.synchronizedList(new ArrayList<IncomingFileRequestListener>());
|
||||
|
||||
|
@ -127,9 +131,60 @@ public final class JingleFileTransferManager extends Manager implements JingleDe
|
|||
return offer;
|
||||
}
|
||||
|
||||
public OutgoingFileOfferController sendStream(InputStream stream, String filename, FullJid to) {
|
||||
//TODO: Implement
|
||||
return null;
|
||||
public OutgoingFileOfferController sendStream(final InputStream stream, JingleFileTransferFile.LocalFile file, FullJid recipient) throws SmackException.FeatureNotSupportedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
|
||||
if (!ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(recipient, getNamespace())) {
|
||||
throw new SmackException.FeatureNotSupportedException(getNamespace(), recipient);
|
||||
}
|
||||
|
||||
JingleSession session = jingleManager.createSession(Role.initiator, recipient);
|
||||
|
||||
JingleContent content = new JingleContent(JingleContentElement.Creator.initiator, JingleContentElement.Senders.initiator);
|
||||
session.addContent(content);
|
||||
|
||||
JingleOutgoingFileOffer outgoingFileOffer = new JingleOutgoingFileOffer(file) {
|
||||
|
||||
@Override
|
||||
public void onBytestreamReady(BytestreamSession bytestreamSession) {
|
||||
OutputStream outputStream;
|
||||
try {
|
||||
outputStream = bytestreamSession.getOutputStream();
|
||||
|
||||
byte[] buf = new byte[4096];
|
||||
while (true) {
|
||||
int r = stream.read(buf);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
outputStream.write(buf, 0, r);
|
||||
}
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Exception while sending file: " + e, e);
|
||||
} finally {
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Could not close FileInputStream: " + e, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
notifyProgressListenersFinished();
|
||||
}
|
||||
};
|
||||
|
||||
content.setDescription(outgoingFileOffer);
|
||||
|
||||
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(recipient);
|
||||
JingleTransport<?> transport = transportManager.createTransportForInitiator(content);
|
||||
content.setTransport(transport);
|
||||
|
||||
session.sendInitiate(connection());
|
||||
|
||||
return outgoingFileOffer;
|
||||
}
|
||||
|
||||
public OutgoingFileRequestController requestFile(JingleFileTransferFile.RemoteFile file, FullJid from) {
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.io.FileOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -42,8 +41,7 @@ import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferChi
|
|||
public class JingleIncomingFileOffer extends AbstractJingleFileOffer<JingleFileTransferFile.RemoteFile> implements IncomingFileOfferController {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(JingleIncomingFileOffer.class.getName());
|
||||
|
||||
private File target;
|
||||
private OutputStream target;
|
||||
|
||||
public JingleIncomingFileOffer(JingleFileTransferChildElement offer) {
|
||||
super(new JingleFileTransferFile.RemoteFile(offer));
|
||||
|
@ -56,27 +54,21 @@ public class JingleIncomingFileOffer extends AbstractJingleFileOffer<JingleFileT
|
|||
|
||||
@Override
|
||||
public void onBytestreamReady(BytestreamSession bytestreamSession) {
|
||||
LOGGER.log(Level.INFO, "Receive file to " + target.getAbsolutePath());
|
||||
File mFile = target;
|
||||
if (!mFile.exists()) {
|
||||
try {
|
||||
mFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Could not create new File!");
|
||||
}
|
||||
if (target == null) {
|
||||
throw new IllegalStateException("Target OutputStream is null");
|
||||
}
|
||||
|
||||
LOGGER.log(Level.INFO, "Receive file");
|
||||
|
||||
InputStream inputStream = null;
|
||||
OutputStream outputStream = null;
|
||||
try {
|
||||
inputStream = bytestreamSession.getInputStream();
|
||||
outputStream = new FileOutputStream(mFile);
|
||||
|
||||
int length = 0;
|
||||
int read = 0;
|
||||
byte[] bufbuf = new byte[4096];
|
||||
while ((length = inputStream.read(bufbuf)) >= 0) {
|
||||
outputStream.write(bufbuf, 0, length);
|
||||
target.write(bufbuf, 0, length);
|
||||
read += length;
|
||||
LOGGER.log(Level.INFO, "Read " + read + " (" + length + ") of " + file.getSize() + " bytes.");
|
||||
if (read == (int) file.getSize()) {
|
||||
|
@ -96,9 +88,9 @@ public class JingleIncomingFileOffer extends AbstractJingleFileOffer<JingleFileT
|
|||
}
|
||||
}
|
||||
|
||||
if (outputStream != null) {
|
||||
if (target != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
target.close();
|
||||
LOGGER.log(Level.INFO, "FileOutputStream closed.");
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Could not close OutputStream: " + e, e);
|
||||
|
@ -119,16 +111,32 @@ public class JingleIncomingFileOffer extends AbstractJingleFileOffer<JingleFileT
|
|||
}
|
||||
|
||||
@Override
|
||||
public Future<Void> accept(XMPPConnection connection, File target)
|
||||
public void accept(XMPPConnection connection, File target)
|
||||
throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException,
|
||||
SmackException.NoResponseException {
|
||||
this.target = target;
|
||||
SmackException.NoResponseException, IOException {
|
||||
|
||||
if (!target.exists()) {
|
||||
target.createNewFile();
|
||||
}
|
||||
|
||||
this.target = new FileOutputStream(target);
|
||||
|
||||
JingleSession session = getParent().getParent();
|
||||
if (session.getSessionState() == JingleSession.SessionState.pending) {
|
||||
session.sendAccept(connection);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@Override
|
||||
public void accept(XMPPConnection connection, OutputStream stream)
|
||||
throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException,
|
||||
SmackException.NoResponseException {
|
||||
target = stream;
|
||||
|
||||
JingleSession session = getParent().getParent();
|
||||
if (session.getSessionState() == JingleSession.SessionState.pending) {
|
||||
session.sendAccept(connection);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -36,7 +36,11 @@ public class JingleOutgoingFileOffer extends AbstractJingleFileOffer<JingleFileT
|
|||
private static final Logger LOGGER = Logger.getLogger(JingleOutgoingFileOffer.class.getName());
|
||||
|
||||
public JingleOutgoingFileOffer(File file) {
|
||||
super(new JingleFileTransferFile.LocalFile(file));
|
||||
this(new JingleFileTransferFile.LocalFile(file));
|
||||
}
|
||||
|
||||
public JingleOutgoingFileOffer(JingleFileTransferFile.LocalFile localFile) {
|
||||
super(localFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
package org.jivesoftware.smackx.jingle_filetransfer.controller;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.Future;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
|
@ -27,5 +28,6 @@ import org.jivesoftware.smack.XMPPException;
|
|||
* User interface for an incoming Jingle file offer.
|
||||
*/
|
||||
public interface IncomingFileOfferController extends JingleFileTransferController {
|
||||
Future<Void> accept(XMPPConnection connection, File target) throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException;
|
||||
void accept(XMPPConnection connection, File target) throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException, IOException;
|
||||
void accept(XMPPConnection connection, OutputStream outputStream) throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException, IOException;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import static org.junit.Assert.assertArrayEquals;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.concurrent.Future;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
|
@ -123,14 +123,14 @@ public class JetIntegrationTest extends AbstractOmemoIntegrationTest {
|
|||
received.signal();
|
||||
}
|
||||
});
|
||||
Future<Void> f = offer.accept(conTwo, target);
|
||||
} catch (InterruptedException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | SmackException.NoResponseException e) {
|
||||
offer.accept(conTwo, target);
|
||||
} catch (InterruptedException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | SmackException.NoResponseException | IOException e) {
|
||||
received.signal(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ja.sendEncryptedFile(conTwo.getUser().asFullJidOrThrow(), source, oa);
|
||||
ja.sendEncryptedFile(source, conTwo.getUser().asFullJidOrThrow(), oa);
|
||||
|
||||
received.waitForResult(60 * 1000);
|
||||
|
||||
|
|
|
@ -107,8 +107,8 @@ public class JingleFileTransferIntegrationTest extends AbstractSmackIntegrationT
|
|||
});
|
||||
|
||||
try {
|
||||
receiveFuture.add(offer.accept(conTwo, target));
|
||||
} catch (InterruptedException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | SmackException.NoResponseException e) {
|
||||
offer.accept(conTwo, target);
|
||||
} catch (InterruptedException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | SmackException.NoResponseException | IOException e) {
|
||||
fail(e.toString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,6 @@ import java.io.File;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
|
@ -95,8 +93,6 @@ public class JingleFileTransferTransportFallbackIntegrationTest extends Abstract
|
|||
JingleFileTransferManager aftm = JingleFileTransferManager.getInstanceFor(conOne);
|
||||
JingleFileTransferManager bftm = JingleFileTransferManager.getInstanceFor(conTwo);
|
||||
|
||||
final ArrayList<Future<Void>> receiveFuture = new ArrayList<>(); //Uglaay
|
||||
|
||||
bftm.addIncomingFileOfferListener(new IncomingFileOfferListener() {
|
||||
@Override
|
||||
public void onIncomingFileOffer(IncomingFileOfferController offer) {
|
||||
|
@ -120,8 +116,8 @@ public class JingleFileTransferTransportFallbackIntegrationTest extends Abstract
|
|||
});
|
||||
|
||||
try {
|
||||
receiveFuture.add(offer.accept(conTwo, target));
|
||||
} catch (InterruptedException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | SmackException.NoResponseException e) {
|
||||
offer.accept(conTwo, target);
|
||||
} catch (InterruptedException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | SmackException.NoResponseException | IOException e) {
|
||||
fail(e.toString());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue