From df216b2141e43bcc72b5f0290b945a8013b900b3 Mon Sep 17 00:00:00 2001 From: vanitasvitae Date: Fri, 2 Jun 2017 18:45:11 +0200 Subject: [PATCH] More progress --- .../JingleFileTransferManager.java | 79 +++++++++++-- .../JingleFileTransferSession.java | 40 ++++++- .../IncomingJingleFileTransferCallback.java | 4 +- .../jingle_filetransfer/element/Checksum.java | 4 +- .../JingleContentDescriptionFileTransfer.java | 4 +- ... => JingleFileTransferPayloadElement.java} | 15 ++- .../handler/FileOfferHandler.java | 10 ++ .../handler/FileRequestHandler.java | 12 ++ ...ontentDescriptionFileTransferProvider.java | 90 ++------------- .../JingleFileTransferPayloadProvider.java | 108 ++++++++++++++++++ ...gleContentDescriptionFileTransferTest.java | 16 +-- ...JingleFileTransferPayloadElementTest.java} | 2 +- .../smackx/jingle/JingleSession.java | 12 ++ .../element/JingleContentDescription.java | 6 +- ...ngleContentDescriptionPayloadElement.java} | 4 +- ...ngleContentDescriptionPayloadProvider.java | 31 +++++ 16 files changed, 316 insertions(+), 121 deletions(-) rename smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/{JingleFileTransferPayload.java => JingleFileTransferPayloadElement.java} (89%) create mode 100644 smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/handler/FileOfferHandler.java create mode 100644 smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/handler/FileRequestHandler.java create mode 100644 smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/provider/JingleFileTransferPayloadProvider.java rename smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/{JingleFileTransferPayloadTest.java => JingleFileTransferPayloadElementTest.java} (97%) rename smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/{JingleContentDescriptionPayloadType.java => JingleContentDescriptionPayloadElement.java} (85%) create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleContentDescriptionPayloadProvider.java 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 7a3fa6bd0..3e57d2dd6 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 @@ -32,10 +32,14 @@ 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.element.JingleContentDescriptionPayloadElement; +import org.jivesoftware.smackx.jingle.element.JingleContentTransport; import org.jivesoftware.smackx.jingle.provider.JingleContentProviderManager; +import org.jivesoftware.smackx.jingle_filetransfer.callback.IncomingJingleFileTransferCallback; import org.jivesoftware.smackx.jingle_filetransfer.element.JingleContentDescriptionFileTransfer; -import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferPayload; +import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferPayloadElement; +import org.jivesoftware.smackx.jingle_filetransfer.handler.FileOfferHandler; +import org.jivesoftware.smackx.jingle_filetransfer.handler.FileRequestHandler; import org.jivesoftware.smackx.jingle_filetransfer.listener.IncomingJingleFileTransferListener; import org.jivesoftware.smackx.jingle_filetransfer.provider.JingleContentDescriptionFileTransferProvider; import org.jivesoftware.smackx.jingle_ibb.JingleInBandByteStreamManager; @@ -56,7 +60,7 @@ import java.util.logging.Logger; * * @author Paul Schaub */ -public final class JingleFileTransferManager extends Manager implements JingleHandler { +public final class JingleFileTransferManager extends Manager implements JingleHandler, FileOfferHandler, FileRequestHandler { private static final Logger LOGGER = Logger.getLogger(JingleFileTransferManager.class.getName()); @@ -106,10 +110,12 @@ public final class JingleFileTransferManager extends Manager implements JingleHa incomingJingleFileTransferListeners.remove(listener); } - public JingleFileTransferPayload createPayloadFromFile(File file) { - JingleFileTransferPayload.Builder payloadBuilder = JingleFileTransferPayload.getBuilder(); - - return payloadBuilder.build(); + public JingleFileTransferPayloadElement.Builder fileTransferPayloadBuilderFromFile(File file) { + JingleFileTransferPayloadElement.Builder payloadBuilder = JingleFileTransferPayloadElement.getBuilder(); + payloadBuilder.setDate(new Date(file.lastModified())); + payloadBuilder.setName(file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf(File.pathSeparator) + 1)); + payloadBuilder.setSize((int) file.length()); + return payloadBuilder; } /** @@ -120,10 +126,10 @@ public final class JingleFileTransferManager extends Manager implements JingleHa 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( + JingleFileTransferPayloadElement payload = new JingleFileTransferPayloadElement( lastModified, "A file", hashElement, "application/octet-stream", file.getName(), (int) file.length(), null); - ArrayList payloadTypes = new ArrayList<>(); + ArrayList payloadTypes = new ArrayList<>(); payloadTypes.add(payload); JingleContentDescriptionFileTransfer descriptionFileTransfer = new JingleContentDescriptionFileTransfer(payloadTypes); @@ -192,17 +198,17 @@ public final class JingleFileTransferManager extends Manager implements JingleHa case session_initiate: // File Offer if (content.getSenders() == JingleContent.Senders.initiator) { - + handleFileOffer(jingle); } //File Request else if (content.getSenders() == JingleContent.Senders.responder) { - + return handleFileRequest(jingle); } //Both or none else { throw new AssertionError("Undefined (see XEP-0234 ยง4.1)"); } - break; + //break; case session_terminate: case transport_accept: case transport_info: @@ -212,4 +218,53 @@ public final class JingleFileTransferManager extends Manager implements JingleHa } return null; } + + @Override + public void handleFileOffer(final Jingle jingle) { + IncomingJingleFileTransferCallback callback = new IncomingJingleFileTransferCallback() { + @Override + public void acceptFileTransfer(File target) throws SmackException.NotConnectedException, InterruptedException { + JingleContent content = jingle.getContents().get(0); + + //TODO: Find more suitable way to select transport methods. + JingleContentTransport preferredTransport = null; + for (JingleContentTransport t : content.getJingleTransports()) { + if (t.getNamespace().equals(JingleInBandByteStreamManager.NAMESPACE_V1)) { + preferredTransport = t; + } + } + + if (preferredTransport != null) { + Jingle.Builder acceptBuilder = Jingle.getBuilder(); + acceptBuilder.setResponder(connection().getUser()); + acceptBuilder.setSessionId(jingle.getSid()); + acceptBuilder.setAction(JingleAction.session_accept); + + JingleContent.Builder contentBuilder = JingleContent.getBuilder(); + contentBuilder.setCreator(content.getCreator()); + contentBuilder.setName(content.getName()); + contentBuilder.setSenders(content.getSenders()); + contentBuilder.setDescription(content.getDescription()); + contentBuilder.addTransport(preferredTransport); + + acceptBuilder.addJingleContent(contentBuilder.build()); + connection().sendStanza(acceptBuilder.build()); + } + } + + @Override + public void cancelFileTransfer() { + // Tear down the session. + } + }; + + for (IncomingJingleFileTransferListener l : incomingJingleFileTransferListeners) { + l.onIncomingJingleFileTransfer(jingle, callback); + } + } + + @Override + public IQ handleFileRequest(Jingle jingle) { + return null; + } } 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 index 51b5be6d7..c33670d57 100644 --- 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 @@ -16,7 +16,12 @@ */ package org.jivesoftware.smackx.jingle_filetransfer; +import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smackx.jingle.JingleSession; +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.JingleReason; import org.jxmpp.jid.Jid; /** @@ -30,22 +35,45 @@ public class JingleFileTransferSession extends JingleSession { /** * A user might choose to abort all active transfers. + * @return Jingle IQ that will abort all active transfers of this session. */ - public void abortAllActiveFileTransfers() { - + IQ abortAllActiveFileTransfers() { + Jingle.Builder builder = Jingle.getBuilder(); + builder.setResponder(getResponder().asFullJidOrThrow()); + builder.setInitiator(getInitiator().asFullJidOrThrow()); + builder.setAction(JingleAction.session_terminate); + builder.setSessionId(getSid()); + builder.setReason(JingleReason.Reason.cancel); + return builder.build(); } /** * A user might want to abort the transfer of a single file. + * @param content content which's transfer will be aborted. + * @return Jingle IQ that will abort the transfer of the given content. */ - public void abortSingleFileTransfer() { - + IQ abortSingleFileTransfer(JingleContent content) { + Jingle.Builder builder = Jingle.getBuilder(); + builder.setResponder(getResponder().asFullJidOrThrow()); + builder.setInitiator(getInitiator().asFullJidOrThrow()); + builder.setAction(JingleAction.content_remove); + builder.setSessionId(getSid()); + builder.addJingleContent(content); + builder.setReason(JingleReason.Reason.cancel); + return builder.build(); } /** * Successfully end session after all files have been transferred. + * @return Jingle IQ that will end the session. */ - void endSession() { - + IQ endSession() { + Jingle.Builder builder = Jingle.getBuilder(); + builder.setResponder(getResponder().asFullJidOrThrow()); + builder.setInitiator(getInitiator().asFullJidOrThrow()); + builder.setAction(JingleAction.session_terminate); + builder.setSessionId(getSid()); + builder.setReason(JingleReason.Reason.success); + return builder.build(); } } 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 index 7039ae3a0..d14ad31a2 100644 --- 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 @@ -16,6 +16,8 @@ */ package org.jivesoftware.smackx.jingle_filetransfer.callback; +import org.jivesoftware.smack.SmackException; + import java.io.File; /** @@ -23,7 +25,7 @@ import java.io.File; */ public interface IncomingJingleFileTransferCallback { - void acceptFileTransfer(File target); + void acceptFileTransfer(File target) throws SmackException.NotConnectedException, InterruptedException; void cancelFileTransfer(); } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/Checksum.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/Checksum.java index 3a144101a..fb1f516fe 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/Checksum.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/Checksum.java @@ -32,9 +32,9 @@ public class Checksum implements ExtensionElement { private final JingleContent.Creator creator; private final String name; - private JingleFileTransferPayload file; + private JingleFileTransferPayloadElement file; - public Checksum(JingleContent.Creator creator, String name, JingleFileTransferPayload file) { + public Checksum(JingleContent.Creator creator, String name, JingleFileTransferPayloadElement file) { this.creator = creator; this.name = name; Objects.requireNonNull(file.getHash(), "file MUST contain at least one hash element."); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleContentDescriptionFileTransfer.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleContentDescriptionFileTransfer.java index 970cfb372..5d99a65ba 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleContentDescriptionFileTransfer.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleContentDescriptionFileTransfer.java @@ -17,7 +17,7 @@ package org.jivesoftware.smackx.jingle_filetransfer.element; import org.jivesoftware.smackx.jingle.element.JingleContentDescription; -import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionPayloadType; +import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionPayloadElement; import org.jivesoftware.smackx.jingle_filetransfer.JingleFileTransferManager; import java.util.List; @@ -27,7 +27,7 @@ import java.util.List; */ public class JingleContentDescriptionFileTransfer extends JingleContentDescription { - public JingleContentDescriptionFileTransfer(List payloadTypes) { + public JingleContentDescriptionFileTransfer(List payloadTypes) { super(payloadTypes); } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleFileTransferPayload.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleFileTransferPayloadElement.java similarity index 89% rename from smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleFileTransferPayload.java rename to smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleFileTransferPayloadElement.java index c8a681ada..82bb5d16f 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleFileTransferPayload.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleFileTransferPayloadElement.java @@ -18,7 +18,7 @@ package org.jivesoftware.smackx.jingle_filetransfer.element; import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smackx.hash.element.HashElement; -import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionPayloadType; +import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionPayloadElement; import java.io.File; import java.util.Date; @@ -26,7 +26,7 @@ import java.util.Date; /** * Content of type File. */ -public class JingleFileTransferPayload extends JingleContentDescriptionPayloadType { +public class JingleFileTransferPayloadElement extends JingleContentDescriptionPayloadElement { public static final String ELEMENT = "file"; public static final String ELEM_DATE = "date"; public static final String ELEM_DESC = "desc"; @@ -42,7 +42,7 @@ public class JingleFileTransferPayload extends JingleContentDescriptionPayloadTy private final int size; private final Range range; - public JingleFileTransferPayload(Date date, String desc, HashElement hash, String mediaType, String name, int size, Range range) { + public JingleFileTransferPayloadElement(Date date, String desc, HashElement hash, String mediaType, String name, int size, Range range) { this.date = date; this.desc = desc; this.hash = hash; @@ -107,6 +107,11 @@ public class JingleFileTransferPayload extends JingleContentDescriptionPayloadTy return new Builder(); } + @Override + public String getNamespace() { + return null; + } + public static final class Builder { private Date date; private String desc; @@ -154,8 +159,8 @@ public class JingleFileTransferPayload extends JingleContentDescriptionPayloadTy return this; } - public JingleFileTransferPayload build() { - return new JingleFileTransferPayload(date, desc, hash, mediaType, name, size, range); + public JingleFileTransferPayloadElement build() { + return new JingleFileTransferPayloadElement(date, desc, hash, mediaType, name, size, range); } public Builder setFile(File file) { diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/handler/FileOfferHandler.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/handler/FileOfferHandler.java new file mode 100644 index 000000000..160cedd76 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/handler/FileOfferHandler.java @@ -0,0 +1,10 @@ +package org.jivesoftware.smackx.jingle_filetransfer.handler; + +import org.jivesoftware.smackx.jingle.element.Jingle; + +/** + * Created by vanitas on 02.06.17. + */ +public interface FileOfferHandler { + void handleFileOffer(Jingle jingle); +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/handler/FileRequestHandler.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/handler/FileRequestHandler.java new file mode 100644 index 000000000..2627eb633 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/handler/FileRequestHandler.java @@ -0,0 +1,12 @@ +package org.jivesoftware.smackx.jingle_filetransfer.handler; + +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smackx.jingle.element.Jingle; + +/** + * Created by vanitas on 02.06.17. + */ +public interface FileRequestHandler { + + IQ handleFileRequest(Jingle jingle); +} 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 f517999bb..8850f40a3 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 @@ -16,14 +16,10 @@ */ package org.jivesoftware.smackx.jingle_filetransfer.provider; -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.element.JingleContentDescriptionPayloadElement; import org.jivesoftware.smackx.jingle.provider.JingleContentDescriptionProvider; import org.jivesoftware.smackx.jingle_filetransfer.element.JingleContentDescriptionFileTransfer; -import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferPayload; -import org.jivesoftware.smackx.jingle_filetransfer.element.Range; -import org.jxmpp.util.XmppDateTime; +import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferPayloadElement; import org.xmlpull.v1.XmlPullParser; import java.util.ArrayList; @@ -38,86 +34,22 @@ public class JingleContentDescriptionFileTransferProvider extends JingleContentDescriptionProvider { @Override public JingleContentDescriptionFileTransfer parse(XmlPullParser parser, int initialDepth) throws Exception { - - boolean inRange = false; - - JingleFileTransferPayload.Builder builder = JingleFileTransferPayload.getBuilder(); - HashElement inRangeHash = null; - - ArrayList payloads = new ArrayList<>(); - - int offset = 0; - int length = -1; - + ArrayList payloads = new ArrayList<>(); while (true) { - int tag = parser.nextTag(); - String elem = parser.getName(); + String name = parser.getName(); if (tag == START_TAG) { - switch (elem) { - - case JingleFileTransferPayload.ELEMENT: - builder = JingleFileTransferPayload.getBuilder(); - break; - - case JingleFileTransferPayload.ELEM_DATE: - builder.setDate(XmppDateTime.parseXEP0082Date(parser.nextText())); - break; - - case JingleFileTransferPayload.ELEM_DESC: - builder.setDescription(parser.nextText()); - break; - - case JingleFileTransferPayload.ELEM_MEDIA_TYPE: - builder.setMediaType(parser.nextText()); - break; - - case JingleFileTransferPayload.ELEM_NAME: - builder.setName(parser.nextText()); - break; - - case JingleFileTransferPayload.ELEM_SIZE: - builder.setSize(Integer.parseInt(parser.nextText())); - break; - - case Range.ELEMENT: - inRange = true; - String offsetString = parser.getAttributeValue(null, Range.ATTR_OFFSET); - String lengthString = parser.getAttributeValue(null, Range.ATTR_LENGTH); - offset = (offsetString != null ? Integer.parseInt(offsetString) : 0); - length = (lengthString != null ? Integer.parseInt(lengthString) : -1); - - if (parser.isEmptyElementTag()) { - inRange = false; - builder.setRange(new Range(offset, length)); - } - break; - - case HashElement.ELEMENT: - if (inRange) { - inRangeHash = new HashElementProvider().parse(parser); - } else { - builder.setHash(new HashElementProvider().parse(parser)); - } + switch (name) { + case JingleFileTransferPayloadElement.ELEMENT: + payloads.add(new JingleFileTransferPayloadProvider().parse(parser)); break; } + } - } else if (tag == END_TAG) { - switch (elem) { - - case Range.ELEMENT: - inRange = false; - builder.setRange(new Range(offset, length, inRangeHash)); - inRangeHash = null; - break; - - case JingleFileTransferPayload.ELEMENT: - payloads.add(builder.build()); - break; - - case JingleContentDescriptionFileTransfer.ELEMENT: - return new JingleContentDescriptionFileTransfer(payloads); + if (tag == END_TAG) { + if (name.equals(JingleContentDescriptionFileTransfer.ELEMENT)) { + return new JingleContentDescriptionFileTransfer(payloads); } } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/provider/JingleFileTransferPayloadProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/provider/JingleFileTransferPayloadProvider.java new file mode 100644 index 000000000..2c2a63630 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/provider/JingleFileTransferPayloadProvider.java @@ -0,0 +1,108 @@ +/** + * + * 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.provider; + +import org.jivesoftware.smackx.hash.element.HashElement; +import org.jivesoftware.smackx.hash.provider.HashElementProvider; +import org.jivesoftware.smackx.jingle.provider.JingleContentDescriptionPayloadProvider; +import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferPayloadElement; +import org.jivesoftware.smackx.jingle_filetransfer.element.Range; +import org.jxmpp.util.XmppDateTime; +import org.xmlpull.v1.XmlPullParser; + +import static org.xmlpull.v1.XmlPullParser.END_TAG; +import static org.xmlpull.v1.XmlPullParser.START_TAG; + +/** + * Provider for JingleFileTransferPayloadElements. + */ +public class JingleFileTransferPayloadProvider extends JingleContentDescriptionPayloadProvider { + + @Override + public JingleFileTransferPayloadElement parse(XmlPullParser parser, int initialDepth) throws Exception { + boolean inRange = false; + JingleFileTransferPayloadElement.Builder builder = JingleFileTransferPayloadElement.getBuilder(); + HashElement inRangeHash = null; + + int offset = 0; + int length = -1; + + while (true) { + + int tag = parser.nextTag(); + String elem = parser.getName(); + + if (tag == START_TAG) { + switch (elem) { + case JingleFileTransferPayloadElement.ELEM_DATE: + builder.setDate(XmppDateTime.parseXEP0082Date(parser.nextText())); + break; + + case JingleFileTransferPayloadElement.ELEM_DESC: + builder.setDescription(parser.nextText()); + break; + + case JingleFileTransferPayloadElement.ELEM_MEDIA_TYPE: + builder.setMediaType(parser.nextText()); + break; + + case JingleFileTransferPayloadElement.ELEM_NAME: + builder.setName(parser.nextText()); + break; + + case JingleFileTransferPayloadElement.ELEM_SIZE: + builder.setSize(Integer.parseInt(parser.nextText())); + break; + + case Range.ELEMENT: + inRange = true; + String offsetString = parser.getAttributeValue(null, Range.ATTR_OFFSET); + String lengthString = parser.getAttributeValue(null, Range.ATTR_LENGTH); + offset = (offsetString != null ? Integer.parseInt(offsetString) : 0); + length = (lengthString != null ? Integer.parseInt(lengthString) : -1); + + if (parser.isEmptyElementTag()) { + inRange = false; + builder.setRange(new Range(offset, length)); + } + break; + + case HashElement.ELEMENT: + if (inRange) { + inRangeHash = new HashElementProvider().parse(parser); + } else { + builder.setHash(new HashElementProvider().parse(parser)); + } + break; + } + + } else if (tag == END_TAG) { + switch (elem) { + + case Range.ELEMENT: + inRange = false; + builder.setRange(new Range(offset, length, inRangeHash)); + inRangeHash = null; + break; + + case JingleFileTransferPayloadElement.ELEMENT: + return builder.build(); + } + } + } + } +} 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 746b1bc08..1bb461d47 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 @@ -21,8 +21,8 @@ import org.jivesoftware.smack.test.util.TestUtils; 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.JingleFileTransferPayload; +import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionPayloadElement; +import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferPayloadElement; import org.jivesoftware.smackx.jingle_filetransfer.element.JingleContentDescriptionFileTransfer; import org.jivesoftware.smackx.jingle_filetransfer.element.Range; import org.jivesoftware.smackx.jingle_filetransfer.provider.JingleContentDescriptionFileTransferProvider; @@ -66,9 +66,9 @@ public class JingleContentDescriptionFileTransferTest extends SmackTestSuite { HashElement hashElement = new HashElement(algorithm, hashB64); Range range = new Range(); Date date = XmppDateTime.parseDate(dateString); - JingleFileTransferPayload jingleFileTransferPayload = new JingleFileTransferPayload(date, descriptionString, hashElement, mediaTypeString, nameString, sizeInt, range); - ArrayList payloads = new ArrayList<>(); - payloads.add(jingleFileTransferPayload); + JingleFileTransferPayloadElement jingleFileTransferPayloadElement = new JingleFileTransferPayloadElement(date, descriptionString, hashElement, mediaTypeString, nameString, sizeInt, range); + ArrayList payloads = new ArrayList<>(); + payloads.add(jingleFileTransferPayloadElement); JingleContentDescriptionFileTransfer descriptionFileTransfer = new JingleContentDescriptionFileTransfer(payloads); @@ -78,7 +78,7 @@ public class JingleContentDescriptionFileTransferTest extends SmackTestSuite { .parse(TestUtils.getParser(xml)); assertEquals(xml, parsed.toXML().toString()); - JingleFileTransferPayload payload = (JingleFileTransferPayload) parsed.getJinglePayloadTypes().get(0); + JingleFileTransferPayloadElement payload = (JingleFileTransferPayloadElement) parsed.getJinglePayloadTypes().get(0); assertEquals(date, payload.getDate()); assertEquals(descriptionString, payload.getDescription()); assertEquals(mediaTypeString, payload.getMediaType()); @@ -107,8 +107,8 @@ public class JingleContentDescriptionFileTransferTest extends SmackTestSuite { "" + "" + ""; - JingleFileTransferPayload payload = new JingleFileTransferPayload(null, null, null, null, null, -1, range); - ArrayList list = new ArrayList<>(); + JingleFileTransferPayloadElement payload = new JingleFileTransferPayloadElement(null, null, null, null, null, -1, range); + ArrayList list = new ArrayList<>(); list.add(payload); JingleContentDescriptionFileTransfer fileTransfer = new JingleContentDescriptionFileTransfer(list); assertEquals(xml, fileTransfer.toXML().toString()); diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferPayloadTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferPayloadElementTest.java similarity index 97% rename from smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferPayloadTest.java rename to smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferPayloadElementTest.java index 7edb14ce7..e8df721cc 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferPayloadTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferPayloadElementTest.java @@ -29,7 +29,7 @@ import static junit.framework.TestCase.assertNull; /** * Test the JingleContentFile class. */ -public class JingleFileTransferPayloadTest extends SmackTestSuite { +public class JingleFileTransferPayloadElementTest extends SmackTestSuite { @Test public void rangeTest() throws Exception { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleSession.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleSession.java index e86223371..e9cbc30b7 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleSession.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleSession.java @@ -41,6 +41,18 @@ public class JingleSession { return hashCode; } + public String getSid() { + return sid; + } + + public Jid getInitiator() { + return initiator; + } + + public Jid getResponder() { + return responder; + } + @Override public boolean equals(Object other) { if (!(other instanceof JingleSession)) { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentDescription.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentDescription.java index a67db188e..68c3482b5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentDescription.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentDescription.java @@ -30,9 +30,9 @@ public abstract class JingleContentDescription implements ExtensionElement { public static final String ELEMENT = "description"; - private final List payloads; + private final List payloads; - protected JingleContentDescription(List payloads) { + protected JingleContentDescription(List payloads) { if (payloads != null) { this.payloads = Collections.unmodifiableList(payloads); } @@ -46,7 +46,7 @@ public abstract class JingleContentDescription implements ExtensionElement { return ELEMENT; } - public List getJinglePayloadTypes() { + public List getJinglePayloadTypes() { return payloads; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentDescriptionPayloadType.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentDescriptionPayloadElement.java similarity index 85% rename from smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentDescriptionPayloadType.java rename to smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentDescriptionPayloadElement.java index ff525b0c1..2d5613999 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentDescriptionPayloadType.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContentDescriptionPayloadElement.java @@ -16,13 +16,13 @@ */ package org.jivesoftware.smackx.jingle.element; -import org.jivesoftware.smack.packet.NamedElement; +import org.jivesoftware.smack.packet.ExtensionElement; /** * An element found usually in 'description' elements. * */ -public abstract class JingleContentDescriptionPayloadType implements NamedElement { +public abstract class JingleContentDescriptionPayloadElement implements ExtensionElement { public static final String ELEMENT = "payload-type"; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleContentDescriptionPayloadProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleContentDescriptionPayloadProvider.java new file mode 100644 index 000000000..364167bdd --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleContentDescriptionPayloadProvider.java @@ -0,0 +1,31 @@ +/** + * + * 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.provider; + +import org.jivesoftware.smack.provider.ExtensionElementProvider; +import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionPayloadElement; +import org.xmlpull.v1.XmlPullParser; + +/** + * Provider for JingleContentDescriptionPayloadElements. + */ +public abstract class JingleContentDescriptionPayloadProvider + extends ExtensionElementProvider { + + @Override + public abstract D parse(XmlPullParser parser, int initialDepth) throws Exception; +}