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 deleted file mode 100644 index 1b0d992f3..000000000 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/DirtyHelper.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * - * Copyright © 2017 Paul Schaub - * - * 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. - */ -package org.jivesoftware.smackx.jingle_filetransfer; - -import org.jivesoftware.smackx.hash.HashManager; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.security.DigestInputStream; - -/** - * Dirty. - */ -public final class DirtyHelper { - - public static BytesAndDigest readFile(File file, HashManager.ALGORITHM algorithm) throws IOException { - byte[] bytes = null; - byte[] digest = null; - int read; - FileInputStream fin = null; - try { - fin = new FileInputStream(file); - DigestInputStream din = new DigestInputStream(fin, HashManager.getMessageDigest(algorithm)); - bytes = new byte[(int) file.length()]; - read = din.read(bytes); - din.close(); - digest = din.getMessageDigest().digest(); - } finally { - if (fin != null) { - fin.close(); - } - } - if (read == -1) { - return null; - } - - return new BytesAndDigest(bytes, digest); - } - - public static class BytesAndDigest { - - private final byte[] bytes, digest; - - public BytesAndDigest(byte[] bytes, byte[] digest) { - this.bytes = bytes; - this.digest = digest; - } - - public byte[] getBytes() { - return bytes; - } - - public byte[] getDigest() { - return digest; - } - } -} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/FileAndHashReader.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/FileAndHashReader.java new file mode 100644 index 000000000..910917a1d --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/FileAndHashReader.java @@ -0,0 +1,83 @@ +/** + * + * Copyright © 2017 Paul Schaub + * + * 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. + */ +package org.jivesoftware.smackx.jingle_filetransfer; + +import org.jivesoftware.smackx.hash.HashManager; +import org.jivesoftware.smackx.hash.element.HashElement; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.security.DigestInputStream; + +/** + * FileReader that reads a file into a byte array while returning the hash of the file. + */ +public final class FileAndHashReader { + + /** + * Read a file into a byte array and calculate the hash sum of the bytes that were read on the fly. + * @param file file to read. + * @param destination byte array where the file is read into. + * @param algorithm algorithm used to calculate the hash. + * @return hashElement containing the hash sum of the read bytes. + * @throws IOException + */ + public static HashElement readAndCalculateHash(File file, final byte[] destination, HashManager.ALGORITHM algorithm) throws IOException { + return readAndCalculateHash(file, destination, 0, algorithm); + } + + /** + * Read a file into a byte array and calculate the hash sum of the bytes that were read on the fly. + * @param file file to read. + * @param destination byte array where the file is read into. + * @param offset offset from the beginning of the file. + * @param algorithm algorithm used to calculate the hash. + * @return hashElement containing the hash sum of the read bytes. + * @throws IOException + */ + public static HashElement readAndCalculateHash(File file, final byte[] destination, int offset, HashManager.ALGORITHM algorithm) throws IOException { + byte[] hash; + int read; + FileInputStream fin = null; + DigestInputStream din = null; + try { + fin = new FileInputStream(file); + try { + din = new DigestInputStream(fin, HashManager.getMessageDigest(algorithm)); + read = din.read(destination, offset, destination.length); + hash = din.getMessageDigest().digest(); + } + finally { + if (din != null) { + din.close(); + } + } + } + finally { + if (fin != null) { + fin.close(); + } + } + + if (read == -1) { + return null; + } + + return HashManager.assembleHashElement(algorithm, hash); + } +} 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 db55476b5..94c662f48 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 @@ -25,6 +25,7 @@ import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager; import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamSession; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; 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; @@ -88,15 +89,22 @@ public final class JingleFileTransferManager extends Manager { return manager; } + public JingleFileTransferPayload createPayloadFromFile(File file) { + JingleFileTransferPayload.Builder payloadBuilder = JingleFileTransferPayload.getBuilder(); + + return payloadBuilder.build(); + } + /** * QnD method. * @param file */ public void sendFile(File file, final FullJid recipient) throws IOException, SmackException.NotConnectedException, InterruptedException { - final DirtyHelper.BytesAndDigest bd = DirtyHelper.readFile(file, HashManager.ALGORITHM.SHA_256); + final byte[] bytes = new byte[(int) file.length()]; + HashElement hashElement = FileAndHashReader.readAndCalculateHash(file, bytes, HashManager.ALGORITHM.SHA_256); Date lastModified = new Date(file.lastModified()); JingleFileTransferPayload payload = new JingleFileTransferPayload( - lastModified, "A file", HashManager.assembleHashElement(HashManager.ALGORITHM.SHA_256, bd.getDigest()), + lastModified, "A file", hashElement, "application/octet-stream", file.getName(), (int) file.length(), null); ArrayList payloadTypes = new ArrayList<>(); payloadTypes.add(payload); @@ -137,7 +145,7 @@ public final class JingleFileTransferManager extends Manager { } try { - session.getOutputStream().write(bd.getBytes()); + session.getOutputStream().write(bytes); } catch (IOException e) { LOGGER.log(Level.SEVERE, "Fail while writing: " + e, e); } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferSession.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferSession.java new file mode 100644 index 000000000..600d0043e --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferSession.java @@ -0,0 +1,51 @@ +/** + * + * Copyright 2017 Paul Schaub + * + * 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. + */ +package org.jivesoftware.smackx.jingle_filetransfer; + +import org.jivesoftware.smackx.jingle.JingleSession; +import org.jxmpp.jid.Jid; + +/** + * Class that represents a jingle session in the context of Jingle File Transfer + */ +public class JingleFileTransferSession extends JingleSession { + + public JingleFileTransferSession(Jid initiator, Jid responder, String sid) { + super(initiator, responder, sid); + } + + /** + * A user might choose to abort all active transfers. + */ + public void abortAllActiveFileTransfers() { + + } + + /** + * A user might want to abort the transfer of a single file. + */ + public void abortSingleFileTransfer() { + + } + + /** + * Successfully end session after all files have been transferred. + */ + void endSession() { + + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/callback/IncomingJingleFileTransferCallback.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/callback/IncomingJingleFileTransferCallback.java new file mode 100644 index 000000000..9620f1e54 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/callback/IncomingJingleFileTransferCallback.java @@ -0,0 +1,27 @@ +/** + * + * Copyright 2017 Paul Schaub + * + * 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. + */ +package org.jivesoftware.smackx.jingle_filetransfer.callback; + +/** + * Callback that allows the user to accept or cancel file transfers. + */ +public interface IncomingJingleFileTransferCallback { + + void acceptFileTransfer(); + + void cancelFileTransfer(); +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/callback/package-info.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/callback/package-info.java new file mode 100644 index 000000000..dbb0faddb --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/callback/package-info.java @@ -0,0 +1,22 @@ +/** + * + * Copyright 2017 Paul Schaub + * + * 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. + */ + +/** + * Smack's API for XEP-0234: Jingle File Transfer. + * Callback classes. + */ +package org.jivesoftware.smackx.jingle_filetransfer.callback; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/listener/IncomingFileTransferContentAddListener.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/listener/IncomingFileTransferContentAddListener.java new file mode 100644 index 000000000..09a5ca7ff --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/listener/IncomingFileTransferContentAddListener.java @@ -0,0 +1,24 @@ +/** + * + * Copyright 2017 Paul Schaub + * + * 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. + */ +package org.jivesoftware.smackx.jingle_filetransfer.listener; + +/** + * Listener for content-add actions. + */ +public interface IncomingFileTransferContentAddListener extends IncomingJingleFileTransferListener { + +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/listener/IncomingJingleFileTransferListener.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/listener/IncomingJingleFileTransferListener.java new file mode 100644 index 000000000..7ec44f0ed --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/listener/IncomingJingleFileTransferListener.java @@ -0,0 +1,28 @@ +/** + * + * Copyright 2017 Paul Schaub + * + * 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. + */ +package org.jivesoftware.smackx.jingle_filetransfer.listener; + +import org.jivesoftware.smackx.jingle_filetransfer.callback.IncomingJingleFileTransferCallback; +import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferPayload; + +/** + * Listener for incoming file transfers. + */ +public interface IncomingJingleFileTransferListener { + + void onIncomingJingleFileTransfer(JingleFileTransferPayload file, IncomingJingleFileTransferCallback callback); +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/listener/package-info.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/listener/package-info.java new file mode 100644 index 000000000..01b948e7e --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/listener/package-info.java @@ -0,0 +1,22 @@ +/** + * + * Copyright 2017 Paul Schaub + * + * 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. + */ + +/** + * Smack's API for XEP-0234: Jingle File Transfer. + * Listener classes. + */ +package org.jivesoftware.smackx.jingle_filetransfer.listener;