1
0
Fork 0
mirror of https://codeberg.org/Mercury-IM/Smack synced 2025-12-08 14:11:07 +01:00

Introduce StanzaBuilder

As first step to immutable Stanza types.
This commit is contained in:
Florian Schmaus 2019-10-24 15:45:08 +02:00
parent 926c5892ad
commit 5db6191110
134 changed files with 2576 additions and 764 deletions

View file

@ -40,9 +40,12 @@ public final class Chat extends Manager {
}
public void send(CharSequence message) throws NotConnectedException, InterruptedException {
Message stanza = new Message();
stanza.setBody(message);
stanza.setType(Message.Type.chat);
Message stanza = connection()
.getStanzaFactory()
.buildMessageStanza()
.ofType(Message.Type.chat)
.setBody(message)
.build();
send(stanza);
}

View file

@ -159,7 +159,7 @@ public class MultipleRecipientManager {
}
// Any <thread/> element from the initial message MUST be copied into the reply.
if (original.getThread() != null) {
reply.setThread(original.getThread());
reply.asBuilder().setThread(original.getThread()).build();
}
MultipleAddresses.Address replyAddress = info.getReplyAddress();
if (replyAddress != null && replyAddress.getJid() != null) {

View file

@ -34,6 +34,7 @@ import org.jivesoftware.smack.filter.StanzaTypeFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.StanzaBuilder;
import org.jivesoftware.smack.packet.StanzaError;
import org.jivesoftware.smack.util.stringencoder.Base64;
@ -835,8 +836,9 @@ public class InBandBytestreamSession implements BytestreamSession {
@Override
protected synchronized void writeToXML(DataPacketExtension data) throws NotConnectedException, InterruptedException {
// create message stanza containing data packet
Message message = new Message(remoteJID);
message.addExtension(data);
Message message = StanzaBuilder.buildMessage().to(remoteJID)
.addExtension(data)
.build();
connection.sendStanza(message);

View file

@ -718,7 +718,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
* @throws InterruptedException if the calling thread was interrupted.
*/
protected void replyRejectPacket(IQ packet) throws NotConnectedException, InterruptedException {
StanzaError.Builder xmppError = StanzaError.getBuilder(StanzaError.Condition.not_acceptable);
StanzaError xmppError = StanzaError.getBuilder(StanzaError.Condition.not_acceptable).build();
IQ errorIQ = IQ.createErrorResponse(packet, xmppError);
connection().sendStanza(errorIQ);
}

View file

@ -333,7 +333,7 @@ public class Socks5BytestreamRequest implements BytestreamRequest {
errorMessage = couldNotConnectException.getMessage();
}
StanzaError.Builder error = StanzaError.from(StanzaError.Condition.item_not_found, errorMessage);
StanzaError error = StanzaError.from(StanzaError.Condition.item_not_found, errorMessage).build();
IQ errorIQ = IQ.createErrorResponse(this.bytestreamRequest, error);
this.manager.getConnection().sendStanza(errorIQ);

View file

@ -43,6 +43,7 @@ import org.jivesoftware.smack.filter.StanzaFilter;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.StanzaBuilder;
import org.jivesoftware.smackx.chatstates.packet.ChatStateExtension;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
@ -218,7 +219,7 @@ public final class ChatStateManager extends Manager {
if (!updateChatState(chat, newState)) {
return;
}
Message message = new Message();
Message message = StanzaBuilder.buildMessage().build();
ChatStateExtension extension = new ChatStateExtension(newState);
message.addExtension(extension);

View file

@ -329,7 +329,10 @@ public final class AdHocCommandManager extends Manager {
}
catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
StanzaError.Builder xmppError = StanzaError.getBuilder().setCondition(StanzaError.Condition.internal_server_error).setDescriptiveEnText(e.getMessage());
StanzaError xmppError = StanzaError.getBuilder()
.setCondition(StanzaError.Condition.internal_server_error)
.setDescriptiveEnText(e.getMessage())
.build();
return respondError(response, xmppError);
}
@ -393,7 +396,7 @@ public final class AdHocCommandManager extends Manager {
response.setStatus(Status.canceled);
executingCommands.remove(sessionId);
}
return respondError(response, StanzaError.getBuilder(error));
return respondError(response, error);
}
}
else {
@ -503,7 +506,7 @@ public final class AdHocCommandManager extends Manager {
response.setStatus(Status.canceled);
executingCommands.remove(sessionId);
}
return respondError(response, StanzaError.getBuilder(error));
return respondError(response, error);
}
}
}
@ -559,7 +562,7 @@ public final class AdHocCommandManager extends Manager {
*/
private static IQ respondError(AdHocCommandData response,
StanzaError.Condition condition) {
return respondError(response, StanzaError.getBuilder(condition));
return respondError(response, StanzaError.getBuilder(condition).build());
}
/**
@ -572,7 +575,9 @@ public final class AdHocCommandManager extends Manager {
*/
private static IQ respondError(AdHocCommandData response, StanzaError.Condition condition,
AdHocCommand.SpecificErrorCondition specificCondition) {
StanzaError.Builder error = StanzaError.getBuilder(condition).addExtension(new AdHocCommandData.SpecificError(specificCondition));
StanzaError error = StanzaError.getBuilder(condition)
.addExtension(new AdHocCommandData.SpecificError(specificCondition))
.build();
return respondError(response, error);
}
@ -583,7 +588,7 @@ public final class AdHocCommandManager extends Manager {
* @param error the error to send.
* @throws NotConnectedException if the XMPP connection is not connected.
*/
private static IQ respondError(AdHocCommandData response, StanzaError.Builder error) {
private static IQ respondError(AdHocCommandData response, StanzaError error) {
response.setType(IQ.Type.error);
response.setError(error);
return response;

View file

@ -112,7 +112,7 @@ public class AdHocCommandDataProvider extends IQProvider<AdHocCommandData> {
adHocCommandData.addNote(new AdHocCommandNote(type, value));
}
else if (parser.getName().equals("error")) {
StanzaError.Builder error = PacketParserUtils.parseError(parser);
StanzaError error = PacketParserUtils.parseError(parser);
adHocCommandData.setError(error);
}
}

View file

@ -146,7 +146,7 @@ public final class ServiceDiscoveryManager extends Manager {
// Return <item-not-found/> error since client doesn't contain
// the specified node
response.setType(IQ.Type.error);
response.setError(StanzaError.getBuilder(StanzaError.Condition.item_not_found));
response.setError(StanzaError.getBuilder(StanzaError.Condition.item_not_found).build());
}
return response;
}
@ -184,7 +184,7 @@ public final class ServiceDiscoveryManager extends Manager {
} else {
// Return <item-not-found/> error since specified node was not found
response.setType(IQ.Type.error);
response.setError(StanzaError.getBuilder(StanzaError.Condition.item_not_found));
response.setError(StanzaError.getBuilder(StanzaError.Condition.item_not_found).build());
}
}
return response;

View file

@ -172,7 +172,7 @@ public final class FileTransferManager extends Manager {
// 'not-acceptable' should be returned. This is done by Smack in
// Socks5BytestreamManager.replyRejectPacket(IQ).
IQ rejection = IQ.createErrorResponse(initiation, StanzaError.getBuilder(
StanzaError.Condition.forbidden));
StanzaError.Condition.forbidden).build());
connection().sendStanza(rejection);
}
}

