Merge branch 'jftPR' into jetPR

This commit is contained in:
vanitasvitae 2017-08-25 16:35:03 +02:00
commit 3260429200
23 changed files with 160 additions and 26 deletions

View File

@ -59,22 +59,33 @@ import org.jivesoftware.smackx.jingle_filetransfer.provider.JingleFileTransferPr
import org.jxmpp.jid.FullJid; import org.jxmpp.jid.FullJid;
/** /**
* Created by vanitas on 22.07.17. * Manager for XEP-0234 - JingleFileTransfers.
*/ */
public final class JingleFileTransferManager extends Manager implements JingleDescriptionManager { public final class JingleFileTransferManager extends Manager implements JingleDescriptionManager {
private static final Logger LOGGER = Logger.getLogger(JingleFileTransferManager.class.getName()); private static final Logger LOGGER = Logger.getLogger(JingleFileTransferManager.class.getName());
private static final WeakHashMap<XMPPConnection, JingleFileTransferManager> INSTANCES = new WeakHashMap<>(); private static final WeakHashMap<XMPPConnection, JingleFileTransferManager> INSTANCES = new WeakHashMap<>();
/**
* Reference to the JingleManager of the connection.
*/
private final JingleManager jingleManager; private final JingleManager jingleManager;
/**
* Listeners for incoming file offers.
*/
private final List<IncomingFileOfferListener> offerListeners = private final List<IncomingFileOfferListener> offerListeners =
Collections.synchronizedList(new ArrayList<IncomingFileOfferListener>()); Collections.synchronizedList(new ArrayList<IncomingFileOfferListener>());
/**
* Listeners for incoming file requests.
*/
private final List<IncomingFileRequestListener> requestListeners = private final List<IncomingFileRequestListener> requestListeners =
Collections.synchronizedList(new ArrayList<IncomingFileRequestListener>()); Collections.synchronizedList(new ArrayList<IncomingFileRequestListener>());
static { static {
// Register adapters and providers.
JingleManager.addJingleDescriptionAdapter(new JingleFileTransferAdapter()); JingleManager.addJingleDescriptionAdapter(new JingleFileTransferAdapter());
JingleManager.addJingleDescriptionProvider(new JingleFileTransferProvider()); JingleManager.addJingleDescriptionProvider(new JingleFileTransferProvider());
} }

View File

@ -31,9 +31,10 @@ import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferChi
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferElement; import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferElement;
/** /**
* Created by vanitas on 28.07.17. * Adapter to convert JingleFileTransferElements (element) to JingleFileTransfer objects (component).
*/ */
public class JingleFileTransferAdapter implements JingleDescriptionAdapter<JingleFileTransfer> { public class JingleFileTransferAdapter implements JingleDescriptionAdapter<JingleFileTransfer> {
private static final Logger LOGGER = Logger.getLogger(JingleFileTransferAdapter.class.getName()); private static final Logger LOGGER = Logger.getLogger(JingleFileTransferAdapter.class.getName());
@Override @Override

View File

@ -17,7 +17,7 @@
package org.jivesoftware.smackx.jingle_filetransfer.component; package org.jivesoftware.smackx.jingle_filetransfer.component;
/** /**
* Created by vanitas on 22.07.17. * This class represents the base of a JingleFileOffer.
*/ */
public abstract class AbstractJingleFileOffer extends JingleFileTransfer { public abstract class AbstractJingleFileOffer extends JingleFileTransfer {

View File

@ -17,7 +17,8 @@
package org.jivesoftware.smackx.jingle_filetransfer.component; package org.jivesoftware.smackx.jingle_filetransfer.component;
/** /**
* Created by vanitas on 22.07.17. * Class representing the base of a JingleFileRequest.
* TODO: Implement.
*/ */
public abstract class AbstractJingleFileRequest extends JingleFileTransfer { public abstract class AbstractJingleFileRequest extends JingleFileTransfer {

View File

@ -29,8 +29,7 @@ import org.jivesoftware.smackx.hashes.element.HashElement;
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferChildElement; import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferChildElement;
/** /**
* Represent a file sent in a file transfer. * Represent a file sent in a file transfer. This class contains metadata of the transferred file.
* This can be both LocalFile (available to the client), or RemoteFile (file not yet available).
*/ */
public class JingleFile { public class JingleFile {

View File

@ -33,7 +33,7 @@ import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferEle
import org.jivesoftware.smackx.jingle_filetransfer.listener.ProgressListener; import org.jivesoftware.smackx.jingle_filetransfer.listener.ProgressListener;
/** /**
* Created by vanitas on 22.07.17. * Base class of a Jingle File Transfer.
*/ */
public abstract class JingleFileTransfer extends JingleDescription<JingleFileTransferElement> implements JingleFileTransferController { public abstract class JingleFileTransfer extends JingleDescription<JingleFileTransferElement> implements JingleFileTransferController {
@ -48,12 +48,24 @@ public abstract class JingleFileTransfer extends JingleDescription<JingleFileTra
private final List<ProgressListener> progressListeners = Collections.synchronizedList(new ArrayList<ProgressListener>()); private final List<ProgressListener> progressListeners = Collections.synchronizedList(new ArrayList<ProgressListener>());
/**
* Create a new JingleFileTransfer.
* @param metadata metadata of the transferred file.
*/
JingleFileTransfer(JingleFile metadata) { JingleFileTransfer(JingleFile metadata) {
this.metadata = metadata; this.metadata = metadata;
} }
/**
* Is this a file offer?
* @return file offer?
*/
public abstract boolean isOffer(); public abstract boolean isOffer();
/**
* Is this a file request?
* @return file request?
*/
public abstract boolean isRequest(); public abstract boolean isRequest();
@Override @Override
@ -92,12 +104,21 @@ public abstract class JingleFileTransfer extends JingleDescription<JingleFileTra
state = State.cancelled; state = State.cancelled;
} }
/**
* Notify ProgressListeners, that the transmission has started. This happens after the negotiation is complete,
* when the transports are ready.
*/
public void notifyProgressListenersStarted() { public void notifyProgressListenersStarted() {
for (ProgressListener p : progressListeners) { for (ProgressListener p : progressListeners) {
p.started(); p.started();
} }
} }
/**
* Notify ProgressListeners, that the transmission has been terminated. This might happen at all times during the
* lifetime of the session.
* @param reason reason of termination.
*/
public void notifyProgressListenersTerminated(JingleReasonElement.Reason reason) { public void notifyProgressListenersTerminated(JingleReasonElement.Reason reason) {
for (ProgressListener p : progressListeners) { for (ProgressListener p : progressListeners) {
p.terminated(reason); p.terminated(reason);

View File

@ -41,8 +41,7 @@ import org.jivesoftware.smackx.jingle_filetransfer.controller.IncomingFileOfferC
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferChildElement; import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferChildElement;
/** /**
* Behind the scenes logic of an incoming Jingle file offer. * Behind the scenes logic of an incoming Jingle file offer (They offer a file).
* Created by vanitas on 26.07.17.
*/ */
public class JingleIncomingFileOffer extends AbstractJingleFileOffer implements IncomingFileOfferController { public class JingleIncomingFileOffer extends AbstractJingleFileOffer implements IncomingFileOfferController {

View File

@ -24,8 +24,8 @@ import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferChi
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferElement; import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferElement;
/** /**
* Created by vanitas on 27.07.17. * Backend logic of an incoming file request (They request a file).
* TODO: RemoteFile???? * TODO: Implement.
*/ */
public class JingleIncomingFileRequest extends AbstractJingleFileRequest implements IncomingFileRequestController { public class JingleIncomingFileRequest extends AbstractJingleFileRequest implements IncomingFileRequestController {

View File

@ -32,7 +32,7 @@ import org.jivesoftware.smackx.jingle.element.JingleReasonElement;
import org.jivesoftware.smackx.jingle_filetransfer.controller.OutgoingFileOfferController; import org.jivesoftware.smackx.jingle_filetransfer.controller.OutgoingFileOfferController;
/** /**
* Created by vanitas on 26.07.17. * Backend logic of an outgoing file offer (We offer a file).
*/ */
public class JingleOutgoingFileOffer extends AbstractJingleFileOffer implements OutgoingFileOfferController { public class JingleOutgoingFileOffer extends AbstractJingleFileOffer implements OutgoingFileOfferController {
private static final Logger LOGGER = Logger.getLogger(JingleOutgoingFileOffer.class.getName()); private static final Logger LOGGER = Logger.getLogger(JingleOutgoingFileOffer.class.getName());

View File

@ -22,7 +22,7 @@ import org.jivesoftware.smackx.jingle.element.JingleElement;
import org.jivesoftware.smackx.jingle_filetransfer.controller.OutgoingFileRequestController; import org.jivesoftware.smackx.jingle_filetransfer.controller.OutgoingFileRequestController;
/** /**
* Created by vanitas on 27.07.17. * Backend logic of an outgoing file request (We request a file).
*/ */
public class JingleOutgoingFileRequest extends AbstractJingleFileRequest implements OutgoingFileRequestController { public class JingleOutgoingFileRequest extends AbstractJingleFileRequest implements OutgoingFileRequestController {

View File

@ -25,11 +25,31 @@ import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException;
/** /**
* User interface for an incoming Jingle file offer. * Interface with methods of an incoming file offer, that are exposed to the user.
*/ */
public interface IncomingFileOfferController extends JingleFileTransferController { public interface IncomingFileOfferController extends JingleFileTransferController {
/**
* Accept an incoming file offer.
* @param connection connection.
* @param target file to save the incoming data to.
* @throws InterruptedException
* @throws XMPPException.XMPPErrorException
* @throws SmackException.NotConnectedException
* @throws SmackException.NoResponseException
* @throws IOException
*/
void accept(XMPPConnection connection, File target) throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException, IOException; void accept(XMPPConnection connection, File target) throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException, IOException;
/**
* Accept an incoming file offer.
* @param connection connection.
* @param outputStream outputStream, to stream the incoming data to.
* @throws InterruptedException
* @throws XMPPException.XMPPErrorException
* @throws SmackException.NotConnectedException
* @throws SmackException.NoResponseException
* @throws IOException
*/
void accept(XMPPConnection connection, OutputStream outputStream) throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException, IOException; void accept(XMPPConnection connection, OutputStream outputStream) throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException, IOException;
} }

View File

@ -17,7 +17,7 @@
package org.jivesoftware.smackx.jingle_filetransfer.controller; package org.jivesoftware.smackx.jingle_filetransfer.controller;
/** /**
* Created by vanitas on 27.07.17. * Interface with methods of an incoming file request, that are exposed to the user.
*/ */
public interface IncomingFileRequestController extends JingleFileTransferController { public interface IncomingFileRequestController extends JingleFileTransferController {
//TODO: Declare methods. //TODO: Declare methods.

View File

@ -23,15 +23,33 @@ import org.jivesoftware.smackx.jingle_filetransfer.component.JingleFile;
import org.jivesoftware.smackx.jingle_filetransfer.listener.ProgressListener; import org.jivesoftware.smackx.jingle_filetransfer.listener.ProgressListener;
/** /**
* User interface for Jingle file transfers. * Interface with methods of a jingle file transfer, that are exposed to the user.
*/ */
public interface JingleFileTransferController extends JingleDescriptionController { public interface JingleFileTransferController extends JingleDescriptionController {
/**
* Add a ProgressListener.
* @param listener listener
*/
void addProgressListener(ProgressListener listener); void addProgressListener(ProgressListener listener);
/**
* Remove a ProgressListener.
* @param listener listener
*/
void removeProgressListener(ProgressListener listener); void removeProgressListener(ProgressListener listener);
/**
* Get the JingleFile object containing metadata about the transferred file.
* @return metadata
*/
JingleFile getMetadata(); JingleFile getMetadata();
/**
* Actively cancel the file transfer.
* @param connection connection
* @throws SmackException.NotConnectedException
* @throws InterruptedException
*/
void cancel(XMPPConnection connection) throws SmackException.NotConnectedException, InterruptedException; void cancel(XMPPConnection connection) throws SmackException.NotConnectedException, InterruptedException;
} }

View File

@ -17,7 +17,7 @@
package org.jivesoftware.smackx.jingle_filetransfer.controller; package org.jivesoftware.smackx.jingle_filetransfer.controller;
/** /**
* Created by vanitas on 27.07.17. * Interface with methods of an outgoing file offer, that are exposed to the user.
*/ */
public interface OutgoingFileOfferController extends JingleFileTransferController { public interface OutgoingFileOfferController extends JingleFileTransferController {
//TODO: Declare methods. //TODO: Declare methods.

View File

@ -17,7 +17,7 @@
package org.jivesoftware.smackx.jingle_filetransfer.controller; package org.jivesoftware.smackx.jingle_filetransfer.controller;
/** /**
* Created by vanitas on 27.07.17. * Interface with methods of an outgoing file request, that are exposed to the user.
*/ */
public interface OutgoingFileRequestController extends JingleFileTransferController { public interface OutgoingFileRequestController extends JingleFileTransferController {
//TODO: Declare methods. //TODO: Declare methods.

View File

@ -23,7 +23,7 @@ import org.jivesoftware.smackx.jingle.element.JingleContentElement;
import org.jivesoftware.smackx.jingle_filetransfer.component.JingleFileTransfer; import org.jivesoftware.smackx.jingle_filetransfer.component.JingleFileTransfer;
/** /**
* Checksum element. * Checksum element declared in <a href="https://xmpp.org/extensions/xep-0234.html#hash">XEP-0234</a>.
*/ */
public class ChecksumElement implements ExtensionElement { public class ChecksumElement implements ExtensionElement {
@ -35,6 +35,12 @@ public class ChecksumElement implements ExtensionElement {
private final String name; private final String name;
private final JingleFileTransferChildElement file; private final JingleFileTransferChildElement file;
/**
* Create a new ChecksumElement.
* @param creator creator of the content (party that added the file to the transmission).
* @param name name of the content.
* @param file metadata of the file.
*/
public ChecksumElement(JingleContentElement.Creator creator, String name, JingleFileTransferChildElement file) { public ChecksumElement(JingleContentElement.Creator creator, String name, JingleFileTransferChildElement file) {
this.creator = creator; this.creator = creator;
this.name = name; this.name = name;

View File

@ -24,7 +24,7 @@ import org.jivesoftware.smackx.hashes.element.HashElement;
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionChildElement; import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionChildElement;
/** /**
* Content of type File. * Metadata about the transferred file.
*/ */
public class JingleFileTransferChildElement extends JingleContentDescriptionChildElement { public class JingleFileTransferChildElement extends JingleContentDescriptionChildElement {
@ -43,6 +43,16 @@ public class JingleFileTransferChildElement extends JingleContentDescriptionChil
private final long size; private final long size;
private final Range range; private final Range range;
/**
* Create a new JingleFileTransferChildElement.
* @param date last-modified date of the file.
* @param desc description of the file.
* @param hash hash value of the file (see XEP-0300).
* @param mediaType mediaType (https://www.iana.org/assignments/media-types/media-types.xhtml).
* @param name name of the file.
* @param size size of the file in bytes.
* @param range range of the transfer (see https://xmpp.org/extensions/xep-0234.html#range).
*/
public JingleFileTransferChildElement(Date date, String desc, HashElement hash, String mediaType, String name, long size, Range range) { public JingleFileTransferChildElement(Date date, String desc, HashElement hash, String mediaType, String name, long size, Range range) {
this.date = date; this.date = date;
this.desc = desc; this.desc = desc;
@ -53,30 +63,58 @@ public class JingleFileTransferChildElement extends JingleContentDescriptionChil
this.range = range; this.range = range;
} }
/**
* Return the last-modified date of the file.
* @return date.
*/
public Date getDate() { public Date getDate() {
return date; return date;
} }
/**
* Return the description of the file.
* @return description.
*/
public String getDescription() { public String getDescription() {
return desc; return desc;
} }
/**
* Return the hash of the file.
* @return hash.
*/
public HashElement getHash() { public HashElement getHash() {
return hash; return hash;
} }
/**
* Return the mediaType of the file (https://www.iana.org/assignments/media-types/media-types.xhtml).
* @return media-type.
*/
public String getMediaType() { public String getMediaType() {
return mediaType; return mediaType;
} }
/**
* Return the name of the file.
* @return filename.
*/
public String getName() { public String getName() {
return name; return name;
} }
/**
* Return the size of the file in bytes.
* @return size.
*/
public long getSize() { public long getSize() {
return size; return size;
} }
/**
* In case of a ranged transfer: Return the range of the transmission. Otherwise return null.
* @return range of the transfer.
*/
public Range getRange() { public Range getRange() {
return range; return range;
} }

View File

@ -24,7 +24,7 @@ import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement;
import org.jivesoftware.smackx.jingle_filetransfer.component.JingleFileTransfer; import org.jivesoftware.smackx.jingle_filetransfer.component.JingleFileTransfer;
/** /**
* File element. * Jingle File Transfer Element.
*/ */
public class JingleFileTransferElement extends JingleContentDescriptionElement { public class JingleFileTransferElement extends JingleContentDescriptionElement {
@ -34,6 +34,9 @@ public class JingleFileTransferElement extends JingleContentDescriptionElement {
public JingleFileTransferElement(List<JingleContentDescriptionChildElement> payloads) { public JingleFileTransferElement(List<JingleContentDescriptionChildElement> payloads) {
super(payloads); super(payloads);
if (payloads.size() != 1) {
throw new IllegalArgumentException("Jingle File Transfers only support one payload element.");
}
} }
@Override @Override

View File

@ -19,9 +19,13 @@ package org.jivesoftware.smackx.jingle_filetransfer.listener;
import org.jivesoftware.smackx.jingle_filetransfer.controller.IncomingFileOfferController; import org.jivesoftware.smackx.jingle_filetransfer.controller.IncomingFileOfferController;
/** /**
* Created by vanitas on 26.07.17. * Listener for incoming file offers.
*/ */
public interface IncomingFileOfferListener { public interface IncomingFileOfferListener {
/**
* Notify client of an incoming file offer.
* @param offer offer.
*/
void onIncomingFileOffer(IncomingFileOfferController offer); void onIncomingFileOffer(IncomingFileOfferController offer);
} }

View File

@ -19,9 +19,13 @@ package org.jivesoftware.smackx.jingle_filetransfer.listener;
import org.jivesoftware.smackx.jingle_filetransfer.controller.IncomingFileRequestController; import org.jivesoftware.smackx.jingle_filetransfer.controller.IncomingFileRequestController;
/** /**
* Created by vanitas on 27.07.17. * Listener for incoming file requests.
*/ */
public interface IncomingFileRequestListener { public interface IncomingFileRequestListener {
/**
* Notify the client of an incoming file request.
* @param request request.
*/
void onIncomingFileRequest(IncomingFileRequestController request); void onIncomingFileRequest(IncomingFileRequestController request);
} }

View File

@ -19,11 +19,18 @@ package org.jivesoftware.smackx.jingle_filetransfer.listener;
import org.jivesoftware.smackx.jingle.element.JingleReasonElement; import org.jivesoftware.smackx.jingle.element.JingleReasonElement;
/** /**
* Created by vanitas on 27.07.17. * ProgressListener that listens for progress changes of a file transfer.
*/ */
public interface ProgressListener { public interface ProgressListener {
/**
* Bytestream transmission has stared. This usually happens after the negotiation is finished.
*/
void started(); void started();
/**
* Transfer has been terminated. This might happen at all times.
* @param reason reason (eg. cancel).
*/
void terminated(JingleReasonElement.Reason reason); void terminated(JingleReasonElement.Reason reason);
} }

View File

@ -36,6 +36,8 @@ import org.xmlpull.v1.XmlPullParser;
*/ */
public class ChecksumProvider extends ExtensionElementProvider<ChecksumElement> { public class ChecksumProvider extends ExtensionElementProvider<ChecksumElement> {
private static HashElementProvider hashProvider = new HashElementProvider();
@Override @Override
public ChecksumElement parse(XmlPullParser parser, int initialDepth) throws Exception { public ChecksumElement parse(XmlPullParser parser, int initialDepth) throws Exception {
JingleContentElement.Creator creator = null; JingleContentElement.Creator creator = null;
@ -58,7 +60,7 @@ public class ChecksumProvider extends ExtensionElementProvider<ChecksumElement>
if (tag == START_TAG) { if (tag == START_TAG) {
switch (n) { switch (n) {
case HashElement.ELEMENT: case HashElement.ELEMENT:
hashElement = new HashElementProvider().parse(parser); hashElement = hashProvider.parse(parser);
break; break;
case Range.ELEMENT: case Range.ELEMENT:

View File

@ -19,7 +19,7 @@ package org.jivesoftware.smackx.jingle.element;
import org.jivesoftware.smack.packet.NamedElement; import org.jivesoftware.smack.packet.NamedElement;
/** /**
* Created by vanitas on 28.07.17. * Info child element of a Jingle Content Description element.
*/ */
public abstract class JingleContentDescriptionInfoElement implements NamedElement { public abstract class JingleContentDescriptionInfoElement implements NamedElement {