Make XMPPError imutable and add stanza reference

This commit is contained in:
Florian Schmaus 2015-12-08 08:22:50 +01:00
parent 83eda4c58d
commit 45feaecdf7
30 changed files with 308 additions and 94 deletions

View File

@ -1050,8 +1050,8 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
}
// If the IQ stanza is of type "get" or "set" with no registered IQ request handler, then answer an
// IQ of type 'error' with condition 'service-unavailable'.
ErrorIQ errorIQ = IQ.createErrorResponse(iq, new XMPPError(
XMPPError.Condition.service_unavailable));
ErrorIQ errorIQ = IQ.createErrorResponse(iq, XMPPError.getBuilder((
XMPPError.Condition.service_unavailable)));
try {
sendStanza(errorIQ);
}

View File

@ -73,6 +73,10 @@ public abstract class XMPPException extends Exception {
private static final long serialVersionUID = 212790389529249604L;
private final XMPPError error;
public XMPPErrorException(XMPPError.Builder xmppErrorBuilder) {
this(xmppErrorBuilder.build());
}
/**
* Creates a new XMPPException with the XMPPError that was the root case of the exception.
*
@ -90,7 +94,9 @@ public abstract class XMPPException extends Exception {
* @param message a description of the exception.
* @param error the root cause of the exception.
* @param wrappedThrowable the root cause of the exception.
* @deprecated use {@link XMPPErrorException(XMPPError)} instead.
*/
@Deprecated
public XMPPErrorException(String message, XMPPError error, Throwable wrappedThrowable) {
super(message, wrappedThrowable);
this.error = error;
@ -102,7 +108,9 @@ public abstract class XMPPException extends Exception {
*
* @param message a description of the exception.
* @param error the root cause of the exception.
* @deprecated use {@link XMPPErrorException(XMPPError)} instead.
*/
@Deprecated
public XMPPErrorException(String message, XMPPError error) {
super(message);
this.error = error;

View File

@ -1,6 +1,6 @@
/**
*
* Copyright 2014 Florian Schmaus
* Copyright 2014-2015 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.smack.packet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@ -26,9 +28,9 @@ import org.jivesoftware.smack.util.XmlStringBuilder;
public class AbstractError {
private final String textNamespace;
protected final String textNamespace;
protected final Map<String, String> descriptiveTexts;
private final List<ExtensionElement> extensions;
protected final List<ExtensionElement> extensions;
protected AbstractError(Map<String, String> descriptiveTexts) {
@ -108,4 +110,53 @@ public class AbstractError {
xml.append(packetExtension.toXML());
}
}
public static abstract class Builder<B extends Builder<B>> {
protected String textNamespace;
protected Map<String, String> descriptiveTexts;
protected List<ExtensionElement> extensions;
public B setDescriptiveTexts(Map<String, String> descriptiveTexts) {
if (this.descriptiveTexts == null) {
this.descriptiveTexts = descriptiveTexts;
}
else {
this.descriptiveTexts.putAll(descriptiveTexts);
}
return getThis();
}
public B setDescriptiveEnText(String descriptiveEnText) {
if (descriptiveTexts == null) {
descriptiveTexts = new HashMap<>();
}
descriptiveTexts.put("en", descriptiveEnText);
return getThis();
}
public B setTextNamespace(String textNamespace) {
this.textNamespace = textNamespace;
return getThis();
}
public B setExtensions(List<ExtensionElement> extensions) {
if (this.extensions == null) {
this.extensions = extensions;
}
else {
this.extensions.addAll(extensions);
}
return getThis();
}
public B addExtension(ExtensionElement extension) {
if (extensions == null) {
extensions = new ArrayList<>();
}
extensions.add(extension);
return getThis();
}
protected abstract B getThis();
}
}

View File

@ -27,13 +27,13 @@ public class ErrorIQ extends SimpleIQ {
* <p>
* According to RFC 6120 § 8.3.1 "4. An error stanza MUST contain an <error/> child element.", so the xmppError argument is mandatory.
* </p>
* @param xmppError the XMPPError (required).
* @param xmppErrorBuilder the XMPPError builder (required).
*/
public ErrorIQ(XMPPError xmppError) {
public ErrorIQ(XMPPError.Builder xmppErrorBuilder) {
super(ELEMENT, null);
Objects.requireNonNull(xmppError, "XMPPError must not be null");
Objects.requireNonNull(xmppErrorBuilder, "xmppErrorBuilder must not be null");
setType(IQ.Type.error);
setError(xmppError);
setError(xmppErrorBuilder);
}
}

View File

@ -241,7 +241,7 @@ public abstract class IQ extends Stanza {
* {@link Type#get IQ.Type.get} or {@link Type#set IQ.Type.set}.
* @return a new {@link Type#error IQ.Type.error} IQ based on the originating IQ.
*/
public static ErrorIQ createErrorResponse(final IQ request, final XMPPError error) {
public static ErrorIQ createErrorResponse(final IQ request, final XMPPError.Builder error) {
if (!(request.getType() == Type.get || request.getType() == Type.set)) {
throw new IllegalArgumentException(
"IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML());
@ -250,9 +250,40 @@ public abstract class IQ extends Stanza {
result.setStanzaId(request.getStanzaId());
result.setFrom(request.getTo());
result.setTo(request.getFrom());
error.setStanza(result);
return result;
}
public static ErrorIQ createErrorResponse(final IQ request, final XMPPError.Condition condition) {
return createErrorResponse(request, XMPPError.getBuilder(condition));
}
/**
* Convenience method to create a new {@link Type#error IQ.Type.error} IQ
* based on a {@link Type#get IQ.Type.get} or {@link Type#set IQ.Type.set}
* IQ. The new stanza(/packet) will be initialized with:<ul>
* <li>The sender set to the recipient of the originating IQ.
* <li>The recipient set to the sender of the originating IQ.
* <li>The type set to {@link Type#error IQ.Type.error}.
* <li>The id set to the id of the originating IQ.
* <li>The child element contained in the associated originating IQ.
* <li>The provided {@link XMPPError XMPPError}.
* </ul>
*
* @param request the {@link Type#get IQ.Type.get} or {@link Type#set IQ.Type.set} IQ packet.
* @param error the error to associate with the created IQ packet.
* @throws IllegalArgumentException if the IQ stanza(/packet) does not have a type of
* {@link Type#get IQ.Type.get} or {@link Type#set IQ.Type.set}.
* @return a new {@link Type#error IQ.Type.error} IQ based on the originating IQ.
* @deprecated use {@link #createErrorResponse(IQ, org.jivesoftware.smack.packet.XMPPError.Builder)} instead.
*/
@Deprecated
public static ErrorIQ createErrorResponse(final IQ request, final XMPPError error) {
return createErrorResponse(request, XMPPError.getBuilder(error));
}
/**
* A enum to represent the type of the IQ stanza.
*/

View File

@ -248,11 +248,26 @@ public abstract class Stanza implements TopLevelStreamElement {
* Sets the error for this packet.
*
* @param error the error to associate with this packet.
* @deprecated use {@link #setError(org.jivesoftware.smack.packet.XMPPError.Builder)} instead.
*/
@Deprecated
public void setError(XMPPError error) {
this.error = error;
}
/**
* Sets the error for this stanza.
*
* @param xmppErrorBuilder the error to associate with this stanza.
*/
public void setError(XMPPError.Builder xmppErrorBuilder) {
if (xmppErrorBuilder == null) {
return;
}
xmppErrorBuilder.setStanza(this);
error = xmppErrorBuilder.build();
}
/**
* Returns the xml:lang of this Stanza, or null if one has not been set.
*

View File

@ -1,6 +1,6 @@
/**
*
* Copyright 2003-2007 Jive Software.
* Copyright 2003-2007 Jive Software, 2015 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -22,6 +22,7 @@ import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.XmlStringBuilder;
@ -91,17 +92,37 @@ public class XMPPError extends AbstractError {
CONDITION_TO_TYPE.put(Condition.subscription_required, Type.WAIT);
CONDITION_TO_TYPE.put(Condition.unexpected_request, Type.MODIFY);
}
private final Condition condition;
private final String conditionText;
private final String errorGenerator;
private final Type type;
private final Stanza stanza;
// TODO: Deprecated constructors
// deprecate in 4.3
/**
* Create a new XMPPError.
*
* @param condition
* @deprecated use {@link Builder} instead.
*/
@Deprecated
public XMPPError(Condition condition) {
this(condition, null, null, null, null, null);
this(condition, null, null, null, null, null, null);
}
/**
* Create a new XMPPError.
*
* @param condition
* @param applicationSpecificCondition
* @deprecated use {@link Builder} instead.
*/
@Deprecated
public XMPPError(Condition condition, ExtensionElement applicationSpecificCondition) {
this(condition, null, null, null, null, Arrays.asList(applicationSpecificCondition));
this(condition, null, null, null, null, Arrays.asList(applicationSpecificCondition), null);
}
/**
@ -114,11 +135,31 @@ public class XMPPError extends AbstractError {
* @param condition the error condition.
* @param descriptiveTexts
* @param extensions list of stanza(/packet) extensions
* @deprecated use {@link Builder} instead.
*/
@Deprecated
public XMPPError(Condition condition, String conditionText, String errorGenerator, Type type, Map<String, String> descriptiveTexts,
List<ExtensionElement> extensions) {
this(condition, conditionText, errorGenerator, type, descriptiveTexts, extensions, null);
}
/**
* Creates a new error with the specified type, condition and message.
* This constructor is used when the condition is not recognized automatically by XMPPError
* i.e. there is not a defined instance of ErrorCondition or it does not apply the default
* specification.
*
* @param type the error type.
* @param condition the error condition.
* @param descriptiveTexts
* @param extensions list of stanza(/packet) extensions
* @param stanza the stanza carrying this XMPP error.
*/
public XMPPError(Condition condition, String conditionText, String errorGenerator, Type type, Map<String, String> descriptiveTexts,
List<ExtensionElement> extensions, Stanza stanza) {
super(descriptiveTexts, NAMESPACE, extensions);
this.condition = condition;
this.condition = Objects.requireNonNull(condition, "condition must not be null");
this.stanza = stanza;
// Some implementations may send the condition as non-empty element containing the empty string, that is
// <condition xmlns='foo'></condition>, in this case the parser may calls this constructor with the empty string
// as conditionText, therefore reset it to null if it's the empty string
@ -176,6 +217,16 @@ public class XMPPError extends AbstractError {
return conditionText;
}
/**
* Get the stanza carrying the XMPP error.
*
* @return the stanza carrying the XMPP error.
* @since 4.2
*/
public Stanza getStanza() {
return stanza;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("XMPPError: ");
@ -215,12 +266,81 @@ public class XMPPError extends AbstractError {
return xml;
}
public static XMPPError from(Condition condition, String descriptiveText) {
public static XMPPError.Builder from(Condition condition, String descriptiveText) {
Map<String, String> descriptiveTexts = new HashMap<String, String>();
descriptiveTexts.put("en", descriptiveText);
return new XMPPError(condition, null, null, null, descriptiveTexts, null);
return getBuilder().setCondition(condition).setDescriptiveTexts(descriptiveTexts);
}
public static Builder getBuilder() {
return new Builder();
}
public static Builder getBuilder(Condition condition) {
return getBuilder().setCondition(condition);
}
public static Builder getBuilder(XMPPError xmppError) {
return getBuilder().copyFrom(xmppError);
}
public static final class Builder extends AbstractError.Builder<Builder> {
private Condition condition;
private String conditionText;
private String errorGenerator;
private Type type;
private Stanza stanza;
private Builder() {
}
public Builder setCondition(Condition condition) {
this.condition = condition;
return this;
}
public Builder setType(Type type) {
this.type = type;
return this;
}
public Builder setConditionText(String conditionText) {
this.conditionText = conditionText;
return this;
}
public Builder setErrorGenerator(String errorGenerator) {
this.errorGenerator = errorGenerator;
return this;
}
public Builder setStanza(Stanza stanza) {
this.stanza = stanza;
return this;
}
public Builder copyFrom(XMPPError xmppError) {
setCondition(xmppError.getCondition());
setType(xmppError.getType());
setConditionText(xmppError.getConditionText());
setErrorGenerator(xmppError.getErrorGenerator());
setStanza(xmppError.getStanza());
setDescriptiveTexts(xmppError.descriptiveTexts);
setTextNamespace(xmppError.textNamespace);
setExtensions(xmppError.extensions);
return this;
}
public XMPPError build() {
return new XMPPError(condition, conditionText, errorGenerator, type, descriptiveTexts,
extensions, stanza);
}
@Override
protected Builder getThis() {
return this;
}
}
/**
* A class to represent the type of the Error. The types are:
*

View File

@ -606,7 +606,7 @@ public class PacketParserUtils {
ParserUtils.assertAtStartTag(parser);
final int initialDepth = parser.getDepth();
IQ iqPacket = null;
XMPPError error = null;
XMPPError.Builder error = null;
final String id = parser.getAttributeValue("", "id");
final Jid to = ParserUtils.getJidAttribute(parser, "to");
@ -846,17 +846,16 @@ public class PacketParserUtils {
* @return an error sub-packet.
* @throws Exception
*/
public static XMPPError parseError(XmlPullParser parser)
public static XMPPError.Builder parseError(XmlPullParser parser)
throws Exception {
final int initialDepth = parser.getDepth();
Map<String, String> descriptiveTexts = null;
XMPPError.Condition condition = null;
String conditionText = null;
List<ExtensionElement> extensions = new ArrayList<ExtensionElement>();
XMPPError.Builder builder = XMPPError.getBuilder();
// Parse the error header
XMPPError.Type errorType = XMPPError.Type.fromString(parser.getAttributeValue("", "type"));
String errorGenerator = parser.getAttributeValue("", "by");
builder.setType(XMPPError.Type.fromString(parser.getAttributeValue("", "type")));
builder.setErrorGenerator(parser.getAttributeValue("", "by"));
outerloop: while (true) {
int eventType = parser.next();
@ -871,9 +870,9 @@ public class PacketParserUtils {
descriptiveTexts = parseDescriptiveTexts(parser, descriptiveTexts);
break;
default:
condition = XMPPError.Condition.fromString(name);
builder.setCondition(XMPPError.Condition.fromString(name));
if (!parser.isEmptyElementTag()) {
conditionText = parser.nextText();
builder.setConditionText(parser.nextText());
}
break;
}
@ -888,7 +887,8 @@ public class PacketParserUtils {
}
}
}
return new XMPPError(condition, conditionText, errorGenerator, errorType, descriptiveTexts, extensions);
builder.setExtensions(extensions).setDescriptiveTexts(descriptiveTexts);
return builder;
}
/**

View File

@ -62,7 +62,7 @@ public class IQResponseTest {
*/
@Test
public void testGeneratingValidErrorResponse() throws XmppStringprepException {
final XMPPError error = new XMPPError(XMPPError.Condition.bad_request);
final XMPPError.Builder error = XMPPError.getBuilder(XMPPError.Condition.bad_request);
final IQ request = new TestIQ(ELEMENT, NAMESPACE);
request.setType(IQ.Type.set);
@ -75,7 +75,7 @@ public class IQResponseTest {
assertNotNull(result.getStanzaId());
assertEquals(request.getStanzaId(), result.getStanzaId());
assertEquals(request.getFrom(), result.getTo());
assertEquals(error, result.getError());
assertEquals(error.build().toXML(), result.getError().toXML());
// TODO this test was never valid
// assertEquals(CHILD_ELEMENT, result.getChildElementXML());
}
@ -110,7 +110,7 @@ public class IQResponseTest {
*/
@Test
public void testGeneratingErrorBasedOnError() throws XmppStringprepException {
final XMPPError error = new XMPPError(XMPPError.Condition.bad_request);
final XMPPError.Builder error = XMPPError.getBuilder(XMPPError.Condition.bad_request);
final IQ request = new TestIQ(ELEMENT, NAMESPACE);
request.setType(IQ.Type.error);

View File

@ -444,8 +444,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
* @throws InterruptedException
*/
protected void replyRejectPacket(IQ request) throws NotConnectedException, InterruptedException {
XMPPError xmppError = new XMPPError(XMPPError.Condition.not_acceptable);
IQ error = IQ.createErrorResponse(request, xmppError);
IQ error = IQ.createErrorResponse(request, XMPPError.Condition.not_acceptable);
this.connection.sendStanza(error);
}
@ -458,8 +457,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
* @throws InterruptedException
*/
protected void replyResourceConstraintPacket(IQ request) throws NotConnectedException, InterruptedException {
XMPPError xmppError = new XMPPError(XMPPError.Condition.resource_constraint);
IQ error = IQ.createErrorResponse(request, xmppError);
IQ error = IQ.createErrorResponse(request, XMPPError.Condition.resource_constraint);
this.connection.sendStanza(error);
}
@ -472,8 +470,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
* @throws InterruptedException
*/
protected void replyItemNotFoundPacket(IQ request) throws NotConnectedException, InterruptedException {
XMPPError xmppError = new XMPPError(XMPPError.Condition.item_not_found);
IQ error = IQ.createErrorResponse(request, xmppError);
IQ error = IQ.createErrorResponse(request, XMPPError.Condition.item_not_found);
this.connection.sendStanza(error);
}

View File

@ -457,8 +457,8 @@ public class InBandBytestreamSession implements BytestreamSession {
* check if sequence was not used already (see XEP-0047 Section 2.2)
*/
if (data.getSeq() <= this.lastSequence) {
IQ unexpectedRequest = IQ.createErrorResponse((IQ) packet, new XMPPError(
XMPPError.Condition.unexpected_request));
IQ unexpectedRequest = IQ.createErrorResponse((IQ) packet,
XMPPError.Condition.unexpected_request);
connection.sendStanza(unexpectedRequest);
return;
@ -467,8 +467,8 @@ public class InBandBytestreamSession implements BytestreamSession {
// check if encoded data is valid (see XEP-0047 Section 2.2)
if (data.getDecodedData() == null) {
// data is invalid; respond with bad-request error
IQ badRequest = IQ.createErrorResponse((IQ) packet, new XMPPError(
XMPPError.Condition.bad_request));
IQ badRequest = IQ.createErrorResponse((IQ) packet,
XMPPError.Condition.bad_request);
connection.sendStanza(badRequest);
return;
}

View File

@ -691,7 +691,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
* @throws InterruptedException
*/
protected void replyRejectPacket(IQ packet) throws NotConnectedException, InterruptedException {
XMPPError xmppError = new XMPPError(XMPPError.Condition.not_acceptable);
XMPPError.Builder xmppError = XMPPError.getBuilder(XMPPError.Condition.not_acceptable);
IQ errorIQ = IQ.createErrorResponse(packet, xmppError);
connection().sendStanza(errorIQ);
}

View File

@ -283,10 +283,10 @@ public class Socks5BytestreamRequest implements BytestreamRequest {
*/
private void cancelRequest() throws XMPPErrorException, NotConnectedException, InterruptedException {
String errorMessage = "Could not establish socket with any provided host";
XMPPError error = XMPPError.from(XMPPError.Condition.item_not_found, errorMessage);
XMPPError.Builder error = XMPPError.from(XMPPError.Condition.item_not_found, errorMessage);
IQ errorIQ = IQ.createErrorResponse(this.bytestreamRequest, error);
this.manager.getConnection().sendStanza(errorIQ);
throw new XMPPErrorException(errorMessage, error);
throw new XMPPErrorException(error);
}
/**

View File

@ -451,7 +451,7 @@ public final class AdHocCommandManager extends Manager {
response.setStatus(Status.canceled);
executingCommands.remove(sessionId);
}
return respondError(response, error);
return respondError(response, XMPPError.getBuilder(error));
}
}
else {
@ -561,7 +561,7 @@ public final class AdHocCommandManager extends Manager {
response.setStatus(Status.canceled);
executingCommands.remove(sessionId);
}
return respondError(response, error);
return respondError(response, XMPPError.getBuilder(error));
}
}
}
@ -576,7 +576,7 @@ public final class AdHocCommandManager extends Manager {
*/
private static IQ respondError(AdHocCommandData response,
XMPPError.Condition condition) {
return respondError(response, new XMPPError(condition));
return respondError(response, XMPPError.getBuilder(condition));
}
/**
@ -590,7 +590,7 @@ public final class AdHocCommandManager extends Manager {
private static IQ respondError(AdHocCommandData response, XMPPError.Condition condition,
AdHocCommand.SpecificErrorCondition specificCondition)
{
XMPPError error = new XMPPError(condition, new AdHocCommandData.SpecificError(specificCondition));
XMPPError.Builder error = XMPPError.getBuilder(condition).addExtension(new AdHocCommandData.SpecificError(specificCondition));
return respondError(response, error);
}
@ -601,7 +601,7 @@ public final class AdHocCommandManager extends Manager {
* @param error the error to send.
* @throws NotConnectedException
*/
private static IQ respondError(AdHocCommandData response, XMPPError error) {
private static IQ respondError(AdHocCommandData response, XMPPError.Builder error) {
response.setType(IQ.Type.error);
response.setError(error);
return response;
@ -626,11 +626,11 @@ public final class AdHocCommandManager extends Manager {
command.setNode(commandInfo.getNode());
}
catch (InstantiationException e) {
throw new XMPPErrorException(new XMPPError(
throw new XMPPErrorException(XMPPError.getBuilder(
XMPPError.Condition.internal_server_error));
}
catch (IllegalAccessException e) {
throw new XMPPErrorException(new XMPPError(
throw new XMPPErrorException(XMPPError.getBuilder(
XMPPError.Condition.internal_server_error));
}
return command;

View File

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

View File

@ -143,7 +143,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(new XMPPError(XMPPError.Condition.item_not_found));
response.setError(XMPPError.getBuilder(XMPPError.Condition.item_not_found));
}
return response;
}
@ -181,7 +181,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(new XMPPError(XMPPError.Condition.item_not_found));
response.setError(XMPPError.getBuilder(XMPPError.Condition.item_not_found));
}
}
return response;

View File

@ -169,7 +169,7 @@ public final class FileTransferManager extends Manager {
// Bytestream rejection as specified in XEP-65 5.3.1 Example 13, which says that
// 'not-acceptable' should be returned. This is done by Smack in
// Socks5BytestreamManager.replyRejectPacket(IQ).
IQ rejection = IQ.createErrorResponse(initiation, new XMPPError(
IQ rejection = IQ.createErrorResponse(initiation, XMPPError.getBuilder(
XMPPError.Condition.forbidden));
connection().sendStanza(rejection);
}

View File

@ -192,7 +192,7 @@ public final class FileTransferNegotiator extends Manager {
if (streamMethodField == null) {
String errorMessage = "No stream methods contained in stanza.";
XMPPError error = XMPPError.from(XMPPError.Condition.bad_request, errorMessage);
XMPPError.Builder error = XMPPError.from(XMPPError.Condition.bad_request, errorMessage);
IQ iqPacket = IQ.createErrorResponse(si, error);
connection().sendStanza(iqPacket);
throw new FileTransferException.NoStreamMethodsOfferedException();

View File

@ -36,7 +36,6 @@ import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.packet.XMPPError.Condition;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.iqlast.packet.LastActivity;
@ -169,7 +168,7 @@ public final class LastActivityManager extends Manager {
@Override
public IQ handleIQRequest(IQ iqRequest) {
if (!enabled)
return IQ.createErrorResponse(iqRequest, new XMPPError(Condition.not_acceptable));
return IQ.createErrorResponse(iqRequest, Condition.not_acceptable);
LastActivity message = new LastActivity();
message.setType(IQ.Type.result);
message.setTo(iqRequest.getFrom());

View File

@ -31,7 +31,6 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.packet.XMPPError.Condition;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.iqversion.packet.Version;
@ -89,7 +88,7 @@ public final class VersionManager extends Manager {
@Override
public IQ handleIQRequest(IQ iqRequest) {
if (ourVersion == null) {
return IQ.createErrorResponse(iqRequest, new XMPPError(Condition.not_acceptable));
return IQ.createErrorResponse(iqRequest, Condition.not_acceptable);
}
return Version.createResultFor(iqRequest, ourVersion);

View File

@ -30,7 +30,6 @@ import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.packet.XMPPError.Condition;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.time.packet.Time;
@ -78,7 +77,7 @@ public final class EntityTimeManager extends Manager {
return Time.createResponse(iqRequest);
}
else {
return IQ.createErrorResponse(iqRequest, new XMPPError(Condition.not_acceptable));
return IQ.createErrorResponse(iqRequest, Condition.not_acceptable);
}
}
});

View File

@ -34,10 +34,11 @@ public class IBBPacketUtils {
*
* @param from the senders JID
* @param to the recipients JID
* @param xmppError the XMPP error
* @param condition the XMPP error condition
* @return an error IQ
*/
public static IQ createErrorIQ(Jid from, Jid to, XMPPError xmppError) {
public static IQ createErrorIQ(Jid from, Jid to, XMPPError.Condition condition) {
XMPPError.Builder xmppError = XMPPError.getBuilder(condition);
IQ errorIQ = new ErrorIQ(xmppError);
errorIQ.setType(IQ.Type.error);
errorIQ.setFrom(from);

View File

@ -115,9 +115,8 @@ public class InBandBytestreamManagerTest extends InitExtensions {
InBandBytestreamManager byteStreamManager = InBandBytestreamManager.getByteStreamManager(connection);
try {
XMPPError xmppError = new XMPPError(
IQ errorIQ = IBBPacketUtils.createErrorIQ(targetJID, initiatorJID,
XMPPError.Condition.feature_not_implemented);
IQ errorIQ = IBBPacketUtils.createErrorIQ(targetJID, initiatorJID, xmppError);
protocol.addResponse(errorIQ);
// start In-Band Bytestream

View File

@ -431,11 +431,10 @@ public class Socks5ByteStreamManagerTest {
Verification.requestTypeGET);
// build error packet to reject SOCKS5 Bytestream
XMPPError xmppError = new XMPPError(XMPPError.Condition.not_acceptable);
IQ rejectPacket = new ErrorIQ(xmppError);
XMPPError.Builder builder = XMPPError.getBuilder(XMPPError.Condition.not_acceptable);
IQ rejectPacket = new ErrorIQ(builder);
rejectPacket.setFrom(targetJID);
rejectPacket.setTo(initiatorJID);
rejectPacket.setError(xmppError);
// return error packet as response to the bytestream initiation
protocol.addResponse(rejectPacket, Verification.correspondingSenderReceiver,
@ -450,7 +449,7 @@ public class Socks5ByteStreamManagerTest {
}
catch (XMPPErrorException e) {
protocol.verifyAll();
assertEquals(xmppError, e.getXMPPError());
assertEquals(rejectPacket.getError(), e.getXMPPError());
}
catch (Exception e) {
fail(e.getMessage());

View File

@ -109,7 +109,7 @@ public class Socks5ByteStreamRequestTest {
fail("exception should be thrown");
}
catch (XMPPErrorException e) {
assertTrue(e.getMessage().contains("Could not establish socket with any provided host"));
assertTrue(e.getXMPPError().getDescriptiveText("en").contains("Could not establish socket with any provided host"));
}
// verify targets response
@ -153,7 +153,7 @@ public class Socks5ByteStreamRequestTest {
fail("exception should be thrown");
}
catch (XMPPErrorException e) {
assertTrue(e.getMessage().contains("Could not establish socket with any provided host"));
assertTrue(e.getXMPPError().getDescriptiveText("en").contains("Could not establish socket with any provided host"));
}
// verify targets response
@ -200,7 +200,7 @@ public class Socks5ByteStreamRequestTest {
fail("exception should be thrown");
}
catch (XMPPErrorException e) {
assertTrue(e.getMessage().contains(
assertTrue(e.getXMPPError().getDescriptiveText("en").contains(
"Could not establish socket with any provided host"));
}
@ -291,8 +291,8 @@ public class Socks5ByteStreamRequestTest {
fail("exception should be thrown");
}
catch (XMPPException e) {
assertTrue(e.getMessage().contains(
catch (XMPPErrorException e) {
assertTrue(e.getXMPPError().getDescriptiveText("en").contains(
"Could not establish socket with any provided host"));
}

View File

@ -201,8 +201,7 @@ public class Socks5ClientForInitiatorTest {
public void shouldFailIfActivateSocks5ProxyFails() throws Exception {
// build error response as reply to the stream activation
XMPPError xmppError = new XMPPError(XMPPError.Condition.internal_server_error);
IQ error = new ErrorIQ(xmppError);
IQ error = new ErrorIQ(XMPPError.getBuilder(XMPPError.Condition.internal_server_error));
error.setFrom(proxyJID);
error.setTo(initiatorJID);

View File

@ -62,7 +62,7 @@ public class ConfigureFormTest
Node node = mgr.getNode("princely_musings");
PubSub errorIq = new PubSub();
XMPPError error = new XMPPError(Condition.forbidden);
XMPPError.Builder error = XMPPError.getBuilder(Condition.forbidden);
errorIq.setError(error);
con.addIQReply(errorIq);

View File

@ -54,7 +54,6 @@ import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.packet.XMPPError.Condition;
import org.jivesoftware.smack.roster.SubscribeListener.SubscribeAnswer;
import org.jivesoftware.smack.roster.packet.RosterPacket;
@ -1538,14 +1537,14 @@ public final class Roster extends Manager {
if (from != null && !from.equals(jid)) {
LOGGER.warning("Ignoring roster push with a non matching 'from' ourJid='" + jid + "' from='" + from
+ "'");
return IQ.createErrorResponse(iqRequest, new XMPPError(Condition.service_unavailable));
return IQ.createErrorResponse(iqRequest, Condition.service_unavailable);
}
// A roster push must contain exactly one entry
Collection<Item> items = rosterPacket.getRosterItems();
if (items.size() != 1) {
LOGGER.warning("Ignoring roster push with not exaclty one entry. size=" + items.size());
return IQ.createErrorResponse(iqRequest, new XMPPError(Condition.bad_request));
return IQ.createErrorResponse(iqRequest, Condition.bad_request);
}
Collection<Jid> addedEntries = new ArrayList<>();

View File

@ -1039,13 +1039,11 @@ public class JingleSession extends JingleNegotiator implements MediaReceivedList
IQ errorPacket = null;
if (jingleError != null) {
// TODO This is wrong according to XEP-166 § 10, but this jingle implementation is deprecated anyways
XMPPError error = new XMPPError(XMPPError.Condition.undefined_condition, jingleError);
XMPPError.Builder builder = XMPPError.getBuilder(XMPPError.Condition.undefined_condition);
builder.addExtension(jingleError);
errorPacket = IQ.createErrorResponse(iq, error);
errorPacket = IQ.createErrorResponse(iq, builder);
// Fill in the fields with the info from the Jingle packet
errorPacket.setStanzaId(iq.getStanzaId());
errorPacket.setError(error);
// errorPacket.addExtension(jingleError);
// NO! Let the normal state machinery do all of the sending.

View File

@ -180,7 +180,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
/**
*
*/
private final SynchronizationPoint<XMPPException> compressSyncPoint = new SynchronizationPoint<XMPPException>(
private final SynchronizationPoint<SmackException> compressSyncPoint = new SynchronizationPoint<>(
this, "stream compression");
/**
@ -774,11 +774,11 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
* </p>
*
* @throws NotConnectedException
* @throws XMPPException
* @throws SmackException
* @throws NoResponseException
* @throws InterruptedException
*/
private void maybeEnableCompression() throws NotConnectedException, NoResponseException, XMPPException, InterruptedException {
private void maybeEnableCompression() throws NotConnectedException, NoResponseException, SmackException, InterruptedException {
if (!config.isCompressionEnabled()) {
return;
}
@ -996,14 +996,14 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
case "urn:ietf:params:xml:ns:xmpp-tls":
// TLS negotiation has failed. The server will close the connection
// TODO Parse failure stanza
throw new XMPPErrorException("TLS negotiation has failed", null);
throw new SmackException("TLS negotiation has failed");
case "http://jabber.org/protocol/compress":
// Stream compression has been denied. This is a recoverable
// situation. It is still possible to authenticate and
// use the connection but using an uncompressed connection
// TODO Parse failure stanza
compressSyncPoint.reportFailure(new XMPPErrorException(
"Could not establish compression", null));
compressSyncPoint.reportFailure(new SmackException(
"Could not establish compression"));
break;
case SaslStreamElements.NAMESPACE:
// SASL authentication has failed. The server may close the connection
@ -1042,10 +1042,10 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
if (enabled.isResumeSet()) {
smSessionId = enabled.getId();
if (StringUtils.isNullOrEmpty(smSessionId)) {
XMPPError.Builder builder = XMPPError.getBuilder(XMPPError.Condition.bad_request);
builder.setDescriptiveEnText("Stream Management 'enabled' element with resume attribute but without session id received");
XMPPErrorException xmppException = new XMPPErrorException(
"Stream Management 'enabled' element with resume attribute but without session id received",
new XMPPError(
XMPPError.Condition.bad_request));
builder);
smEnabledSyncPoint.reportFailure(xmppException);
throw xmppException;
}
@ -1061,8 +1061,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
break;
case Failed.ELEMENT:
Failed failed = ParseStreamManagement.failed(parser);
XMPPError xmppError = new XMPPError(failed.getXMPPErrorCondition());
XMPPException xmppException = new XMPPErrorException("Stream Management failed", xmppError);
XMPPError.Builder xmppError = XMPPError.getBuilder(failed.getXMPPErrorCondition());
XMPPException xmppException = new XMPPErrorException(xmppError);
// If only XEP-198 would specify different failure elements for the SM
// enable and SM resume failure case. But this is not the case, so we
// need to determine if this is a 'Failed' response for either 'Enable'