View file

@ -194,7 +194,7 @@ public final class FileTransferNegotiator extends Manager {
if (streamMethodField == null) {
String errorMessage = "No stream methods contained in stanza.";
StanzaError.Builder error = StanzaError.from(StanzaError.Condition.bad_request, errorMessage);
StanzaError error = StanzaError.from(StanzaError.Condition.bad_request, errorMessage).build();
IQ iqPacket = IQ.createErrorResponse(si, error);
connection().sendStanza(iqPacket);
throw new FileTransferException.NoStreamMethodsOfferedException();
@ -206,7 +206,7 @@ public final class FileTransferNegotiator extends Manager {
selectedStreamNegotiator = getNegotiator(streamMethodField);
}
catch (NoAcceptableTransferMechanisms e) {
IQ iqPacket = IQ.createErrorResponse(si, StanzaError.from(StanzaError.Condition.bad_request, "No acceptable transfer mechanism"));
IQ iqPacket = IQ.createErrorResponse(si, StanzaError.from(StanzaError.Condition.bad_request, "No acceptable transfer mechanism").build());
connection().sendStanza(iqPacket);
throw e;
}

View file

@ -80,8 +80,10 @@ public final class GeoLocationManager extends Manager {
final XMPPConnection connection = connection();
Message geoLocationMessage = new Message(jid);
geoLocationMessage.addExtension(geoLocation);
Message geoLocationMessage = connection.getStanzaFactory().buildMessageStanza()
.to(jid)
.addExtension(geoLocation)
.build();
connection.sendStanza(geoLocationMessage);

View file

@ -424,9 +424,10 @@ public class JingleUtil {
*/
public IQ createErrorUnknownSession(Jingle request) {
StanzaError.Builder error = StanzaError.getBuilder();
error.setCondition(StanzaError.Condition.item_not_found)
.addExtension(JingleError.UNKNOWN_SESSION);
StanzaError error = StanzaError.getBuilder()
.setCondition(StanzaError.Condition.item_not_found)
.addExtension(JingleError.UNKNOWN_SESSION)
.build();
return IQ.createErrorResponse(request, error);
}
@ -445,9 +446,10 @@ public class JingleUtil {
}
public IQ createErrorUnsupportedInfo(Jingle request) {
StanzaError.Builder error = StanzaError.getBuilder();
error.setCondition(StanzaError.Condition.feature_not_implemented)
.addExtension(JingleError.UNSUPPORTED_INFO);
StanzaError error = StanzaError.getBuilder()
.setCondition(StanzaError.Condition.feature_not_implemented)
.addExtension(JingleError.UNSUPPORTED_INFO)
.build();
return IQ.createErrorResponse(request, error);
}
@ -457,9 +459,10 @@ public class JingleUtil {
}
public IQ createErrorTieBreak(Jingle request) {
StanzaError.Builder error = StanzaError.getBuilder();
error.setCondition(StanzaError.Condition.conflict)
.addExtension(JingleError.TIE_BREAK);
StanzaError error = StanzaError.getBuilder()
.setCondition(StanzaError.Condition.conflict)
.addExtension(JingleError.TIE_BREAK)
.build();
return IQ.createErrorResponse(request, error);
}
@ -469,9 +472,10 @@ public class JingleUtil {
}
public IQ createErrorOutOfOrder(Jingle request) {
StanzaError.Builder error = StanzaError.getBuilder();
error.setCondition(StanzaError.Condition.unexpected_request)
.addExtension(JingleError.OUT_OF_ORDER);
StanzaError error = StanzaError.getBuilder()
.setCondition(StanzaError.Condition.unexpected_request)
.addExtension(JingleError.OUT_OF_ORDER)
.build();
return IQ.createErrorResponse(request, error);
}

View file

@ -21,6 +21,8 @@ import java.util.Collections;
import java.util.Map;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.StanzaBuilder;
import org.jivesoftware.smack.packet.StanzaView;
import org.jivesoftware.smackx.jiveproperties.packet.JivePropertiesExtension;
@ -54,7 +56,10 @@ public class JivePropertiesManager {
* @param packet the stanza to add the property to.
* @param name the name of the property to add.
* @param value the value of the property to add.
* @deprecated use {@link #addProperty(StanzaBuilder, String, Object)} instead.
*/
@Deprecated
// TODO: Remove in Smack 4.5.
public static void addProperty(Stanza packet, String name, Object value) {
JivePropertiesExtension jpe = (JivePropertiesExtension) packet.getExtension(JivePropertiesExtension.NAMESPACE);
if (jpe == null) {
@ -64,6 +69,22 @@ public class JivePropertiesManager {
jpe.setProperty(name, value);
}
/**
* Convenience method to add a property to a stanza.
*
* @param stanzaBuilder the stanza to add the property to.
* @param name the name of the property to add.
* @param value the value of the property to add.
*/
public static void addProperty(StanzaBuilder<?> stanzaBuilder, String name, Object value) {
JivePropertiesExtension jpe = (JivePropertiesExtension) stanzaBuilder.getExtension(JivePropertiesExtension.QNAME);
if (jpe == null) {
jpe = new JivePropertiesExtension();
stanzaBuilder.addExtension(jpe);
}
jpe.setProperty(name, value);
}
/**
* Convenience method to get a property from a packet. Will return null if the stanza contains
* not property with the given name.
@ -72,9 +93,9 @@ public class JivePropertiesManager {
* @param name TODO javadoc me please
* @return the property or <code>null</code> if none found.
*/
public static Object getProperty(Stanza packet, String name) {
public static Object getProperty(StanzaView packet, String name) {
Object res = null;
JivePropertiesExtension jpe = (JivePropertiesExtension) packet.getExtension(JivePropertiesExtension.NAMESPACE);
JivePropertiesExtension jpe = (JivePropertiesExtension) packet.getExtension(JivePropertiesExtension.QNAME);
if (jpe != null) {
res = jpe.getProperty(name);
}

View file

@ -27,6 +27,8 @@ import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.util.XmlStringBuilder;
@ -47,6 +49,8 @@ public class JivePropertiesExtension implements ExtensionElement {
public static final String ELEMENT = "properties";
public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
private static final Logger LOGGER = Logger.getLogger(JivePropertiesExtension.class.getName());
private final Map<String, Object> properties;

View file

@ -18,7 +18,10 @@ package org.jivesoftware.smackx.muc;
import java.util.Date;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.PresenceBuilder;
import org.jivesoftware.smack.util.Consumer;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smackx.muc.packet.MUCInitialPresence;
@ -58,7 +61,7 @@ public final class MucEnterConfiguration {
timeout = builder.timeout;
if (builder.joinPresence == null) {
joinPresence = new Presence(Presence.Type.available);
joinPresence = builder.joinPresenceBuilder.ofType(Presence.Type.available).build();
}
else {
joinPresence = builder.joinPresence.clone();
@ -87,11 +90,17 @@ public final class MucEnterConfiguration {
private int seconds = -1;
private Date since;
private long timeout;
private final PresenceBuilder joinPresenceBuilder;
private Presence joinPresence;
Builder(Resourcepart nickname, long timeout) {
Builder(Resourcepart nickname, XMPPConnection connection) {
this.nickname = Objects.requireNonNull(nickname, "Nickname must not be null");
timeout = connection.getReplyTimeout();
timeoutAfter(timeout);
joinPresenceBuilder = connection.getStanzaFactory().buildPresenceStanza();
}
/**
@ -103,7 +112,10 @@ public final class MucEnterConfiguration {
*
* @param presence TODO javadoc me please
* @return a reference to this builder.
* @deprecated use {@link #withPresence(Consumer)} instead.
*/
@Deprecated
// TODO: Remove in Smack 4.5.
public Builder withPresence(Presence presence) {
if (presence.getType() != Presence.Type.available) {
throw new IllegalArgumentException("Presence must be of type 'available'");
@ -113,6 +125,26 @@ public final class MucEnterConfiguration {
return this;
}
/**
* Set the presence used to join the MUC room.
* <p>
* The consumer must not modify the presence type, otherwise an {@link IllegalArgumentException} will be thrown.
* <p>
*
* @param presenceBuilderConsumer a consumer which will be passed the presence build.
* @return a reference to this builder.
* @since 4.5
*/
public Builder withPresence(Consumer<? super PresenceBuilder> presenceBuilderConsumer) {
presenceBuilderConsumer.accept(joinPresenceBuilder);
if (joinPresenceBuilder.getType() != Presence.Type.available) {
throw new IllegalArgumentException("Presence must be of type 'available'");
}
return this;
}
/**
* Use the given password to join the MUC room.
*

View file

@ -56,6 +56,7 @@ import org.jivesoftware.smack.filter.StanzaTypeFilter;
import org.jivesoftware.smack.filter.ToMatchesFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.MessageBuilder;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.util.Objects;
@ -419,7 +420,7 @@ public class MultiUserChat {
* @since 4.2
*/
public MucEnterConfiguration.Builder getEnterConfigurationBuilder(Resourcepart nickname) {
return new MucEnterConfiguration.Builder(nickname, connection.getReplyTimeout());
return new MucEnterConfiguration.Builder(nickname, connection);
}
/**
@ -744,8 +745,10 @@ public class MultiUserChat {
// We leave a room by sending a presence packet where the "to"
// field is in the form "roomName@service/nickname"
Presence leavePresence = new Presence(Presence.Type.unavailable);
leavePresence.setTo(myRoomJid);
Presence leavePresence = connection.getStanzaFactory().buildPresenceStanza()
.ofType(Presence.Type.unavailable)
.to(myRoomJid)
.build();
StanzaFilter reflectedLeavePresenceFilter = new AndFilter(
StanzaTypeFilter.PRESENCE,
@ -927,7 +930,7 @@ public class MultiUserChat {
* @throws InterruptedException if the calling thread was interrupted.
*/
public void invite(EntityBareJid user, String reason) throws NotConnectedException, InterruptedException {
invite(new Message(), user, reason);
invite(connection.getStanzaFactory().buildMessageStanza(), user, reason);
}
/**
@ -942,7 +945,10 @@ public class MultiUserChat {
* @param reason the reason why the user is being invited.
* @throws NotConnectedException if the XMPP connection is not connected.
* @throws InterruptedException if the calling thread was interrupted.
* @deprecated use {@link #invite(MessageBuilder, EntityBareJid, String)} instead.
*/
@Deprecated
// TODO: Remove in Smack 4.5.
public void invite(Message message, EntityBareJid user, String reason) throws NotConnectedException, InterruptedException {
// TODO listen for 404 error code when inviter supplies a non-existent JID
message.setTo(room);
@ -957,6 +963,34 @@ public class MultiUserChat {
connection.sendStanza(message);
}
/**
* Invites another user to the room in which one is an occupant using a given Message. The invitation
* will be sent to the room which in turn will forward the invitation to the invitee.<p>
*
* If the room is password-protected, the invitee will receive a password to use to join
* the room. If the room is members-only, the the invitee may be added to the member list.
*
* @param messageBuilder the message to use for sending the invitation.
* @param user the user to invite to the room.(e.g. hecate@shakespeare.lit)
* @param reason the reason why the user is being invited.
* @throws NotConnectedException if the XMPP connection is not connected.
* @throws InterruptedException if the calling thread was interrupted.
*/
public void invite(MessageBuilder messageBuilder, EntityBareJid user, String reason) throws NotConnectedException, InterruptedException {
// TODO listen for 404 error code when inviter supplies a non-existent JID
messageBuilder.to(room);
// Create the MUCUser packet that will include the invitation
MUCUser mucUser = new MUCUser();
MUCUser.Invite invite = new MUCUser.Invite(reason, user);
mucUser.setInvite(invite);
// Add the MUCUser packet that includes the invitation to the message
messageBuilder.addExtension(mucUser);
Message message = messageBuilder.build();
connection.sendStanza(message);
}
/**
* Adds a listener to invitation rejections notifications. The listener will be fired anytime
* an invitation is declined.
@ -1126,8 +1160,10 @@ public class MultiUserChat {
// We change the nickname by sending a presence packet where the "to"
// field is in the form "roomName@service/nickname"
// We don't have to signal the MUC support again
Presence joinPresence = new Presence(Presence.Type.available);
joinPresence.setTo(jid);
Presence joinPresence = connection.getStanzaFactory().buildPresenceStanza()
.to(jid)
.ofType(Presence.Type.available)
.build();
// Wait for a presence packet back from the server.
StanzaFilter responseFilter =
@ -1167,10 +1203,12 @@ public class MultiUserChat {
}
// We change the availability status by sending a presence packet to the room with the
// new presence status and mode
Presence joinPresence = new Presence(Presence.Type.available);
joinPresence.setStatus(status);
joinPresence.setMode(mode);
joinPresence.setTo(myRoomJid);
Presence joinPresence = connection.getStanzaFactory().buildPresenceStanza()
.to(myRoomJid)
.ofType(Presence.Type.available)
.setStatus(status)
.setMode(mode)
.build();
// Send join packet.
connection.sendStanza(joinPresence);
@ -1220,8 +1258,11 @@ public class MultiUserChat {
requestVoiceField.setLabel("Requested role");
requestVoiceField.addValue("participant");
form.addField(requestVoiceField.build());
Message message = new Message(room);
message.addExtension(form);
Message message = connection.getStanzaFactory().buildMessageStanza()
.to(room)
.addExtension(form)
.build();
connection.sendStanza(message);
}
@ -1887,8 +1928,9 @@ public class MultiUserChat {
* @throws InterruptedException if the calling thread was interrupted.
*/
public void sendMessage(String text) throws NotConnectedException, InterruptedException {
Message message = createMessage();
message.setBody(text);
Message message = buildMessage()
.setBody(text)
.build();
connection.sendStanza(message);
}
@ -1914,9 +1956,28 @@ public class MultiUserChat {
* Creates a new Message to send to the chat room.
*
* @return a new Message addressed to the chat room.
* @deprecated use {@link #buildMessage()} instead.
*/
@Deprecated
// TODO: Remove when stanza builder is ready.
public Message createMessage() {
return new Message(room, Message.Type.groupchat);
return connection.getStanzaFactory().buildMessageStanza()
.ofType(Message.Type.groupchat)
.to(room)
.build();
}
/**
* Constructs a new message builder for messages send to this MUC room.
*
* @return a new message builder.
*/
public MessageBuilder buildMessage() {
return connection.getStanzaFactory()
.buildMessageStanza()
.ofType(Message.Type.groupchat)
.to(room)
;
}
/**
@ -1925,10 +1986,23 @@ public class MultiUserChat {
* @param message the message.
* @throws NotConnectedException if the XMPP connection is not connected.
* @throws InterruptedException if the calling thread was interrupted.
* @deprecated use {@link #sendMessage(MessageBuilder)} instead.
*/
@Deprecated
// TODO: Remove in Smack 4.5.
public void sendMessage(Message message) throws NotConnectedException, InterruptedException {
message.setTo(room);
message.setType(Message.Type.groupchat);
sendMessage(message.asBuilder());
}
/**
* Sends a Message to the chat room.
*
* @param messageBuilder the message.
* @throws NotConnectedException if the XMPP connection is not connected.
* @throws InterruptedException if the calling thread was interrupted.
*/
public void sendMessage(MessageBuilder messageBuilder) throws NotConnectedException, InterruptedException {
Message message = messageBuilder.to(room).ofType(Message.Type.groupchat).build();
connection.sendStanza(message);
}
@ -2024,7 +2098,7 @@ public class MultiUserChat {
* @throws InterruptedException if the calling thread was interrupted.
*/
public void changeSubject(final String subject) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
Message message = createMessage();
MessageBuilder message = buildMessage();
message.setSubject(subject);
// Wait for an error or confirmation message back from the server.
StanzaFilter responseFilter = new AndFilter(fromRoomGroupchatFilter, new StanzaFilter() {
@ -2034,7 +2108,7 @@ public class MultiUserChat {
return subject.equals(msg.getSubject());
}
});
StanzaCollector response = connection.createStanzaCollectorAndSend(responseFilter, message);
StanzaCollector response = connection.createStanzaCollectorAndSend(responseFilter, message.build());
// Wait up to a certain number of seconds for a reply.
response.nextResultOrThrow();
}

View file

@ -44,6 +44,7 @@ import org.jivesoftware.smack.filter.StanzaExtensionFilter;
import org.jivesoftware.smack.filter.StanzaFilter;
import org.jivesoftware.smack.filter.StanzaTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.MessageBuilder;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.util.Async;
import org.jivesoftware.smack.util.CleaningWeakReferenceMap;
@ -438,16 +439,18 @@ public final class MultiUserChatManager extends Manager {
* @throws InterruptedException if the calling thread was interrupted.
*/
public void decline(EntityBareJid room, EntityBareJid inviter, String reason) throws NotConnectedException, InterruptedException {
Message message = new Message(room);
XMPPConnection connection = connection();
MessageBuilder messageBuilder = connection.getStanzaFactory().buildMessageStanza().to(room);
// Create the MUCUser packet that will include the rejection
MUCUser mucUser = new MUCUser();
MUCUser.Decline decline = new MUCUser.Decline(reason, inviter);
mucUser.setDecline(decline);
// Add the MUCUser packet that includes the rejection
message.addExtension(mucUser);
messageBuilder.addExtension(mucUser);
connection().sendStanza(message);
connection.sendStanza(messageBuilder.build());
}
/**

View file

@ -193,8 +193,9 @@ public final class PingManager extends Manager {
}
};
Ping ping = new Ping(jid);
connection().sendIqRequestAsync(ping, pongTimeout)
XMPPConnection connection = connection();
Ping ping = new Ping(connection, jid);
connection.sendIqRequestAsync(ping, pongTimeout)
.onSuccess(new SuccessCallback<IQ>() {
@Override
public void onSuccess(IQ result) {
@ -233,7 +234,7 @@ public final class PingManager extends Manager {
if (!connection.isAuthenticated()) {
throw new NotConnectedException();
}
Ping ping = new Ping(jid);
Ping ping = new Ping(connection, jid);
try {
connection.createStanzaCollectorAndSend(ping).nextResultOrThrow(pingTimeout);
}

View file

@ -1,6 +1,6 @@
/**
*
* Copyright 2012-2015 Florian Schmaus
* Copyright 2012-2019 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,7 +16,9 @@
*/
package org.jivesoftware.smackx.ping.packet;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.IqBuilder;
import org.jivesoftware.smack.packet.SimpleIQ;
import org.jxmpp.jid.Jid;
@ -36,6 +38,18 @@ public class Ping extends SimpleIQ {
setType(IQ.Type.get);
}
public Ping(XMPPConnection connection, Jid to) {
this(connection.getStanzaFactory().buildIqStanza(), to);
}
public Ping(IqBuilder iqBuilder, Jid to) {
super(iqBuilder.to(to).ofType(IQ.Type.get), ELEMENT, NAMESPACE);
}
public Ping(IqBuilder iqBuilder) {
super(iqBuilder, ELEMENT, NAMESPACE);
}
/**
* Create an XMPP Pong for this Ping.
*

View file

@ -39,6 +39,7 @@ import org.jivesoftware.smack.filter.StanzaFilter;
import org.jivesoftware.smack.filter.StanzaTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.StanzaBuilder;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.util.StringUtils;
@ -342,8 +343,11 @@ public final class DeliveryReceiptManager extends Manager {
if (StringUtils.isNullOrEmpty(stanzaId)) {
return null;
}
Message message = new Message(messageWithReceiptRequest.getFrom(), messageWithReceiptRequest.getType());
message.addExtension(new DeliveryReceipt(stanzaId));
Message message = StanzaBuilder.buildMessage()
.ofType(messageWithReceiptRequest.getType())
.to(messageWithReceiptRequest.getFrom())
.addExtension(new DeliveryReceipt(stanzaId))
.build();
return message;
}
}

View file

@ -20,6 +20,7 @@ import java.io.IOException;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.MessageBuilder;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.provider.ExtensionElementProvider;
@ -81,12 +82,28 @@ public class DeliveryReceiptRequest implements ExtensionElement {
* @param message Message object to add a request to
* @return the Message ID which will be used as receipt ID
*/
// TODO: Deprecate in favor of addTo(MessageBuilder) once connection's stanza interceptors use StanzaBuilder.
public static String addTo(Message message) {
message.ensureStanzaIdSet();
message.throwIfNoStanzaId();
message.addExtension(new DeliveryReceiptRequest());
return message.getStanzaId();
}
/**
* Add a delivery receipt request to an outgoing packet.
*
* Only message packets may contain receipt requests as of XEP-0184,
* therefore only allow Message as the parameter type.
*
* @param messageBuilder Message object to add a request to
*/
public static void addTo(MessageBuilder messageBuilder) {
messageBuilder.throwIfNoStanzaId();
messageBuilder.overrideExtension(new DeliveryReceiptRequest());
}
/**
* This Provider parses and returns DeliveryReceiptRequest packets.
*/

View file

@ -98,13 +98,15 @@ public final class VCardManager extends Manager {
* @throws NotConnectedException if the XMPP connection is not connected.
* @throws InterruptedException if the calling thread was interrupted.
*/
// TODO: Split VCard into VCardIq and VCardData, then create saveVCard(VCardData) and deprecate this method.
@SuppressWarnings("deprecation")
public void saveVCard(VCard vcard) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
// XEP-54 § 3.2 "A user may publish or update his or her vCard by sending an IQ of type "set" with no 'to' address…"
vcard.setTo((Jid) null);
vcard.setType(IQ.Type.set);
// Also make sure to generate a new stanza id (the given vcard could be a vcard result), in which case we don't
// want to use the same stanza id again (although it wouldn't break if we did)
vcard.setNewStanzaId();
vcard.setStanzaId();
connection().createStanzaCollectorAndSend(vcard).nextResultOrThrow();
}