diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/DirtyHelper.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/DirtyHelper.java new file mode 100644 index 000000000..34bd10722 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/DirtyHelper.java @@ -0,0 +1,31 @@ +package org.jivesoftware.smackx.jingle_filetransfer; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +/** + * Dirty. + */ +public final class DirtyHelper { + + public static byte[] readFile(File file) throws IOException { + byte[] bytes = null; + int read; + FileInputStream fin = null; + try { + fin = new FileInputStream(file); + bytes = new byte[(int) file.length()]; + read = fin.read(bytes); + } finally { + if (fin != null) { + fin.close(); + } + } + if (read == -1) { + return null; + } + + return bytes; + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferManager.java index 72eadfef7..a7ef3fcbb 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferManager.java @@ -17,11 +17,35 @@ package org.jivesoftware.smackx.jingle_filetransfer; import org.jivesoftware.smack.Manager; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager; +import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamSession; +import org.jivesoftware.smackx.hash.HashManager; +import org.jivesoftware.smackx.hash.element.HashElement; +import org.jivesoftware.smackx.jingle.JingleManager; +import org.jivesoftware.smackx.jingle.JingleSessionHandler; +import org.jivesoftware.smackx.jingle.element.Jingle; +import org.jivesoftware.smackx.jingle.element.JingleAction; +import org.jivesoftware.smackx.jingle.element.JingleContent; +import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionPayloadType; import org.jivesoftware.smackx.jingle.provider.JingleContentProviderManager; +import org.jivesoftware.smackx.jingle_filetransfer.element.JingleContentDescriptionFileTransfer; +import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferPayload; import org.jivesoftware.smackx.jingle_filetransfer.provider.JingleContentDescriptionFileTransferProvider; +import org.jivesoftware.smackx.jingle_ibb.JingleInBandByteStreamManager; +import org.jivesoftware.smackx.jingle_ibb.element.JingleInBandByteStreamTransport; +import org.jxmpp.jid.FullJid; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; import java.util.WeakHashMap; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Manager for Jingle File Transfers. @@ -30,6 +54,8 @@ import java.util.WeakHashMap; */ public final class JingleFileTransferManager extends Manager { + private static final Logger LOGGER = Logger.getLogger(JingleFileTransferManager.class.getName()); + public static final String NAMESPACE_V5 = "urn:xmpp:jingle:apps:file-transfer:5"; private static final WeakHashMap INSTANCES = new WeakHashMap<>(); @@ -59,4 +85,69 @@ public final class JingleFileTransferManager extends Manager { } return manager; } + + /** + * QnD method. + * @param file + */ + public void sendFile(File file, final FullJid recipient) throws IOException, SmackException.NotConnectedException, InterruptedException { + final byte[] bytes = DirtyHelper.readFile(file); + if (bytes == null) { + LOGGER.log(Level.SEVERE, "bytes are null."); + return; + } + Date lastModified = new Date(file.lastModified()); + JingleFileTransferPayload payload = new JingleFileTransferPayload( + lastModified, "A file", HashElement.fromData(HashManager.ALGORITHM.SHA_256, bytes), + "application/octet-stream", file.getName(), (int) file.length(), null); + ArrayList payloadTypes = new ArrayList<>(); + payloadTypes.add(payload); + + JingleContentDescriptionFileTransfer descriptionFileTransfer = new JingleContentDescriptionFileTransfer(payloadTypes); + final JingleInBandByteStreamTransport transport = new JingleInBandByteStreamTransport(); + JingleContent.Builder cb = JingleContent.getBuilder(); + cb.setDescription(descriptionFileTransfer) + .addTransport(transport) + .setCreator(JingleContent.Creator.initiator) + .setSenders(JingleContent.Senders.initiator); + JingleContent content = cb.build(); + + final String sid = JingleInBandByteStreamManager.generateSessionId(); + + Jingle.Builder jb = Jingle.getBuilder(); + jb.setInitiator(connection().getUser()) + .setResponder(recipient) + .setAction(JingleAction.session_initiate) + .addJingleContent(content) + .setSessionId(sid); + Jingle jingle = jb.build(); + + JingleManager.getInstanceFor(connection()).registerJingleSessionHandler(recipient, sid, new JingleSessionHandler() { + @Override + public IQ handleRequest(Jingle jingle, String sessionId) { + if (sessionId.equals(sid)) { + if (jingle.getAction() == JingleAction.session_accept) { + + InBandBytestreamSession session; + try { + session = InBandBytestreamManager.getByteStreamManager(connection()) + .establishSession(recipient, sid); + } catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { + LOGGER.log(Level.SEVERE, "Fail in handle request: " + e, e); + return null; + } + + try { + session.getOutputStream().write(bytes); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Fail while writing: " + e, e); + } + } + } + return null; + } + }); + + connection().sendStanza(jingle); + } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/FileTransferPayload.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleFileTransferPayload.java similarity index 93% rename from smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/FileTransferPayload.java rename to smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleFileTransferPayload.java index 310aae8b6..fceaabbd2 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/FileTransferPayload.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleFileTransferPayload.java @@ -25,7 +25,7 @@ import java.util.Date; /** * Content of type File. */ -public class FileTransferPayload extends JingleContentDescriptionPayloadType { +public class JingleFileTransferPayload extends JingleContentDescriptionPayloadType { public static final String ELEMENT = "file"; public static final String ELEM_DATE = "date"; public static final String ELEM_DESC = "desc"; @@ -41,7 +41,7 @@ public class FileTransferPayload extends JingleContentDescriptionPayloadType { private final int size; private final Range range; - public FileTransferPayload(Date date, String desc, HashElement hash, String mediaType, String name, int size, Range range) { + public JingleFileTransferPayload(Date date, String desc, HashElement hash, String mediaType, String name, int size, Range range) { this.date = date; this.desc = desc; this.hash = hash; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/provider/JingleContentDescriptionFileTransferProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/provider/JingleContentDescriptionFileTransferProvider.java index a523080a3..56456129a 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/provider/JingleContentDescriptionFileTransferProvider.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/provider/JingleContentDescriptionFileTransferProvider.java @@ -20,7 +20,7 @@ import org.jivesoftware.smackx.hash.element.HashElement; import org.jivesoftware.smackx.hash.provider.HashElementProvider; import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionPayloadType; import org.jivesoftware.smackx.jingle.provider.JingleContentDescriptionProvider; -import org.jivesoftware.smackx.jingle_filetransfer.element.FileTransferPayload; +import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferPayload; import org.jivesoftware.smackx.jingle_filetransfer.element.JingleContentDescriptionFileTransfer; import org.jivesoftware.smackx.jingle_filetransfer.element.Range; import org.jxmpp.util.XmppDateTime; @@ -64,7 +64,7 @@ public class JingleContentDescriptionFileTransferProvider if (tag == START_TAG) { switch (elem) { - case FileTransferPayload.ELEMENT: + case JingleFileTransferPayload.ELEMENT: date = null; desc = null; mediaType = null; @@ -75,23 +75,23 @@ public class JingleContentDescriptionFileTransferProvider hash = null; break; - case FileTransferPayload.ELEM_DATE: + case JingleFileTransferPayload.ELEM_DATE: date = XmppDateTime.parseXEP0082Date(parser.nextText()); break; - case FileTransferPayload.ELEM_DESC: + case JingleFileTransferPayload.ELEM_DESC: desc = parser.nextText(); break; - case FileTransferPayload.ELEM_MEDIA_TYPE: + case JingleFileTransferPayload.ELEM_MEDIA_TYPE: mediaType = parser.nextText(); break; - case FileTransferPayload.ELEM_NAME: + case JingleFileTransferPayload.ELEM_NAME: name = parser.nextText(); break; - case FileTransferPayload.ELEM_SIZE: + case JingleFileTransferPayload.ELEM_SIZE: size = Integer.parseInt(parser.nextText()); break; @@ -125,8 +125,8 @@ public class JingleContentDescriptionFileTransferProvider range = new Range(offset, length, inRangeHash); break; - case FileTransferPayload.ELEMENT: - payloads.add(new FileTransferPayload(date, desc, hash, mediaType, name, size, range)); + case JingleFileTransferPayload.ELEMENT: + payloads.add(new JingleFileTransferPayload(date, desc, hash, mediaType, name, size, range)); break; case JingleContentDescriptionFileTransfer.ELEMENT: diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/JingleContentDescriptionFileTransferTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/JingleContentDescriptionFileTransferTest.java index 3e2dceee0..523c9e660 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/JingleContentDescriptionFileTransferTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/JingleContentDescriptionFileTransferTest.java @@ -22,7 +22,7 @@ import org.jivesoftware.smackx.hash.HashManager; import org.jivesoftware.smackx.hash.element.HashElement; import org.jivesoftware.smackx.jingle.element.JingleContentDescription; import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionPayloadType; -import org.jivesoftware.smackx.jingle_filetransfer.element.FileTransferPayload; +import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferPayload; import org.jivesoftware.smackx.jingle_filetransfer.element.JingleContentDescriptionFileTransfer; import org.jivesoftware.smackx.jingle_filetransfer.element.Range; import org.jivesoftware.smackx.jingle_filetransfer.provider.JingleContentDescriptionFileTransferProvider; @@ -65,9 +65,9 @@ public class JingleContentDescriptionFileTransferTest extends SmackTestSuite { HashElement hashElement = new HashElement(algorithm, hashB64); Range range = new Range(); Date date = XmppDateTime.parseDate(dateString); - FileTransferPayload fileTransferPayload = new FileTransferPayload(date, descriptionString, hashElement, mediaTypeString, nameString, sizeInt, range); + JingleFileTransferPayload jingleFileTransferPayload = new JingleFileTransferPayload(date, descriptionString, hashElement, mediaTypeString, nameString, sizeInt, range); ArrayList payloads = new ArrayList<>(); - payloads.add(fileTransferPayload); + payloads.add(jingleFileTransferPayload); JingleContentDescriptionFileTransfer descriptionFileTransfer = new JingleContentDescriptionFileTransfer(payloads); @@ -78,7 +78,7 @@ public class JingleContentDescriptionFileTransferTest extends SmackTestSuite { .parse(TestUtils.getParser(xml)); assertEquals(xml, parsed.toXML().toString()); - FileTransferPayload payload = (FileTransferPayload) parsed.getJinglePayloadTypes().get(0); + JingleFileTransferPayload payload = (JingleFileTransferPayload) parsed.getJinglePayloadTypes().get(0); assertEquals(date, payload.getDate()); assertEquals(descriptionString, payload.getDescription()); assertEquals(mediaTypeString, payload.getMediaType()); @@ -104,7 +104,7 @@ public class JingleContentDescriptionFileTransferTest extends SmackTestSuite { "" + "" + ""; - FileTransferPayload payload = new FileTransferPayload(null, null, null, null, null, -1, range); + JingleFileTransferPayload payload = new JingleFileTransferPayload(null, null, null, null, null, -1, range); ArrayList list = new ArrayList<>(); list.add(payload); JingleContentDescriptionFileTransfer fileTransfer = new JingleContentDescriptionFileTransfer(list); diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/FileTransferPayloadTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferPayloadTest.java similarity index 97% rename from smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/FileTransferPayloadTest.java rename to smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferPayloadTest.java index 883a90d12..7edb14ce7 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/FileTransferPayloadTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferPayloadTest.java @@ -29,7 +29,7 @@ import static junit.framework.TestCase.assertNull; /** * Test the JingleContentFile class. */ -public class FileTransferPayloadTest extends SmackTestSuite { +public class JingleFileTransferPayloadTest extends SmackTestSuite { @Test public void rangeTest() throws Exception { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleAction.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleAction.java index 81daeb227..706690778 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleAction.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleAction.java @@ -36,7 +36,7 @@ public enum JingleAction { session_accept, session_info, session_initiate, - sessio_terminate, + session_terminate, transport_accept, transport_info, transport_reject, diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle_ibb/JingleInBandByteStreamManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle_ibb/JingleInBandByteStreamManager.java index 0f137b1c2..4b2622fe0 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle_ibb/JingleInBandByteStreamManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle_ibb/JingleInBandByteStreamManager.java @@ -18,10 +18,10 @@ package org.jivesoftware.smackx.jingle_ibb; import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.jingle.provider.JingleContentProviderManager; import org.jivesoftware.smackx.jingle_ibb.provider.JingleInBandByteStreamTransportProvider; -import java.util.Random; import java.util.WeakHashMap; /** @@ -52,6 +52,6 @@ public final class JingleInBandByteStreamManager extends Manager { * @return */ public static String generateSessionId() { - return Integer.toString(64,new Random().nextInt()); + return StringUtils.randomString(24); } }