Anonymous progress

This commit is contained in:
vanitasvitae 2017-07-27 00:12:42 +02:00
parent 186dfd224e
commit 4234e1d5ab
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
14 changed files with 180 additions and 22 deletions

View File

@ -0,0 +1,26 @@
package org.jivesoftware.smackx.jft;
import java.io.File;
import org.jivesoftware.smackx.jft.internal.JingleIncomingFileOffer;
/**
* Created by vanitas on 26.07.17.
*/
public class IncomingFileTransferCallback {
private JingleIncomingFileOffer offer;
public IncomingFileTransferCallback(JingleIncomingFileOffer offer) {
this.offer = offer;
}
public JingleIncomingFileOffer accept(File target) {
offer.accept(target);
return offer;
}
public void decline() {
offer.decline();
}
}

View File

@ -0,0 +1,9 @@
package org.jivesoftware.smackx.jft;
/**
* Created by vanitas on 26.07.17.
*/
public interface IncomingFileTransferListener {
void onIncomingFileTransfer(IncomingFileTransferCallback callback);
}

View File

@ -1,18 +1,30 @@
package org.jivesoftware.smackx.jft;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.WeakHashMap;
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.jft.internal.JingleFileTransfer;
import org.jivesoftware.smackx.jft.internal.JingleIncomingFileOffer;
import org.jivesoftware.smackx.jft.internal.JingleOutgoingFileOffer;
import org.jivesoftware.smackx.jft.provider.JingleFileTransferProvider;
import org.jivesoftware.smackx.jingle.JingleDescriptionManager;
import org.jivesoftware.smackx.jingle.JingleManager;
import org.jivesoftware.smackx.jingle.Role;
import org.jivesoftware.smackx.jingle.callbacks.ContentAddCallback;
import org.jivesoftware.smackx.jingle.element.JingleContentElement;
import org.jivesoftware.smackx.jingle.element.JingleElement;
import org.jivesoftware.smackx.jingle.internal.JingleContent;
import org.jivesoftware.smackx.jingle.internal.JingleSession;
import org.jivesoftware.smackx.jingle.provider.JingleContentProviderManager;
import org.jivesoftware.smackx.jingle.transport.JingleTransportManager;
import org.jxmpp.jid.FullJid;
/**
* Created by vanitas on 22.07.17.
@ -22,6 +34,9 @@ public final class JingleFileTransferManager extends Manager implements JingleDe
private static final WeakHashMap<XMPPConnection, JingleFileTransferManager> INSTANCES = new WeakHashMap<>();
private final JingleManager jingleManager;
private final List<IncomingFileTransferListener> listeners =
Collections.synchronizedList(new ArrayList<IncomingFileTransferListener>());
private JingleFileTransferManager(XMPPConnection connection) {
super(connection);
ServiceDiscoveryManager.getInstanceFor(connection).addFeature(getNamespace());
@ -41,6 +56,43 @@ public final class JingleFileTransferManager extends Manager implements JingleDe
return manager;
}
public OutgoingFileHandler sendFile(File file, FullJid to) {
if (file == null || !file.exists()) {
throw new IllegalArgumentException("File MUST NOT be null and MUST exist.");
}
JingleSession session = jingleManager.createSession(Role.initiator, to);
JingleContent content = new JingleContent(JingleContentElement.Creator.initiator, JingleContentElement.Senders.initiator);
session.addContent(content);
JingleOutgoingFileOffer offer = new JingleOutgoingFileOffer(file);
content.setDescription(offer);
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager();
content.setTransport(transportManager.createTransport(content));
OutgoingFileHandler handler = new OutgoingFileHandler();
//TODO
return handler;
}
public void addIncomingFileTransferListener(IncomingFileTransferListener listener) {
listeners.add(listener);
}
public void removeIncomingFileTransferListener(IncomingFileTransferListener listener) {
listeners.remove(listener);
}
public void notifyIncomingFileTransferListeners(JingleIncomingFileOffer offer) {
for (IncomingFileTransferListener l : listeners) {
l.onIncomingFileTransfer(new IncomingFileTransferCallback(offer));
}
}
@Override
public String getNamespace() {
return JingleFileTransfer.NAMESPACE;

View File

@ -0,0 +1,7 @@
package org.jivesoftware.smackx.jft;
/**
* Created by vanitas on 26.07.17.
*/
public class OutgoingFileHandler {
}

View File

@ -1,7 +1,7 @@
package org.jivesoftware.smackx.jft.internal;
import java.io.IOException;
import java.io.OutputStream;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -21,11 +21,11 @@ public class JingleIncomingFileOffer extends JingleFileOffer<RemoteFile> {
@Override
public void onTransportReady(BytestreamSession bytestreamSession) {
OutputStream outputStream;
InputStream inputStream;
try {
outputStream = bytestreamSession.getOutputStream();
inputStream = bytestreamSession.getInputStream();
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Cannot get OutputStream from BytestreamSession: " + e, e);
LOGGER.log(Level.SEVERE, "Cannot get InputStream from BytestreamSession: " + e, e);
return;
}
}

View File

@ -29,19 +29,21 @@ import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
import org.jivesoftware.smack.iqrequest.IQRequestHandler;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.jingle.adapter.JingleDescriptionAdapter;
import org.jivesoftware.smackx.jingle.adapter.JingleTransportAdapter;
import org.jivesoftware.smackx.jingle.element.JingleElement;
import org.jivesoftware.smackx.jingle.exception.UnsupportedTransportException;
import org.jivesoftware.smackx.jingle.provider.JingleContentSecurityProvider;
import org.jivesoftware.smackx.jingle.adapter.JingleSecurityAdapter;
import org.jivesoftware.smackx.jingle.adapter.JingleTransportAdapter;
import org.jivesoftware.smackx.jingle.element.JingleAction;
import org.jivesoftware.smackx.jingle.element.JingleElement;
import org.jivesoftware.smackx.jingle.element.JingleReasonElement;
import org.jivesoftware.smackx.jingle.exception.UnsupportedDescriptionException;
import org.jivesoftware.smackx.jingle.exception.UnsupportedSecurityException;
import org.jivesoftware.smackx.jingle.exception.UnsupportedTransportException;
import org.jivesoftware.smackx.jingle.internal.JingleSession;
import org.jivesoftware.smackx.jingle.provider.JingleContentDescriptionProvider;
import org.jivesoftware.smackx.jingle.provider.JingleContentSecurityProvider;
import org.jivesoftware.smackx.jingle.provider.JingleContentTransportProvider;
import org.jivesoftware.smackx.jingle.transport.JingleTransportManager;
import org.jxmpp.jid.FullJid;
@ -65,6 +67,8 @@ public class JingleManager extends Manager {
private final ConcurrentHashMap<FullJidAndSessionId, JingleSession> jingleSessions = new ConcurrentHashMap<>();
public static boolean ALLOW_MULTIPLE_CONTENT_PER_SESSION = false;
private JingleManager(XMPPConnection connection) {
super(connection);
@ -198,7 +202,7 @@ public class JingleManager extends Manager {
return getAvailableTransportManagers(Collections.<String>emptySet());
}
private List<JingleTransportManager> getAvailableTransportManagers(Set<String> except) {
public List<JingleTransportManager> getAvailableTransportManagers(Set<String> except) {
Set<String> available = new HashSet<>(transportManagers.keySet());
available.removeAll(except);
List<JingleTransportManager> remaining = new ArrayList<>();
@ -207,10 +211,42 @@ public class JingleManager extends Manager {
remaining.add(transportManagers.get(namespace));
}
Collections.sort(remaining);
return remaining;
}
public JingleTransportManager getBestAvailableTransportManager() {
return getBestAvailableTransportManager(Collections.<String>emptySet());
}
public JingleTransportManager getBestAvailableTransportManager(Set<String> except) {
List<JingleTransportManager> managers = getAvailableTransportManagers(except);
Collections.sort(managers);
if (managers.size() > 0) {
return managers.get(0);
}
return null;
}
public XMPPConnection getConnection() {
return connection();
}
public JingleSession createSession(Role role, FullJid peer) {
JingleSession session;
if (role == Role.initiator) {
session = new JingleSession(this, connection().getUser().asDomainFullJidOrThrow(), peer,
role, StringUtils.randomString(24));
} else {
session = new JingleSession(this, peer, connection().getUser().asDomainFullJidOrThrow(),
role, StringUtils.randomString(24));
}
jingleSessions.put(new FullJidAndSessionId(peer, session.getSessionId()), session);
return session;
}
}

View File

@ -236,7 +236,7 @@ public final class JingleElement extends IQ {
* @param content content
* @return session-accept stanza.
*/
public JingleElement createSessionAccept(FullJid initiator,
public static JingleElement createSessionAccept(FullJid initiator,
FullJid responder,
String sessionId,
JingleContentElement content) {
@ -252,7 +252,7 @@ public final class JingleElement extends IQ {
* @param contents contents
* @return session-accept stanza.
*/
public JingleElement createSessionAccept(FullJid initiator,
public static JingleElement createSessionAccept(FullJid initiator,
FullJid responder,
String sessionId,
List<JingleContentElement> contents) {
@ -281,7 +281,7 @@ public final class JingleElement extends IQ {
* @param content content.
* @return session-initiate stanza.
*/
public JingleElement createSessionInitiate(FullJid initiator,
public static JingleElement createSessionInitiate(FullJid initiator,
FullJid responder,
String sessionId,
JingleContentElement content) {
@ -297,7 +297,7 @@ public final class JingleElement extends IQ {
* @param contents contents.
* @return session-initiate stanza.
*/
public JingleElement createSessionInitiate(FullJid initiator,
public static JingleElement createSessionInitiate(FullJid initiator,
FullJid responder,
String sessionId,
List<JingleContentElement> contents) {

View File

@ -51,6 +51,10 @@ public class JingleContent {
private final List<Callback> callbacks = Collections.synchronizedList(new ArrayList<Callback>());
private final Set<String> transportBlacklist = Collections.synchronizedSet(new HashSet<String>());
public JingleContent(JingleContentElement.Creator creator, JingleContentElement.Senders senders) {
this(null, null, null, StringUtils.randomString(24), null, creator, senders);
}
public JingleContent(JingleDescription description, JingleTransport transport, JingleSecurity security, String name, String disposition, JingleContentElement.Creator creator, JingleContentElement.Senders senders) {
this.description = description;
this.transport = transport;

View File

@ -71,12 +71,12 @@ public class JingleSession {
this.sessionId = sessionId;
}
void addContent(JingleContent content) {
public void addContent(JingleContent content) {
contents.put(content.getName(), content);
content.setParent(this);
}
void addContent(JingleContentElement content)
public void addContent(JingleContentElement content)
throws UnsupportedSecurityException, UnsupportedTransportException, UnsupportedDescriptionException {
addContent(JingleContent.fromElement(content));
}
@ -97,6 +97,19 @@ public class JingleSession {
return session;
}
public JingleElement createSessionInitiate() {
if (role != Role.initiator) {
throw new IllegalStateException("Sessions role is not initiator.");
}
List<JingleContentElement> contentElements = new ArrayList<>();
for (JingleContent c : contents.values()) {
contentElements.add(c.getElement());
}
return JingleElement.createSessionInitiate(getInitiator(), getResponder(), getSessionId(), contentElements);
}
public IQ handleJingleRequest(JingleElement request) {
switch (request.getAction()) {
case content_accept:
@ -268,7 +281,7 @@ public class JingleSession {
List<JingleElement> responses = new ArrayList<>();
for (Map.Entry<JingleContentElement, JingleContent> entry : affectedContents.entrySet()) {
responses.add(entry.getValue().getSecurity().handleSecurityInfo(entry.getKey().getSecurity().getSecurityInfo()));
responses.add(entry.getValue().getSecurity().handleSecurityInfo(entry.getKey().getSecurity().getSecurityInfo(), request));
}
for (JingleElement response : responses) {

View File

@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackFuture;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
@ -29,7 +30,7 @@ import org.jivesoftware.smackx.jingle.element.JingleElement;
/**
* Class that represents a contents transport component.
*/
public abstract class JingleTransport<D extends JingleContentTransportElement> {
public abstract class JingleTransport<D extends JingleContentTransportElement> extends SmackFuture<BytestreamSession> {
private JingleContent parent;
private final ArrayList<JingleTransportCandidate<?>> candidates = new ArrayList<>();
@ -42,7 +43,7 @@ public abstract class JingleTransport<D extends JingleContentTransportElement> {
public abstract D getElement();
public void addCandidate(JingleTransportCandidate<?> candidate) {
// Insert sorted by priority descending
// Insert sorted by descending priority
// Empty list -> insert
if (candidates.isEmpty()) {

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.jingle;
package org.jivesoftware.smackx.jingle.transport;
import org.jivesoftware.smackx.jingle.internal.JingleContent;
import org.jivesoftware.smackx.jingle.internal.JingleTransport;

View File

@ -19,6 +19,7 @@ package org.jivesoftware.smackx.jingle.transport.jingle_ibb;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamListener;
@ -29,7 +30,6 @@ import org.jivesoftware.smackx.jingle.element.JingleElement;
import org.jivesoftware.smackx.jingle.internal.JingleSession;
import org.jivesoftware.smackx.jingle.internal.JingleTransport;
import org.jivesoftware.smackx.jingle.internal.JingleTransportCandidate;
import org.jivesoftware.smackx.jingle.transport.BytestreamSessionEstablishedListener;
import org.jivesoftware.smackx.jingle.transport.jingle_ibb.element.JingleIBBTransportElement;
/**
@ -125,4 +125,14 @@ public class JingleIBBTransport extends JingleTransport<JingleIBBTransportElemen
public void handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping) {
// Nothing to do.
}
@Override
protected boolean isNonFatalException(Exception exception) {
return false;
}
@Override
protected void handleStanza(Stanza stanza) throws SmackException.NotConnectedException, InterruptedException {
}
}

View File

@ -6,7 +6,7 @@ import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.jingle.JingleManager;
import org.jivesoftware.smackx.jingle.JingleTransportManager;
import org.jivesoftware.smackx.jingle.transport.JingleTransportManager;
import org.jivesoftware.smackx.jingle.internal.JingleContent;
import org.jivesoftware.smackx.jingle.internal.JingleTransport;
import org.jivesoftware.smackx.jingle.provider.JingleContentProviderManager;

View File

@ -46,7 +46,7 @@ import org.jivesoftware.smackx.jingle.transport.jingle_s5b.element.JingleS5BTran
import org.jivesoftware.smackx.jingle.transport.jingle_s5b.element.JingleS5BTransportElement;
import org.jivesoftware.smackx.jingle.transport.jingle_s5b.element.JingleS5BTransportInfoElement;
import org.jivesoftware.smackx.jingle.transport.jingle_s5b.provider.JingleS5BTransportProvider;
import org.jivesoftware.smackx.jingle.JingleTransportManager;
import org.jivesoftware.smackx.jingle.transport.JingleTransportManager;
import org.jivesoftware.smackx.jingle.element.JingleAction;
import org.jivesoftware.smackx.jingle.element.JingleContentElement;