Add javadoc

More javadoc

Merge branch 'jftPR' into jetPR
This commit is contained in:
vanitasvitae 2017-08-26 17:47:04 +02:00
parent 3260429200
commit 1b1268cdc6
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
32 changed files with 891 additions and 40 deletions

View File

@ -33,7 +33,7 @@ import org.jivesoftware.smackx.ciphers.AesGcmNoPadding;
import org.jivesoftware.smackx.jet.JetManager;
import org.jivesoftware.smackx.jet.JingleEnvelopeManager;
import org.jivesoftware.smackx.jet.element.JetSecurityElement;
import org.jivesoftware.smackx.jingle.callbacks.JingleSecurityCallback;
import org.jivesoftware.smackx.jingle.callback.JingleSecurityCallback;
import org.jivesoftware.smackx.jingle.component.JingleSecurity;
import org.jivesoftware.smackx.jingle.element.JingleContentSecurityInfoElement;
import org.jivesoftware.smackx.jingle.element.JingleElement;

View File

@ -16,8 +16,10 @@
*/
package org.jivesoftware.smackx.jingle;
import org.jivesoftware.smackx.jingle.component.JingleDescription;
/**
* Created by vanitas on 27.07.17.
* User interface which provides methods for the client to use.
*/
public interface JingleDescriptionController {
@ -29,5 +31,9 @@ public interface JingleDescriptionController {
ended //Successfully ended
}
/**
* Return the state of the {@link JingleDescription}.
* @return state.
*/
State getState();
}

View File

@ -17,16 +17,30 @@
package org.jivesoftware.smackx.jingle;
import org.jivesoftware.smackx.jingle.component.JingleContent;
import org.jivesoftware.smackx.jingle.component.JingleDescription;
import org.jivesoftware.smackx.jingle.component.JingleSession;
/**
* Manager for JingleDescription components.
* Manager for {@link JingleDescription} components.
*/
public interface JingleDescriptionManager {
/**
* Return the namespace of the {@link JingleDescription}.
* @return namespace.
*/
String getNamespace();
/**
* Notify about an incoming session-initiate wich contains a suitable {@link JingleDescription}.
* @param session initiated jingleSession.
*/
void notifySessionInitiate(JingleSession session);
/**
* Notify about a content-add request which tries to add a suitable {@link JingleDescription}.
* @param session affected jingleSession.
* @param content content which will be added.
*/
void notifyContentAdd(JingleSession session, JingleContent content);
}

View File

@ -59,21 +59,60 @@ import org.jxmpp.jid.Jid;
* Manager for Jingle (XEP-0166).
*/
public final class JingleManager extends Manager {
private static final Logger LOGGER = Logger.getLogger(JingleManager.class.getName());
private static final WeakHashMap<XMPPConnection, JingleManager> INSTANCES = new WeakHashMap<>();
/**
* Map of registered {@link JingleContentDescriptionProvider}s and their namespaces.
*/
private static final WeakHashMap<String, JingleContentDescriptionProvider<?>> descriptionProviders = new WeakHashMap<>();
/**
* Map of registered {@link JingleContentTransportProvider}s and their namespaces.
*/
private static final WeakHashMap<String, JingleContentTransportProvider<?>> transportProviders = new WeakHashMap<>();
/**
* Map of registered {@link JingleContentSecurityProvider}s and their namespaces.
*/
private static final WeakHashMap<String, JingleContentSecurityProvider<?>> securityProviders = new WeakHashMap<>();
/**
* Map of registered {@link JingleDescriptionAdapter}s and their namespaces.
*/
private static final WeakHashMap<String, JingleDescriptionAdapter<?>> descriptionAdapters = new WeakHashMap<>();
/**
* Map of registered {@link JingleTransportAdapter}s and their namespaces.
*/
private static final WeakHashMap<String, JingleTransportAdapter<?>> transportAdapters = new WeakHashMap<>();
/**
* Map of registered {@link JingleSecurityAdapter}s and their namespaces.
*/
private static final WeakHashMap<String, JingleSecurityAdapter<?>> securityAdapters = new WeakHashMap<>();
/**
* Map of registered {@link JingleDescriptionManager}s and their namespaces.
*/
private final WeakHashMap<String, JingleDescriptionManager> descriptionManagers = new WeakHashMap<>();
/**
* Map of registered {@link JingleTransportManager}s and their namespaces.
*/
private final WeakHashMap<String, JingleTransportManager> transportManagers = new WeakHashMap<>();
/**
* Map of registered {@link JingleSecurityManager}s and their namespaces.
*/
private final WeakHashMap<String, JingleSecurityManager> securityManagers = new WeakHashMap<>();
/**
* Map of active {@link JingleSession}s.
*/
private final ConcurrentHashMap<FullJidAndSessionId, JingleSession> jingleSessions = new ConcurrentHashMap<>();
private JingleManager(final XMPPConnection connection) {
@ -123,6 +162,11 @@ public final class JingleManager extends Manager {
});
}
/**
* Return connections Instance of the JingleManager.
* @param connection connection
* @return connections instance.
*/
public static JingleManager getInstanceFor(XMPPConnection connection) {
JingleManager manager = INSTANCES.get(connection);
@ -134,94 +178,207 @@ public final class JingleManager extends Manager {
return manager;
}
/**
* Register a {@link JingleDescriptionAdapter}.
* @param adapter adapter.
*/
public static void addJingleDescriptionAdapter(JingleDescriptionAdapter<?> adapter) {
descriptionAdapters.put(adapter.getNamespace(), adapter);
}
/**
* Register a {@link JingleTransportAdapter}.
* @param adapter adapter.
*/
public static void addJingleTransportAdapter(JingleTransportAdapter<?> adapter) {
transportAdapters.put(adapter.getNamespace(), adapter);
}
/**
* Register a {@link JingleSecurityAdapter}.
* @param adapter adapter.
*/
public static void addJingleSecurityAdapter(JingleSecurityAdapter<?> adapter) {
securityAdapters.put(adapter.getNamespace(), adapter);
}
/**
* Return the registered {@link JingleDescriptionAdapter} with namespace namespace or null.
* @param namespace namespace.
* @return adapter or null.
*/
public static JingleDescriptionAdapter<?> getJingleDescriptionAdapter(String namespace) {
return descriptionAdapters.get(namespace);
}
/**
* Return the registered {@link JingleTransportAdapter} with namespace namespace or null.
* @param namespace namespace.
* @return adapter or null.
*/
public static JingleTransportAdapter<?> getJingleTransportAdapter(String namespace) {
return transportAdapters.get(namespace);
}
/**
* Return the registered {@link JingleSecurityAdapter} with namespace namespace or null.
* @param namespace namespace.
* @return adapter or null.
*/
public static JingleSecurityAdapter<?> getJingleSecurityAdapter(String namespace) {
return securityAdapters.get(namespace);
}
/**
* Add a {@link JingleContentDescriptionProvider}.
* @param provider provider.
*/
public static void addJingleDescriptionProvider(JingleContentDescriptionProvider<?> provider) {
descriptionProviders.put(provider.getNamespace(), provider);
}
/**
* Remove the {@link JingleContentDescriptionProvider} with namespace namespace.
* @param namespace namespace.
*/
public static void removeJingleDescriptionProvider(String namespace) {
descriptionProviders.remove(namespace);
}
/**
* Return the {@link JingleContentDescriptionProvider} with namespace namespace or null.
* @param namespace namespace.
* @return provider or null.
*/
public static JingleContentDescriptionProvider<?> getJingleDescriptionProvider(String namespace) {
return descriptionProviders.get(namespace);
}
/**
* Add a {@link JingleContentTransportProvider}.
* @param provider provider.
*/
public static void addJingleTransportProvider(JingleContentTransportProvider<?> provider) {
transportProviders.put(provider.getNamespace(), provider);
}
/**
* Remove the {@link JingleContentTransportProvider} with namespace namespace.
* @param namespace namespace.
*/
public static void removeJingleTransportProvider(String namespace) {
transportProviders.remove(namespace);
}
/**
* Return the {@link JingleContentTransportProvider} with namespace namespace or null.
* @param namespace namespace.
* @return provider or null.
*/
public static JingleContentTransportProvider<?> getJingleTransportProvider(String namespace) {
return transportProviders.get(namespace);
}
/**
* Add a {@link JingleContentSecurityProvider}.
* @param provider provider.
*/
public static void addJingleSecurityProvider(JingleContentSecurityProvider<?> provider) {
securityProviders.put(provider.getNamespace(), provider);
}
/**
* Remove the {@link JingleContentSecurityProvider} with namespace namespace.
* @param namespace namespace.
*/
public static void removeJingleSecurityProvider(String namespace) {
securityProviders.remove(namespace);
}
/**
* Return the {@link JingleContentSecurityProvider} with namespace namespace or null.
* @param namespace namespace.
* @return provider or null.
*/
public static JingleContentSecurityProvider<?> getJingleSecurityProvider(String namespace) {
return securityProviders.get(namespace);
}
/**
* Add a {@link JingleDescriptionManager}.
* @param manager manager
*/
public void addJingleDescriptionManager(JingleDescriptionManager manager) {
descriptionManagers.put(manager.getNamespace(), manager);
}
/**
* Get the {@link JingleDescriptionManager} with namespace namespace.
* @param namespace namespace
* @return manager or null.
*/
public JingleDescriptionManager getDescriptionManager(String namespace) {
return descriptionManagers.get(namespace);
}
/**
* Add a {@link JingleTransportManager}.
* @param manager manager
*/
public void addJingleTransportManager(JingleTransportManager manager) {
transportManagers.put(manager.getNamespace(), manager);
}
/**
* Get the {@link JingleTransportManager} with namespace namespace.
* @param namespace namespace
* @return manager or null.
*/
public JingleTransportManager getTransportManager(String namespace) {
return transportManagers.get(namespace);
}
/**
* Add a {@link JingleSecurityManager}.
* @param manager manager
*/
public void addJingleSecurityManager(JingleSecurityManager manager) {
securityManagers.put(manager.getNamespace(), manager);
}
/**
* Get the {@link JingleSecurityManager} with namespace namespace.
* @param namespace namespace
* @return manager or null.
*/
public JingleSecurityManager getSecurityManager(String namespace) {
return securityManagers.get(namespace);
}
/**
* Return a list of all available {@link JingleTransportManager}s that the recipient and we support.
* @param to recipient
* @return list of {@link JingleTransportManager}s.
* @throws XMPPException.XMPPErrorException
* @throws SmackException.NotConnectedException
* @throws InterruptedException
* @throws SmackException.NoResponseException
*/
public List<JingleTransportManager> getAvailableTransportManagers(Jid to) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
return getAvailableTransportManagers(to, Collections.<String>emptySet());
}
/**
* Return a list of all available {@link JingleTransportManager}s that the recipient and we support,
* but exclude all managers whos namespaces are in the except set.
* @param to recipient
* @param except blacklist.
* @return list of {@link JingleTransportManager}s.
* @throws XMPPException.XMPPErrorException
* @throws SmackException.NotConnectedException
* @throws InterruptedException
* @throws SmackException.NoResponseException
*/
public List<JingleTransportManager> getAvailableTransportManagers(Jid to, Set<String> except) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
Set<String> available = new HashSet<>(transportManagers.keySet());
available.removeAll(except);
@ -243,10 +400,30 @@ public final class JingleManager extends Manager {
return remaining;
}
/**
* Return the best available {@link JingleTransportManager}, which both we and the recipient support.
* @param to recipient.
* @return best available {@link JingleTransportManager}.
* @throws XMPPException.XMPPErrorException
* @throws SmackException.NotConnectedException
* @throws InterruptedException
* @throws SmackException.NoResponseException
*/
public JingleTransportManager getBestAvailableTransportManager(Jid to) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
return getBestAvailableTransportManager(to, Collections.<String>emptySet());
}
/**
* Return the best available {@link JingleTransportManager}, which both we and the recipient support,
* and whichs namespace is not on the blacklist.
* @param to recipient.
* @param except blacklist.
* @return best available {@link JingleTransportManager}.
* @throws XMPPException.XMPPErrorException
* @throws SmackException.NotConnectedException
* @throws InterruptedException
* @throws SmackException.NoResponseException
*/
public JingleTransportManager getBestAvailableTransportManager(Jid to, Set<String> except) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
List<JingleTransportManager> managers = getAvailableTransportManagers(to, except);
@ -257,10 +434,21 @@ public final class JingleManager extends Manager {
return null;
}
/**
* Return the connection.
* @return connection.
*/
public XMPPConnection getConnection() {
return connection();
}
/**
* Create a new {@link JingleSession} and add it to the list of sessions.
* Then return it.
* @param role our role.
* @param peer peer.
* @return session.
*/
public JingleSession createSession(Role role, FullJid peer) {
JingleSession session;
@ -276,12 +464,20 @@ public final class JingleManager extends Manager {
return session;
}
/**
* Add a {@link JingleSession} to the list of active sessions.
* @param session session.
*/
public void addSession(JingleSession session) {
if (!jingleSessions.containsValue(session)) {
jingleSessions.put(new FullJidAndSessionId(session.getPeer(), session.getSessionId()), session);
}
}
/**
* Remove a {@link JingleSession} from the list of active sessions.
* @param session session.
*/
public void removeSession(JingleSession session) {
jingleSessions.remove(new FullJidAndSessionId(session.getPeer(), session.getSessionId()));
}

View File

@ -21,7 +21,7 @@ import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement;
import org.jivesoftware.smackx.jingle.element.JingleContentElement;
/**
* Adapter that creates a Description object from an element.
* Adapter that creates a {@link JingleDescription} object from a {@link JingleContentDescriptionElement}.
*/
public interface JingleDescriptionAdapter<D extends JingleDescription<?>> {

View File

@ -20,7 +20,7 @@ import org.jivesoftware.smackx.jingle.component.JingleSecurity;
import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement;
/**
* Adapter that creates a Security object from an element.
* Adapter that creates a {@link JingleSecurity} object from a {@link JingleContentSecurityElement}.
*/
public interface JingleSecurityAdapter<S extends JingleSecurity<?>> {

View File

@ -20,7 +20,7 @@ import org.jivesoftware.smackx.jingle.component.JingleTransport;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
/**
* Adapter that creates a Transport element from an element.
* Adapter that creates a {@link JingleTransport} element from a {@link JingleContentTransportElement}.
*/
public interface JingleTransportAdapter<T extends JingleTransport<?>> {

View File

@ -17,6 +17,6 @@
/**
* Smack's API for <a href="https://xmpp.org/extensions/xep-0166.html">XEP-0166: Jingle</a>.
* Adapters.
* Content adapters.
*/
package org.jivesoftware.smackx.jingle.adapter;

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.callbacks;
package org.jivesoftware.smackx.jingle.callback;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;

View File

@ -14,16 +14,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.jingle.callbacks;
package org.jivesoftware.smackx.jingle.callback;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
/**
* Created by vanitas on 27.07.17.
* Callback used to signal success/failure of the transport component.
*/
public interface JingleTransportCallback {
/**
* The {@link org.jivesoftware.smackx.jingle.component.JingleTransport} is ready to transfer data.
* @param bytestreamSession bytestreamSession which was established.
*/
void onTransportReady(BytestreamSession bytestreamSession);
/**
* The {@link org.jivesoftware.smackx.jingle.component.JingleTransport} failed to establish a session.
* @param e exception.
*/
void onTransportFailed(Exception e);
}

View File

@ -19,4 +19,4 @@
* Smack's API for <a href="https://xmpp.org/extensions/xep-0166.html">XEP-0166: Jingle</a>.
* Callbacks.
*/
package org.jivesoftware.smackx.jingle.callbacks;
package org.jivesoftware.smackx.jingle.callback;

View File

@ -35,8 +35,8 @@ import org.jivesoftware.smackx.jingle.JingleTransportManager;
import org.jivesoftware.smackx.jingle.adapter.JingleDescriptionAdapter;
import org.jivesoftware.smackx.jingle.adapter.JingleSecurityAdapter;
import org.jivesoftware.smackx.jingle.adapter.JingleTransportAdapter;
import org.jivesoftware.smackx.jingle.callbacks.JingleSecurityCallback;
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.callback.JingleSecurityCallback;
import org.jivesoftware.smackx.jingle.callback.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement;
import org.jivesoftware.smackx.jingle.element.JingleContentElement;
import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement;
@ -64,10 +64,25 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
private final Set<String> transportBlacklist = Collections.synchronizedSet(new HashSet<String>());
/**
* Create an empty JingleContent with random name.
* @param creator creator.
* @param senders sender.
*/
public JingleContent(JingleContentElement.Creator creator, JingleContentElement.Senders senders) {
this(null, null, null, randomName(), null, creator, senders);
}
/**
* Create a JingleContent.
* @param description description component.
* @param transport transport component.
* @param security security component.
* @param name content name.
* @param disposition disposition.
* @param creator creator.
* @param senders senders.
*/
public JingleContent(JingleDescription<?> description, JingleTransport<?> transport, JingleSecurity<?> security, String name, String disposition, JingleContentElement.Creator creator, JingleContentElement.Senders senders) {
setDescription(description);
setTransport(transport);
@ -78,6 +93,11 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
this.senders = senders;
}
/**
* Create a new JingleContent from a {@link JingleContentElement}.
* @param content contentElement.
* @return jingleContent.
*/
public static JingleContent fromElement(JingleContentElement content) {
JingleDescription<?> description = null;
JingleTransport<?> transport = null;
@ -116,12 +136,23 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
return new JingleContent(description, transport, security, content.getName(), content.getDisposition(), content.getCreator(), content.getSenders());
}
/**
* Set the senders attribute.
* @param senders new value.
*/
public void setSenders(JingleContentElement.Senders senders) {
this.senders = senders;
}
/* HANDLE_XYZ */
/**
* Handle an incoming jingle request. This method basically routes incoming requests to different methods based on
* the value of the request's action attribute.
* @param request request.
* @param connection connection.
* @return result.
*/
public IQ handleJingleRequest(JingleElement request, XMPPConnection connection) {
switch (request.getAction()) {
case content_modify:
@ -145,11 +176,21 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
}
}
/**
* Handle incoming content-accept.
* @param request request.
* @param connection connection.
*/
void handleContentAccept(JingleElement request, XMPPConnection connection) {
start(connection);
}
/**
* Handle incoming session-accept. This means activating the transport and starting the transmission.
* @param request request.
* @param connection connection.
* @return result.
*/
IQ handleSessionAccept(JingleElement request, XMPPConnection connection) {
LOGGER.log(Level.INFO, "RECEIVED SESSION ACCEPT!");
JingleContentElement contentElement = null;
@ -169,26 +210,68 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
return IQ.createResultIQ(request);
}
/**
* Handle a content-modify request.
* TODO: Implement.
* @param request request.
* @param connection connection.
* @return result.
*/
private IQ handleContentModify(JingleElement request, XMPPConnection connection) {
return IQ.createErrorResponse(request, XMPPError.Condition.feature_not_implemented);
}
/**
* Handle a description-info request.
* TODO: Implement.
* @param request request.
* @param connection connection.
* @return result.
*/
private IQ handleDescriptionInfo(JingleElement request, XMPPConnection connection) {
return IQ.createErrorResponse(request, XMPPError.Condition.feature_not_implemented);
//return description.handleDescriptionInfo(request.getContents().get(0).getDescription().getDescriptionInfo());
}
/**
* Handle a content-remove request.
* TODO: Implement.
* @param session session that has this content as child.
* @param connection connection.
*/
public void handleContentRemove(JingleSession session, XMPPConnection connection) {
}
/**
* Handle security-info requests.
* TODO: Implement.
* @param request request.
* @param connection connection.
* @return result.
*/
private IQ handleSecurityInfo(JingleElement request, XMPPConnection connection) {
return IQ.createErrorResponse(request, XMPPError.Condition.feature_not_implemented);
}
/**
* Handle session-info requests.
* TODO: Implement.
* @param request request.
* @param connection connection.
* @return result.
*/
private IQ handleSessionInfo(JingleElement request, XMPPConnection connection) {
return IQ.createResultIQ(request);
}
/**
* Handle transport-accept requests.
* This includes starting the transport and afterwards starting transmission.
* @param request request.
* @param connection connection.
* @return result.
*/
private IQ handleTransportAccept(JingleElement request, XMPPConnection connection) {
if (pendingReplacingTransport == null) {
@ -204,6 +287,13 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
return IQ.createResultIQ(request);
}
/**
* Handle transport-info requests.
* Pass the request down to the transport.
* @param request request.
* @param connection connection.
* @return result.
*/
private IQ handleTransportInfo(JingleElement request, XMPPConnection connection) {
assert request.getContents().size() == 1;
JingleContentElement content = request.getContents().get(0);
@ -211,8 +301,16 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
return transport.handleTransportInfo(content.getTransport().getInfo(), request);
}
/**
* Handle a transport-reject request.
* That includes replacing the transport with the next choice.
* @param request request.
* @param connection connection.
* @return result.
*/
private IQ handleTransportReject(JingleElement request, final XMPPConnection connection) {
if (pendingReplacingTransport == null) {
// TODO: Throw other exception?
throw new AssertionError("We didn't try to replace the transport.");
}
Async.go(new Runnable() {
@ -230,6 +328,14 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
return IQ.createResultIQ(request);
}
/**
* Handle a transport-replace request.
* That includes replacing the transport if suitable and starting the transmission.
* Otherwise reject the transport.
* @param request request.
* @param connection connection.
* @return result.
*/
private IQ handleTransportReplace(final JingleElement request, final XMPPConnection connection) {
//Tie Break?
if (pendingReplacingTransport != null) {
@ -299,6 +405,10 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
/* MISCELLANEOUS */
/**
* Return a {@link JingleContentElement} representing this {@link JingleContent}.
* @return contentElement.
*/
public JingleContentElement getElement() {
JingleContentElement.Builder builder = JingleContentElement.getBuilder()
.setName(name)
@ -321,36 +431,70 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
return builder.build();
}
/**
* Return the transportBlacklist of this content.
* The blacklist contains the namespaces of {@link JingleTransport} classes, that this content will not offer/accept.
* @return transport blacklist.
*/
public Set<String> getTransportBlacklist() {
return transportBlacklist;
}
/**
* Get the creator of the content. The creator is the party that added the content to the session.
* @return creator.
*/
public JingleContentElement.Creator getCreator() {
return creator;
}
/**
* Get the name of the content.
* @return content-name.
*/
public String getName() {
return name;
}
/**
* Get the senders of the content.
* @return senders.
*/
public JingleContentElement.Senders getSenders() {
return senders;
}
/**
* Set the parent {@link JingleSession} of the content.
* @param session session that has this content as child.
*/
public void setParent(JingleSession session) {
if (this.parent != session) {
this.parent = session;
}
}
/**
* Return the parent {@link JingleSession} of this content.
* @return parent session.
*/
public JingleSession getParent() {
return parent;
}
/**
* Return the {@link JingleDescription} of this content.
* @return jingle description component.
*/
public JingleDescription<?> getDescription() {
return description;
}
/**
* Set the {@link JingleDescription} of this content.
* If needed, set the parent of the description to this content.
* @param description jingle description component.
*/
public void setDescription(JingleDescription<?> description) {
if (description != null && this.description != description) {
this.description = description;
@ -358,10 +502,19 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
}
}
/**
* Return the {@link JingleTransport} of this content.
* @return jingle transport component.
*/
public JingleTransport<?> getTransport() {
return transport;
}
/**
* Set the {@link JingleTransport} of this content.
* If needed, set the parent of the transport component to this content.
* @param transport jingle transport component.
*/
public void setTransport(JingleTransport<?> transport) {
if (transport != null && this.transport != transport) {
this.transport = transport;
@ -369,10 +522,19 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
}
}
/**
* Return the {@link JingleSecurity} of this content.
* @return jingle security component.
*/
public JingleSecurity<?> getSecurity() {
return security;
}
/**
* Set the {@link JingleSecurity} of this content.
* If needed, set the parent of the security component to this content.
* @param security jingle security component.
*/
public void setSecurity(JingleSecurity<?> security) {
if (security != null && this.security != security) {
this.security = security;
@ -380,18 +542,30 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
}
}
/**
* Return true, if we are the sending party. Otherwise return false.
* @return true if we are sending.
*/
public boolean isSending() {
return (getSenders() == JingleContentElement.Senders.initiator && getParent().isInitiator()) ||
(getSenders() == JingleContentElement.Senders.responder && getParent().isResponder()) ||
getSenders() == JingleContentElement.Senders.both;
}
/**
* Return true if we are the receiving party. Otherwise return false.
* @return true if we are receiving.
*/
public boolean isReceiving() {
return (getSenders() == JingleContentElement.Senders.initiator && getParent().isResponder()) ||
(getSenders() == JingleContentElement.Senders.responder && getParent().isInitiator()) ||
getSenders() == JingleContentElement.Senders.both;
}
/**
* Prepare the security component (if any) and establish a bytestream session.
* @param connection connection
*/
public void start(final XMPPConnection connection) {
transport.prepare(connection);
@ -466,24 +640,48 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
LOGGER.log(Level.SEVERE, "Security failed: " + e, e);
}
/**
* Content finished locally.
*/
public void onContentFinished() {
JingleSession session = getParent();
session.onContentFinished(this);
}
/**
* Content failed locally.
* @param e exception.
*/
public void onContentFailed(Exception e) {
}
/**
* Content cancelled locally.
*/
public void onContentCancel() {
JingleSession session = getParent();
session.onContentCancel(this);
}
/**
* Handle incoming content-terminate.
* Pass it down to the description.
* @param reason reason.
*/
public void handleContentTerminate(JingleReasonElement.Reason reason) {
description.handleContentTerminate(reason);
}
/**
* Locally replace the transport method.
* @param blacklist ignore all methods on the blacklist.
* @param connection connection.
* @throws SmackException.NotConnectedException
* @throws InterruptedException
* @throws XMPPException.XMPPErrorException
* @throws SmackException.NoResponseException
*/
private void replaceTransport(Set<String> blacklist, XMPPConnection connection)
throws SmackException.NotConnectedException, InterruptedException,
XMPPException.XMPPErrorException, SmackException.NoResponseException {
@ -510,6 +708,10 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
connection.createStanzaCollectorAndSend(transportReplace).nextResultOrThrow();
}
/**
* Return a random content name.
* @return random name.
*/
private static String randomName() {
return "cont-" + StringUtils.randomString(16);
}

View File

@ -27,25 +27,57 @@ import org.jivesoftware.smackx.jingle.element.JingleReasonElement;
*/
public abstract class JingleDescription<D extends JingleContentDescriptionElement> {
/**
* Parent {@link JingleContent}.
*/
private JingleContent parent;
/**
* Return a {@link JingleContentDescriptionElement} that represents this.
* @return element.
*/
public abstract D getElement();
/**
* Set the parent {@link JingleContent}.
* @param parent content.
*/
public void setParent(JingleContent parent) {
if (this.parent != parent) {
this.parent = parent;
}
}
/**
* Handle a descriptionInfo.
* @param info info.
* @return result.
*/
public abstract JingleElement handleDescriptionInfo(JingleContentDescriptionInfoElement info);
/**
* Return the parent {@link JingleContent} of this description.
* @return parent.
*/
public JingleContent getParent() {
return parent;
}
/**
* Do work once the bytestreams are ready.
* @param bytestreamSession established bytestream session.
*/
public abstract void onBytestreamReady(BytestreamSession bytestreamSession);
/**
* Return the namespace of the description.
* @return namespace.
*/
public abstract String getNamespace();
/**
* Handle an incoming session-terminate.
* @param reason reason of termination.
*/
public abstract void handleContentTerminate(JingleReasonElement.Reason reason);
}

View File

@ -18,7 +18,7 @@ package org.jivesoftware.smackx.jingle.component;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.jingle.callbacks.JingleSecurityCallback;
import org.jivesoftware.smackx.jingle.callback.JingleSecurityCallback;
import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement;
import org.jivesoftware.smackx.jingle.element.JingleContentSecurityInfoElement;
import org.jivesoftware.smackx.jingle.element.JingleElement;
@ -30,27 +30,71 @@ import org.jxmpp.jid.FullJid;
*/
public abstract class JingleSecurity<D extends JingleContentSecurityElement> {
/**
* Parent of this security component.
*/
private JingleContent parent;
/**
* Return a {@link JingleContentSecurityElement} that represents this {@link JingleSecurity} component.
* @return element.
*/
public abstract D getElement();
/**
* Handle an incoming security-info.
* @param element security info.
* @param wrapping jingleElement that contains the security info.
* @return result.
*/
public abstract JingleElement handleSecurityInfo(JingleContentSecurityInfoElement element, JingleElement wrapping);
/**
* Set the parent {@link JingleContent} of this security component.
* @param parent parent.
*/
public void setParent(JingleContent parent) {
if (this.parent != parent) {
this.parent = parent;
}
}
/**
* Return the parent {@link JingleContent} of this security component.
* @return parent.
*/
public JingleContent getParent() {
return parent;
}
/**
* Decrypt an incoming bytestream.
* This includes wrapping the incoming {@link BytestreamSession} in a {@link JingleSecurityBytestreamSession} and
* pass it to the callbacks {@link JingleSecurityCallback#onSecurityReady(BytestreamSession)} method.
* @param bytestreamSession encrypted bytestreamSession.
* @param callback callback.
*/
public abstract void decryptIncomingBytestream(BytestreamSession bytestreamSession, JingleSecurityCallback callback);
public abstract void encryptOutgoingBytestream(BytestreamSession bytestreamSession, JingleSecurityCallback callbacks);
/**
* Encrypt an incoming bytestream.
* This includes wrapping the incoming {@link BytestreamSession} in a {@link JingleSecurityBytestreamSession} and
* pass it to the callbacks {@link JingleSecurityCallback#onSecurityReady(BytestreamSession)} method.
* @param bytestreamSession encrypted bytestreamSession.
* @param callback callback.
*/
public abstract void encryptOutgoingBytestream(BytestreamSession bytestreamSession, JingleSecurityCallback callback);
/**
* Return the namespace of this security component.
* @return namespace.
*/
public abstract String getNamespace();
public abstract void prepare(XMPPConnection connection, FullJid sender);
/**
* Prepare the security session.
* @param connection connection.
* @param peer peer.
*/
public abstract void prepare(XMPPConnection connection, FullJid peer);
}

View File

@ -21,12 +21,23 @@ import java.io.IOException;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
/**
* Created by vanitas on 27.07.17.
* Wrapper class that wraps a {@link BytestreamSession} to add a layer of security.
*/
public abstract class JingleSecurityBytestreamSession implements BytestreamSession {
/**
* Wrapped {@link BytestreamSession}.
*/
protected BytestreamSession wrapped;
/**
* Constructor.
* @param session {@link BytestreamSession} that will be wrapped.
*/
public JingleSecurityBytestreamSession(BytestreamSession session) {
this.wrapped = session;
}
@Override
public int getReadTimeout() throws IOException {
return wrapped.getReadTimeout();
@ -36,8 +47,4 @@ public abstract class JingleSecurityBytestreamSession implements BytestreamSessi
public void setReadTimeout(int timeout) throws IOException {
wrapped.setReadTimeout(timeout);
}
public JingleSecurityBytestreamSession(BytestreamSession session) {
this.wrapped = session;
}
}

View File

@ -48,11 +48,29 @@ import org.jxmpp.jid.FullJid;
public class JingleSession {
private static final Logger LOGGER = Logger.getLogger(JingleSession.class.getName());
/**
* Map of contents in this session.
*/
private final ConcurrentHashMap<String, JingleContent> contents = new ConcurrentHashMap<>();
/**
* Map of proposed (added, but not yet accepted contents) in this session.
*/
private final ConcurrentHashMap<String, JingleContent> proposedContents = new ConcurrentHashMap<>();
/**
* Reference to jingleManager.
*/
private final JingleManager jingleManager;
/**
* Initiator and responder of the session.
*/
private final FullJid initiator, responder;
/**
* Our role in the session (initiator or responder).
*/
private final Role role;
private final String sessionId;
@ -63,8 +81,19 @@ public class JingleSession {
ended //post-session-terminate
}
/**
* Current state of the session.
*/
private SessionState sessionState;
/**
* Create a new JingleSession.
* @param manager jingleManager.
* @param initiator initiator of the session.
* @param responder responder of the session.
* @param role our role in the session.
* @param sessionId session id.
*/
public JingleSession(JingleManager manager, FullJid initiator, FullJid responder, Role role, String sessionId) {
this.jingleManager = manager;
this.initiator = initiator;
@ -74,6 +103,16 @@ public class JingleSession {
this.sessionState = SessionState.fresh;
}
/**
* Parse a {@link JingleSession} from a {@link JingleElement} with action session-initiate.
* @param manager jingleManager.
* @param initiate {@link JingleElement} with session-initiate action.
* @return jingleSession.
* TODO: Throw exceptions.
* @throws UnsupportedSecurityException
* @throws UnsupportedDescriptionException
* @throws UnsupportedTransportException
*/
public static JingleSession fromSessionInitiate(JingleManager manager, JingleElement initiate)
throws UnsupportedSecurityException, UnsupportedDescriptionException, UnsupportedTransportException {
if (initiate.getAction() != JingleAction.session_initiate) {
@ -92,21 +131,47 @@ public class JingleSession {
return session;
}
/**
* Send a session-initiate request to the responder.
* This sets the state from fresh to pending.
* @param connection connection.
* @throws SmackException.NotConnectedException
* @throws InterruptedException
* @throws XMPPException.XMPPErrorException
* @throws SmackException.NoResponseException
*/
public void sendInitiate(XMPPConnection connection) throws SmackException.NotConnectedException, InterruptedException, XMPPException.XMPPErrorException, SmackException.NoResponseException {
if (this.sessionState != SessionState.fresh) {
throw new IllegalStateException("Session is not in fresh state.");
}
if (!isInitiator()) {
throw new IllegalStateException("We are not the initiator.");
}
connection.createStanzaCollectorAndSend(createSessionInitiate()).nextResultOrThrow();
this.sessionState = SessionState.pending;
}
/**
* Send a session-accept to the initiator.
* This sets the state from pending to active.
* @param connection connection.
* @throws SmackException.NotConnectedException
* @throws InterruptedException
* @throws XMPPException.XMPPErrorException
* @throws SmackException.NoResponseException
*/
public void sendAccept(XMPPConnection connection) throws SmackException.NotConnectedException, InterruptedException, XMPPException.XMPPErrorException, SmackException.NoResponseException {
LOGGER.log(Level.INFO, "Accepted session.");
if (this.sessionState != SessionState.pending) {
throw new IllegalStateException("Session is not in pending state.");
}
if (!isResponder()) {
throw new IllegalStateException("We are not the responder.");
}
if (contents.values().size() == 0) {
LOGGER.log(Level.WARNING, "0 contents!");
}
@ -119,6 +184,10 @@ public class JingleSession {
this.sessionState = SessionState.active;
}
/**
* Create a session-initiate request.
* @return request.
*/
public JingleElement createSessionInitiate() {
if (role != Role.initiator) {
throw new IllegalStateException("Sessions role is not initiator.");
@ -132,6 +201,10 @@ public class JingleSession {
return JingleElement.createSessionInitiate(getInitiator(), getResponder(), getSessionId(), contentElements);
}
/**
* Create a session-accept request.
* @return request.
*/
public JingleElement createSessionAccept() {
if (role != Role.responder) {
throw new IllegalStateException("Sessions role is not responder.");
@ -207,9 +280,16 @@ public class JingleSession {
} catch (SmackException.NotConnectedException | InterruptedException e) {
LOGGER.log(Level.SEVERE, "Could not send session-terminate: " + e, e);
}
this.sessionState = SessionState.ended;
jingleManager.removeSession(this);
}
/**
* Handle incoming jingle request.
* This is a routing function which routes the request to the suitable method based on the value of the action field.
* @param request incoming request.
* @return result.
*/
public IQ handleJingleRequest(JingleElement request) {
switch (request.getAction()) {
case content_modify:
@ -243,8 +323,9 @@ public class JingleSession {
/* ############## Processed in this class ############## */
/**
* Handle incoming session-accept stanza.
* @param request session-accept stanza.
* Handle incoming session-accept request.
* This passes the session-accept to all contents.
* @param request session-accept request.
* @return result.
*/
private IQ handleSessionAccept(final JingleElement request) {
@ -262,13 +343,17 @@ public class JingleSession {
return IQ.createResultIQ(request);
}
/**
* Handle incoming session-initiate request.
* Notifies content listeners of respective descriptions about incoming requests.
* @param request request.
* @return result.
*/
private IQ handleSessionInitiate(JingleElement request) {
final JingleDescription<?> description = getSoleContentOrThrow().getDescription();
final JingleDescriptionManager descriptionManager = jingleManager.getDescriptionManager(description.getNamespace());
sessionState = SessionState.pending;
if (descriptionManager == null) {
}
Async.go(new Runnable() {
@Override
public void run() {
@ -290,6 +375,13 @@ public class JingleSession {
return IQ.createResultIQ(request);
}
/**
* Handle incoming session-terminate request.
* This includes passing down the request to child contents, setting the sessionState to ended and removing the session
* from the {@link JingleManager}.
* @param request request.
* @return result.
*/
private IQ handleSessionTerminate(JingleElement request) {
this.sessionState = SessionState.ended;
JingleReasonElement reason = request.getReason();
@ -304,17 +396,25 @@ public class JingleSession {
content.handleContentTerminate(r);
}
sessionState = SessionState.ended;
jingleManager.removeSession(this);
return IQ.createResultIQ(request);
}
/**
* Handle incoming content-accept request.
* This includes moving affected contents from proposedContents to contents and notifying them.
* @param request request.
* @return result.
*/
private IQ handleContentAccept(final JingleElement request) {
for (JingleContentElement a : request.getContents()) {
final JingleContent accepted = proposedContents.get(a.getName());
if (accepted == null) {
throw new AssertionError("Illegal content name!");
//TODO: Throw other exception?
}
proposedContents.remove(accepted.getName());
@ -331,6 +431,12 @@ public class JingleSession {
return IQ.createResultIQ(request);
}
/**
* Handle a content-add request.
* This includes notifying respective {@link JingleDescriptionManager} about the request.
* @param request request.
* @return result.
*/
private IQ handleContentAdd(JingleElement request) {
final JingleContent proposed = getSoleProposedContentOrThrow(request);
@ -350,6 +456,12 @@ public class JingleSession {
return IQ.createResultIQ(request);
}
/**
* Handle incoming content-reject requests.
* That includes removing the affected contents from the proposedContents map.
* @param request request.
* @return result.
*/
private IQ handleContentReject(JingleElement request) {
for (JingleContentElement r : request.getContents()) {
final JingleContent rejected = proposedContents.get(r.getName());
@ -373,6 +485,12 @@ public class JingleSession {
return IQ.createResultIQ(request);
}
/**
* Handle incoming content-remove requests.
* TODO: Implement.
* @param request request.
* @return result.
*/
private IQ handleContentRemove(final JingleElement request) {
return IQ.createErrorResponse(request, XMPPError.Condition.feature_not_implemented);
/*
@ -397,34 +515,66 @@ public class JingleSession {
*/
}
/**
* Return the {@link FullJid} of the initiator.
* @return initiators {@link FullJid}
*/
public FullJid getInitiator() {
return initiator;
}
/**
* Return the {@link FullJid} of the responder.
* @return responders {@link FullJid}
*/
public FullJid getResponder() {
return responder;
}
/**
* Return the {@link FullJid} of the peer (the other party of the session).
* @return peers {@link FullJid}
*/
public FullJid getPeer() {
return role == Role.initiator ? responder : initiator;
}
/**
* Return our {@link FullJid}.
* @return our {@link FullJid}.
*/
public FullJid getOurJid() {
return role == Role.initiator ? initiator : responder;
}
/**
* Return true, if we are the initiator.
* @return initiator?
*/
public boolean isInitiator() {
return role == Role.initiator;
}
/**
* Return true, if we are the responder.
* @return responder?
*/
public boolean isResponder() {
return role == Role.responder;
}
/**
* Return the SID of this session.
* @return sessionId.
*/
public String getSessionId() {
return sessionId;
}
/**
* Return the {@link JingleManager} of this session.
* @return jingleManager.
*/
public JingleManager getJingleManager() {
return jingleManager;
}
@ -441,6 +591,15 @@ public class JingleSession {
return map;
}
/**
* If the request contains only one {@link JingleContentElement} and this session contains the
* related {@link JingleContent}, return that {@link JingleContent}.
* If the request contains more than one {@link JingleContentElement}, throw an AssertionError.
* If the session does not contain the {@link JingleContent} related to the {@link JingleContentElement} from the
* request, throw an AssertionError.
* @param request request.
* @return the only affected content, or throw.
*/
private JingleContent getSoleAffectedContentOrThrow(JingleElement request) {
if (request.getContents().size() != 1) {
throw new AssertionError("More/less than 1 content in request!");
@ -454,6 +613,12 @@ public class JingleSession {
return content;
}
/**
* If the request cotains only one {@link JingleContentElement}, parse it in a {@link JingleContent} and return it.
* Otherwise throw an AssertionError.
* @param request request.
* @return sole proposed content or throw.
*/
private static JingleContent getSoleProposedContentOrThrow(JingleElement request) {
if (request.getContents().size() != 1) {
throw new AssertionError("More/less than 1 content in request!");
@ -462,6 +627,11 @@ public class JingleSession {
return JingleContent.fromElement(request.getContents().get(0));
}
/**
* Add a {@link JingleContent} to the session.
* @throws IllegalArgumentException if the session already contains the content.
* @param content content.
*/
public void addContent(JingleContent content) {
if (contents.get(content.getName()) != null) {
throw new IllegalArgumentException("Session already contains a content with the name " + content.getName());
@ -470,15 +640,32 @@ public class JingleSession {
content.setParent(this);
}
/**
* Add a {@link JingleContent}, which gets parsed from the given {@link JingleContentElement} to the session.
* @param content contentElement.
* @param manager JingleManager.
* @throws UnsupportedSecurityException
* @throws UnsupportedTransportException
* @throws UnsupportedDescriptionException
*/
public void addContent(JingleContentElement content, JingleManager manager)
throws UnsupportedSecurityException, UnsupportedTransportException, UnsupportedDescriptionException {
addContent(JingleContent.fromElement(content));
}
/**
* Return the map of {@link JingleContent}s of this session.
* @return contents.
*/
public ConcurrentHashMap<String, JingleContent> getContents() {
return contents;
}
/**
* Return the {@link JingleContent} with the given name, or null if the session does not contain that content.
* @param name name.
* @return content or null.
*/
public JingleContent getContent(String name) {
return contents.get(name);
}
@ -502,6 +689,10 @@ public class JingleSession {
return contents.values().iterator().next();
}
/**
* Return the state of the session.
* @return state.
*/
public SessionState getSessionState() {
return sessionState;
}

View File

@ -23,7 +23,7 @@ import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.callback.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportInfoElement;
import org.jivesoftware.smackx.jingle.element.JingleElement;
@ -34,15 +34,35 @@ import org.jivesoftware.smackx.jingle.element.JingleElement;
public abstract class JingleTransport<D extends JingleContentTransportElement> {
private JingleContent parent;
/**
* List of transport candidates that we proposed to the peer.
*/
private final ArrayList<JingleTransportCandidate<?>> ourCandidates = new ArrayList<>();
/**
* List of transport candidates that our peer proposed to us.
*/
private final ArrayList<JingleTransportCandidate<?>> theirCandidates = new ArrayList<>();
/**
* The {@link BytestreamSession} we try to establish.
*/
protected BytestreamSession bytestreamSession;
/**
* Return a {@link JingleContentTransportElement} which represents the state of this.
* @return element.
*/
public abstract D getElement();
/**
* Add a {@link JingleTransportCandidate} to the list of our proposed candidates.
* The insertion is made sorted with descending priority.
* @param candidate candidate.
*/
public void addOurCandidate(JingleTransportCandidate<?> candidate) {
// Insert sorted by descending priority
// Insert sorted by descending priority
int i;
// Find appropriate index
for (i = 0; i < ourCandidates.size(); i++) {
@ -62,6 +82,11 @@ public abstract class JingleTransport<D extends JingleContentTransportElement> {
candidate.setParent(this);
}
/**
* Add a {@link JingleTransportCandidate} to the list of their proposed candidates.
* The insertion is made sorted with descending priority.
* @param candidate candidate.
*/
public void addTheirCandidate(JingleTransportCandidate<?> candidate) {
// Insert sorted by descending priority
int i;
@ -83,35 +108,93 @@ public abstract class JingleTransport<D extends JingleContentTransportElement> {
candidate.setParent(this);
}
/**
* Prepare the transport (can be used to register listeners etc.).
* @param connection connection.
*/
public abstract void prepare(XMPPConnection connection);
/**
* Return the list of {@link JingleTransportCandidate}s we proposed.
* @return our candidates
*/
public List<JingleTransportCandidate<?>> getOurCandidates() {
return ourCandidates;
}
/**
* Return the list of {@link JingleTransportCandidate}s our peer proposed to us.
* @return their candidates.
*/
public List<JingleTransportCandidate<?>> getTheirCandidates() {
return theirCandidates;
}
/**
* Return the namespace of this transport.
* @return namespace.
*/
public abstract String getNamespace();
/**
* Establish a incoming {@link BytestreamSession} with peer.
* On success, call {@link JingleTransportCallback#onTransportReady(BytestreamSession)}.
* On failure, call {@link JingleTransportCallback#onTransportFailed(Exception)}.
* @param connection connection
* @param callback callback
* @param session {@link JingleSession} in which's context we try to connect.
* @throws SmackException.NotConnectedException
* @throws InterruptedException
*/
public abstract void establishIncomingBytestreamSession(XMPPConnection connection, JingleTransportCallback callback, JingleSession session)
throws SmackException.NotConnectedException, InterruptedException;
/**
* Establish a outgoing {@link BytestreamSession} with peer.
* On success, call {@link JingleTransportCallback#onTransportReady(BytestreamSession)}.
* On failure, call {@link JingleTransportCallback#onTransportFailed(Exception)}.
* @param connection connection
* @param callback callback
* @param session {@link JingleSession} in which's context we try to connect.
* @throws SmackException.NotConnectedException
* @throws InterruptedException
*/
public abstract void establishOutgoingBytestreamSession(XMPPConnection connection, JingleTransportCallback callback, JingleSession session)
throws SmackException.NotConnectedException, InterruptedException;
/**
* Handle an incoming transport-info request.
* @param info info
* @param wrapping wrapping {@link JingleElement}.
* @return result.
*/
public abstract IQ handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping);
/**
* Set the parent {@link JingleContent} of this transport component.
* @param parent content.
*/
public void setParent(JingleContent parent) {
this.parent = parent;
}
/**
* Return the parent {@link JingleContent} of this transport component.
* @return content.
*/
public JingleContent getParent() {
return parent;
}
/**
* Handle an incoming session-accept request.
* @param transportElement the {@link JingleContentTransportElement} we received
* @param connection connection.
*/
public abstract void handleSessionAccept(JingleContentTransportElement transportElement, XMPPConnection connection);
/**
* Shut down components etc.
*/
public abstract void cleanup();
}

View File

@ -23,26 +23,53 @@ import org.jivesoftware.smackx.jingle.element.JingleContentTransportCandidateEle
*/
public abstract class JingleTransportCandidate<E extends JingleContentTransportCandidateElement> {
/**
* Parent {@link JingleTransport}, which contains this as a child candidate.
*/
private JingleTransport<?> parent;
/**
* Priority of this candidate.
*/
private int priority;
/**
* Set the parent {@link JingleTransport}.
* @param transport parent.
*/
public void setParent(JingleTransport<?> transport) {
if (parent != transport) {
parent = transport;
}
}
/**
* Return the parent {@link JingleTransport}.
* @return parent transport.
*/
public JingleTransport<?> getParent() {
return parent;
}
/**
* Return the priority of this candidate.
* @return priority.
*/
public int getPriority() {
return priority;
}
/**
* Set the priority of this candidate.
* @param priority priority.
*/
public void setPriority(int priority) {
this.priority = priority;
}
/**
* Return an {@link JingleContentTransportCandidateElement} which represents this.
* @return element.
*/
public abstract E getElement();
}

View File

@ -22,9 +22,10 @@ import java.util.List;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smackx.jingle.component.JingleDescription;
/**
* Jingle content description.
* {@link ExtensionElement} representing a {@link JingleDescription}.
* <jingle>
* <content>
* <description/> <- This element is us.

View File

@ -20,9 +20,10 @@ import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smackx.jingle.component.JingleContent;
/**
* Jingle content element.
* {@link NamedElement} representing a {@link JingleContent}.
* <jingle>
* <content> <- Me.
* ...

View File

@ -17,9 +17,10 @@
package org.jivesoftware.smackx.jingle.element;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smackx.jingle.component.JingleSecurity;
/**
* Jingle security element.
* {@link ExtensionElement} representing a {@link JingleSecurity}.
* <jingle>
* <content>
* <description/>

View File

@ -19,7 +19,7 @@ package org.jivesoftware.smackx.jingle.element;
import org.jivesoftware.smack.packet.NamedElement;
/**
* Created by vanitas on 19.07.17.
* JingleSecurity info element.
*/
public abstract class JingleContentSecurityInfoElement implements NamedElement {

View File

@ -17,9 +17,10 @@
package org.jivesoftware.smackx.jingle.element;
import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smackx.jingle.component.JingleTransportCandidate;
/**
* An element found usually in Jingle 'transport' elements.
* {@link NamedElement} representing a {@link JingleTransportCandidate}
* <jingle>
* <content>
* <description/>

View File

@ -21,9 +21,10 @@ import java.util.List;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smackx.jingle.component.JingleTransport;
/**
* A jingle transport extension.
* {@link ExtensionElement} representing a {@link JingleTransport}.
* <jingle>
* <content>
* <description/>

View File

@ -25,11 +25,12 @@ import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.jingle.component.JingleSession;
import org.jxmpp.jid.FullJid;
/**
* The Jingle element.
* The Jingle element. This represents a {@link JingleSession}.
*
* @author Florian Schmaus
*/
@ -136,6 +137,12 @@ public final class JingleElement extends IQ {
return contents;
}
/**
* If there is only one {@link JingleContentElement}, return it.
* If there is none, return null.
* Otherwise throw a new {@link IllegalStateException}.
* @return jingleContentElement or null.
*/
public JingleContentElement getSoleContentOrThrow() {
if (contents.isEmpty()) {
return null;

View File

@ -18,7 +18,12 @@ package org.jivesoftware.smackx.jingle.element;
import org.jivesoftware.smack.packet.StandardExtensionElement;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smackx.jingle.provider.JingleContentDescriptionProvider;
/**
* Default {@link JingleContentDescriptionElement}, which gets returned, if there is no suitable
* {@link JingleContentDescriptionProvider} registered.
*/
public final class UnknownJingleContentDescriptionElement extends JingleContentDescriptionElement {
private final StandardExtensionElement standardExtensionElement;
@ -43,6 +48,10 @@ public final class UnknownJingleContentDescriptionElement extends JingleContentD
return standardExtensionElement.toXML();
}
/**
* Return the {@link StandardExtensionElement} which represents this.
* @return element.
*/
public StandardExtensionElement getStandardExtensionElement() {
return standardExtensionElement;
}

View File

@ -18,7 +18,12 @@ package org.jivesoftware.smackx.jingle.element;
import org.jivesoftware.smack.packet.StandardExtensionElement;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smackx.jingle.provider.JingleContentSecurityProvider;
/**
* Default {@link JingleContentSecurityElement}, which gets returned, if there is no suitable
* {@link JingleContentSecurityProvider} registered.
*/
public final class UnknownJingleContentSecurityElement extends JingleContentSecurityElement {
private final StandardExtensionElement standardExtensionElement;
@ -48,6 +53,10 @@ public final class UnknownJingleContentSecurityElement extends JingleContentSecu
throw new UnsupportedOperationException();
}
/**
* Return the {@link StandardExtensionElement} which represents this.
* @return element.
*/
public StandardExtensionElement getStandardExtensionElement() {
return standardExtensionElement;
}

View File

@ -20,7 +20,12 @@ import java.util.List;
import org.jivesoftware.smack.packet.StandardExtensionElement;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smackx.jingle.provider.JingleContentTransportProvider;
/**
* Default {@link JingleContentTransportElement}, which gets returned, if there is no suitable
* {@link JingleContentTransportProvider} registered.
*/
public final class UnknownJingleContentTransportElement extends JingleContentTransportElement {
private final StandardExtensionElement standardExtensionElement;
@ -55,6 +60,10 @@ public final class UnknownJingleContentTransportElement extends JingleContentTra
throw new UnsupportedOperationException();
}
/**
* Return the {@link StandardExtensionElement} which represents this.
* @return element.
*/
public StandardExtensionElement getStandardExtensionElement() {
return standardExtensionElement;
}

View File

@ -16,8 +16,10 @@
*/
package org.jivesoftware.smackx.jingle.exception;
import org.jivesoftware.smackx.jingle.component.JingleTransport;
/**
* Created by vanitas on 25.07.17.
* Exception that gets thrown, if we failed to negotiate a {@link JingleTransport}.
*/
public class FailedTransportException extends Exception {

View File

@ -28,7 +28,7 @@ import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamListener;
import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamRequest;
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.callback.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.component.JingleSession;
import org.jivesoftware.smackx.jingle.component.JingleTransport;
import org.jivesoftware.smackx.jingle.component.JingleTransportCandidate;

View File

@ -33,7 +33,7 @@ import org.jivesoftware.smackx.bytestreams.socks5.Socks5Proxy;
import org.jivesoftware.smackx.bytestreams.socks5.Socks5Utils;
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
import org.jivesoftware.smackx.jingle.JingleManager;
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.callback.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.component.JingleSession;
import org.jivesoftware.smackx.jingle.component.JingleTransport;
import org.jivesoftware.smackx.jingle.component.JingleTransportCandidate;

View File

@ -29,7 +29,7 @@ import org.jivesoftware.smack.util.Async;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.bytestreams.socks5.Socks5Proxy;
import org.jivesoftware.smackx.jingle.JingleManager;
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.callback.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.component.JingleContent;
import org.jivesoftware.smackx.jingle.component.JingleSession;
import org.jivesoftware.smackx.jingle.component.JingleTransport;