mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-23 20:42:06 +01:00
First state representing stuff
This commit is contained in:
parent
1912ebb8d0
commit
e0a54c19d6
9 changed files with 221 additions and 18 deletions
|
@ -16,7 +16,15 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.jingle_filetransfer;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smackx.jingle.JingleManager;
|
||||
import org.jivesoftware.smackx.jingle.Role;
|
||||
import org.jivesoftware.smackx.jingle.element.Jingle;
|
||||
import org.jivesoftware.smackx.jingle_filetransfer.callback.IncomingFileOfferCallback;
|
||||
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransfer;
|
||||
|
||||
import org.jxmpp.jid.FullJid;
|
||||
|
||||
|
@ -25,7 +33,43 @@ import org.jxmpp.jid.FullJid;
|
|||
*/
|
||||
public class JingleFileOffer extends JingleFileTransferSession {
|
||||
|
||||
public JingleFileOffer(FullJid initiator, FullJid responder, Role role, String sid) {
|
||||
super(initiator, responder, role, sid, Type.offer);
|
||||
public JingleFileOffer(XMPPConnection connection, FullJid initiator, FullJid responder, Role role, String sid) {
|
||||
super(connection, initiator, responder, role, sid, Type.offer);
|
||||
}
|
||||
|
||||
public static JingleFileOffer createOutgoingFileOffer(XMPPConnection connection, FullJid recipient) {
|
||||
return new JingleFileOffer(connection, connection.getUser().asFullJidOrThrow(), recipient,
|
||||
Role.initiator, JingleManager.randomSid());
|
||||
}
|
||||
|
||||
public static JingleFileOffer createIncomingFileOffer(XMPPConnection connection, Jingle request) {
|
||||
return new JingleFileOffer(connection, request.getInitiator(), connection.getUser().asFullJidOrThrow(),
|
||||
Role.responder, request.getSid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQ handleSessionInitiate(Jingle initiate) {
|
||||
if (role == Role.initiator) {
|
||||
|
||||
}
|
||||
|
||||
if (getState() != State.fresh) {
|
||||
return jutil.createErrorOutOfOrder(initiate);
|
||||
}
|
||||
|
||||
IncomingFileOfferCallback callback = new IncomingFileOfferCallback() {
|
||||
@Override
|
||||
public void accept(JingleFileTransfer file, File target) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decline() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
JingleFileTransferManager.getInstanceFor(connection).notifyIncomingFileOffer(initiate, callback);
|
||||
return jutil.createAck(initiate);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.jingle_filetransfer;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smackx.jingle.JingleManager;
|
||||
import org.jivesoftware.smackx.jingle.Role;
|
||||
import org.jivesoftware.smackx.jingle.element.Jingle;
|
||||
|
||||
|
@ -27,12 +28,17 @@ import org.jxmpp.jid.FullJid;
|
|||
*/
|
||||
public class JingleFileRequest extends JingleFileTransferSession {
|
||||
|
||||
public JingleFileRequest(FullJid initiator, FullJid responder, Role role, String sid) {
|
||||
super(initiator, responder, role, sid, Type.request);
|
||||
public JingleFileRequest(XMPPConnection connection, FullJid initiator, FullJid responder, Role role, String sid) {
|
||||
super(connection, initiator, responder, role, sid, Type.request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQ handleJingleSessionRequest(Jingle jingle) {
|
||||
return null;
|
||||
public static JingleFileRequest createOutgoingFileRequest(XMPPConnection connection, FullJid recipient) {
|
||||
return new JingleFileRequest(connection, connection.getUser().asFullJidOrThrow(), recipient, Role.initiator,
|
||||
JingleManager.randomSid());
|
||||
}
|
||||
|
||||
public static JingleFileRequest createIncomingFileRequest(XMPPConnection connection, Jingle request) {
|
||||
return new JingleFileRequest(connection, request.getInitiator(), connection.getUser().asFullJidOrThrow(), Role.responder,
|
||||
request.getSid());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,10 +24,11 @@ import org.jivesoftware.smack.packet.IQ;
|
|||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||
import org.jivesoftware.smackx.jingle.JingleHandler;
|
||||
import org.jivesoftware.smackx.jingle.JingleManager;
|
||||
import org.jivesoftware.smackx.jingle.Role;
|
||||
import org.jivesoftware.smackx.jingle.JingleUtil;
|
||||
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_filetransfer.callback.IncomingFileOfferCallback;
|
||||
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransfer;
|
||||
|
||||
import org.jxmpp.jid.FullJid;
|
||||
|
@ -38,12 +39,14 @@ import org.jxmpp.jid.FullJid;
|
|||
public final class JingleFileTransferManager extends Manager implements JingleHandler {
|
||||
|
||||
private static final WeakHashMap<XMPPConnection, JingleFileTransferManager> INSTANCES = new WeakHashMap<>();
|
||||
private final JingleUtil jutil;
|
||||
|
||||
private JingleFileTransferManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
ServiceDiscoveryManager.getInstanceFor(connection).addFeature(JingleFileTransfer.NAMESPACE_V5);
|
||||
JingleManager jingleManager = JingleManager.getInstanceFor(connection);
|
||||
jingleManager.registerDescriptionHandler(JingleFileTransfer.NAMESPACE_V5, this);
|
||||
jutil = new JingleUtil(connection);
|
||||
}
|
||||
|
||||
public static JingleFileTransferManager getInstanceFor(XMPPConnection connection) {
|
||||
|
@ -60,22 +63,44 @@ public final class JingleFileTransferManager extends Manager implements JingleHa
|
|||
FullJid fullJid = jingle.getFrom().asFullJidOrThrow();
|
||||
String sid = jingle.getSid();
|
||||
|
||||
JingleFileTransferSession handler = createSession(jingle);
|
||||
//Get handler
|
||||
JingleFileTransferSession handler;
|
||||
try {
|
||||
handler = createSessionHandler(jingle);
|
||||
} catch (IllegalArgumentException malformed) {
|
||||
// If senders is neither initiator, nor responder, consider session malformed.
|
||||
// See XEP-0166 §6.3 Example 16 and XEP-0234 §4.1
|
||||
return jutil.createErrorMalformedRequest(jingle);
|
||||
}
|
||||
|
||||
JingleManager.getInstanceFor(connection()).registerJingleSessionHandler(fullJid, sid, handler);
|
||||
return handler.handleJingleSessionRequest(jingle);
|
||||
}
|
||||
|
||||
private JingleFileTransferSession createSession(Jingle request) {
|
||||
/**
|
||||
* Create a session handler (FileOffer or FileRequest) for the request.
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
private JingleFileTransferSession createSessionHandler(Jingle request) {
|
||||
if (request.getAction() != JingleAction.session_initiate) {
|
||||
throw new IllegalArgumentException("Requests action MUST be session-initiate.");
|
||||
}
|
||||
|
||||
JingleContent content = request.getContents().get(0);
|
||||
//File Offer
|
||||
if (content.getSenders() == JingleContent.Senders.initiator) {
|
||||
return new JingleFileOffer(request.getInitiator(), request.getResponder(), Role.responder, request.getSid());
|
||||
} else if (content.getSenders() == JingleContent.Senders.responder) {
|
||||
return new JingleFileRequest(request.getInitiator(), request.getResponder(), Role.responder, request.getSid());
|
||||
} else {
|
||||
return JingleFileOffer.createIncomingFileOffer(connection(), request);
|
||||
} //File Request
|
||||
else if (content.getSenders() == JingleContent.Senders.responder) {
|
||||
return JingleFileRequest.createIncomingFileRequest(connection(), request);
|
||||
} //Malformed Request
|
||||
else {
|
||||
throw new IllegalArgumentException("Requests content.senders MUST be either responder or initiator.");
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyIncomingFileOffer(Jingle initiate, IncomingFileOfferCallback callback) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.jingle_filetransfer;
|
||||
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smackx.jingle.JingleSession;
|
||||
import org.jivesoftware.smackx.jingle.JingleUtil;
|
||||
import org.jivesoftware.smackx.jingle.Role;
|
||||
|
||||
import org.jxmpp.jid.FullJid;
|
||||
|
@ -33,23 +35,39 @@ public abstract class JingleFileTransferSession extends JingleSession {
|
|||
}
|
||||
|
||||
public enum State {
|
||||
fresh,
|
||||
pending,
|
||||
active,
|
||||
terminated,
|
||||
;
|
||||
}
|
||||
|
||||
private final Type type;
|
||||
protected final XMPPConnection connection;
|
||||
protected final JingleUtil jutil;
|
||||
|
||||
public JingleFileTransferSession(FullJid initiator, FullJid responder, Role role, String sid, Type type) {
|
||||
private final Type type;
|
||||
private State state;
|
||||
|
||||
public JingleFileTransferSession(XMPPConnection connection, FullJid initiator, FullJid responder, Role role, String sid, Type type) {
|
||||
super(initiator, responder, role, sid);
|
||||
this.type = type;
|
||||
this.state = State.fresh;
|
||||
this.connection = connection;
|
||||
this.jutil = new JingleUtil(connection);
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public boolean isOffer() {
|
||||
return this.type == Type.offer;
|
||||
}
|
||||
|
|
|
@ -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_filetransfer.callback;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransfer;
|
||||
|
||||
/**
|
||||
* Callback used to accept/decline file offers.
|
||||
*/
|
||||
public interface IncomingFileOfferCallback {
|
||||
|
||||
void accept(JingleFileTransfer file, File target);
|
||||
|
||||
void decline();
|
||||
}
|
|
@ -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_filetransfer.callback;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransfer;
|
||||
|
||||
/**
|
||||
* Callback used to accept/decline file requests.
|
||||
*/
|
||||
public interface IncomingFileRequestCallback {
|
||||
|
||||
void accept(JingleFileTransfer file, File source);
|
||||
|
||||
void decline();
|
||||
}
|
|
@ -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 <a href="https://xmpp.org/extensions/xep-0234.html">XEP-0234: Jingle File Transfer</a>.
|
||||
* Callbacks.
|
||||
*/
|
||||
package org.jivesoftware.smackx.jingle_filetransfer.callback;
|
|
@ -27,6 +27,7 @@ import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
|
|||
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.IQ.Type;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smackx.jingle.element.Jingle;
|
||||
import org.jivesoftware.smackx.jingle.element.JingleAction;
|
||||
import org.jivesoftware.smackx.jingle.element.JingleContent;
|
||||
|
@ -73,7 +74,7 @@ public final class JingleManager extends Manager {
|
|||
JingleSessionHandler sessionHandler = jingleSessionHandlers.get(fullJidAndSessionId);
|
||||
if (sessionHandler != null) {
|
||||
//Handle existing session
|
||||
return sessionHandler.handleJingleSessionRequest(jingle, jingle.getSid());
|
||||
return sessionHandler.handleJingleSessionRequest(jingle);
|
||||
}
|
||||
|
||||
if (jingle.getAction() == JingleAction.session_initiate) {
|
||||
|
@ -109,4 +110,8 @@ public final class JingleManager extends Manager {
|
|||
FullJidAndSessionId fullJidAndSessionId = new FullJidAndSessionId(otherJid, sessionId);
|
||||
return jingleSessionHandlers.remove(fullJidAndSessionId);
|
||||
}
|
||||
|
||||
public static String randomSid() {
|
||||
return StringUtils.randomString(24);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -324,6 +324,10 @@ public class JingleUtil {
|
|||
return connection.createStanzaCollectorAndSend(jingle).nextResultOrThrow();
|
||||
}
|
||||
|
||||
public IQ sendContentRejectFileNotAvailable(FullJid recipient, String sessionId, JingleContentDescription description) {
|
||||
return null; //TODO Later
|
||||
}
|
||||
|
||||
public Jingle createSessionPing(FullJid recipient, String sessionId) {
|
||||
Jingle.Builder jb = Jingle.getBuilder();
|
||||
jb.setSessionId(sessionId)
|
||||
|
@ -343,6 +347,14 @@ public class JingleUtil {
|
|||
return connection.createStanzaCollectorAndSend(jingle).nextResultOrThrow();
|
||||
}
|
||||
|
||||
public IQ createAck(Jingle jingle) {
|
||||
return IQ.createResultIQ(jingle);
|
||||
}
|
||||
|
||||
public void sendAck(Jingle jingle) throws SmackException.NotConnectedException, InterruptedException {
|
||||
connection.sendStanza(createAck(jingle));
|
||||
}
|
||||
|
||||
public IQ createErrorUnknownSession(Jingle request) {
|
||||
XMPPError.Builder error = XMPPError.getBuilder();
|
||||
error.setCondition(XMPPError.Condition.item_not_found)
|
||||
|
@ -399,4 +411,13 @@ public class JingleUtil {
|
|||
throws SmackException.NotConnectedException, InterruptedException {
|
||||
connection.sendStanza(createErrorOutOfOrder(request));
|
||||
}
|
||||
|
||||
public IQ createErrorMalformedRequest(Jingle request) {
|
||||
return IQ.createErrorResponse(request, XMPPError.Condition.bad_request);
|
||||
}
|
||||
|
||||
public void sendErrorMalformedRequest(Jingle request)
|
||||
throws SmackException.NotConnectedException, InterruptedException {
|
||||
connection.sendStanza(createErrorMalformedRequest(request));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue