1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2025-09-09 17:19:39 +02:00

Merge branch '4.4'

This commit is contained in:
Florian Schmaus 2021-10-19 14:33:21 +02:00
commit e842195b71
28 changed files with 282 additions and 86 deletions

View file

@ -153,7 +153,7 @@ public class DataPacketExtension implements ExtensionElement {
@Override
public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
XmlStringBuilder xml = getIQChildElementBuilder(new IQChildElementXmlStringBuilder(this));
XmlStringBuilder xml = getIQChildElementBuilder(new IQChildElementXmlStringBuilder(this, enclosingNamespace));
xml.closeElement(this);
return xml;
}

View file

@ -615,9 +615,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
if (annouceLocalStreamHost) {
// add local proxy on first position if exists
List<StreamHost> localProxies = getLocalStreamHost();
if (localProxies != null) {
streamHosts.addAll(localProxies);
}
streamHosts.addAll(localProxies);
}
// query SOCKS5 proxies for network settings
@ -652,12 +650,14 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
/**
* Returns the stream host information of the local SOCKS5 proxy containing the IP address and
* the port or null if local SOCKS5 proxy is not running.
* the port. The returned list may be empty if the local SOCKS5 proxy is not running.
*
* @return the stream host information of the local SOCKS5 proxy or null if local SOCKS5 proxy
* is not running
* @return the stream host information of the local SOCKS5 proxy
*/
public List<StreamHost> getLocalStreamHost() {
// Ensure that the local SOCKS5 proxy is running (if enabled).
Socks5Proxy.getSocks5Proxy();
List<StreamHost> streamHosts = new ArrayList<>();
XMPPConnection connection = connection();

View file

@ -258,6 +258,14 @@ public class DiscoverInfo extends IQ implements DiscoverInfoView {
return features.contains(new Feature(feature));
}
public static boolean nullSafeContainsFeature(DiscoverInfo discoverInfo, CharSequence feature) {
if (discoverInfo == null) {
return false;
}
return discoverInfo.containsFeature(feature);
}
@Override
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
xml.optAttribute("node", getNode());

View file

@ -53,7 +53,7 @@ public class JingleUtil {
JingleContentDescription description,
JingleContentTransport transport) {
Jingle.Builder jb = Jingle.getBuilder();
Jingle.Builder jb = Jingle.builder(connection);
jb.setAction(JingleAction.session_initiate)
.setSessionId(sessionId)
.setInitiator(connection.getUser());
@ -118,7 +118,7 @@ public class JingleUtil {
JingleContentDescription description,
JingleContentTransport transport) {
Jingle.Builder jb = Jingle.getBuilder();
Jingle.Builder jb = Jingle.builder(connection);
jb.setResponder(connection.getUser())
.setAction(JingleAction.session_accept)
.setSessionId(sessionId);
@ -153,7 +153,7 @@ public class JingleUtil {
}
public Jingle createSessionTerminate(FullJid recipient, String sessionId, JingleReason reason) {
Jingle.Builder jb = Jingle.getBuilder();
Jingle.Builder jb = Jingle.builder(connection);
jb.setAction(JingleAction.session_terminate)
.setSessionId(sessionId)
.setReason(reason);
@ -232,7 +232,7 @@ public class JingleUtil {
public Jingle createSessionTerminateContentCancel(FullJid recipient, String sessionId,
JingleContent.Creator contentCreator, String contentName) {
Jingle.Builder jb = Jingle.getBuilder();
Jingle.Builder jb = Jingle.builder(connection);
jb.setAction(JingleAction.session_terminate)
.setSessionId(sessionId);
@ -314,7 +314,7 @@ public class JingleUtil {
}
public Jingle createSessionPing(FullJid recipient, String sessionId) {
Jingle.Builder jb = Jingle.getBuilder();
Jingle.Builder jb = Jingle.builder(connection);
jb.setSessionId(sessionId)
.setAction(JingleAction.session_info);
@ -343,7 +343,7 @@ public class JingleUtil {
public Jingle createTransportReplace(FullJid recipient, FullJid initiator, String sessionId,
JingleContent.Creator contentCreator, String contentName,
JingleContentTransport transport) {
Jingle.Builder jb = Jingle.getBuilder();
Jingle.Builder jb = Jingle.builder(connection);
jb.setInitiator(initiator)
.setSessionId(sessionId)
.setAction(JingleAction.transport_replace);
@ -370,7 +370,7 @@ public class JingleUtil {
public Jingle createTransportAccept(FullJid recipient, FullJid initiator, String sessionId,
JingleContent.Creator contentCreator, String contentName,
JingleContentTransport transport) {
Jingle.Builder jb = Jingle.getBuilder();
Jingle.Builder jb = Jingle.builder(connection);
jb.setAction(JingleAction.transport_accept)
.setInitiator(initiator)
.setSessionId(sessionId);
@ -397,7 +397,7 @@ public class JingleUtil {
public Jingle createTransportReject(FullJid recipient, FullJid initiator, String sessionId,
JingleContent.Creator contentCreator, String contentName,
JingleContentTransport transport) {
Jingle.Builder jb = Jingle.getBuilder();
Jingle.Builder jb = Jingle.builder(connection);
jb.setAction(JingleAction.transport_reject)
.setInitiator(initiator)
.setSessionId(sessionId);

View file

@ -1,6 +1,6 @@
/**
*
* Copyright 2003-2007 Jive Software, 2014-2017 Florian Schmaus
* Copyright 2003-2007 Jive Software, 2014-2021 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,7 +21,11 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.IqBuilder;
import org.jivesoftware.smack.packet.IqData;
import org.jivesoftware.smack.packet.id.StandardStanzaIdSource;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smack.util.StringUtils;
@ -65,9 +69,9 @@ public final class Jingle extends IQ {
private final List<JingleContent> contents;
private Jingle(String sessionId, JingleAction action, FullJid initiator, FullJid responder, JingleReason reason,
private Jingle(Builder builder, String sessionId, JingleAction action, FullJid initiator, FullJid responder, JingleReason reason,
List<JingleContent> contents) {
super(ELEMENT, NAMESPACE);
super(builder, ELEMENT, NAMESPACE);
this.sessionId = StringUtils.requireNotNullNorEmpty(sessionId, "Jingle session ID must not be null");
this.action = Objects.requireNonNull(action, "Jingle action must not be null");
this.initiator = initiator;
@ -169,11 +173,31 @@ public final class Jingle extends IQ {
return xml;
}
/**
* Deprecated, do not use.
*
* @return a builder.
* @deprecated use {@link #builder(XMPPConnection)} instead.
*/
@Deprecated
// TODO: Remove in Smack 4.6.
public static Builder getBuilder() {
return new Builder();
return builder(StandardStanzaIdSource.DEFAULT.getNewStanzaId());
}
public static final class Builder {
public static Builder builder(XMPPConnection connection) {
return new Builder(connection);
}
public static Builder builder(IqData iqData) {
return new Builder(iqData);
}
public static Builder builder(String stanzaId) {
return new Builder(stanzaId);
}
public static final class Builder extends IqBuilder<Builder, Jingle> {
private String sid;
private JingleAction action;
@ -186,7 +210,16 @@ public final class Jingle extends IQ {
private List<JingleContent> contents;
private Builder() {
Builder(IqData iqCommon) {
super(iqCommon);
}
Builder(XMPPConnection connection) {
super(connection);
}
Builder(String stanzaId) {
super(stanzaId);
}
public Builder setSessionId(String sessionId) {
@ -228,8 +261,14 @@ public final class Jingle extends IQ {
return this;
}
@Override
public Jingle build() {
return new Jingle(sid, action, initiator, responder, reason, contents);
return new Jingle(this, sid, action, initiator, responder, reason, contents);
}
@Override
public Builder getThis() {
return this;
}
}
}

View file

@ -145,6 +145,11 @@ public final class JingleContent implements XmlElement {
xml.optAttribute(DISPOSITION_ATTRIBUTE_NAME, disposition);
xml.attribute(NAME_ATTRIBUTE_NAME, name);
xml.optAttribute(SENDERS_ATTRIBUTE_NAME, senders);
if (description == null && transport == null) {
return xml.closeEmptyElement();
}
xml.rightAngleBracket();
xml.optAppend(description);

View file

@ -1,6 +1,6 @@
/**
*
* Copyright 2017-2019 Florian Schmaus
* Copyright 2017-2021 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,11 +19,12 @@ package org.jivesoftware.smackx.jingle.provider;
import java.io.IOException;
import java.util.logging.Logger;
import org.jivesoftware.smack.packet.IqData;
import org.jivesoftware.smack.packet.StandardExtensionElement;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.parsing.SmackParsingException;
import org.jivesoftware.smack.parsing.StandardExtensionElementProvider;
import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.provider.IqProvider;
import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
@ -40,13 +41,13 @@ import org.jivesoftware.smackx.jingle.element.UnknownJingleContentTransport;
import org.jxmpp.jid.FullJid;
public class JingleProvider extends IQProvider<Jingle> {
public class JingleProvider extends IqProvider<Jingle> {
private static final Logger LOGGER = Logger.getLogger(JingleProvider.class.getName());
@Override
public Jingle parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException {
Jingle.Builder builder = Jingle.getBuilder();
public Jingle parse(XmlPullParser parser, int initialDepth, IqData iqData, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException {
Jingle.Builder builder = Jingle.builder(iqData);
String actionString = parser.getAttributeValue("", Jingle.ACTION_ATTRIBUTE_NAME);
if (actionString != null) {

View file

@ -36,6 +36,10 @@ public abstract class JingleTransportManager<D extends JingleContentTransport> i
}
public XMPPConnection getConnection() {
return connection();
}
public XMPPConnection connection() {
return connection;
}

View file

@ -148,7 +148,7 @@ public final class JingleS5BTransportManager extends JingleTransportManager<Jing
public Jingle createCandidateUsed(FullJid recipient, FullJid initiator, String sessionId, JingleContent.Senders contentSenders,
JingleContent.Creator contentCreator, String contentName, String streamId,
String candidateId) {
Jingle.Builder jb = Jingle.getBuilder();
Jingle.Builder jb = Jingle.builder(connection());
jb.setSessionId(sessionId).setInitiator(initiator).setAction(JingleAction.transport_info);
JingleContent.Builder cb = JingleContent.getBuilder();
@ -165,7 +165,7 @@ public final class JingleS5BTransportManager extends JingleTransportManager<Jing
}
public Jingle createCandidateError(FullJid remote, FullJid initiator, String sessionId, JingleContent.Senders senders, JingleContent.Creator creator, String name, String streamId) {
Jingle.Builder jb = Jingle.getBuilder();
Jingle.Builder jb = Jingle.builder(connection());
jb.setSessionId(sessionId).setInitiator(initiator).setAction(JingleAction.transport_info);
JingleContent.Builder cb = JingleContent.getBuilder();
@ -184,7 +184,7 @@ public final class JingleS5BTransportManager extends JingleTransportManager<Jing
public Jingle createProxyError(FullJid remote, FullJid initiator, String sessionId,
JingleContent.Senders senders, JingleContent.Creator creator,
String name, String streamId) {
Jingle.Builder jb = Jingle.getBuilder();
Jingle.Builder jb = Jingle.builder(connection());
jb.setSessionId(sessionId).setAction(JingleAction.transport_info).setInitiator(initiator);
JingleContent.Builder cb = JingleContent.getBuilder();
@ -202,7 +202,7 @@ public final class JingleS5BTransportManager extends JingleTransportManager<Jing
public Jingle createCandidateActivated(FullJid remote, FullJid initiator, String sessionId,
JingleContent.Senders senders, JingleContent.Creator creator,
String name, String streamId, String candidateId) {
Jingle.Builder jb = Jingle.getBuilder();
Jingle.Builder jb = Jingle.builder(connection());
jb.setInitiator(initiator).setSessionId(sessionId).setAction(JingleAction.transport_info);
JingleContent.Builder cb = JingleContent.getBuilder();

View file

@ -212,7 +212,12 @@ public class MultiUserChat {
switch (presence.getType()) {
case available:
Presence oldPresence = occupantsMap.put(from, presence);
if (oldPresence != null) {
if (mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110)) {
processedReflectedSelfPresence = true;
synchronized (this) {
notify();
}
} else if (oldPresence != null) {
// Get the previous occupant's affiliation & role
MUCUser mucExtension = MUCUser.from(oldPresence);
MUCAffiliation oldAffiliation = mucExtension.getItem().getAffiliation();
@ -228,11 +233,6 @@ public class MultiUserChat {
newAffiliation,
isUserStatusModification,
from);
} else if (mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110)) {
processedReflectedSelfPresence = true;
synchronized (this) {
notify();
}
} else {
// A new occupant has joined the room
for (ParticipantStatusListener listener : participantStatusListeners) {
@ -259,23 +259,24 @@ public class MultiUserChat {
listener.left(from);
}
}
}
Destroy destroy = mucUser.getDestroy();
// The room has been destroyed.
if (destroy != null) {
EntityBareJid alternateMucJid = destroy.getJid();
final MultiUserChat alternateMuc;
if (alternateMucJid == null) {
alternateMuc = null;
} else {
alternateMuc = multiUserChatManager.getMultiUserChat(alternateMucJid);
}
Destroy destroy = mucUser.getDestroy();
// The room has been destroyed.
if (destroy != null) {
EntityBareJid alternateMucJid = destroy.getJid();
final MultiUserChat alternateMuc;
if (alternateMucJid == null) {
alternateMuc = null;
} else {
alternateMuc = multiUserChatManager.getMultiUserChat(alternateMucJid);
}
for (UserStatusListener listener : userStatusListeners) {
listener.roomDestroyed(alternateMuc, destroy.getReason());
}
for (UserStatusListener listener : userStatusListeners) {
listener.roomDestroyed(alternateMuc, destroy.getReason());
}
}
if (isUserStatusModification) {
for (UserStatusListener listener : userStatusListeners) {
listener.removed(mucUser, presence);
@ -793,11 +794,14 @@ public class MultiUserChat {
StanzaFilter reflectedLeavePresenceFilter = new AndFilter(reflectedLeavePresenceFilters);
// Reset occupant information first so that we are assume that we left the room even if sendStanza() would
// throw.
userHasLeft();
Presence reflectedLeavePresence = connection.createStanzaCollectorAndSend(reflectedLeavePresenceFilter, leavePresence).nextResultOrThrow();
Presence reflectedLeavePresence;
try {
reflectedLeavePresence = connection.createStanzaCollectorAndSend(reflectedLeavePresenceFilter, leavePresence).nextResultOrThrow();
} finally {
// Reset occupant information after we send the leave presence. This ensures that we only call userHasLeft()
// and reset the local MUC state after we successfully left the MUC (or if an exception occurred).
userHasLeft();
}
return reflectedLeavePresence;
}
@ -2579,7 +2583,7 @@ public class MultiUserChat {
}
public boolean serviceSupportsStableIds() {
return mucServiceDiscoInfo.containsFeature(MultiUserChatConstants.STABLE_ID_FEATURE);
return DiscoverInfo.nullSafeContainsFeature(mucServiceDiscoInfo, MultiUserChatConstants.STABLE_ID_FEATURE);
}
@Override

View file

@ -75,8 +75,7 @@ public class JingleContentTest extends SmackTestSuite {
assertEquals(content1.toXML().toString(), builder.build().toXML().toString());
String xml =
"<content xmlns='urn:xmpp:jingle:1' creator='initiator' disposition='session' name='A name' senders='both'>" +
"</content>";
"<content xmlns='urn:xmpp:jingle:1' creator='initiator' disposition='session' name='A name' senders='both'/>";
assertEquals(xml, content1.toXML().toString());
}
}

View file

@ -38,7 +38,7 @@ public class JingleTest extends SmackTestSuite {
@Test
public void emptyBuilderTest() {
Jingle.Builder builder = Jingle.getBuilder();
Jingle.Builder builder = Jingle.builder("id");
assertThrows(IllegalArgumentException.class, () -> {
builder.build();
});
@ -48,7 +48,7 @@ public class JingleTest extends SmackTestSuite {
public void onlySessionIdBuilderTest() {
String sessionId = "testSessionId";
Jingle.Builder builder = Jingle.getBuilder();
Jingle.Builder builder = Jingle.builder("id");
builder.setSessionId(sessionId);
assertThrows(IllegalArgumentException.class, () -> {
builder.build();
@ -59,7 +59,7 @@ public class JingleTest extends SmackTestSuite {
public void parserTest() throws XmppStringprepException {
String sessionId = "testSessionId";
Jingle.Builder builder = Jingle.getBuilder();
Jingle.Builder builder = Jingle.builder("id");
builder.setSessionId(sessionId);
builder.setAction(JingleAction.session_initiate);

View file

@ -0,0 +1,48 @@
/**
*
* Copyright 2021 Florian Schmaus
*
* 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.element;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.jivesoftware.smack.packet.StreamOpen;
import org.junit.jupiter.api.Test;
public class JingleTest {
@Test
public void noRedundantNamespaceTest() {
Jingle.Builder jingleBuilder = Jingle.builder("test-id");
jingleBuilder.setSessionId("MySession");
jingleBuilder.setAction(JingleAction.content_accept);
JingleContent.Builder jingleContentBuilder = JingleContent.getBuilder();
jingleContentBuilder.setName("Hello world");
jingleContentBuilder.setCreator(JingleContent.Creator.initiator);
jingleBuilder.addJingleContent(jingleContentBuilder.build());
Jingle iq = jingleBuilder.build();
String actualXml = iq.toXML(StreamOpen.CLIENT_NAMESPACE).toString();
String expectedXml
= "<iq id='test-id' type='set'>"
+ "<jingle xmlns='urn:xmpp:jingle:1' action='content-accept' sid='MySession'>"
+ "<content creator='initiator' name='Hello world'/>"
+ "</jingle></iq>";
assertEquals(expectedXml, actualXml);
}
}